diff --git a/app/config/GuiceModule.scala b/app/config/GuiceModule.scala index abf1ec1..91966af 100644 --- a/app/config/GuiceModule.scala +++ b/app/config/GuiceModule.scala @@ -28,8 +28,7 @@ import uk.gov.hmrc.play.bootstrap.config.ControllerConfig class GuiceModule(val environment: Environment, val configuration: Configuration) extends AbstractModule { override def configure() = { - bind(classOf[AuthConnector]).annotatedWith(Names.named("v1Connector")).to(classOf[AuthConnectorV1]) - bind(classOf[AuthConnector]).to(classOf[AuthConnectorV2]) + bind(classOf[AuthConnector]).to(classOf[AuthConnectorV1]) bind(classOf[HttpClient]).to(classOf[DefaultHttpClient]) bind(classOf[UserInfoService]).annotatedWith(Names.named("live")).to(classOf[LiveUserInfoService]) bind(classOf[UserInfoService]).annotatedWith(Names.named("sandbox")).to(classOf[SandboxUserInfoService]) diff --git a/app/connectors/AuthConnector.scala b/app/connectors/AuthConnector.scala index b3a4933..3fa0524 100644 --- a/app/connectors/AuthConnector.scala +++ b/app/connectors/AuthConnector.scala @@ -77,8 +77,3 @@ import scala.concurrent.{ExecutionContext, Future} class AuthConnectorV1 @Inject() (val appContext: AppContext, val http: CorePost)(implicit val executionContext: ExecutionContext) extends AuthConnector with AuthV1UserDetailsFetcher - -@Singleton -class AuthConnectorV2 @Inject() (val appContext: AppContext, val http: CorePost)(implicit val executionContext: ExecutionContext) - extends AuthConnector - with AuthV2UserDetailsFetcher diff --git a/app/connectors/AuthV2UserDetailsFetcher.scala b/app/connectors/AuthV2UserDetailsFetcher.scala deleted file mode 100644 index 8569361..0000000 --- a/app/connectors/AuthV2UserDetailsFetcher.scala +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2023 HM Revenue & Customs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package connectors - -import uk.gov.hmrc.auth.core.AuthorisedFunctions -import uk.gov.hmrc.auth.core.retrieve.v2.Retrievals -import uk.gov.hmrc.auth.core.retrieve.~ -import uk.gov.hmrc.http.{HeaderCarrier, NotFoundException} -import domain.UserDetails - -import scala.concurrent.{ExecutionContext, Future} - -trait AuthV2UserDetailsFetcher extends UserDetailsFetcher { - self: AuthorisedFunctions => - - def fetchDetails()(implicit hc: HeaderCarrier, ec: ExecutionContext): Future[Option[UserDetails]] = { - authorised() - .retrieve( - Retrievals.allUserDetails and Retrievals.mdtpInformation and Retrievals.gatewayInformation and Retrievals.profile and Retrievals.groupProfile - ) { - case credentials ~ maybeName ~ birthDate ~ postCode ~ email ~ affinityGroup ~ agentCode ~ agentInformation ~ - credentialRole ~ description ~ groupId ~ mdtp ~ gatewayInformation ~ profile ~ groupProfile => - Future.successful( - Some( - UserDetails( - authProviderId = credentials.map(_.providerId), - authProviderType = credentials.map(_.providerType), - name = maybeName.flatMap(_.name), - lastName = maybeName.flatMap(_.lastName), - dateOfBirth = birthDate, - postCode = postCode, - email = email, - affinityGroup = affinityGroup.map(_.toString()), - agentCode = agentCode, - agentFriendlyName = agentInformation.agentFriendlyName, - credentialRole = credentialRole.map(_.toString), - description = description, - groupIdentifier = groupId, - agentId = agentInformation.agentId, - gatewayInformation = gatewayInformation, - mdtpInformation = mdtp, - profile = profile, - groupProfile = groupProfile - ) - ) - ) - case _ => Future.successful(None) - } - .recover { case e: NotFoundException => - None - } - } - -} diff --git a/app/services/UserInfoService.scala b/app/services/UserInfoService.scala index a717cc7..58a59a2 100644 --- a/app/services/UserInfoService.scala +++ b/app/services/UserInfoService.scala @@ -32,7 +32,7 @@ trait UserInfoService { } class LiveUserInfoService @Inject() ( - @Named("v1Connector") v1AuthConnector: AuthConnector, + v1AuthConnector: AuthConnector, userInfoTransformer: UserInfoTransformer, thirdPartyDelegatedAuthorityConnector: ThirdPartyDelegatedAuthorityConnector )(implicit ec: ExecutionContext) diff --git a/it/UserInfoServiceISpec.scala b/it/UserInfoServiceISpec.scala index 94405e4..8de7721 100644 --- a/it/UserInfoServiceISpec.scala +++ b/it/UserInfoServiceISpec.scala @@ -19,7 +19,6 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.github.fge.jsonschema.core.report.LogLevel import com.github.fge.jsonschema.main.JsonSchemaFactory import config.{FeatureSwitch, UserInfoFeatureSwitches} -import controllers.Version_1_1 import domain._ import java.time.LocalDate import play.api.libs.json.Json @@ -380,73 +379,6 @@ class UserInfoServiceISpec extends BaseFeatureISpec with AuthStub with ThirdPart json shouldBe Json.toJson(userInfo_v1) } - Scenario("fetch user profile v2") { - - Given( - "A Auth token with 'openid', 'profile', 'address', 'openid:gov-uk-identifiers', 'openid:hmrc-enrolments', 'openid:mdtp'," + - "'email' and 'openid:government-gateway' scopes" - ) - willReturnScopesForAuthBearerToken( - authBearerToken, - Set( - "openid", - "profile", - "address", - "openid:gov-uk-identifiers", - "openid:hmrc-enrolments", - "openid:government-gateway", - "email", - "agentInformation", - "openid:mdtp" - ) - ) - willAuthoriseWith(200) - - And("The Auth token has a NINO") - willReturnAuthorityWith(Nino(nino)) - - And("The authority has enrolments") - willReturnEnrolmentsWith() - - And("The auth will authorise DES contains user information for the NINO") - willFindUser( - Some(desUserInfo), - Some(AgentInformation(government_gateway_v1.agent_id, government_gateway_v1.agent_code, government_gateway_v1.agent_friendly_name)), - Some(Credentials("1304372065861347", "")), - Some(uk.gov.hmrc.auth.core.retrieve.Name(Some("Bob"), None)), - Some(Email(email)), - Some(AffinityGroup.Individual), - Some(User), - Some(authMdtp), - Some(gatewayInformation), - Some(10), - Some("some_url"), - Some("some_other_url"), - Version_1_1 - ) - - When("We request the user information") - val result = Http(s"$serviceUrl") - .options(HttpOptions.readTimeout(1000000), HttpOptions.connTimeout(1000000)) - .headers(Seq("Authorization" -> s"Bearer $authBearerToken", "Accept" -> "application/vnd.hmrc.1.1+json", "token" -> "ggToken")) - .asString - - val validator = JsonSchemaFactory.byDefault().getValidator - val mapper = new ObjectMapper - val schema = mapper.readTree(Paths.get(getClass.getResource("1.1/schemas/userinfo.json").toURI).toFile) - val json = Json.parse(result.body) - - val report = validator.validate(schema, mapper.readTree(json.toString())) - - Then("The user information is returned") - result.code shouldBe 200 - - import scala.jdk.CollectionConverters._ - assert(report.isSuccess, report.asScala.filter(_.getLogLevel == LogLevel.ERROR).map(m => m)) - - json shouldBe Json.toJson(userInfo_v2) - } - Scenario("fetch user profile without family name") { Given("A Auth token with 'openid', 'profile', 'address', 'openid:gov-uk-identifiers' and 'openid:hmrc-enrolments' scopes") diff --git a/it/stubs/AuthStub.scala b/it/stubs/AuthStub.scala index d5d8a31..34b834d 100644 --- a/it/stubs/AuthStub.scala +++ b/it/stubs/AuthStub.scala @@ -23,7 +23,7 @@ import uk.gov.hmrc.auth.core.retrieve._ import uk.gov.hmrc.auth.core.retrieve.v2.{Retrievals => V2Retrievals} import uk.gov.hmrc.auth.core.{AffinityGroup, CredentialRole} import uk.gov.hmrc.domain.Nino -import controllers.{Version, Version_1_0, Version_1_1} +import controllers.{Version, Version_1_0} import domain.{DesUserInfo, _} import com.github.ghik.silencer.silent @@ -173,31 +173,6 @@ import com.github.ghik.silencer.silent .withStatus(200) ) ) - case Version_1_1 => - stubFor( - post(urlPathEqualTo(s"/auth/authorise")) - .withRequestBody( - equalToJson( - Json - .obj( - "authorise" -> JsArray(), - "retrieve" -> JsArray( - (V2Retrievals.allUserDetails - and V2Retrievals.mdtpInformation - and V2Retrievals.gatewayInformation - and V2Retrievals.profile - and V2Retrievals.groupProfile).propertyNames.map(JsString) - ) - ) - .toString() - ) - ) - .willReturn( - aResponse() - .withBody(v11response.toString()) - .withStatus(200) - ) - ) } stubFor( diff --git a/test/services/UserInfoServiceSpec.scala b/test/services/UserInfoServiceSpec.scala index 70c4278..2c792e2 100644 --- a/test/services/UserInfoServiceSpec.scala +++ b/test/services/UserInfoServiceSpec.scala @@ -93,13 +93,20 @@ class UserInfoServiceSpec extends UnitSpec with MockitoSugar with ScalaFutures { "requests all available data" in new Setup { val scopes = Set("openid", "address", "profile", "openid:gov-uk-identifiers", "openid:hmrc-enrolments", "email", "openid:government-gateway") - given(mockThirdPartyDelegatedAuthorityConnector.fetchScopes(authBearerToken)(headers, implicitly)).willReturn(scopes) - given(mockAuthConnector.fetchAuthority()(headers, implicitly)).willReturn(Some(authority)) - given(mockAuthConnector.fetchEnrolments()(headers, implicitly)).willReturn(Some(enrolments)) - given(mockAuthConnector.fetchDesUserInfo()(headers, implicitly)).willReturn(Some(desUserInfo)) + given(mockThirdPartyDelegatedAuthorityConnector.fetchScopes(eqTo(authBearerToken))(eqTo(headers), any[ExecutionContext])).willReturn(scopes) + given(mockAuthConnector.fetchAuthority()(eqTo(headers), any[ExecutionContext])).willReturn(Some(authority)) + given(mockAuthConnector.fetchEnrolments()(eqTo(headers), any[ExecutionContext])).willReturn(Some(enrolments)) + given(mockAuthConnector.fetchDesUserInfo()(eqTo(headers), any[ExecutionContext])).willReturn(Some(desUserInfo)) when(mockAuthConnector.fetchUserDetails()(eqTo(headers), any[ExecutionContext])).thenReturn(Future.successful(Some(userDetails))) - given(mockUserInfoTransformer.transform(scopes, Some(authority), Some(desUserInfo), Some(enrolments), Some(userDetails))) - .willReturn(any[UserInfo], any[UserInfo]) + given( + mockUserInfoTransformer.transform(eqTo(scopes), + eqTo(Some(authority)), + eqTo(Some(desUserInfo)), + eqTo(Some(enrolments)), + eqTo(Some(userDetails)) + ) + ) + .willReturn(UserInfo()) await(liveInfoService.fetchUserInfo(Version_1_0)) @@ -109,12 +116,11 @@ class UserInfoServiceSpec extends UnitSpec with MockitoSugar with ScalaFutures { verify(mockAuthConnector).fetchUserDetails()(any[HeaderCarrier], any[ExecutionContext]) } - "should fail with BadRequestException when the NINO is not in the authority and a scope that requires a NINO is requested" in new Setup { + "should fail with BadRequestException when the NINO is not in the authority and a scope that requires a NINO is requested UNICORN" in new Setup { val scopes = Set("address", "profile", "openid:gov-uk-identifiers", "openid:hmrc-enrolments") - given(mockThirdPartyDelegatedAuthorityConnector.fetchScopes(authBearerToken)(headers, implicitly)).willReturn(scopes) - given(mockAuthConnector.fetchAuthority()(headers, implicitly)).willReturn(Future(Some(authority.copy(nino = None)))) - given(mockAuthConnector.fetchEnrolments()(headers, implicitly)).willReturn(Future(None)) - when(mockAuthConnector.fetchUserDetails()(eqTo(headers), any[ExecutionContext])).thenReturn(Future.successful(Some(userDetails))) + given(mockThirdPartyDelegatedAuthorityConnector.fetchScopes(eqTo(authBearerToken))(eqTo(headers), any[ExecutionContext])).willReturn(scopes) + given(mockAuthConnector.fetchAuthority()(eqTo(headers), any[ExecutionContext])).willReturn(Future(Some(authority.copy(nino = None)))) + given(mockAuthConnector.fetchEnrolments()(eqTo(headers), any[ExecutionContext])).willReturn(Future(None)) a[BadRequestException] should be thrownBy await(liveInfoService.fetchUserInfo(Version_1_0)) } @@ -122,48 +128,51 @@ class UserInfoServiceSpec extends UnitSpec with MockitoSugar with ScalaFutures { "does not request DES::fetchUserInfo when the scopes does not contain 'address' nor 'profile'" in new Setup { val scopes = Set("openid:gov-uk-identifiers", "openid:hmrc-enrolments") - given(mockThirdPartyDelegatedAuthorityConnector.fetchScopes(authBearerToken)(headers, implicitly)).willReturn(scopes) - given(mockAuthConnector.fetchAuthority()(headers, implicitly)).willReturn(Some(authority)) - given(mockAuthConnector.fetchEnrolments()(headers, implicitly)).willReturn(Future(Some(enrolments))) - given(mockUserInfoTransformer.transform(scopes, Some(authority), None, Some(enrolments), None)).willReturn(any[UserInfo], any[UserInfo]) - given(mockAuthConnector.fetchUserDetails()(headers, implicitly)).willReturn(Future.successful(Some(userDetails))) + given(mockThirdPartyDelegatedAuthorityConnector.fetchScopes(eqTo(authBearerToken))(eqTo(headers), any[ExecutionContext])).willReturn(scopes) + given(mockAuthConnector.fetchAuthority()(eqTo(headers), any[ExecutionContext])).willReturn(Some(authority)) + given(mockAuthConnector.fetchEnrolments()(eqTo(headers), any[ExecutionContext])).willReturn(Future(Some(enrolments))) + given(mockUserInfoTransformer.transform(eqTo(scopes), eqTo(Some(authority)), eqTo(None), eqTo(Some(enrolments)), eqTo(None))) + .willReturn(UserInfo()) await(liveInfoService.fetchUserInfo(Version_1_0)) verify(mockAuthConnector, never).fetchDesUserInfo()(any[HeaderCarrier], any[ExecutionContext]) verify(mockAuthConnector).fetchEnrolments() + verify(mockAuthConnector, never).fetchUserDetails()(any[HeaderCarrier], any[ExecutionContext]) } "does not request AUTH::fetchNino nor DES::fetchUserInfo when the scopes does not contain 'address' nor 'profile' nor 'openid:gov-uk-identifiers'" in new Setup { val scopes = Set("openid:hmrc-enrolments") - given(mockThirdPartyDelegatedAuthorityConnector.fetchScopes(authBearerToken)(headers, implicitly)).willReturn(scopes) + given(mockThirdPartyDelegatedAuthorityConnector.fetchScopes(eqTo(authBearerToken))(eqTo(headers), any[ExecutionContext])).willReturn(scopes) - given(mockAuthConnector.fetchAuthority()(headers, implicitly)).willReturn(Some(authority)) - given(mockAuthConnector.fetchEnrolments()(headers, implicitly)).willReturn(Some(enrolments)) - given(mockUserInfoTransformer.transform(scopes, Some(authority), None, Some(enrolments), None)).willReturn(any[UserInfo], any[UserInfo]) - given(mockAuthConnector.fetchUserDetails()(headers, implicitly)).willReturn(Future.successful(Some(userDetails))) + given(mockAuthConnector.fetchAuthority()(eqTo(headers), any[ExecutionContext])).willReturn(Some(authority)) + given(mockAuthConnector.fetchEnrolments()(eqTo(headers), any[ExecutionContext])).willReturn(Some(enrolments)) + given(mockUserInfoTransformer.transform(eqTo(scopes), eqTo(Some(authority)), eqTo(None), eqTo(Some(enrolments)), eqTo(None))) + .willReturn(UserInfo()) await(liveInfoService.fetchUserInfo(Version_1_0)) verify(mockAuthConnector, never).fetchDesUserInfo()(any[HeaderCarrier], any[ExecutionContext]) verify(mockAuthConnector).fetchEnrolments() + verify(mockAuthConnector, never).fetchUserDetails()(any[HeaderCarrier], any[ExecutionContext]) } "does not request AUTH::fetchEnrolments when the scopes does not contain 'openid:hmrc-enrolments'" in new Setup { val scopes = Set("address", "profile", "openid:gov-uk-identifiers") - given(mockThirdPartyDelegatedAuthorityConnector.fetchScopes(authBearerToken)(headers, implicitly)).willReturn(scopes) + given(mockThirdPartyDelegatedAuthorityConnector.fetchScopes(eqTo(authBearerToken))(eqTo(headers), any[ExecutionContext])).willReturn(scopes) - given(mockAuthConnector.fetchAuthority()(headers, implicitly)).willReturn(Some(authority)) - given(mockAuthConnector.fetchDesUserInfo()(headers, implicitly)).willReturn(None) - given(mockUserInfoTransformer.transform(scopes, Some(authority), None, None, None)).willReturn(any[UserInfo], any[UserInfo]) - given(mockAuthConnector.fetchUserDetails()(headers, implicitly)).willReturn(Future.successful(Some(userDetails))) + given(mockAuthConnector.fetchAuthority()(eqTo(headers), any[ExecutionContext])).willReturn(Some(authority)) + given(mockAuthConnector.fetchDesUserInfo()(eqTo(headers), any[ExecutionContext])).willReturn(None) + given(mockUserInfoTransformer.transform(eqTo(scopes), eqTo(Some(authority)), eqTo(None), eqTo(None), eqTo(None))) + .willReturn(UserInfo()) await(liveInfoService.fetchUserInfo(Version_1_0)) verify(mockAuthConnector, never).fetchEnrolments()(any[HeaderCarrier], any[ExecutionContext]) verify(mockAuthConnector).fetchDesUserInfo()(any[HeaderCarrier], any[ExecutionContext]) + verify(mockAuthConnector, never).fetchUserDetails()(any[HeaderCarrier], any[ExecutionContext]) } }