Skip to content

Commit

Permalink
feat(authz): add a special upsert mode for clients
Browse files Browse the repository at this point in the history
  • Loading branch information
bobeal committed Aug 11, 2024
1 parent 130d834 commit 7426cb5
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,23 @@ class SubjectReferentialService(
.bind("groups_memberships", subjectReferential.groupsMemberships?.toTypedArray())
.execute()

@Transactional
suspend fun upsertClient(subjectReferential: SubjectReferential): Either<APIException, Unit> =
databaseClient
.sql(
"""
INSERT INTO subject_referential
(subject_id, subject_type, subject_info)
VALUES (:subject_id, :subject_type, :subject_info)
ON CONFLICT (subject_id)
DO UPDATE SET subject_info = :subject_info
""".trimIndent()
)
.bind("subject_id", subjectReferential.subjectId)
.bind("subject_type", subjectReferential.subjectType.toString())
.bind("subject_info", subjectReferential.subjectInfo)
.execute()

suspend fun retrieve(sub: Sub): Either<APIException, SubjectReferential> =
databaseClient
.sql(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,24 @@ class IAMListener(
tenantName: String,
entityCreateEvent: EntityCreateEvent
): Either<APIException, Unit> = either {
val subjectType = SubjectType.valueOf(entityCreateEvent.entityTypes.first().uppercase())
val operationPayload = entityCreateEvent.operationPayload.deserializeAsMap()
val subjectInfo = operationPayload
.filter { !JSONLD_COMPACTED_ENTITY_CORE_MEMBERS.contains(it.key) }
.toSubjectInfo()
val roles = extractRoles(operationPayload)
val subjectReferential = SubjectReferential(
subjectId = entityCreateEvent.entityId.extractSub(),
subjectType = SubjectType.valueOf(entityCreateEvent.entityTypes.first().uppercase()),
subjectType = subjectType,
subjectInfo = Json.of(subjectInfo),
globalRoles = roles
)

mono {
subjectReferentialService.create(subjectReferential)
if (subjectType == SubjectType.CLIENT)
subjectReferentialService.upsertClient(subjectReferential)
else
subjectReferentialService.create(subjectReferential)
}.writeContextAndSubscribe(tenantName, entityCreateEvent)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,43 @@ class SubjectReferentialServiceTests : WithTimescaleContainer {
}, {})
}

@Test
fun `it should persist a subject referential for a non-existing client`() = runTest {
val subjectReferential = SubjectReferential(
subjectId = serviceAccountUuid,
subjectType = SubjectType.CLIENT,
subjectInfo = getSubjectInfoForClient("client-id", "kc-id")
)

subjectReferentialService.create(subjectReferential)
.fold({
fail("it should have created a subject referential for the client")
}, {})
}

@Test
fun `it should upsert a subject referential for an existing client`() = runTest {
val subjectReferential = SubjectReferential(
subjectId = serviceAccountUuid,
subjectType = SubjectType.CLIENT,
subjectInfo = getSubjectInfoForClient("client-id-updated", "kc-id-updated")
)

subjectReferentialService.create(subjectReferential)
.fold({
fail("it should have created a subject referential for the client")
}, {})

subjectReferentialService.retrieve(serviceAccountUuid)
.shouldSucceedWith {
val subjectInfo = it.getSubjectInfoValue()
assertTrue(subjectInfo.containsKey("clientId"))
assertEquals("client-id-updated", subjectInfo["clientId"])
assertTrue(subjectInfo.containsKey("internalClientId"))
assertEquals("kc-id-updated", subjectInfo["internalClientId"])
}
}

@Test
fun `it should retrieve a subject referential`() = runTest {
val subjectReferential = SubjectReferential(
Expand Down

0 comments on commit 7426cb5

Please sign in to comment.