Inject AuthInterceptor to deal with retrofit dynamic url and credentials

This commit is contained in:
Shinokuni 2020-10-15 19:04:50 +02:00
parent add729f5e2
commit 49c5ba06b3
6 changed files with 71 additions and 98 deletions

View File

@ -11,7 +11,7 @@ import com.readrops.api.services.nextcloudnews.NextNewsService
import com.readrops.api.services.nextcloudnews.adapters.NextNewsFeedsAdapter
import com.readrops.api.services.nextcloudnews.adapters.NextNewsFoldersAdapter
import com.readrops.api.services.nextcloudnews.adapters.NextNewsItemsAdapter
import com.readrops.api.utils.HttpManager
import com.readrops.api.utils.AuthInterceptor
import com.readrops.db.entities.Item
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
@ -29,7 +29,7 @@ val apiModule = module {
OkHttpClient.Builder()
.callTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.HOURS)
.addInterceptor(HttpManager.getInstance().AuthInterceptor())
.addInterceptor(get<AuthInterceptor>())
.build()
}
@ -95,4 +95,8 @@ val apiModule = module {
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(get<OkHttpClient>())
}
single {
AuthInterceptor()
}
}

View File

@ -1,61 +0,0 @@
package com.readrops.api.services;
import androidx.annotation.NonNull;
import com.readrops.api.utils.HttpManager;
import com.squareup.moshi.Moshi;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.moshi.MoshiConverterFactory;
/**
* Abstraction level for services APIs
*
* @param <T> an API service interface
*/
public abstract class API<T> {
protected static final int MAX_ITEMS = 5000;
protected T api;
private Retrofit retrofit;
private Class<T> clazz;
private String endPoint;
public API(Credentials credentials, @NonNull Class<T> clazz, @NonNull String endPoint) {
this.clazz = clazz;
this.endPoint = endPoint;
api = createAPI(credentials);
}
protected abstract Moshi buildMoshi();
protected Retrofit getConfiguredRetrofitInstance() {
return new Retrofit.Builder()
.baseUrl(HttpManager.getInstance().getCredentials().getUrl() + endPoint)
.addConverterFactory(MoshiConverterFactory.create(buildMoshi()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(HttpManager.getInstance().getOkHttpClient())
.build();
}
private T createAPI(@NonNull Credentials credentials) {
HttpManager.getInstance().setCredentials(credentials);
retrofit = getConfiguredRetrofitInstance();
return retrofit.create(clazz);
}
public void setCredentials(@NonNull Credentials credentials) {
HttpManager.getInstance().setCredentials(credentials);
retrofit = retrofit.newBuilder()
.baseUrl(credentials.getUrl() + endPoint)
.build();
api = retrofit.create(clazz);
}
}

View File

@ -1,16 +1,17 @@
package com.readrops.api.services;
import androidx.annotation.Nullable;
import com.readrops.db.entities.account.Account;
import com.readrops.api.services.freshrss.FreshRSSCredentials;
import com.readrops.api.services.freshrss.FreshRSSService;
import com.readrops.api.services.nextcloudnews.NextNewsCredentials;
import com.readrops.api.services.nextcloudnews.NextNewsService;
import com.readrops.db.entities.account.Account;
import com.readrops.db.entities.account.AccountType;
public abstract class Credentials {
private String authorization;
private final String authorization;
private String url;
private final String url;
public Credentials(String authorization, String url) {
this.authorization = authorization;
@ -25,15 +26,27 @@ public abstract class Credentials {
return url;
}
@Nullable
public static Credentials toCredentials(Account account) {
String endPoint = getEndPoint(account.getAccountType());
switch (account.getAccountType()) {
case NEXTCLOUD_NEWS:
return new NextNewsCredentials(account.getLogin(), account.getPassword(), account.getUrl());
return new NextNewsCredentials(account.getLogin(), account.getPassword(), account.getUrl() + endPoint);
case FRESHRSS:
return new FreshRSSCredentials(account.getToken(), account.getUrl());
return new FreshRSSCredentials(account.getToken(), account.getUrl() + endPoint);
default:
return null;
throw new IllegalArgumentException("Unknown account type");
}
}
private static String getEndPoint(AccountType accountType) {
switch (accountType) {
case FRESHRSS:
return FreshRSSService.END_POINT;
case NEXTCLOUD_NEWS:
return NextNewsService.END_POINT;
default:
throw new IllegalArgumentException("Unknown account type");
}
}
}

View File

@ -0,0 +1,35 @@
package com.readrops.api.utils
import android.net.Uri
import com.readrops.api.services.Credentials
import com.readrops.api.services.freshrss.FreshRSSService
import com.readrops.api.services.nextcloudnews.NextNewsService
import com.readrops.db.entities.account.Account
import com.readrops.db.entities.account.AccountType
import okhttp3.Interceptor
import okhttp3.Response
import java.lang.IllegalArgumentException
class AuthInterceptor(var credentials: Credentials? = null) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val requestBuilder = chain.request().newBuilder()
val urlBuilder = chain.request().url.newBuilder()
if (credentials != null) {
if (credentials!!.url != null) {
val uri = Uri.parse(credentials!!.url)
urlBuilder
.scheme(uri.scheme!!)
.host(uri.host!!)
.encodedPath(uri.encodedPath + chain.request().url.encodedPath)
}
if (credentials!!.authorization != null) {
requestBuilder.addHeader("Authorization", credentials!!.authorization)
}
}
return chain.proceed(requestBuilder.url(urlBuilder.build()).build())
}
}

View File

@ -4,13 +4,9 @@ import androidx.annotation.Nullable;
import com.readrops.api.services.Credentials;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class HttpManager {
@ -25,7 +21,6 @@ public class HttpManager {
okHttpClient = new OkHttpClient.Builder()
.callTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.HOURS)
.addInterceptor(new AuthInterceptor())
.build();
}
@ -54,24 +49,4 @@ public class HttpManager {
public static void setInstance(OkHttpClient client) {
instance.okHttpClient = client;
}
public class AuthInterceptor implements Interceptor {
public AuthInterceptor() {
// empty constructor
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (credentials != null && credentials.getAuthorization() != null) {
request = request.newBuilder()
.addHeader("Authorization", credentials.getAuthorization())
.build();
}
return chain.proceed(request);
}
}
}

View File

@ -6,6 +6,9 @@ import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.readrops.api.services.Credentials;
import com.readrops.api.services.SyncResult;
import com.readrops.api.utils.AuthInterceptor;
import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.ParsingResult;
import com.readrops.app.utils.feedscolors.FeedColorsKt;
@ -16,7 +19,8 @@ import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
import com.readrops.db.entities.account.Account;
import com.readrops.db.entities.account.AccountType;
import com.readrops.api.services.SyncResult;
import org.koin.java.KoinJavaComponent;
import java.util.ArrayList;
import java.util.Comparator;
@ -42,6 +46,9 @@ public abstract class ARepository {
this.context = context;
this.database = database;
this.account = account;
KoinJavaComponent.get(AuthInterceptor.class)
.setCredentials(account != null && !account.isLocal() ? Credentials.toCredentials(account) : null);
}
// TODO : replace Single by Completable