From 8a3619d9cb784f569eaa13a3380d96f42b76a741 Mon Sep 17 00:00:00 2001 From: this-Aditya Date: Fri, 27 Mar 2026 17:20:25 +0000 Subject: [PATCH 1/8] Use oauth2 by default --- .../java/org/radarbase/authorizer/config/RestSourceClient.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/config/RestSourceClient.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/config/RestSourceClient.kt index 82ec61af..032ebf5d 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/config/RestSourceClient.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/config/RestSourceClient.kt @@ -15,7 +15,7 @@ data class RestSourceClient( val scope: String? = null, val state: String? = null, val usesPkce: Boolean = false, - val oauthVersion: String = "oauth1", + val oauthVersion: String = "oauth2", ) { fun withEnv(): RestSourceClient = this.copyEnv("${sourceType.uppercase(Locale.US)}_CLIENT_ID") { copy(clientId = it) } From b1e3e53a9092fb6dc328f3b3ef8ab65c25a80c7f Mon Sep 17 00:00:00 2001 From: this-Aditya Date: Mon, 30 Mar 2026 15:30:27 +0100 Subject: [PATCH 2/8] Use speicific logger per oauth service --- .../authorizer/service/GarminOAuth2AuthorizationService.kt | 3 +++ .../authorizer/service/OAuth2RestSourceAuthorizationService.kt | 2 +- .../radarbase/authorizer/service/OuraAuthorizationService.kt | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt index 199ae649..2f0845ab 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt @@ -46,6 +46,7 @@ import org.radarbase.jersey.exception.HttpBadGatewayException import org.radarbase.jersey.exception.HttpInternalServerException import org.radarbase.jersey.service.AsyncCoroutineService import org.radarbase.kotlin.coroutines.forkJoin +import org.slf4j.LoggerFactory import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.TimeUnit @@ -252,6 +253,8 @@ class GarminOAuth2AuthorizationService( } companion object { + private val logger = LoggerFactory.getLogger(GarminOAuth2AuthorizationService::class.java) + private const val PKCE_CODE_CHALLENGE_METHOD = "S256" private const val GARMIN_USER_ID_ENDPOINT = "https://apis.garmin.com/wellness-api/rest/user/id" private const val DEREGISTER_CHECK_PERIOD = 3600000L diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth2RestSourceAuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth2RestSourceAuthorizationService.kt index e379e809..16ec72b5 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth2RestSourceAuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth2RestSourceAuthorizationService.kt @@ -141,6 +141,6 @@ open class OAuth2RestSourceAuthorizationService( } companion object { - val logger: Logger = LoggerFactory.getLogger(OAuth2RestSourceAuthorizationService::class.java) + private val logger: Logger = LoggerFactory.getLogger(OAuth2RestSourceAuthorizationService::class.java) } } diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OuraAuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OuraAuthorizationService.kt index b0c8ddf1..e6eabde0 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OuraAuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OuraAuthorizationService.kt @@ -19,6 +19,7 @@ import org.radarbase.authorizer.api.RestOauth2AccessToken import org.radarbase.authorizer.config.AuthorizerConfig import org.radarbase.authorizer.doa.entity.RestSourceUser import org.radarbase.jersey.exception.HttpBadGatewayException +import org.slf4j.LoggerFactory import java.io.IOException class OuraAuthorizationService( @@ -106,6 +107,7 @@ class OuraAuthorizationService( } companion object { + private val logger = LoggerFactory.getLogger(OuraAuthorizationService::class.java) private const val OURA_USER_ID_ENDPOINT = "https://api.ouraring.com/v2/usercollection/personal_info" } } From 79e8b00c6f23719cff206fe389e4d87988591e52 Mon Sep 17 00:00:00 2001 From: this-Aditya Date: Tue, 31 Mar 2026 16:50:46 +0100 Subject: [PATCH 3/8] Simplifying service selection based on oauth2 --- .../enhancer/AuthorizerResourceEnhancer.kt | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt index d2f72533..a24aab34 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt @@ -52,14 +52,8 @@ class AuthorizerResourceEnhancer( }, ) - /** - * Maps a source type to its configured OAuth version (e.g., "oauth1" or "oauth2"). - * This is used to conditionally bind the correct authorization service implementation. - * Configure via the `oauthVersion` field in `authorizer.yml` under each `restSourceClients` entry. - */ - private val sourceTypeOauthMap: Map = config.restSourceClients.associate { - it.sourceType to it.oauthVersion.lowercase() - } + // Bind Garmin service based on configured oauthVersion: "oauth2" → PKCE flow, "oauth1" → legacy flow. + val garminOauthVersion = config.restSourceClients.firstOrNull { it.sourceType == GARMIN_AUTH }?.oauthVersion override val classes: Array> get() = listOfNotNull( @@ -112,8 +106,7 @@ class AuthorizerResourceEnhancer( bind(DelegatedRestSourceAuthorizationService::class.java) .to(RestSourceAuthorizationService::class.java) - // Bind Garmin service based on a configured oauthVersion: "oauth2" → PKCE flow, "oauth1" → legacy flow. - if (sourceTypeOauthMap[GARMIN_AUTH].equals("oauth2", ignoreCase = true)) { + if (garminOauthVersion.equals("oauth2", ignoreCase = true)) { bind(GarminOAuth2AuthorizationService::class.java) .to(RestSourceAuthorizationService::class.java) .named(GARMIN_AUTH) From 1196cd16ebf0a37b348cae5605e50cdc31d4fa6e Mon Sep 17 00:00:00 2001 From: this-Aditya Date: Tue, 31 Mar 2026 19:50:05 +0100 Subject: [PATCH 4/8] Using the overloaded requestAccessToken in auth services --- .../service/DelegatedRestSourceAuthorizationService.kt | 3 +++ .../service/OAuth1RestSourceAuthorizationService.kt | 2 +- .../service/OAuth2RestSourceAuthorizationService.kt | 2 +- .../radarbase/authorizer/service/OuraAuthorizationService.kt | 4 ++-- .../authorizer/service/RestSourceAuthorizationService.kt | 5 ++++- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/DelegatedRestSourceAuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/DelegatedRestSourceAuthorizationService.kt index 332d8321..dd9ce665 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/DelegatedRestSourceAuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/DelegatedRestSourceAuthorizationService.kt @@ -33,6 +33,9 @@ class DelegatedRestSourceAuthorizationService( return provider.get() } + override suspend fun requestAccessToken(payload: RequestTokenPayload, sourceType: String): RestOauth2AccessToken = + delegate(sourceType).requestAccessToken(payload, sourceType) + override suspend fun requestAccessToken(payload: RequestTokenPayload, sourceType: String, token: String?): RestOauth2AccessToken = delegate(sourceType).requestAccessToken(payload, sourceType, token) diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth1RestSourceAuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth1RestSourceAuthorizationService.kt index 834686ef..b40d10f5 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth1RestSourceAuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth1RestSourceAuthorizationService.kt @@ -58,7 +58,7 @@ abstract class OAuth1RestSourceAuthorizationService( ) : RestSourceAuthorizationService { private val httpClient = RestSourceAuthorizationService.httpClient() - override suspend fun requestAccessToken(payload: RequestTokenPayload, sourceType: String, token: String?): RestOauth2AccessToken { + override suspend fun requestAccessToken(payload: RequestTokenPayload, sourceType: String): RestOauth2AccessToken { val authConfig = clientService.forSourceType(sourceType) logger.info("Requesting access token..") diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth2RestSourceAuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth2RestSourceAuthorizationService.kt index 16ec72b5..90cd7d3b 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth2RestSourceAuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OAuth2RestSourceAuthorizationService.kt @@ -48,7 +48,7 @@ open class OAuth2RestSourceAuthorizationService( ) : RestSourceAuthorizationService { protected val httpClient = RestSourceAuthorizationService.httpClient() - override suspend fun requestAccessToken(payload: RequestTokenPayload, sourceType: String, token: String?): RestOauth2AccessToken = withContext(Dispatchers.IO) { + override suspend fun requestAccessToken(payload: RequestTokenPayload, sourceType: String): RestOauth2AccessToken = withContext(Dispatchers.IO) { logger.info("Requesting access token with authorization code") val response = submitForm(sourceType) { authorizationConfig -> payload.code?.let { append("code", it) } diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OuraAuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OuraAuthorizationService.kt index e6eabde0..516a4a6e 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OuraAuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/OuraAuthorizationService.kt @@ -26,8 +26,8 @@ class OuraAuthorizationService( @Context private val clients: RestSourceClientService, @Context private val config: AuthorizerConfig, ) : OAuth2RestSourceAuthorizationService(clients, config) { - override suspend fun requestAccessToken(payload: RequestTokenPayload, sourceType: String, token: String?): RestOauth2AccessToken { - val accessToken: RestOauth2AccessToken = super.requestAccessToken(payload, sourceType, token) + override suspend fun requestAccessToken(payload: RequestTokenPayload, sourceType: String): RestOauth2AccessToken { + val accessToken: RestOauth2AccessToken = super.requestAccessToken(payload, sourceType) return accessToken.copy(externalUserId = getExternalId(accessToken.accessToken)) } diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/RestSourceAuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/RestSourceAuthorizationService.kt index 0a455d04..842814af 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/RestSourceAuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/RestSourceAuthorizationService.kt @@ -31,7 +31,10 @@ import org.radarbase.authorizer.doa.entity.RestSourceUser import kotlin.time.Duration.Companion.seconds interface RestSourceAuthorizationService { - suspend fun requestAccessToken(payload: RequestTokenPayload, sourceType: String, token: String? = null): RestOauth2AccessToken + suspend fun requestAccessToken(payload: RequestTokenPayload, sourceType: String): RestOauth2AccessToken + + suspend fun requestAccessToken(payload: RequestTokenPayload, sourceType: String, token: String?): RestOauth2AccessToken = + requestAccessToken(payload, sourceType) suspend fun refreshToken(user: RestSourceUser): RestOauth2AccessToken? From 394aa80ae5cc7f15b6c17b8b4c598bbe76501d84 Mon Sep 17 00:00:00 2001 From: this-Aditya Date: Tue, 31 Mar 2026 20:33:59 +0100 Subject: [PATCH 5/8] Deriving the usesPkce config --- authorizer-app-backend/authorizer.yml | 3 --- .../enhancer/AuthorizerResourceEnhancer.kt | 14 ++++++++++---- docker/etc/rest-source-authorizer/authorizer.yml | 2 -- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/authorizer-app-backend/authorizer.yml b/authorizer-app-backend/authorizer.yml index 7e0c83ad..4edde83b 100644 --- a/authorizer-app-backend/authorizer.yml +++ b/authorizer-app-backend/authorizer.yml @@ -26,11 +26,9 @@ restSourceClients: clientId: clientSecret: scope: activity heartrate sleep profile - usesPkce: false # Garmin OAuth2 PKCE configuration. # oauthVersion: "oauth2" selects the GarminOAuth2AuthorizationService; # "oauth1" selects the legacy GarminOAuth1AuthorizationService. - # usesPkce: must be true for Garmin OAuth2 (Garmin requires PKCE). - sourceType: Garmin authorizationEndpoint: https://connect.garmin.com/oauth2Confirm tokenEndpoint: https://diauth.garmin.com/di-oauth2-service/oauth/token @@ -38,4 +36,3 @@ restSourceClients: clientId: clientSecret: oauthVersion: oauth2 - usesPkce: true diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt index a24aab34..e694ed5e 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt @@ -46,15 +46,19 @@ class AuthorizerResourceEnhancer( private val restSourceClients = RestSourceClients( config.restSourceClients .map { it.withEnv() } + .map { + if (it.sourceType == GARMIN_AUTH && it.oauthVersion.equals("oauth2", ignoreCase = true)) { + it.copy(usesPkce = true) + } else { + it + } + } .onEach { requireNotNull(it.clientId) { "Client ID of ${it.sourceType} is missing" } requireNotNull(it.clientSecret) { "Client secret of ${it.sourceType} is missing" } }, ) - // Bind Garmin service based on configured oauthVersion: "oauth2" → PKCE flow, "oauth1" → legacy flow. - val garminOauthVersion = config.restSourceClients.firstOrNull { it.sourceType == GARMIN_AUTH }?.oauthVersion - override val classes: Array> get() = listOfNotNull( Filters.cache, @@ -106,7 +110,9 @@ class AuthorizerResourceEnhancer( bind(DelegatedRestSourceAuthorizationService::class.java) .to(RestSourceAuthorizationService::class.java) - if (garminOauthVersion.equals("oauth2", ignoreCase = true)) { + // Bind Garmin service based on configured oauthVersion: "oauth2" → PKCE flow, "oauth1" → legacy flow. + val garminUsesPkce = restSourceClients.clients.firstOrNull { it.sourceType == GARMIN_AUTH }?.usesPkce == true + if (garminUsesPkce) { bind(GarminOAuth2AuthorizationService::class.java) .to(RestSourceAuthorizationService::class.java) .named(GARMIN_AUTH) diff --git a/docker/etc/rest-source-authorizer/authorizer.yml b/docker/etc/rest-source-authorizer/authorizer.yml index 4846e50b..470e5d71 100644 --- a/docker/etc/rest-source-authorizer/authorizer.yml +++ b/docker/etc/rest-source-authorizer/authorizer.yml @@ -39,7 +39,6 @@ restSourceClients: # Garmin OAuth2 PKCE configuration. # oauthVersion: "oauth2" selects the GarminOAuth2AuthorizationService; # "oauth1" selects the legacy GarminOAuth1AuthorizationService. - # usesPkce: must be true for Garmin OAuth2 (Garmin requires PKCE). - sourceType: Garmin authorizationEndpoint: https://connect.garmin.com/oauth2Confirm tokenEndpoint: https://diauth.garmin.com/di-oauth2-service/oauth/token @@ -47,4 +46,3 @@ restSourceClients: clientId: Garmin-clientid clientSecret: Garmin-clientsecret oauthVersion: oauth2 - usesPkce: true \ No newline at end of file From 94ada978fe4cdf883b37bc21d554dc416053d400 Mon Sep 17 00:00:00 2001 From: this-Aditya Date: Tue, 31 Mar 2026 20:43:26 +0100 Subject: [PATCH 6/8] Revoke token only for the authorized user in scheduler --- .../authorizer/service/GarminOAuth2AuthorizationService.kt | 1 + .../authorizer/service/GarminOauth1AuthorizationService.kt | 1 + 2 files changed, 2 insertions(+) diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt index 2f0845ab..ca380bae 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt @@ -226,6 +226,7 @@ class GarminOAuth2AuthorizationService( asyncService.runBlocking { userRepository .queryAllWithElapsedEndDate(GARMIN_AUTH) + .filter { it.authorized } .forkJoin { revokeToken(it) } } } diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOauth1AuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOauth1AuthorizationService.kt index d630d4e3..0cb0604e 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOauth1AuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOauth1AuthorizationService.kt @@ -80,6 +80,7 @@ class GarminOauth1AuthorizationService( asyncService.runBlocking { userRepository .queryAllWithElapsedEndDate(GARMIN_AUTH) + .filter { it.authorized } .forkJoin { revokeToken(it) } } } From 2d73820dbceac7363b3d91986c23d01ca142cc0f Mon Sep 17 00:00:00 2001 From: this-Aditya Date: Tue, 31 Mar 2026 21:02:41 +0100 Subject: [PATCH 7/8] Including original exception stack when fetching external user id --- .../authorizer/service/GarminOAuth2AuthorizationService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt index ca380bae..e8fb7fd7 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/GarminOAuth2AuthorizationService.kt @@ -246,7 +246,7 @@ class GarminOAuth2AuthorizationService( HttpStatusCode.OK -> response.body().userId HttpStatusCode.BadRequest, HttpStatusCode.Unauthorized, HttpStatusCode.Forbidden -> throw HttpBadGatewayException( - "Service was unable to fetch the external ID", + "Unable to fetch external ID (HTTP status ${response.status}): ${response.bodyAsText()}", ) else -> throw HttpBadGatewayException("Cannot connect to ${response.request.url}: HTTP status ${response.status}") From d364ef49c3794673337acbd1403ce457eb8c93a4 Mon Sep 17 00:00:00 2001 From: Pauline Date: Wed, 1 Jul 2026 15:26:27 +0100 Subject: [PATCH 8/8] Minor fixes --- .../authorizer/enhancer/AuthorizerResourceEnhancer.kt | 7 ------- .../authorizer/service/HuaweiAuthorizationService.kt | 5 +++++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt index b9ecc0b8..357381ea 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/enhancer/AuthorizerResourceEnhancer.kt @@ -51,13 +51,6 @@ class AuthorizerResourceEnhancer( private val restSourceClients = RestSourceClients( config.restSourceClients .map { it.withEnv() } - .map { - if (it.sourceType == GARMIN_AUTH && it.oauthVersion.equals("oauth2", ignoreCase = true)) { - it.copy(usesPkce = true) - } else { - it - } - } .onEach { requireNotNull(it.clientId) { "Client ID of ${it.sourceType} is missing" } requireNotNull(it.clientSecret) { "Client secret of ${it.sourceType} is missing" } diff --git a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/HuaweiAuthorizationService.kt b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/HuaweiAuthorizationService.kt index c32a0526..6bcf1cc7 100644 --- a/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/HuaweiAuthorizationService.kt +++ b/authorizer-app-backend/src/main/java/org/radarbase/authorizer/service/HuaweiAuthorizationService.kt @@ -21,6 +21,7 @@ import org.radarbase.authorizer.api.RestOauth2AccessToken import org.radarbase.authorizer.config.AuthorizerConfig import org.radarbase.authorizer.doa.entity.RestSourceUser import org.radarbase.jersey.exception.HttpBadGatewayException +import org.slf4j.LoggerFactory import java.util.Base64 /** @@ -162,6 +163,10 @@ class HuaweiAuthorizationService( } } + companion object { + private val logger = LoggerFactory.getLogger(HuaweiAuthorizationService::class.java) + } + @Serializable private data class HuaweiTokenResponse( @SerialName("access_token") val accessToken: String,