diff --git a/Jenkinsfile_CNP b/Jenkinsfile_CNP index 464ffaa082..e46afd244c 100644 --- a/Jenkinsfile_CNP +++ b/Jenkinsfile_CNP @@ -107,6 +107,9 @@ env.ROLE_ASSIGNMENT_API_GATEWAY_S2S_CLIENT_ID = "ccd_data" env.BEFTA_TEST_STUB_SERVICE_BASE_URL = "http://ccd-test-stubs-service-aat.service.core-compute-aat.internal" env.BEFTA_S2S_CLIENT_ID_OF_CCD_DATA = "ccd_data" env.BEFTA_S2S_CLIENT_ID_OF_XUI_WEBAPP = "xui_webapp" +env.OAUTH2_ACCESS_TOKEN_TYPE = "OIDC" // use new OIDC authentication for BEFTA tests +env.OAUTH2_SCOPE_VARIABLES = "profile openid roles" + // BEFTA retry env variables env.BEFTA_RETRY_MAX_ATTEMPTS = "3" env.BEFTA_RETRY_STATUS_CODES = "500,502,503,504" diff --git a/Jenkinsfile_nightly b/Jenkinsfile_nightly index 60d57c4334..21c0162239 100644 --- a/Jenkinsfile_nightly +++ b/Jenkinsfile_nightly @@ -97,6 +97,9 @@ env.ELASTIC_SEARCH_FTA_ENABLED = "true" env.DEFAULT_COLLECTION_ASSERTION_MODE="UNORDERED" env.BEFTA_TEST_STUB_SERVICE_BASE_URL = "http://ccd-test-stubs-service-aat.service.core-compute-aat.internal" env.DEFINITION_STORE_HOST = "http://ccd-definition-store-api-aat.service.core-compute-aat.internal" +env.OAUTH2_ACCESS_TOKEN_TYPE = "OIDC" // use new OIDC authentication for BEFTA tests +env.OAUTH2_SCOPE_VARIABLES = "profile openid roles" + // BEFTA retry env variables env.BEFTA_RETRY_MAX_ATTEMPTS = "3" env.BEFTA_RETRY_STATUS_CODES = "500,502,503,504" diff --git a/build.gradle b/build.gradle index 7a9e1c591d..9ab4fa0ae4 100644 --- a/build.gradle +++ b/build.gradle @@ -42,7 +42,7 @@ ext { elasticVersion = '9.2.4' testContainersVersion = '2.0.5' cucumber = '7.34.3' - beftaFwVersion = '9.2.6' + beftaFwVersion = '9.2.7_CCD-7454-SNAPSHOT1' ccdTestDefinitionVersion = '7.26.4' limits = [ 'instruction': 90, diff --git a/charts/ccd-data-store-api/Chart.yaml b/charts/ccd-data-store-api/Chart.yaml index 107ddcffe7..14a854c346 100644 --- a/charts/ccd-data-store-api/Chart.yaml +++ b/charts/ccd-data-store-api/Chart.yaml @@ -2,7 +2,7 @@ description: Helm chart for the HMCTS CCD Data Store name: ccd-data-store-api apiVersion: v2 home: https://github.com/hmcts/ccd-data-store-api -version: 2.0.41 +version: 2.0.43 maintainers: - name: HMCTS CCD Dev Team email: ccd-devops@HMCTS.NET diff --git a/charts/ccd-data-store-api/values.preview.template.yaml b/charts/ccd-data-store-api/values.preview.template.yaml index f8c1854b9d..046032e77a 100644 --- a/charts/ccd-data-store-api/values.preview.template.yaml +++ b/charts/ccd-data-store-api/values.preview.template.yaml @@ -32,6 +32,7 @@ java: DEFINITION_STORE_HOST: http://${SERVICE_NAME}-ccd-definition-store USER_PROFILE_HOST: http://${SERVICE_NAME}-ccd-user-profile-api ROLE_ASSIGNMENT_URL: http://${SERVICE_NAME}-am-role-assignment-service + IDAM_HMCTS_ACCESS_URL: https://idam-web-public.aat.platform.hmcts.net ELASTIC_SEARCH_ENABLED: true ELASTIC_SEARCH_NODES_DISCOVERY_ENABLED: false ELASTIC_SEARCH_HOSTS: "{{ .Release.Name }}-es-master:9200" @@ -85,7 +86,7 @@ ccd: ccdDefinitionStoreUrl: http://${SERVICE_NAME}-ccd-definition-store ccdUserProfileUrl: http://${SERVICE_NAME}-ccd-user-profile-api dmStoreUrl: http://dm-store-aat.service.core-compute-aat.internal - idamApiUrl: https://idam-api.aat.platform.hmcts.net + idamApiUrl: https://idam-web-public.aat.platform.hmcts.net idamWebUrl: https://idam-web-public.aat.platform.hmcts.net s2sUrl: http://rpe-service-auth-provider-aat.service.core-compute-aat.internal enableKeyVaults: true diff --git a/charts/ccd-data-store-api/values.yaml b/charts/ccd-data-store-api/values.yaml index 5ea78a9432..619ce33126 100644 --- a/charts/ccd-data-store-api/values.yaml +++ b/charts/ccd-data-store-api/values.yaml @@ -74,7 +74,8 @@ java: DEFINITION_STORE_HOST: http://ccd-definition-store-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal USER_PROFILE_HOST: http://ccd-user-profile-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal CCD_DOCUMENT_URL_PATTERN: ^https?://(((?:api-gateway\.preprod\.dm\.reform\.hmcts\.net|dm-store-{{ .Values.global.environment }}\.service\.core-compute-{{ .Values.global.environment }}\.internal(?::\d+)?)\/documents\/[A-Za-z0-9-]+(?:\/binary)?)|(em-hrs-api-{{ .Values.global.environment }}\.service\.core-compute-{{ .Values.global.environment }}\.internal(?::\d+)?\/hearing-recordings\/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\/((segments\/[0-9]+)|(file/\S+)))) - IDAM_API_BASE_URL: https://idam-api.{{ .Values.global.environment }}.platform.hmcts.net + IDAM_API_BASE_URL: https://idam-web-public.{{ .Values.global.environment }}.platform.hmcts.net + IDAM_HMCTS_ACCESS_URL: https://idam-web-public.{{ .Values.global.environment }}.platform.hmcts.net IDAM_OIDC_URL: https://idam-web-public.{{ .Values.global.environment }}.platform.hmcts.net OIDC_ISSUER: https://forgerock-am.service.core-compute-idam-{{ .Values.global.environment }}.internal:8443/openam/oauth2/hmcts CCD_DRAFT_STORE_URL: http://draft-store-service-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal diff --git a/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/IdamApi.java b/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/IdamApi.java index ef0187579d..45d28ce6fa 100644 --- a/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/IdamApi.java +++ b/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/IdamApi.java @@ -10,23 +10,17 @@ public interface IdamApi { - @RequestLine("POST /oauth2/authorize") - @Headers({"Authorization: {authorization}", "Content-Type: application/x-www-form-urlencoded"}) - @Body("response_type={response_type}&redirect_uri={redirect_uri}&client_id={client_id}") - AuthenticateUserResponse authenticateUser(@Param("authorization") String authorization, - @Param("response_type") String responseType, - @Param("client_id") String clientId, - @Param("redirect_uri") String redirectUri); - - @RequestLine("POST /oauth2/token") + @RequestLine("POST /o/token") @Headers("Content-Type: application/x-www-form-urlencoded") - @Body("code={code}&grant_type={grant_type}&client_id={client_id}&client_secret={client_secret}" - + "&redirect_uri={redirect_uri}") - TokenExchangeResponse exchangeCode(@Param("code") String code, - @Param("grant_type") String grantType, + @Body("grant_type={grant_type}&client_id={client_id}&client_secret={client_secret}" + + "&redirect_uri={redirect_uri}&scope={scope}&username={username}&password={password}") + TokenResponse generateOpenIdToken(@Param("grant_type") String grantType, @Param("client_id") String clientId, @Param("client_secret") String clientSecret, - @Param("redirect_uri") String redirectUri); + @Param("redirect_uri") String redirectUri, + @Param("scope") String scope, + @Param("username") String username, + @Param("password") String password); @RequestLine("GET /o/userinfo") @Headers("Authorization: Bearer {access_token}") @@ -41,14 +35,48 @@ public String getCode() { } } - class TokenExchangeResponse { - + class TokenResponse { @JsonProperty("access_token") private String accessToken; + @JsonProperty("expires_in") + private String expiresIn; + + @JsonProperty("id_token") + private String idToken; + + @JsonProperty("refresh_token") + private String refreshToken; + + @JsonProperty("scope") + private String scope; + + @JsonProperty("token_type") + private String tokenType; + public String getAccessToken() { return accessToken; } + + public String getExpiresIn() { + return expiresIn; + } + + public String getIdToken() { + return idToken; + } + + public String getRefreshToken() { + return refreshToken; + } + + public String getScope() { + return scope; + } + + public String getTokenType() { + return tokenType; + } } class IdamUser { diff --git a/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/IdamHelper.java b/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/IdamHelper.java index 5616d34ea8..bc750a05b5 100644 --- a/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/IdamHelper.java +++ b/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/IdamHelper.java @@ -1,6 +1,5 @@ package uk.gov.hmcts.ccd.datastore.tests.helper.idam; -import java.util.Base64; import java.util.HashMap; import java.util.Map; @@ -10,9 +9,7 @@ public class IdamHelper { - private static final String AUTHORIZATION_CODE = "authorization_code"; - private static final String CODE = "code"; - private static final String BASIC = "Basic "; + private static final String GRANT_TYPE = "password"; private final Map users = new HashMap<>(); @@ -37,24 +34,16 @@ public AuthenticatedUser authenticate(String email, String password) { } public String getIdamOauth2Token(String username, String password) { - String authorisation = username + ":" + password; - String base64Authorisation = Base64.getEncoder().encodeToString(authorisation.getBytes()); - - IdamApi.AuthenticateUserResponse authenticateUserResponse = idamApi.authenticateUser( - BASIC + base64Authorisation, - CODE, - oauth2.getClientId(), - oauth2.getRedirectUri() - ); - - IdamApi.TokenExchangeResponse tokenExchangeResponse = idamApi.exchangeCode( - authenticateUserResponse.getCode(), - AUTHORIZATION_CODE, + IdamApi.TokenResponse tokenResponse = idamApi.generateOpenIdToken( + GRANT_TYPE, oauth2.getClientId(), oauth2.getClientSecret(), - oauth2.getRedirectUri() + oauth2.getRedirectUri(), + oauth2.getScope(), + username, + password ); - return tokenExchangeResponse.getAccessToken(); + return tokenResponse.getAccessToken(); } } diff --git a/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/OAuth2.java b/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/OAuth2.java index 8d157e9045..86e43df422 100644 --- a/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/OAuth2.java +++ b/src/aat/java/uk/gov/hmcts/ccd/datastore/tests/helper/idam/OAuth2.java @@ -9,11 +9,13 @@ public enum OAuth2 { private final String clientId; private final String clientSecret; private final String redirectUri; + private final String scope; OAuth2() { clientId = Env.require("CCD_API_GATEWAY_OAUTH2_CLIENT_ID"); clientSecret = Env.require("CCD_API_GATEWAY_OAUTH2_CLIENT_SECRET"); redirectUri = Env.require("CCD_API_GATEWAY_OAUTH2_REDIRECT_URL"); + scope = Env.require("CCD_API_GATEWAY_OAUTH2_SCOPE"); } public String getClientId() { @@ -27,4 +29,8 @@ public String getClientSecret() { public String getRedirectUri() { return redirectUri; } + + public String getScope() { + return scope; + } } diff --git a/src/contractTest/java/uk/gov/hmcts/ccd/v2/external/controller/CasesControllerProviderTest.java b/src/contractTest/java/uk/gov/hmcts/ccd/v2/external/controller/CasesControllerProviderTest.java index 80dd7cbc06..ed6d07b200 100644 --- a/src/contractTest/java/uk/gov/hmcts/ccd/v2/external/controller/CasesControllerProviderTest.java +++ b/src/contractTest/java/uk/gov/hmcts/ccd/v2/external/controller/CasesControllerProviderTest.java @@ -72,8 +72,7 @@ import uk.gov.hmcts.ccd.domain.service.validate.ValidateCaseFieldsOperation; import uk.gov.hmcts.ccd.domain.types.BaseType; import uk.gov.hmcts.ccd.infrastructure.user.UserAuthorisation; -import uk.gov.hmcts.reform.idam.client.models.AuthenticateUserResponse; -import uk.gov.hmcts.reform.idam.client.models.TokenExchangeResponse; +import uk.gov.hmcts.reform.idam.client.models.TokenResponse; import java.io.IOException; import java.io.InputStream; @@ -226,15 +225,10 @@ void before(PactVerificationContext context) throws JsonProcessingException { when(userAuthorisation.getAccessLevel()).thenReturn(UserAuthorisation.AccessLevel.ALL); when(userAuthorisation.getUserId()).thenReturn("userId"); - AuthenticateUserResponse authenticateUserResponse = new AuthenticateUserResponse("200"); + TokenResponse tokenResponse = new TokenResponse("some access token",null, null, null, null, null); - stubFor(WireMock.post(urlMatching("/oauth2/authorize")) - .willReturn(okJson(objectMapper.writeValueAsString(authenticateUserResponse)).withStatus(200))); - - TokenExchangeResponse tokenExchangeResponse = new TokenExchangeResponse("some access token"); - - stubFor(WireMock.post(urlMatching("/oauth2/token")) - .willReturn(okJson(objectMapper.writeValueAsString(tokenExchangeResponse)).withStatus(200))); + stubFor(WireMock.post(urlMatching("/o/token")) + .willReturn(okJson(objectMapper.writeValueAsString(tokenResponse)).withStatus(200))); when(validateCaseFieldsOperation.validateCaseDetails(any())).thenReturn(new HashMap<>()); } diff --git a/src/contractTest/java/uk/gov/hmcts/ccd/v2/external/controller/ContractTestSecurityUtils.java b/src/contractTest/java/uk/gov/hmcts/ccd/v2/external/controller/ContractTestSecurityUtils.java index 0f684e9fc9..ca76201068 100644 --- a/src/contractTest/java/uk/gov/hmcts/ccd/v2/external/controller/ContractTestSecurityUtils.java +++ b/src/contractTest/java/uk/gov/hmcts/ccd/v2/external/controller/ContractTestSecurityUtils.java @@ -1,6 +1,7 @@ package uk.gov.hmcts.ccd.v2.external.controller; import lombok.extern.slf4j.Slf4j; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Primary; @@ -8,16 +9,14 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; + import uk.gov.hmcts.ccd.data.SecurityUtils; import uk.gov.hmcts.ccd.security.idam.IdamRepository; import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; import uk.gov.hmcts.reform.idam.client.IdamApi; -import uk.gov.hmcts.reform.idam.client.models.AuthenticateUserRequest; -import uk.gov.hmcts.reform.idam.client.models.AuthenticateUserResponse; -import uk.gov.hmcts.reform.idam.client.models.ExchangeCodeRequest; -import uk.gov.hmcts.reform.idam.client.models.TokenExchangeResponse; +import uk.gov.hmcts.reform.idam.client.models.TokenRequest; +import uk.gov.hmcts.reform.idam.client.models.TokenResponse; -import java.util.Base64; import java.util.HashMap; @Service @@ -35,9 +34,10 @@ public class ContractTestSecurityUtils extends SecurityUtils { @Value("${auth.provider.client.secret}") private String authClientSecret; - private static final String BASIC = "Basic "; - private static final String AUTHORIZATION_CODE = "authorization_code"; - private static final String CODE = "code"; + @Value("${auth.provider.client.scope}") + private String authScope; + + private static final String GRANT_TYPE = "password"; private HashMap caseTypeUserCredentials = new HashMap<>(); private HashMap eventUserCredentials = new HashMap<>(); @@ -98,29 +98,18 @@ private String getCaseworkerToken(String caseworkerUserName, String caseworkerPa } private String getIdamOauth2Token(String username, String password) { - String basicAuthHeader = getBasicAuthHeader(username, password); log.info("Client ID: {} . Authenticating...", authClientId); - AuthenticateUserResponse authenticateUserResponse = idamClient.authenticateUser( - basicAuthHeader, new AuthenticateUserRequest(CODE, authClientId, authRedirectUrl) + log.info("Authenticated. Exchanging..."); + TokenResponse tokenExchangeResponse = idamClient.generateOpenIdToken( + new TokenRequest(authClientId, authClientSecret, GRANT_TYPE, authRedirectUrl, username, password, authScope, + null, null) ); - log.info("Authenticated. Exchanging..."); - TokenExchangeResponse tokenExchangeResponse = idamClient.exchangeCode( - new ExchangeCodeRequest(authenticateUserResponse.getCode(), - AUTHORIZATION_CODE, - authRedirectUrl, - authClientId, - authClientSecret)); log.info("Getting AccessToken..."); - return tokenExchangeResponse.getAccessToken(); - } - - private String getBasicAuthHeader(String username, String password) { - String authorisation = username + ":" + password; - return BASIC + Base64.getEncoder().encodeToString(authorisation.getBytes()); + return tokenExchangeResponse.accessToken; } class UserCredentials { diff --git a/src/contractTest/resources/application.properties b/src/contractTest/resources/application.properties index 064ab7e8e2..0a0afbb5fd 100644 --- a/src/contractTest/resources/application.properties +++ b/src/contractTest/resources/application.properties @@ -256,6 +256,7 @@ auth.provider.caseworker.password=${CW_PWD} auth.provider.client.redirect=${IDAM_API_REDIRECT_URL:http://localhost:3451/oauth2redirect} auth.provider.client.id=${IDAM_CLIENT_ID:ccd_gateway} auth.provider.client.secret=${AUTH2_CLIENT_SECRET:ccd_gateway_secret} +auth.provider.client.scope=profile openid roles manage-user ccd.callback.log.control=${LOG_CALLBACK_DETAILS:} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 67c9733f40..e51b7c6342 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -90,7 +90,7 @@ document.hash.check.enabled=${HASH_CHECK_ENABLED:false} ccd.documentHashCloneEnabled=${DOCUMENT_HASH_CLONE_ENABLED:true} -idam.api.url=${IDAM_API_BASE_URL:http://localhost:5000} +idam.api.url=${IDAM_HMCTS_ACCESS_URL:http://localhost:5000} # open id spring.security.oauth2.client.provider.oidc.issuer-uri = ${IDAM_OIDC_URL:http://localhost:5000}/o # Dummy oidc client required even though data-store doesn't use