mirror of
https://github.com/bitwarden/android.git
synced 2026-03-11 20:54:58 -05:00
[PM-20306] Migrate Auth Token Interceptor (#5065)
This commit is contained in:
@@ -2,8 +2,10 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android.library)
|
||||
alias(libs.plugins.hilt)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
alias(libs.plugins.ksp)
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -46,6 +48,8 @@ dependencies {
|
||||
implementation(project(":core"))
|
||||
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.google.hilt.android)
|
||||
ksp(libs.google.hilt.compiler)
|
||||
implementation(libs.kotlinx.serialization)
|
||||
implementation(libs.square.okhttp)
|
||||
implementation(libs.square.okhttp.logging)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.bitwarden.network.interceptor
|
||||
|
||||
import com.bitwarden.network.util.HEADER_KEY_AUTHORIZATION
|
||||
import com.bitwarden.network.util.HEADER_VALUE_BEARER_PREFIX
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import java.io.IOException
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Interceptor responsible for adding the auth token(Bearer) to API requests.
|
||||
*/
|
||||
@Singleton
|
||||
class AuthTokenInterceptor(
|
||||
private val authTokenProvider: AuthTokenProvider,
|
||||
) : Interceptor {
|
||||
private val missingTokenMessage = "Auth token is missing!"
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val token = authTokenProvider.getActiveAccessTokenOrNull()
|
||||
?: throw IOException(IllegalStateException(missingTokenMessage))
|
||||
val request = chain
|
||||
.request()
|
||||
.newBuilder()
|
||||
.addHeader(
|
||||
name = HEADER_KEY_AUTHORIZATION,
|
||||
value = "${HEADER_VALUE_BEARER_PREFIX}$token",
|
||||
)
|
||||
.build()
|
||||
return chain
|
||||
.proceed(request)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.bitwarden.network.interceptor
|
||||
|
||||
/**
|
||||
* A provider for all the functionality needed to properly refresh the users access token.
|
||||
*/
|
||||
interface AuthTokenProvider {
|
||||
|
||||
/**
|
||||
* The currently active user's access token.
|
||||
*/
|
||||
fun getActiveAccessTokenOrNull(): String?
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.bitwarden.network.interceptor
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import okhttp3.Request
|
||||
import org.junit.Assert.assertThrows
|
||||
import org.junit.Test
|
||||
import java.io.IOException
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class AuthTokenInterceptorTest {
|
||||
private val mockAuthTokenProvider = mockk<AuthTokenProvider> {
|
||||
every { getActiveAccessTokenOrNull() } returns null
|
||||
}
|
||||
private val interceptor: AuthTokenInterceptor = AuthTokenInterceptor(
|
||||
authTokenProvider = mockAuthTokenProvider,
|
||||
)
|
||||
private val request: Request = Request
|
||||
.Builder()
|
||||
.url("http://localhost")
|
||||
.build()
|
||||
|
||||
@Test
|
||||
fun `intercept should add the auth token when set`() {
|
||||
every { mockAuthTokenProvider.getActiveAccessTokenOrNull() } returns ACCESS_TOKEN
|
||||
|
||||
val response = interceptor.intercept(
|
||||
chain = FakeInterceptorChain(request = request),
|
||||
)
|
||||
assertEquals(
|
||||
"Bearer $ACCESS_TOKEN",
|
||||
response.request.header("Authorization"),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `intercept should throw an exception when an auth token is missing`() {
|
||||
val throwable = assertThrows(IOException::class.java) {
|
||||
interceptor.intercept(
|
||||
chain = FakeInterceptorChain(request = request),
|
||||
)
|
||||
}
|
||||
assertEquals(
|
||||
"Auth token is missing!",
|
||||
throwable.cause?.message,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private const val ACCESS_TOKEN: String = "access_token"
|
||||
Reference in New Issue
Block a user