diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/SubjectReferentialService.kt b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/SubjectReferentialService.kt index 8f53e719a..ba9bbc8dc 100644 --- a/search-service/src/main/kotlin/com/egm/stellio/search/authorization/SubjectReferentialService.kt +++ b/search-service/src/main/kotlin/com/egm/stellio/search/authorization/SubjectReferentialService.kt @@ -39,6 +39,23 @@ class SubjectReferentialService( .bind("groups_memberships", subjectReferential.groupsMemberships?.toTypedArray()) .execute() + @Transactional + suspend fun upsertClient(subjectReferential: SubjectReferential): Either = + 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 = databaseClient .sql( diff --git a/search-service/src/main/kotlin/com/egm/stellio/search/listener/IAMListener.kt b/search-service/src/main/kotlin/com/egm/stellio/search/listener/IAMListener.kt index 348c85ba6..ad68c4960 100644 --- a/search-service/src/main/kotlin/com/egm/stellio/search/listener/IAMListener.kt +++ b/search-service/src/main/kotlin/com/egm/stellio/search/listener/IAMListener.kt @@ -77,6 +77,7 @@ class IAMListener( tenantName: String, entityCreateEvent: EntityCreateEvent ): Either = 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) } @@ -84,13 +85,16 @@ class IAMListener( 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) } diff --git a/search-service/src/test/kotlin/com/egm/stellio/search/authorization/SubjectReferentialServiceTests.kt b/search-service/src/test/kotlin/com/egm/stellio/search/authorization/SubjectReferentialServiceTests.kt index 4ce8b59a2..3fac48ba3 100644 --- a/search-service/src/test/kotlin/com/egm/stellio/search/authorization/SubjectReferentialServiceTests.kt +++ b/search-service/src/test/kotlin/com/egm/stellio/search/authorization/SubjectReferentialServiceTests.kt @@ -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(