Skip to content

Commit

Permalink
Merge pull request #86 from com-pas/who-claimname
Browse files Browse the repository at this point in the history
Make configurable which claim to use for Who.
  • Loading branch information
Flurb authored Sep 2, 2021
2 parents d65944a + 4363833 commit da25e8a
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 23 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ You can then execute your native executable with: `./app/target/code-with-quarku
If you want to learn more about building native executables, please consult https://quarkus.io/guides/maven-tooling.html
.

## Environment variables

Below environment variable(s) can be used to configure which claims are used to fill user information, for instance Who
in History Record.

| Environment variable | Java Property | Description | Example |
| -------------------------------- | ------------------------------ | --------------------------------------------- | ---------------- |
| USERINFO_WHO_CLAIMNAME | compas.userinfo.who.claimname | The Name of the user used in the Who History. | name |

## Security

To use most of the endpoints the users needs to be authenticated using JWT in the authorization header. There are 4
Expand Down
2 changes: 1 addition & 1 deletion app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ SPDX-License-Identifier: Apache-2.0
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-security</artifactId>
<artifactId>quarkus-test-security-jwt</artifactId>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2021 Alliander N.V.
//
// SPDX-License-Identifier: Apache-2.0
package org.lfenergy.compas.cim.mapping.rest;

import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithName;

@ConfigMapping(prefix = "compas.userinfo")
public interface UserInfoProperties {
@WithName("who.claimname")
String who();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
package org.lfenergy.compas.cim.mapping.rest.v1;

import io.quarkus.security.Authenticated;
import io.quarkus.security.identity.SecurityIdentity;
import org.eclipse.microprofile.jwt.JsonWebToken;
import org.lfenergy.compas.cim.mapping.rest.UserInfoProperties;
import org.lfenergy.compas.cim.mapping.rest.v1.model.MapRequest;
import org.lfenergy.compas.cim.mapping.rest.v1.model.MapResponse;
import org.lfenergy.compas.cim.mapping.service.CompasCimMappingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
Expand All @@ -22,10 +25,15 @@
@RequestScoped
@Path("/cim/v1/")
public class CompasCimMappingResource {
private static final Logger LOGGER = LoggerFactory.getLogger(CompasCimMappingResource.class);

private CompasCimMappingService compasCimMappingService;

@Inject
SecurityIdentity securityIdentity;
JsonWebToken jsonWebToken;

@Inject
UserInfoProperties userInfoProperties;

@Inject
public CompasCimMappingResource(CompasCimMappingService compasCimMappingService) {
Expand All @@ -37,8 +45,11 @@ public CompasCimMappingResource(CompasCimMappingService compasCimMappingService)
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public MapResponse mapCimToScl(@Valid MapRequest request) {
String who = jsonWebToken.getClaim(userInfoProperties.who());
LOGGER.trace("Username used for Who {}", who);

var response = new MapResponse();
response.setScl(compasCimMappingService.map(request.getCimData(), securityIdentity.getPrincipal()));
response.setScl(compasCimMappingService.map(request.getCimData(), who));
return response;
}
}
2 changes: 2 additions & 0 deletions app/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#
# SPDX-License-Identifier: Apache-2.0

compas.userinfo.who.claimname = ${USERINFO_WHO_CLAIMNAME:name}

quarkus.http.cors = false
quarkus.http.root-path = /compas-cim-mapping/
quarkus.http.limits.max-body-size = 150M
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.mockito.InjectMock;
import io.quarkus.test.security.TestSecurity;
import io.quarkus.test.security.jwt.Claim;
import io.quarkus.test.security.jwt.JwtSecurity;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;
import org.lfenergy.compas.cim.mapping.model.CimData;
Expand All @@ -18,7 +20,6 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Principal;
import java.util.List;

import static io.restassured.RestAssured.given;
Expand All @@ -32,6 +33,10 @@
@QuarkusTest
@TestHTTPEndpoint(CompasCimMappingResource.class)
@TestSecurity(user = "test-mapper")
@JwtSecurity(claims = {
// Default the claim "name" is configured for Who, so we will set this claim for the test.
@Claim(key = "name", value = "Test User")
})
class CompasCimMappingResourceTest {
@InjectMock
private CompasCimMappingService compasCimMappingService;
Expand All @@ -47,7 +52,7 @@ void mapCimToScl_WhenCalled_ThenCorrectMessageIsRetrieved() throws IOException {

var scl = new SCL();
scl.setVersion("2007");
when(compasCimMappingService.map(any(), any(Principal.class))).thenReturn(scl);
when(compasCimMappingService.map(any(), eq("Test User"))).thenReturn(scl);

var response = given()
.contentType(ContentType.XML)
Expand All @@ -65,7 +70,7 @@ void mapCimToScl_WhenCalled_ThenCorrectMessageIsRetrieved() throws IOException {
var sclVersion = xmlPath.getString("cms:MapResponse.scl:SCL.@version");
assertNotNull(sclVersion);
assertEquals("2007", sclVersion);
verify(compasCimMappingService, times(1)).map(any(), any(Principal.class));
verify(compasCimMappingService, times(1)).map(any(), eq("Test User"));
}

private String readFile() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
Expand Down Expand Up @@ -43,12 +42,12 @@ public CompasCimMappingService(CgmesCimReader cgmesCimReader,
/**
* Map the passed CIM XML to IEC SCL Model.
*
* @param cimData The CIM XML Data.
* @param principal
* @param cimData The CIM XML Data.
* @param who The name of the user who created the SCL from the CIM Data.
* @return The created SCL Model.
*/
public SCL map(List<CimData> cimData, Principal principal) {
var scl = createBasicSCL(cimData, principal);
public SCL map(List<CimData> cimData, String who) {
var scl = createBasicSCL(cimData, who);

if (cimData != null && !cimData.isEmpty()) {
// Convert the Data to the Network Model from PowSyBl
Expand All @@ -60,11 +59,13 @@ public SCL map(List<CimData> cimData, Principal principal) {
}

/**
* Create a basic SCL Obejct with common values filled.
* Create a basic SCL Object with common values filled.
*
* @param cimData The CIM XML Data.
* @param who The name of the user who created the SCL from the CIM Data.
* @return The created SCL Model.
*/
SCL createBasicSCL(List<CimData> cimData, Principal principal) {
SCL createBasicSCL(List<CimData> cimData, String who) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssXXX");
ObjectFactory factory = new ObjectFactory();

Expand All @@ -87,7 +88,7 @@ SCL createBasicSCL(List<CimData> cimData, Principal principal) {
item.setVersion(INITIAL_VERSION);
item.setRevision(INITIAL_REVISION);
item.setWhen(formatter.format(new Date()));
item.setWho(principal.getName());
item.setWho(who);

// Add all CIM filenames that where used to create the SCL Content.
String what = "SCL created from CIM File(s)";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.security.Principal;
import java.util.Collections;
import java.util.List;

Expand All @@ -27,8 +26,6 @@
class CompasCimMappingServiceTest {
@Mock
private CgmesModel cgmesModel;
@Mock
private Principal principal;

@Mock
private CgmesCimReader cgmesCimReader;
Expand All @@ -43,7 +40,7 @@ void map_WhenCalledWithData_ThenReaderAndMapperAreCalled() {
when(cgmesCimReader.readModel(any())).thenReturn(cgmesModel);

var cimDataList = List.of(new CimData());
var scl = compasCimMappingService.map(cimDataList, principal);
var scl = compasCimMappingService.map(cimDataList, "username");

assertNotNull(scl);
verify(cgmesCimReader, times(1)).readModel(cimDataList);
Expand All @@ -53,15 +50,15 @@ void map_WhenCalledWithData_ThenReaderAndMapperAreCalled() {

@Test
void map_WhenCalledWithoutData_ThenReaderAndMapperAreNotCalled() {
var scl = compasCimMappingService.map(Collections.emptyList(), principal);
var scl = compasCimMappingService.map(Collections.emptyList(), "username");

assertNotNull(scl);
verifyNoInteractions(cgmesCimReader, cimToSclMapper);
}

@Test
void map_WhenCalledWithNullValue_ThenReaderAndMapperAreNotCalled() {
var scl = compasCimMappingService.map(null, principal);
var scl = compasCimMappingService.map(null, "username");

assertNotNull(scl);
verifyNoInteractions(cgmesCimReader, cimToSclMapper);
Expand All @@ -88,9 +85,8 @@ void createBasicSCL_WhenCalledWithNullValue_ThenNewSCLInstanceReturnedWithPartsF

private void createBasicSCL_WhenCalled_ThenExpectedName(List<CimData> cimDataList) {
var expectedName = "Mr. Name";
when(principal.getName()).thenReturn(expectedName);

var scl = compasCimMappingService.createBasicSCL(cimDataList, principal);
var scl = compasCimMappingService.createBasicSCL(cimDataList, expectedName);

assertNotNull(scl);
assertEquals("2007", scl.getVersion());
Expand Down

0 comments on commit da25e8a

Please sign in to comment.