diff --git a/backend/pom.xml b/backend/pom.xml
index 96df1433..c16d35b9 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -162,6 +162,10 @@
h2
test
+
+ org.springframework.security
+ spring-security-test
+
diff --git a/backend/src/main/java/ca/bc/gov/restapi/results/config/SecurityConfig.java b/backend/src/main/java/ca/bc/gov/restapi/results/config/SecurityConfig.java
index f0c2678c..b38e20be 100644
--- a/backend/src/main/java/ca/bc/gov/restapi/results/config/SecurityConfig.java
+++ b/backend/src/main/java/ca/bc/gov/restapi/results/config/SecurityConfig.java
@@ -3,7 +3,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/backend/src/main/java/ca/bc/gov/restapi/results/security/LoggedUserService.java b/backend/src/main/java/ca/bc/gov/restapi/results/security/LoggedUserService.java
index 90f55b6e..7ec5fb97 100644
--- a/backend/src/main/java/ca/bc/gov/restapi/results/security/LoggedUserService.java
+++ b/backend/src/main/java/ca/bc/gov/restapi/results/security/LoggedUserService.java
@@ -78,19 +78,10 @@ public String getLoggedUserIdirOrBceId() {
}
UserInfo userInfo = userInfoOp.get();
- switch (userInfo.identityProvider()) {
- case IDIR:
- {
- return userInfo.idirUsername();
- }
- case BUSINESS_BCEID:
- {
- return userInfo.businessName();
- }
- default:
- {
- return "";
- }
+ if (IdentityProvider.IDIR.equals(userInfo.identityProvider())) {
+ return userInfo.idirUsername();
}
+
+ return userInfo.businessName();
}
}
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index 9e578c39..96bd9c11 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -41,4 +41,8 @@ nr-results-team-email-address = Team.Silva@gov.bc.ca
# Certificate for the Database
ca.bc.gov.nrs.oracle.keystore = ${ORACLEDB_KEYSTORE:jssecacerts-path}
ca.bc.gov.nrs.oracle.secret = ${ORACLEDB_SECRET:changeit}
-ca.bc.gov.nrs.oracle.host = ${DATABASE_HOST}
\ No newline at end of file
+ca.bc.gov.nrs.oracle.host = ${DATABASE_HOST}
+
+# FAM
+spring.security.oauth2.resourceserver.jwt.issuer-uri = ${AWS_COGNITO_ISSUER_URI:aws-cognito-any-url.com}
+spring.security.oauth2.resourceserver.jwt.jwk-set-uri = ${AWS_COGNITO_ISSUER_URI:aws-cognito-any-url.com}/.well-known/jwks.json
diff --git a/backend/src/test/java/ca/bc/gov/restapi/results/endpoint/OpeningEndpointTest.java b/backend/src/test/java/ca/bc/gov/restapi/results/endpoint/OpeningEndpointTest.java
index 515e41b9..856929c8 100644
--- a/backend/src/test/java/ca/bc/gov/restapi/results/endpoint/OpeningEndpointTest.java
+++ b/backend/src/test/java/ca/bc/gov/restapi/results/endpoint/OpeningEndpointTest.java
@@ -21,9 +21,11 @@
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
+import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
@WebMvcTest(OpeningEndpoint.class)
+@WithMockUser(roles = "user_read")
class OpeningEndpointTest {
@Autowired private MockMvc mockMvc;
diff --git a/backend/src/test/java/ca/bc/gov/restapi/results/security/UserAuthenticationHelperTest.java b/backend/src/test/java/ca/bc/gov/restapi/results/security/UserAuthenticationHelperTest.java
new file mode 100644
index 00000000..8299d477
--- /dev/null
+++ b/backend/src/test/java/ca/bc/gov/restapi/results/security/UserAuthenticationHelperTest.java
@@ -0,0 +1,113 @@
+package ca.bc.gov.restapi.results.security;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import java.util.Optional;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.jwt.Jwt;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+class UserAuthenticationHelperTest {
+
+ private UserAuthenticationHelper userAuthenticationHelper;
+
+ @BeforeEach
+ void setup() {
+ userAuthenticationHelper = new UserAuthenticationHelper();
+ }
+
+ @Test
+ @DisplayName("getUserInfoIdirTest")
+ void getUserInfoIdirTest() {
+ Authentication authentication = mock(Authentication.class);
+ SecurityContext securityContext = mock(SecurityContext.class);
+ SecurityContextHolder.setContext(securityContext);
+
+ when(securityContext.getAuthentication()).thenReturn(authentication);
+ when(authentication.isAuthenticated()).thenReturn(true);
+
+ Jwt.Builder builder = Jwt.withTokenValue("myTokenValue");
+ builder.subject("BAGGINGS");
+ builder.header("alg", "HS256");
+ builder.header("typ", "JWT");
+ builder.claim("email", "bilbo.baggings@gov.bc.ca");
+ builder.claim("custom:idp_display_name", "from Baggings, Bilbo LWRS:EX");
+ builder.claim("custom:idp_username", "BAGGINGS");
+ builder.claim("custom:idp_name", "idir");
+ builder.claim("cognito:username", "IDIR@BAGGINGS");
+ builder.claim("client_roles", List.of("admin", "manager"));
+
+ when(authentication.getPrincipal()).thenReturn(builder.build());
+
+ Optional userInfoOptional = userAuthenticationHelper.getUserInfo();
+ Assertions.assertTrue(userInfoOptional.isPresent());
+
+ UserInfo userInfo = userInfoOptional.get();
+ Assertions.assertEquals("IDIR@BAGGINGS", userInfo.id());
+ Assertions.assertEquals("Bilbo", userInfo.firstName());
+ Assertions.assertEquals("Baggings", userInfo.lastName());
+ Assertions.assertEquals("bilbo.baggings@gov.bc.ca", userInfo.email());
+ Assertions.assertEquals("from Baggings, Bilbo LWRS:EX", userInfo.displayName());
+ Assertions.assertEquals("BAGGINGS", userInfo.idirUsername());
+ Assertions.assertEquals(IdentityProvider.IDIR, userInfo.identityProvider());
+ Assertions.assertEquals(2, userInfo.roles().size());
+ }
+
+ @Test
+ @DisplayName("getUserInfoBusinessBceidTest")
+ void getUserInfoBusinessBceidTest() {
+ Authentication authentication = mock(Authentication.class);
+ SecurityContext securityContext = mock(SecurityContext.class);
+ SecurityContextHolder.setContext(securityContext);
+
+ when(securityContext.getAuthentication()).thenReturn(authentication);
+ when(authentication.isAuthenticated()).thenReturn(true);
+
+ Jwt.Builder builder = Jwt.withTokenValue("myTokenValue");
+ builder.subject("MORDOR-BCEID");
+ builder.header("alg", "HS256");
+ builder.header("typ", "JWT");
+ builder.claim("email", "lord.sauron@mordor.middleearth");
+ builder.claim("custom:idp_display_name", "Lord Sauron of Mordor");
+ builder.claim("custom:idp_username", "MORDOR-BCEID");
+ builder.claim("custom:idp_name", "bceidbusiness");
+ builder.claim("cognito:username", "BCEIDBUSINESS@MORDOR-BCEID");
+
+ when(authentication.getPrincipal()).thenReturn(builder.build());
+
+ Optional userInfoOptional = userAuthenticationHelper.getUserInfo();
+ Assertions.assertTrue(userInfoOptional.isPresent());
+
+ UserInfo userInfo = userInfoOptional.get();
+ Assertions.assertEquals("BCEIDBUSINESS@MORDOR-BCEID", userInfo.id());
+ Assertions.assertEquals("Lord", userInfo.firstName());
+ Assertions.assertEquals("Sauron of Mordor", userInfo.lastName());
+ Assertions.assertEquals("lord.sauron@mordor.middleearth", userInfo.email());
+ Assertions.assertEquals("Lord Sauron of Mordor", userInfo.displayName());
+ Assertions.assertEquals("MORDOR-BCEID", userInfo.businessName());
+ Assertions.assertEquals(IdentityProvider.BUSINESS_BCEID, userInfo.identityProvider());
+ }
+
+ @Test
+ @DisplayName("getUserInfoTestNotAuthenticated")
+ void getUserInfoTestNotAuthenticated() {
+ Authentication authentication = mock(Authentication.class);
+ SecurityContext securityContext = mock(SecurityContext.class);
+ SecurityContextHolder.setContext(securityContext);
+
+ when(securityContext.getAuthentication()).thenReturn(authentication);
+
+ Optional userInfoOptional = userAuthenticationHelper.getUserInfo();
+ Assertions.assertFalse(userInfoOptional.isPresent());
+ }
+}
diff --git a/backend/src/test/java/ca/bc/gov/restapi/results/security/UserInfoTest.java b/backend/src/test/java/ca/bc/gov/restapi/results/security/UserInfoTest.java
new file mode 100644
index 00000000..4f7b5fda
--- /dev/null
+++ b/backend/src/test/java/ca/bc/gov/restapi/results/security/UserInfoTest.java
@@ -0,0 +1,142 @@
+package ca.bc.gov.restapi.results.security;
+
+import java.util.Set;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+class UserInfoTest {
+
+ @Test
+ @DisplayName("createUserInfo")
+ void createUserInfo() {
+ UserInfo userInfo =
+ new UserInfo(
+ "123456789@idir",
+ "Bilbo",
+ "Baggings",
+ "bilbo.baggings@gov.bc.ca",
+ "Baggings, Bilbo LWRS:EX",
+ "BAGGINGS",
+ null,
+ IdentityProvider.IDIR,
+ Set.of(),
+ "abcdef123456789");
+
+ Assertions.assertNotNull(userInfo);
+ Assertions.assertEquals("Bilbo", userInfo.firstName());
+ Assertions.assertEquals("Baggings", userInfo.lastName());
+ Assertions.assertEquals("bilbo.baggings@gov.bc.ca", userInfo.email());
+ Assertions.assertEquals("Baggings, Bilbo LWRS:EX", userInfo.displayName());
+ Assertions.assertEquals("BAGGINGS", userInfo.idirUsername());
+ Assertions.assertNull(userInfo.businessName());
+ Assertions.assertEquals(IdentityProvider.IDIR, userInfo.identityProvider());
+ Assertions.assertTrue(userInfo.roles().isEmpty());
+ }
+
+ @Test
+ @DisplayName("createInvalidNullUser")
+ void createInvalidNullUser() {
+ // Id not null
+ Assertions.assertThrows(
+ NullPointerException.class,
+ () -> {
+ new UserInfo(
+ null,
+ "Bilbo",
+ "Baggings",
+ "bilbo.baggings@gov.bc.ca",
+ "Baggings, Bilbo LWRS:EX",
+ "BAGGINGS",
+ null,
+ IdentityProvider.IDIR,
+ Set.of(),
+ "abcdef123456789");
+ });
+
+ // E-mail not null
+ Assertions.assertThrows(
+ NullPointerException.class,
+ () -> {
+ new UserInfo(
+ "123456789@idir",
+ "Bilbo",
+ "Baggings",
+ null,
+ "Baggings, Bilbo LWRS:EX",
+ "BAGGINGS",
+ null,
+ IdentityProvider.IDIR,
+ Set.of(),
+ "abcdef123456789");
+ });
+
+ // Display name not null
+ Assertions.assertThrows(
+ NullPointerException.class,
+ () -> {
+ new UserInfo(
+ "123456789@idir",
+ "Bilbo",
+ "Baggings",
+ "bilbo.baggings@gov.bc.ca",
+ null,
+ "BAGGINGS",
+ null,
+ IdentityProvider.IDIR,
+ Set.of(),
+ "abcdef123456789");
+ });
+
+ // Identity provider not null
+ Assertions.assertThrows(
+ NullPointerException.class,
+ () -> {
+ new UserInfo(
+ "123456789@idir",
+ "Bilbo",
+ "Baggings",
+ "bilbo.baggings@gov.bc.ca",
+ "Baggings, Bilbo LWRS:EX",
+ "BAGGINGS",
+ null,
+ null,
+ Set.of(),
+ "abcdef123456789");
+ });
+
+ // Roles not null
+ Assertions.assertThrows(
+ NullPointerException.class,
+ () -> {
+ new UserInfo(
+ "123456789@idir",
+ "Bilbo",
+ "Baggings",
+ "bilbo.baggings@gov.bc.ca",
+ "Baggings, Bilbo LWRS:EX",
+ "BAGGINGS",
+ null,
+ IdentityProvider.IDIR,
+ null,
+ "abcdef123456789");
+ });
+
+ // Token not null
+ Assertions.assertThrows(
+ NullPointerException.class,
+ () -> {
+ new UserInfo(
+ "123456789@idir",
+ "Bilbo",
+ "Baggings",
+ "bilbo.baggings@gov.bc.ca",
+ "Baggings, Bilbo LWRS:EX",
+ "BAGGINGS",
+ null,
+ IdentityProvider.IDIR,
+ Set.of(),
+ null);
+ });
+ }
+}
diff --git a/backend/src/test/java/ca/bc/gov/restapi/results/security/UserServiceTest.java b/backend/src/test/java/ca/bc/gov/restapi/results/security/UserServiceTest.java
new file mode 100644
index 00000000..9de777bc
--- /dev/null
+++ b/backend/src/test/java/ca/bc/gov/restapi/results/security/UserServiceTest.java
@@ -0,0 +1,168 @@
+package ca.bc.gov.restapi.results.security;
+
+import static org.mockito.Mockito.when;
+
+import ca.bc.gov.restapi.results.exception.UserNotFoundException;
+import java.util.Optional;
+import java.util.Set;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+class UserServiceTest {
+
+ @Mock UserAuthenticationHelper userAuthenticationHelper;
+
+ private LoggedUserService loggedUserService;
+
+ private UserInfo userInfo;
+
+ private UserInfo createUserInfo(boolean isIdir) {
+ IdentityProvider provider = isIdir ? IdentityProvider.IDIR : IdentityProvider.BUSINESS_BCEID;
+
+ return new UserInfo(
+ "123456789@idir",
+ "User",
+ "Test",
+ "user@test.com",
+ "Test, User: LWRS:EX",
+ isIdir ? "USERT" : null,
+ !isIdir ? "user-my-bceid" : null,
+ provider,
+ Set.of(),
+ "abcdef123456789");
+ }
+
+ @BeforeEach
+ void setup() {
+ loggedUserService = new LoggedUserService(userAuthenticationHelper);
+ userInfo = createUserInfo(true);
+ }
+
+ @Test
+ @DisplayName("getLoggedUserEmailTest")
+ void getLoggedUserEmailTest() {
+ when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(userInfo));
+
+ String userEmail = loggedUserService.getLoggedUserEmail();
+
+ Assertions.assertEquals("user@test.com", userEmail);
+ }
+
+ @Test
+ @DisplayName("getLoggedUserEmailExceptionTest")
+ void getLoggedUserEmailExceptionTest() {
+ Exception e =
+ Assertions.assertThrows(
+ UserNotFoundException.class,
+ () -> {
+ loggedUserService.getLoggedUserEmail();
+ });
+
+ Assertions.assertEquals("404 NOT_FOUND \"User not registered!\"", e.getMessage());
+ }
+
+ @Test
+ @DisplayName("getLoggerUserInfoTest")
+ void getLoggerUserInfoTest() {
+ when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(userInfo));
+
+ Optional userInfoOp = loggedUserService.getLoggedUserInfo();
+
+ Assertions.assertTrue(userInfoOp.isPresent());
+ }
+
+ @Test
+ void createUserService() {
+ LoggedUserService loggedUserService1 = new LoggedUserService(userAuthenticationHelper);
+ Assertions.assertNotNull(loggedUserService1);
+ }
+
+ @Test
+ @DisplayName("getLoggedUserTokenTest")
+ void getLoggedUserTokenTest() {
+ when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(userInfo));
+
+ String userToken = loggedUserService.getLoggedUserToken();
+
+ Assertions.assertEquals("abcdef123456789", userToken);
+ }
+
+ @Test
+ @DisplayName("getLoggedUserTokenEmptyTest")
+ void getLoggedUserTokenEmptyTest() {
+ Exception e =
+ Assertions.assertThrows(
+ UserNotFoundException.class,
+ () -> {
+ loggedUserService.getLoggedUserToken();
+ });
+
+ Assertions.assertEquals("404 NOT_FOUND \"User not registered!\"", e.getMessage());
+ }
+
+ @Test
+ @DisplayName("getLoggedUserIdEmptyTest")
+ void getLoggedUserIdEmptyTest() {
+ when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.empty());
+
+ Exception e =
+ Assertions.assertThrows(
+ UserNotFoundException.class,
+ () -> {
+ loggedUserService.getLoggedUserId();
+ });
+
+ Assertions.assertEquals("404 NOT_FOUND \"User not registered!\"", e.getMessage());
+ }
+
+ @Test
+ @DisplayName("getLoggedUserIdSuccessTest")
+ void getLoggedUserIdSuccessTest() {
+ when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(userInfo));
+
+ String userId = loggedUserService.getLoggedUserId();
+
+ Assertions.assertEquals("123456789@idir", userId);
+ }
+
+ @Test
+ @DisplayName("getLoggedUserIdirOrBceIdSuccessTest")
+ void getLoggedUserIdirOrBceIdSuccessTest() {
+ // IDIR
+ UserInfo idirUser = createUserInfo(true);
+ when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(idirUser));
+ String userId = loggedUserService.getLoggedUserIdirOrBceId();
+
+ Assertions.assertFalse(userId.isEmpty());
+ Assertions.assertEquals("USERT", idirUser.idirUsername());
+ Assertions.assertNull(idirUser.businessName());
+
+ // BCeID
+ UserInfo bceIdUser = createUserInfo(false);
+ when(userAuthenticationHelper.getUserInfo()).thenReturn(Optional.of(bceIdUser));
+ userId = loggedUserService.getLoggedUserIdirOrBceId();
+
+ Assertions.assertFalse(userId.isEmpty());
+ Assertions.assertEquals("user-my-bceid", bceIdUser.businessName());
+ Assertions.assertNull(bceIdUser.idirUsername());
+ }
+
+ @Test
+ @DisplayName("getLoggedUserIdirOrBceIdEmptyTest")
+ void getLoggedUserIdirOrBceIdEmptyTest() {
+ Exception e =
+ Assertions.assertThrows(
+ UserNotFoundException.class,
+ () -> {
+ loggedUserService.getLoggedUserIdirOrBceId();
+ });
+
+ Assertions.assertEquals("404 NOT_FOUND \"User not registered!\"", e.getMessage());
+ }
+}
diff --git a/backend/src/test/resources/application.properties b/backend/src/test/resources/application.properties
index b4c6c298..16d57820 100644
--- a/backend/src/test/resources/application.properties
+++ b/backend/src/test/resources/application.properties
@@ -11,3 +11,7 @@ spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.generate-ddl = true
spring.jpa.hibernate.ddl-auto = create-drop
+
+# FAM
+spring.security.oauth2.resourceserver.jwt.issuer-uri = https://aws-cognito-issuer-uri.aws.com
+spring.security.oauth2.resourceserver.jwt.jwk-set-uri = https://aws-cognito-issuer-uri.aws.com/.well-known/jwks.json