-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #213 from guardian/improve-backfill
Improve zuora/salesforce identity id backfill
- Loading branch information
Showing
11 changed files
with
261 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
handlers/identity-backfill/src/main/scala/com/gu/identity/GetByIdentityId.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package com.gu.identity | ||
|
||
import com.gu.identity.GetByIdentityId.RawWireModel.{User, UserResponse} | ||
import com.gu.identityBackfill.salesforce.UpdateSalesforceIdentityId.IdentityId | ||
import com.gu.util.resthttp.HttpOp.HttpOpWrapper | ||
import com.gu.util.resthttp.RestRequestMaker | ||
import com.gu.util.resthttp.RestRequestMaker.{GetRequest, RelativePath} | ||
import com.gu.util.resthttp.Types.{ClientFailableOp, ClientSuccess, GenericError} | ||
import play.api.libs.json.{JsValue, Json, Reads} | ||
|
||
object GetByIdentityId { | ||
|
||
case class IdentityUser(id: IdentityId, hasPassword: Boolean) | ||
|
||
object RawWireModel { | ||
|
||
case class User(id: String, hasPassword: Boolean) | ||
implicit val userReads: Reads[User] = Json.reads[User] | ||
|
||
case class UserResponse(status: String, user: User) | ||
implicit val userResponseReads: Reads[UserResponse] = Json.reads[UserResponse] | ||
|
||
} | ||
|
||
val jsToWireModel: JsValue => ClientFailableOp[UserResponse] = RestRequestMaker.toResult[UserResponse] | ||
|
||
def userFromResponse(userResponse: UserResponse): ClientFailableOp[User] = | ||
userResponse match { | ||
case UserResponse("ok", user) => ClientSuccess(user) | ||
case error => GenericError(s"not an OK response from api: $error") | ||
} | ||
|
||
def wireToDomainModel(userResponse: UserResponse): ClientFailableOp[IdentityUser] = { | ||
for { | ||
user <- userFromResponse(userResponse) | ||
} yield IdentityUser(IdentityId(user.id), user.hasPassword) | ||
} | ||
|
||
val wrapper: HttpOpWrapper[IdentityId, GetRequest, JsValue, IdentityUser] = | ||
HttpOpWrapper[IdentityId, GetRequest, JsValue, IdentityUser]( | ||
fromNewParam = id => GetRequest(RelativePath(s"/user/${id.value}")), | ||
toNewResponse = jsToWireModel.andThen(_.flatMap(wireToDomainModel)) | ||
) | ||
|
||
} |
37 changes: 37 additions & 0 deletions
37
...ers/identity-backfill/src/main/scala/com/gu/identityBackfill/FindExistingIdentityId.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.gu.identityBackfill | ||
|
||
import com.gu.identity.GetByEmail.IdentityAccount | ||
import com.gu.identity.{GetByEmail, GetByIdentityId} | ||
import com.gu.identity.GetByIdentityId.IdentityUser | ||
import com.gu.identityBackfill.Types.EmailAddress | ||
import com.gu.identityBackfill.salesforce.UpdateSalesforceIdentityId.IdentityId | ||
import com.gu.util.apigateway.ApiGatewayResponse | ||
import com.gu.util.reader.Types.ApiGatewayOp | ||
import com.gu.util.reader.Types.ApiGatewayOp.{ContinueProcessing, ReturnWithResponse} | ||
import com.gu.util.resthttp.Types.{ClientFailableOp, ClientFailure, ClientSuccess, NotFound} | ||
|
||
object FindExistingIdentityId { | ||
|
||
def apply( | ||
getByEmail: EmailAddress => ClientFailableOp[GetByEmail.IdentityAccount], | ||
getByIdentityId: IdentityId => ClientFailableOp[GetByIdentityId.IdentityUser] | ||
)(emailAddress: EmailAddress): ApiGatewayOp[Option[IdentityId]] = { | ||
|
||
def continueIfNoPassword(identityId: IdentityId) = { | ||
getByIdentityId(identityId) match { | ||
case ClientSuccess(IdentityUser(_, false)) => ContinueProcessing(Some(identityId)) | ||
case _ => ReturnWithResponse(ApiGatewayResponse.notFound(s"identity email not validated but password is set $identityId")) | ||
} | ||
} | ||
|
||
val result = getByEmail(emailAddress) match { | ||
case ClientSuccess(IdentityAccount(identityId, true)) => ContinueProcessing(Some(identityId)) | ||
case ClientSuccess(IdentityAccount(identityId, false)) => continueIfNoPassword(identityId) | ||
case NotFound(_) => ContinueProcessing(None) | ||
case other: ClientFailure => ReturnWithResponse(ApiGatewayResponse.internalServerError(other.toString)) | ||
} | ||
|
||
result.withLogging("FindExistingIdentityId") | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
handlers/identity-backfill/src/test/scala/com/gu/identity/GetByIdentityIdEffectsTest.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.gu.identity | ||
|
||
import com.gu.effects.{GetFromS3, RawEffects} | ||
import com.gu.identity.GetByIdentityId.IdentityUser | ||
import com.gu.identityBackfill.salesforce.UpdateSalesforceIdentityId.IdentityId | ||
import com.gu.test.EffectsTest | ||
import com.gu.util.config.{LoadConfigModule, Stage} | ||
import com.gu.util.resthttp.JsonHttp | ||
import org.scalatest.{FlatSpec, Matchers} | ||
import scalaz.\/- | ||
|
||
// run this manually | ||
class GetByIdentityIdEffectsTest extends FlatSpec with Matchers { | ||
|
||
it should "successfull run the health check using the local code against real backend" taggedAs EffectsTest in { | ||
|
||
val actual = for { | ||
identityConfig <- LoadConfigModule(Stage("DEV"), GetFromS3.fetchString)[IdentityConfig] | ||
|
||
response = RawEffects.response | ||
identityClient = IdentityClient(response, identityConfig) | ||
getByIdentityId = identityClient.wrapWith(JsonHttp.get).wrapWith(GetByIdentityId.wrapper) | ||
identityId <- getByIdentityId.runRequest(IdentityId("21814163")).toDisjunction | ||
} yield identityId | ||
actual should be(\/-(IdentityUser(IdentityId("21814163"), hasPassword = true))) | ||
|
||
} | ||
|
||
} |
44 changes: 44 additions & 0 deletions
44
handlers/identity-backfill/src/test/scala/com/gu/identity/GetByIdentityIdTest.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package com.gu.identity | ||
|
||
import com.gu.identity.GetByIdentityId.IdentityUser | ||
import com.gu.identityBackfill.salesforce.UpdateSalesforceIdentityId.IdentityId | ||
import com.gu.util.resthttp.RestRequestMaker.{GetRequest, RelativePath} | ||
import com.gu.util.resthttp.Types.ClientSuccess | ||
import org.scalatest.{FlatSpec, Matchers} | ||
import play.api.libs.json.Json | ||
|
||
class GetByIdentityIdTest extends FlatSpec with Matchers { | ||
it should "formulate a request" in { | ||
GetByIdentityId.wrapper.fromNewParam(IdentityId("1234")) should be(GetRequest(RelativePath("/user/1234"))) | ||
} | ||
|
||
it should "extract user with password" in { | ||
val identityResponse: String = | ||
""" | ||
|{ | ||
| "status": "ok", | ||
| "user": { | ||
| "id": "1234", | ||
| "hasPassword": true | ||
| } | ||
|} | ||
""".stripMargin | ||
val actual = GetByIdentityId.wrapper.toNewResponse(Json.parse(identityResponse)) | ||
actual should be(ClientSuccess(IdentityUser(IdentityId("1234"), hasPassword = true))) | ||
} | ||
|
||
it should "extract user without password" in { | ||
val identityResponse: String = | ||
""" | ||
|{ | ||
| "status": "ok", | ||
| "user": { | ||
| "id": "1234", | ||
| "hasPassword": false | ||
| } | ||
|} | ||
""".stripMargin | ||
val actual = GetByIdentityId.wrapper.toNewResponse(Json.parse(identityResponse)) | ||
actual should be(ClientSuccess(IdentityUser(IdentityId("1234"), hasPassword = false))) | ||
} | ||
} |
Oops, something went wrong.