Fix recursive calls to getAuthToken
This commit is contained in:
@@ -23,7 +23,7 @@ class AuthDataSourceImpl @Inject constructor(
|
||||
|
||||
override suspend fun authenticate(username: String, password: String): String {
|
||||
Timber.v("authenticate() called with: username = $username, password = $password")
|
||||
val authService = authServiceFactory.provideService()
|
||||
val authService = authServiceFactory.provideService(needAuth = false)
|
||||
val response = sendRequest(authService, username, password)
|
||||
val accessToken = parseToken(response)
|
||||
Timber.v("authenticate() returned: $accessToken")
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package gq.kirmanak.mealient.data.network
|
||||
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class OkHttpBuilder @Inject constructor(
|
||||
// Use @JvmSuppressWildcards because otherwise dagger can't inject it (https://stackoverflow.com/a/43149382)
|
||||
private val authenticationInterceptor: AuthenticationInterceptor,
|
||||
private val interceptors: Set<@JvmSuppressWildcards Interceptor>,
|
||||
) {
|
||||
|
||||
fun buildOkHttp(): OkHttpClient {
|
||||
Timber.v("buildOkHttp() called")
|
||||
return OkHttpClient.Builder().apply {
|
||||
addInterceptor(authenticationInterceptor)
|
||||
for (interceptor in interceptors) addNetworkInterceptor(interceptor)
|
||||
}.build()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package gq.kirmanak.mealient.data.network
|
||||
|
||||
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
|
||||
import gq.kirmanak.mealient.di.AUTH_OK_HTTP
|
||||
import gq.kirmanak.mealient.di.NO_AUTH_OK_HTTP
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
@@ -8,22 +10,25 @@ import okhttp3.OkHttpClient
|
||||
import retrofit2.Retrofit
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class RetrofitBuilder @Inject constructor(
|
||||
private val okHttpClient: OkHttpClient,
|
||||
@Named(AUTH_OK_HTTP) private val authOkHttpClient: OkHttpClient,
|
||||
@Named(NO_AUTH_OK_HTTP) private val noAuthOkHttpClient: OkHttpClient,
|
||||
private val json: Json
|
||||
) {
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
fun buildRetrofit(baseUrl: String): Retrofit {
|
||||
fun buildRetrofit(baseUrl: String, needAuth: Boolean): Retrofit {
|
||||
Timber.v("buildRetrofit() called with: baseUrl = $baseUrl")
|
||||
val contentType = "application/json".toMediaType()
|
||||
val converterFactory = json.asConverterFactory(contentType)
|
||||
val client = if (needAuth) authOkHttpClient else noAuthOkHttpClient
|
||||
return Retrofit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
.client(okHttpClient)
|
||||
.client(client)
|
||||
.addConverterFactory(converterFactory)
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -13,21 +13,28 @@ class RetrofitServiceFactory<T>(
|
||||
private val baseURLStorage: BaseURLStorage,
|
||||
) : ServiceFactory<T> {
|
||||
|
||||
private val cache: MutableMap<String, T> = mutableMapOf()
|
||||
private val cache: MutableMap<ServiceParams, T> = mutableMapOf()
|
||||
|
||||
override suspend fun provideService(baseUrl: String?): T = runCatchingExceptCancel {
|
||||
override suspend fun provideService(
|
||||
baseUrl: String?,
|
||||
needAuth: Boolean,
|
||||
): T = runCatchingExceptCancel {
|
||||
Timber.v("provideService() called with: baseUrl = $baseUrl, class = ${serviceClass.simpleName}")
|
||||
val url = baseUrl ?: baseURLStorage.requireBaseURL()
|
||||
synchronized(cache) { cache[url] ?: createService(url, serviceClass) }
|
||||
val params = ServiceParams(url, needAuth)
|
||||
synchronized(cache) { cache[params] ?: createService(params, serviceClass) }
|
||||
}.getOrElse {
|
||||
Timber.e(it, "provideService: can't provide service for $baseUrl")
|
||||
throw NetworkError.MalformedUrl(it)
|
||||
}
|
||||
|
||||
private fun createService(url: String, serviceClass: Class<T>): T {
|
||||
Timber.v("createService() called with: url = $url, serviceClass = ${serviceClass.simpleName}")
|
||||
val service = retrofitBuilder.buildRetrofit(url).create(serviceClass)
|
||||
cache[url] = service
|
||||
private fun createService(serviceParams: ServiceParams, serviceClass: Class<T>): T {
|
||||
Timber.v("createService() called with: serviceParams = $serviceParams, serviceClass = ${serviceClass.simpleName}")
|
||||
val (url, needAuth) = serviceParams
|
||||
val service = retrofitBuilder.buildRetrofit(url, needAuth).create(serviceClass)
|
||||
cache[serviceParams] = service
|
||||
return service
|
||||
}
|
||||
|
||||
data class ServiceParams(val baseUrl: String, val needAuth: Boolean)
|
||||
}
|
||||
@@ -2,5 +2,5 @@ package gq.kirmanak.mealient.data.network
|
||||
|
||||
interface ServiceFactory<T> {
|
||||
|
||||
suspend fun provideService(baseUrl: String? = null): T
|
||||
suspend fun provideService(baseUrl: String? = null, needAuth: Boolean = true): T
|
||||
}
|
||||
@@ -4,19 +4,41 @@ import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import gq.kirmanak.mealient.data.network.OkHttpBuilder
|
||||
import gq.kirmanak.mealient.data.network.AuthenticationInterceptor
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
|
||||
const val AUTH_OK_HTTP = "auth"
|
||||
const val NO_AUTH_OK_HTTP = "noauth"
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object NetworkModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun createOkHttp(okHttpBuilder: OkHttpBuilder): OkHttpClient =
|
||||
okHttpBuilder.buildOkHttp()
|
||||
@Named(AUTH_OK_HTTP)
|
||||
fun createAuthOkHttp(
|
||||
// Use @JvmSuppressWildcards because otherwise dagger can't inject it (https://stackoverflow.com/a/43149382)
|
||||
interceptors: Set<@JvmSuppressWildcards Interceptor>,
|
||||
authenticationInterceptor: AuthenticationInterceptor,
|
||||
): OkHttpClient = OkHttpClient.Builder()
|
||||
.addInterceptor(authenticationInterceptor)
|
||||
.apply { for (interceptor in interceptors) addNetworkInterceptor(interceptor) }
|
||||
.build()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named(NO_AUTH_OK_HTTP)
|
||||
fun createNoAuthOkHttp(
|
||||
// Use @JvmSuppressWildcards because otherwise dagger can't inject it (https://stackoverflow.com/a/43149382)
|
||||
interceptors: Set<@JvmSuppressWildcards Interceptor>,
|
||||
): OkHttpClient = OkHttpClient.Builder()
|
||||
.apply { for (interceptor in interceptors) addNetworkInterceptor(interceptor) }
|
||||
.build()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
|
||||
@@ -5,15 +5,17 @@ import com.squareup.picasso.OkHttp3Downloader
|
||||
import com.squareup.picasso.Picasso
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import gq.kirmanak.mealient.BuildConfig
|
||||
import gq.kirmanak.mealient.di.AUTH_OK_HTTP
|
||||
import okhttp3.OkHttpClient
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class PicassoBuilder @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
private val okHttpClient: OkHttpClient
|
||||
@Named(AUTH_OK_HTTP) private val okHttpClient: OkHttpClient
|
||||
) {
|
||||
|
||||
fun buildPicasso(): Picasso {
|
||||
|
||||
Reference in New Issue
Block a user