Untitled

 avatar
unknown
kotlin
4 years ago
2.8 kB
7
Indexable
@Singleton
class AccessTokenAuthenticator @Inject constructor(
    private val loginRepository: Lazy<LoginRepository>,
    private val appSharedPreferences: AppSharedPreferences,
    private val accountHelper: AccountHelper,
    private val rxBusWrapper: RxBusWrapper
) : Authenticator {

    override fun authenticate(route: Route?, response: Response): Request? {
        if (response.request().header("UserEndpoint") == null) {
            synchronized(this) {
                return try {
                    val token = loginRepository.get().basicLogin().blockingFirst()
                    requestWithAuthToken(response, token.accessToken)
                } catch (exception: Exception) {
                    when (exception) {
                        is IOException -> null
                        else -> {
                            appSharedPreferences.setAnonToken(null)
                            null
                        }
                    }
                }
            }
        } else {
            if (accountHelper.refreshToken != null) {
                synchronized(this) {
                    return try {
                        val token = loginRepository.get().refreshToken(accountHelper.refreshToken)
                            .blockingFirst()
                        requestWithAuthToken(response, token.accessToken)
                    } catch (exception: Exception) {
                        when (exception) {
                            is IOException -> null
                            is AuthApiException -> {
                                val statusCode = exception.statusCode
                                val errorCodes = listOf(400, 401, 403)
                                if (statusCode in errorCodes) {
                                    val authException: Throwable = AuthException(
                                        "Failed to refresh token, fatal refresh error", exception
                                    )
                                    rxBusWrapper.sendLogoutEvent(authException)
                                }
                                null
                            }
                            else -> null
                        }
                    }
                }
            } else {
                Timber.w("Token can not be refreshed")
                val authException: Throwable = AuthException("No refresh token")
                rxBusWrapper.sendLogoutEvent(authException)
            }

        }

        return null
    }

    private fun requestWithAuthToken(response: Response, token: String?): Request {
        val builder = response.request().newBuilder()
        if (token != null)
            builder.header("Authorization", String.format("Bearer %s", token))
        return builder.build()
    }
}
Editor is loading...