Skip to content

Commit a0a9a43

Browse files
committed
[#228] Add TokenAuthenticator to template-xml
1 parent 66b5f5d commit a0a9a43

File tree

17 files changed

+314
-15
lines changed

17 files changed

+314
-15
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package co.nimblehq.template.xml.di
2+
3+
import javax.inject.Qualifier
4+
5+
@Qualifier
6+
@Retention(AnnotationRetention.BINARY)
7+
annotation class Authenticate
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package co.nimblehq.template.xml.di.modules
2+
3+
import co.nimblehq.template.xml.data.repository.SessionManagerImpl
4+
import co.nimblehq.template.xml.data.repository.TokenRefresherImpl
5+
import co.nimblehq.template.xml.data.service.AuthService
6+
import co.nimblehq.template.xml.data.service.SessionManager
7+
import co.nimblehq.template.xml.data.service.authenticator.TokenRefresher
8+
import dagger.Module
9+
import dagger.Provides
10+
import dagger.hilt.InstallIn
11+
import dagger.hilt.components.SingletonComponent
12+
13+
@Module
14+
@InstallIn(SingletonComponent::class)
15+
class AuthModule {
16+
17+
@Provides
18+
fun provideAuthService(authService: AuthService): TokenRefresher = TokenRefresherImpl(authService)
19+
20+
@Provides
21+
fun provideSessionManager(): SessionManager = SessionManagerImpl()
22+
}

template-xml/app/src/main/java/co/nimblehq/template/xml/di/modules/OkHttpClientModule.kt

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ package co.nimblehq.template.xml.di.modules
22

33
import android.content.Context
44
import co.nimblehq.template.xml.BuildConfig
5+
import co.nimblehq.template.xml.data.service.SessionManager
6+
import co.nimblehq.template.xml.data.service.authenticator.ApplicationRequestAuthenticator
7+
import co.nimblehq.template.xml.data.service.authenticator.TokenRefresher
8+
import co.nimblehq.template.xml.di.Authenticate
59
import com.chuckerteam.chucker.api.*
610
import dagger.Module
711
import dagger.Provides
@@ -20,16 +24,42 @@ class OkHttpClientModule {
2024

2125
@Provides
2226
fun provideOkHttpClient(
23-
chuckerInterceptor: ChuckerInterceptor
24-
) = OkHttpClient.Builder().apply {
25-
if (BuildConfig.DEBUG) {
26-
addInterceptor(HttpLoggingInterceptor().apply {
27-
level = HttpLoggingInterceptor.Level.BODY
28-
})
29-
addInterceptor(chuckerInterceptor)
30-
readTimeout(READ_TIME_OUT, TimeUnit.SECONDS)
31-
}
32-
}.build()
27+
chuckerInterceptor: ChuckerInterceptor,
28+
sessionManager: SessionManager,
29+
tokenRefresher: TokenRefresher?
30+
): OkHttpClient {
31+
val authenticator =
32+
tokenRefresher?.let { ApplicationRequestAuthenticator(it, sessionManager) }
33+
return OkHttpClient.Builder()
34+
.apply {
35+
if (BuildConfig.DEBUG) {
36+
addInterceptor(HttpLoggingInterceptor().apply {
37+
level = HttpLoggingInterceptor.Level.BODY
38+
})
39+
addInterceptor(chuckerInterceptor)
40+
readTimeout(READ_TIME_OUT, TimeUnit.SECONDS)
41+
}
42+
}
43+
.build()
44+
.apply { authenticator?.okHttpClient = this }
45+
46+
}
47+
48+
@Authenticate
49+
@Provides
50+
fun provideAuthOkHttpClient(chuckerInterceptor: ChuckerInterceptor): OkHttpClient {
51+
return OkHttpClient.Builder()
52+
.apply {
53+
if (BuildConfig.DEBUG) {
54+
addInterceptor(HttpLoggingInterceptor().apply {
55+
level = HttpLoggingInterceptor.Level.BODY
56+
})
57+
addInterceptor(chuckerInterceptor)
58+
readTimeout(READ_TIME_OUT, TimeUnit.SECONDS)
59+
}
60+
}
61+
.build()
62+
}
3363

3464
@Provides
3565
fun provideChuckerInterceptor(

template-xml/app/src/main/java/co/nimblehq/template/xml/di/modules/RetrofitModule.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package co.nimblehq.template.xml.di.modules
22

33
import co.nimblehq.template.xml.BuildConfig
44
import co.nimblehq.template.xml.data.service.ApiService
5+
import co.nimblehq.template.xml.data.service.AuthService
56
import co.nimblehq.template.xml.data.service.providers.ApiServiceProvider
67
import co.nimblehq.template.xml.data.service.providers.ConverterFactoryProvider
78
import co.nimblehq.template.xml.data.service.providers.RetrofitProvider
9+
import co.nimblehq.template.xml.di.Authenticate
810
import com.squareup.moshi.Moshi
911
import dagger.Module
1012
import dagger.Provides
@@ -37,4 +39,21 @@ class RetrofitModule {
3739
@Provides
3840
fun provideApiService(retrofit: Retrofit): ApiService =
3941
ApiServiceProvider.getApiService(retrofit)
42+
43+
44+
@Authenticate
45+
@Provides
46+
fun provideAuthRetrofit(
47+
baseUrl: String,
48+
@Authenticate okHttpClient: OkHttpClient,
49+
converterFactory: Converter.Factory,
50+
): Retrofit = RetrofitProvider
51+
.getRetrofitBuilder(baseUrl, okHttpClient, converterFactory)
52+
.build()
53+
54+
@Provides
55+
fun provideAuthService(
56+
@Authenticate retrofit: Retrofit
57+
): AuthService =
58+
ApiServiceProvider.getAuthService(retrofit)
4059
}

template-xml/data/src/main/java/co/nimblehq/template/xml/data/extensions/ResponseMapping.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ private fun Throwable.mapError(): Throwable {
4242
}
4343
}
4444

45-
private fun parseErrorResponse(response: Response<*>?): ErrorResponse? {
45+
fun parseErrorResponse(response: Response<*>?): ErrorResponse? {
4646
val jsonString = response?.errorBody()?.string()
4747
return try {
4848
val moshi = MoshiBuilderProvider.moshiBuilder.build()
@@ -54,3 +54,15 @@ private fun parseErrorResponse(response: Response<*>?): ErrorResponse? {
5454
null
5555
}
5656
}
57+
58+
fun parseErrorResponse(jsonString: String?): ErrorResponse? {
59+
return try {
60+
val moshi = MoshiBuilderProvider.moshiBuilder.build()
61+
val adapter = moshi.adapter(ErrorResponse::class.java)
62+
adapter.fromJson(jsonString.orEmpty())
63+
} catch (exception: IOException) {
64+
null
65+
} catch (exception: JsonDataException) {
66+
null
67+
}
68+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package co.nimblehq.template.xml.data.repository
2+
3+
import co.nimblehq.template.xml.data.response.AuthenticateResponse
4+
import co.nimblehq.template.xml.data.service.SessionManager
5+
6+
class SessionManagerImpl: SessionManager {
7+
8+
override suspend fun getAccessToken(): String {
9+
TODO("Not yet implemented")
10+
}
11+
12+
override suspend fun getRefreshToken(): String {
13+
TODO("Not yet implemented")
14+
}
15+
16+
override suspend fun getRegistrationToken(): String {
17+
TODO("Not yet implemented")
18+
}
19+
20+
override suspend fun getTokenType(): String {
21+
TODO("Not yet implemented")
22+
}
23+
24+
override suspend fun refresh(authenticateResponse: AuthenticateResponse) {
25+
TODO("Not yet implemented")
26+
}
27+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package co.nimblehq.template.xml.data.repository
2+
3+
import co.nimblehq.template.xml.data.extensions.flowTransform
4+
import co.nimblehq.template.xml.data.response.AuthenticateResponse
5+
import co.nimblehq.template.xml.data.service.AuthService
6+
import co.nimblehq.template.xml.data.service.authenticator.TokenRefresher
7+
import kotlinx.coroutines.flow.Flow
8+
9+
class TokenRefresherImpl constructor(
10+
private val authService: AuthService
11+
) : TokenRefresher {
12+
13+
override suspend fun refreshToken(): Flow<AuthenticateResponse> = flowTransform {
14+
authService.refreshToken()
15+
}
16+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package co.nimblehq.template.xml.data.response
2+
3+
import co.nimblehq.template.xml.domain.model.AuthStatus
4+
import com.squareup.moshi.Json
5+
6+
data class AuthenticateResponse(
7+
@Json(name = "access_token")
8+
val accessToken: String,
9+
@Json(name = "refresh_token")
10+
val refreshToken: String,
11+
@Json(name = "status")
12+
val status: String,
13+
@Json(name = "token_type")
14+
val tokenType: String?
15+
)
16+
17+
fun AuthenticateResponse.toModel() = AuthStatus.Authenticated(
18+
accessToken = accessToken,
19+
refreshToken = refreshToken,
20+
status = status,
21+
tokenType = tokenType
22+
)

template-xml/data/src/main/java/co/nimblehq/template/xml/data/response/ErrorResponse.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import com.squareup.moshi.Json
55

66
data class ErrorResponse(
77
@Json(name = "message")
8-
val message: String
8+
val message: String,
9+
@Json(name = "type")
10+
val type: String?
911
)
1012

11-
internal fun ErrorResponse.toModel() = Error(message = message)
13+
internal fun ErrorResponse.toModel() = Error(message = message, type = type)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package co.nimblehq.template.xml.data.service
2+
3+
import co.nimblehq.template.xml.data.response.AuthenticateResponse
4+
import retrofit2.http.POST
5+
6+
interface AuthService {
7+
8+
@POST("refreshToken")
9+
suspend fun refreshToken(): AuthenticateResponse
10+
}

0 commit comments

Comments
 (0)