Skip to content
Merged
1 change: 0 additions & 1 deletion authorizer-app-backend/authorizer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ restSourceClients:
clientId: <CLIENT_ID>
clientSecret: <CLIENT_SECRET>
scope: activity heartrate sleep profile

- sourceType: Huawei
authorizationEndpoint: https://oauth-login.cloud.huawei.com/oauth2/v2/authorize
tokenEndpoint: https://oauth-login.cloud.huawei.com/oauth2/v3/token
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -225,6 +226,7 @@ class GarminOAuth2AuthorizationService(
asyncService.runBlocking {
userRepository
.queryAllWithElapsedEndDate(GARMIN_AUTH)
.filter { it.authorized }
.forkJoin { revokeToken(it) }
}
}
Expand All @@ -244,14 +246,16 @@ class GarminOAuth2AuthorizationService(
HttpStatusCode.OK -> response.body<RestOauth2UserId>().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}")
}
}

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class GarminOauth1AuthorizationService(
asyncService.runBlocking {
userRepository
.queryAllWithElapsedEndDate(GARMIN_AUTH)
.filter { it.authorized }
.forkJoin { revokeToken(it) }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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..")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
Expand Down Expand Up @@ -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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ 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(
@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))
}

Expand Down Expand Up @@ -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"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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?

Expand Down
Loading