From 4d3b5784bba39efeb7b3a135ed0a5234ee921da7 Mon Sep 17 00:00:00 2001 From: Amir Rajabi Date: Mon, 28 Jul 2025 17:38:56 +0330 Subject: [PATCH 1/2] Add internal ID generator for Keycloak user creation --- .../co/nilin/opex/auth/proxy/KeycloakProxy.kt | 22 ++++++++++++++++--- .../opex/auth/utils/InternalIdGenerator.kt | 9 ++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/utils/InternalIdGenerator.kt diff --git a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/proxy/KeycloakProxy.kt b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/proxy/KeycloakProxy.kt index eb3a0cc42..fdab3deaa 100644 --- a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/proxy/KeycloakProxy.kt +++ b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/proxy/KeycloakProxy.kt @@ -2,6 +2,7 @@ package co.nilin.opex.auth.proxy import co.nilin.opex.auth.config.KeycloakConfig import co.nilin.opex.auth.model.* +import co.nilin.opex.auth.utils.generateRandomID import co.nilin.opex.common.OpexError import co.nilin.opex.common.utils.LoggerDelegate import kotlinx.coroutines.reactive.awaitFirstOrElse @@ -13,7 +14,10 @@ import org.springframework.http.HttpHeaders import org.springframework.http.HttpStatus import org.springframework.http.MediaType import org.springframework.stereotype.Service -import org.springframework.web.reactive.function.client.* +import org.springframework.web.reactive.function.client.WebClient +import org.springframework.web.reactive.function.client.awaitBodilessEntity +import org.springframework.web.reactive.function.client.awaitBody +import org.springframework.web.reactive.function.client.bodyToMono @Service class KeycloakProxy( @@ -146,14 +150,14 @@ class KeycloakProxy( ) { val keycloakUrl = "${keycloakConfig.url}/admin/realms/${keycloakConfig.realm}/users" val token = getAdminAccessToken() - + val internalID = generateRandomInternalID() val response = keycloakClient.post() .uri(keycloakUrl) .header("Content-Type", "application/json") .withAdminToken(token) .bodyValue( hashMapOf( - "username" to username.value, + "username" to internalID, "emailVerified" to enabled, "firstName" to firstName, "lastName" to lastName, @@ -305,4 +309,16 @@ class KeycloakProxy( return this } + private suspend fun generateRandomInternalID(): String { + var internalId: String; + var attempts = 0 + do { + if (attempts >= 20) { + throw OpexError.InternalServerError.exception("Couldn't generate unique internalId after 20 attempts") + } + internalId = generateRandomID() + attempts++ + } while (findUserByAttribute(Attribute("username", internalId)).isNotEmpty()) + return internalId + } } \ No newline at end of file diff --git a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/utils/InternalIdGenerator.kt b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/utils/InternalIdGenerator.kt new file mode 100644 index 000000000..5ea735977 --- /dev/null +++ b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/utils/InternalIdGenerator.kt @@ -0,0 +1,9 @@ +package co.nilin.opex.auth.utils + +fun generateRandomID(length: Int = 8): String { + val charset = ('0'..'9') + ('A'..'Z') + return (1..length) + .map { charset.random() } + .joinToString("") +} + From e602e6f23f6dcf3464633bf54883259ca8643da9 Mon Sep 17 00:00:00 2001 From: Amir Rajabi Date: Tue, 29 Jul 2025 15:46:27 +0330 Subject: [PATCH 2/2] some improvement --- .../src/main/kotlin/co/nilin/opex/auth/proxy/KeycloakProxy.kt | 4 ++-- .../kotlin/co/nilin/opex/auth/utils/InternalIdGenerator.kt | 2 +- common/src/main/kotlin/co/nilin/opex/common/OpexError.kt | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/proxy/KeycloakProxy.kt b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/proxy/KeycloakProxy.kt index fdab3deaa..b6403ac9d 100644 --- a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/proxy/KeycloakProxy.kt +++ b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/proxy/KeycloakProxy.kt @@ -313,8 +313,8 @@ class KeycloakProxy( var internalId: String; var attempts = 0 do { - if (attempts >= 20) { - throw OpexError.InternalServerError.exception("Couldn't generate unique internalId after 20 attempts") + if (attempts >= 10) { + throw OpexError.InternalIdGenerateFailed.exception() } internalId = generateRandomID() attempts++ diff --git a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/utils/InternalIdGenerator.kt b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/utils/InternalIdGenerator.kt index 5ea735977..558d874f6 100644 --- a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/utils/InternalIdGenerator.kt +++ b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/utils/InternalIdGenerator.kt @@ -1,7 +1,7 @@ package co.nilin.opex.auth.utils fun generateRandomID(length: Int = 8): String { - val charset = ('0'..'9') + ('A'..'Z') + val charset = ('0'..'9') + ('a'..'z') return (1..length) .map { charset.random() } .joinToString("") diff --git a/common/src/main/kotlin/co/nilin/opex/common/OpexError.kt b/common/src/main/kotlin/co/nilin/opex/common/OpexError.kt index 33b7e7711..85362b0b9 100644 --- a/common/src/main/kotlin/co/nilin/opex/common/OpexError.kt +++ b/common/src/main/kotlin/co/nilin/opex/common/OpexError.kt @@ -50,6 +50,7 @@ enum class OpexError(val code: Int, val message: String?, val status: HttpStatus InvalidUserCredentials(5015, "Invalid user credentials", HttpStatus.BAD_REQUEST), InvalidRegisterToken(5016, "Invalid register token", HttpStatus.BAD_REQUEST), ExpiredOTP(5017, "OTP is expired", HttpStatus.BAD_REQUEST), + InternalIdGenerateFailed(5018, "Internal id generate failed", HttpStatus.INTERNAL_SERVER_ERROR), // code 6000: wallet