Further reduced coupling between classes and the need to @Inject the account utils class, fixed imports.

This commit is contained in:
Paul Hawke 2017-09-10 10:23:47 -05:00
parent 9c0cbe7ad5
commit a208c9f273
19 changed files with 66 additions and 84 deletions

View file

@ -5,11 +5,7 @@ import org.apache.commons.codec.digest.DigestUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

View file

@ -6,16 +6,20 @@ import android.accounts.AccountManager;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import fr.free.nrw.commons.contributions.ContributionsContentProvider;
import fr.free.nrw.commons.modifications.ModificationsContentProvider;
import timber.log.Timber;
import static android.accounts.AccountManager.ERROR_CODE_REMOTE_EXCEPTION;
import static android.accounts.AccountManager.KEY_ACCOUNT_NAME;
import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE;
public class AccountUtil {
private Context context;
static final String ACCOUNT_TYPE = "fr.free.nrw.commons";
private final Context context;
public AccountUtil(Context context) {
this.context = context;
@ -24,7 +28,7 @@ public class AccountUtil {
public void createAccount(@Nullable AccountAuthenticatorResponse response,
String username, String password) {
Account account = new Account(username, accountType());
Account account = new Account(username, ACCOUNT_TYPE);
boolean created = accountManager().addAccountExplicitly(account, password, null);
Timber.d("account creation " + (created ? "successful" : "failure"));
@ -32,8 +36,8 @@ public class AccountUtil {
if (created) {
if (response != null) {
Bundle bundle = new Bundle();
bundle.putString(AccountManager.KEY_ACCOUNT_NAME, username);
bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType());
bundle.putString(KEY_ACCOUNT_NAME, username);
bundle.putString(KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
response.onResult(bundle);
@ -41,7 +45,7 @@ public class AccountUtil {
} else {
if (response != null) {
response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "");
response.onError(ERROR_CODE_REMOTE_EXCEPTION, "");
}
Timber.d("account creation failure");
}
@ -51,11 +55,6 @@ public class AccountUtil {
ContentResolver.setSyncAutomatically(account, ModificationsContentProvider.AUTHORITY, true); // Enable sync by default!
}
@NonNull
public String accountType() {
return "fr.free.nrw.commons";
}
private AccountManager accountManager() {
return AccountManager.get(context);
}

View file

@ -13,9 +13,11 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;
import static android.accounts.AccountManager.KEY_ACCOUNT_NAME;
import static fr.free.nrw.commons.auth.AccountUtil.ACCOUNT_TYPE;
public abstract class AuthenticatedActivity extends NavigationBaseActivity {
@Inject AccountUtil accountUtil;
@Inject SessionManager sessionManager;
private String authCookie;
@ -31,20 +33,21 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity {
}
private void addAccount(AccountManager accountManager) {
Single.just(accountManager.addAccount(accountUtil.accountType(), null, null, null, AuthenticatedActivity.this, null, null))
Single.just(accountManager.addAccount(ACCOUNT_TYPE, null, null,
null, AuthenticatedActivity.this, null, null))
.subscribeOn(Schedulers.io())
.map(AccountManagerFuture::getResult)
.doOnEvent((bundle, throwable) -> {
if (!bundle.containsKey(AccountManager.KEY_ACCOUNT_NAME)) {
if (!bundle.containsKey(KEY_ACCOUNT_NAME)) {
throw new RuntimeException("Bundle doesn't contain account-name key: "
+ AccountManager.KEY_ACCOUNT_NAME);
+ KEY_ACCOUNT_NAME);
}
})
.map(bundle -> bundle.getString(AccountManager.KEY_ACCOUNT_NAME))
.map(bundle -> bundle.getString(KEY_ACCOUNT_NAME))
.doOnError(Timber::e)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(s -> {
Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType());
Account[] allAccounts = accountManager.getAccountsByType(ACCOUNT_TYPE);
Account curAccount = allAccounts[0];
getAuthCookie(curAccount, accountManager);
},

View file

@ -1,7 +1,6 @@
package fr.free.nrw.commons.auth;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.AccountManager;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
@ -15,6 +14,11 @@ import fr.free.nrw.commons.mwapi.EventLog;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import timber.log.Timber;
import static android.accounts.AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE;
import static android.accounts.AccountManager.KEY_ACCOUNT_NAME;
import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE;
import static fr.free.nrw.commons.auth.AccountUtil.ACCOUNT_TYPE;
class LoginTask extends AsyncTask<String, String, String> {
private LoginActivity loginActivity;
@ -87,11 +91,11 @@ class LoginTask extends AsyncTask<String, String, String> {
Bundle extras = loginActivity.getIntent().getExtras();
if (extras != null) {
Timber.d("Bundle of extras: %s", extras);
response = extras.getParcelable(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE);
response = extras.getParcelable(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE);
if (response != null) {
Bundle authResult = new Bundle();
authResult.putString(AccountManager.KEY_ACCOUNT_NAME, username);
authResult.putString(AccountManager.KEY_ACCOUNT_TYPE, accountUtil.accountType());
authResult.putString(KEY_ACCOUNT_NAME, username);
authResult.putString(KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
response.onResult(authResult);
}
}

View file

@ -12,18 +12,18 @@ import fr.free.nrw.commons.mwapi.MediaWikiApi;
import io.reactivex.Completable;
import io.reactivex.Observable;
import static fr.free.nrw.commons.auth.AccountUtil.ACCOUNT_TYPE;
/**
* Manage the current logged in user session.
*/
public class SessionManager {
private final Context context;
private final AccountUtil accountUtil;
private final MediaWikiApi mediaWikiApi;
private Account currentAccount; // Unlike a savings account... ;-)
public SessionManager(Context context, AccountUtil accountUtil, MediaWikiApi mediaWikiApi) {
public SessionManager(Context context, MediaWikiApi mediaWikiApi) {
this.context = context;
this.accountUtil = accountUtil;
this.mediaWikiApi = mediaWikiApi;
this.currentAccount = null;
}
@ -34,7 +34,7 @@ public class SessionManager {
public Account getCurrentAccount() {
if (currentAccount == null) {
AccountManager accountManager = AccountManager.get(context);
Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType());
Account[] allAccounts = accountManager.getAccountsByType(ACCOUNT_TYPE);
if (allAccounts.length != 0) {
currentAccount = allAccounts[0];
}
@ -50,7 +50,7 @@ public class SessionManager {
return false; // This should never happen
}
accountManager.invalidateAuthToken(accountUtil.accountType(), mediaWikiApi.getAuthCookie());
accountManager.invalidateAuthToken(ACCOUNT_TYPE, mediaWikiApi.getAuthCookie());
try {
String authCookie = accountManager.blockingGetAuthToken(curAccount, "", false);
mediaWikiApi.setAuthCookie(authCookie);
@ -63,7 +63,7 @@ public class SessionManager {
public Completable clearAllAccounts() {
AccountManager accountManager = AccountManager.get(context);
Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType());
Account[] allAccounts = accountManager.getAccountsByType(ACCOUNT_TYPE);
return Completable.fromObservable(Observable.fromArray(allAccounts)
.map(a -> accountManager.removeAccount(a, null, null).getResult()))
.doOnComplete(() -> currentAccount = null);

View file

@ -15,31 +15,41 @@ import java.io.IOException;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import static android.accounts.AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION;
import static android.accounts.AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE;
import static android.accounts.AccountManager.KEY_ACCOUNT_NAME;
import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE;
import static android.accounts.AccountManager.KEY_AUTHTOKEN;
import static android.accounts.AccountManager.KEY_BOOLEAN_RESULT;
import static android.accounts.AccountManager.KEY_ERROR_CODE;
import static android.accounts.AccountManager.KEY_ERROR_MESSAGE;
import static android.accounts.AccountManager.KEY_INTENT;
import static fr.free.nrw.commons.auth.AccountUtil.ACCOUNT_TYPE;
import static fr.free.nrw.commons.auth.LoginActivity.PARAM_USERNAME;
public class WikiAccountAuthenticator extends AbstractAccountAuthenticator {
private final Context context;
private final AccountUtil accountUtil;
private MediaWikiApi mediaWikiApi;
public WikiAccountAuthenticator(Context context, AccountUtil accountUtil, MediaWikiApi mwApi) {
public WikiAccountAuthenticator(Context context, MediaWikiApi mwApi) {
super(context);
this.context = context;
this.accountUtil = accountUtil;
this.mediaWikiApi = mwApi;
}
private Bundle unsupportedOperation() {
Bundle bundle = new Bundle();
bundle.putInt(AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION);
bundle.putInt(KEY_ERROR_CODE, ERROR_CODE_UNSUPPORTED_OPERATION);
// HACK: the docs indicate that this is a required key bit it's not displayed to the user.
bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "");
bundle.putString(KEY_ERROR_MESSAGE, "");
return bundle;
}
private boolean supportedAccountType(@Nullable String type) {
return accountUtil.accountType().equals(type);
return ACCOUNT_TYPE.equals(type);
}
@Override
@ -57,10 +67,10 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator {
private Bundle addAccount(AccountAuthenticatorResponse response) {
Intent Intent = new Intent(context, LoginActivity.class);
Intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
Intent.putExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, Intent);
bundle.putParcelable(KEY_INTENT, Intent);
return bundle;
}
@ -80,12 +90,13 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator {
private String getAuthCookie(String username, String password) throws IOException {
//TODO add 2fa support here
String result = mediaWikiApi.login(username, password);
if(result.equals("PASS")) {
if (result.equals("PASS")) {
return mediaWikiApi.getAuthCookie();
} else {
return null;
}
}
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
// Extract the username and password from the Account Manager, and ask
@ -103,9 +114,9 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator {
}
if (authCookie != null) {
final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, accountUtil.accountType());
result.putString(AccountManager.KEY_AUTHTOKEN, authCookie);
result.putString(KEY_ACCOUNT_NAME, account.name);
result.putString(KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
result.putString(KEY_AUTHTOKEN, authCookie);
return result;
}
}
@ -114,10 +125,10 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator {
// need to re-prompt them for their credentials. We do that by creating
// an intent to display our AuthenticatorActivity panel.
final Intent intent = new Intent(context, LoginActivity.class);
intent.putExtra(LoginActivity.PARAM_USERNAME, account.name);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(PARAM_USERNAME, account.name);
intent.putExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
bundle.putParcelable(KEY_INTENT, intent);
return bundle;
}
@ -135,7 +146,7 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator {
@NonNull Account account, @NonNull String[] features)
throws NetworkErrorException {
Bundle bundle = new Bundle();
bundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
bundle.putBoolean(KEY_BOOLEAN_RESULT, false);
return bundle;
}

View file

@ -1,31 +1,28 @@
package fr.free.nrw.commons.auth;
import android.accounts.AccountManager;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import javax.inject.Inject;
import dagger.android.DaggerService;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import static android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT;
public class WikiAccountAuthenticatorService extends DaggerService {
@Inject MediaWikiApi mwApi;
@Inject AccountUtil accountUtil;
private WikiAccountAuthenticator wikiAccountAuthenticator = null;
@Override
public IBinder onBind(Intent intent) {
if (!intent.getAction().equals(AccountManager.ACTION_AUTHENTICATOR_INTENT)) {
if (!intent.getAction().equals(ACTION_AUTHENTICATOR_INTENT)) {
return null;
}
if (wikiAccountAuthenticator == null) {
wikiAccountAuthenticator = new WikiAccountAuthenticator(this, accountUtil, mwApi);
wikiAccountAuthenticator = new WikiAccountAuthenticator(this, mwApi);
}
return wikiAccountAuthenticator.getIBinder();
}

View file

@ -4,7 +4,6 @@ import android.content.ContentProviderClient;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
@ -35,7 +34,6 @@ import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import dagger.android.support.DaggerFragment;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.data.Category;
import fr.free.nrw.commons.mwapi.MediaWikiApi;

View file

@ -8,10 +8,8 @@ import dagger.android.AndroidInjector;
import dagger.android.support.AndroidSupportInjectionModule;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.MediaWikiImageView;
import fr.free.nrw.commons.auth.WikiAccountAuthenticatorService;
import fr.free.nrw.commons.contributions.ContributionsSyncAdapter;
import fr.free.nrw.commons.modifications.ModificationsSyncAdapter;
import fr.free.nrw.commons.upload.UploadService;
@Singleton
@Component(modules = {

View file

@ -30,8 +30,8 @@ public class CommonsApplicationModule {
@Provides
@Singleton
public SessionManager providesSessionManager(AccountUtil accountUtil, MediaWikiApi mediaWikiApi) {
return new SessionManager(application, accountUtil, mediaWikiApi);
public SessionManager providesSessionManager(MediaWikiApi mediaWikiApi) {
return new SessionManager(application, mediaWikiApi);
}
@Provides

View file

@ -2,10 +2,7 @@ package fr.free.nrw.commons.di;
import dagger.Module;
import dagger.android.ContributesAndroidInjector;
import fr.free.nrw.commons.auth.LoginActivity;
import fr.free.nrw.commons.auth.SignupActivity;
import fr.free.nrw.commons.category.CategoryContentProvider;
import fr.free.nrw.commons.contributions.ContributionsActivity;
import fr.free.nrw.commons.contributions.ContributionsContentProvider;
import fr.free.nrw.commons.modifications.ModificationsContentProvider;

View file

@ -3,15 +3,6 @@ package fr.free.nrw.commons.di;
import dagger.Module;
import dagger.android.ContributesAndroidInjector;
import fr.free.nrw.commons.auth.WikiAccountAuthenticatorService;
import fr.free.nrw.commons.category.CategorizationFragment;
import fr.free.nrw.commons.contributions.ContributionsListFragment;
import fr.free.nrw.commons.media.MediaDetailFragment;
import fr.free.nrw.commons.media.MediaDetailPagerFragment;
import fr.free.nrw.commons.nearby.NearbyListFragment;
import fr.free.nrw.commons.nearby.NoPermissionsFragment;
import fr.free.nrw.commons.settings.SettingsFragment;
import fr.free.nrw.commons.upload.MultipleUploadListFragment;
import fr.free.nrw.commons.upload.SingleUploadFragment;
import fr.free.nrw.commons.upload.UploadService;
@Module

View file

@ -6,7 +6,6 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
@ -25,7 +24,6 @@ import java.util.Locale;
import javax.inject.Inject;
import dagger.android.support.DaggerFragment;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.License;
import fr.free.nrw.commons.LicenseList;
import fr.free.nrw.commons.Media;

View file

@ -5,7 +5,6 @@ import android.support.annotation.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import io.reactivex.Observable;
import io.reactivex.Single;

View file

@ -2,7 +2,6 @@ package fr.free.nrw.commons.nearby;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;

View file

@ -4,7 +4,6 @@ import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -13,7 +12,6 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.PolygonOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
@ -22,7 +20,6 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.services.android.telemetry.MapboxTelemetry;
import java.lang.reflect.Type;

View file

@ -1,7 +1,6 @@
package fr.free.nrw.commons.nearby;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

View file

@ -5,7 +5,6 @@ import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;

View file

@ -14,13 +14,10 @@ import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Observer;
import java.util.Set;
import fr.free.nrw.commons.BuildConfig;
import io.reactivex.Single;
import io.reactivex.observers.TestObserver;
import io.reactivex.subscribers.TestSubscriber;
import okhttp3.HttpUrl;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;