Some work on account removal

Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2017-11-07 15:41:14 +01:00
parent 540aab27ab
commit 45f07f6118
8 changed files with 117 additions and 28 deletions

View File

@ -32,6 +32,7 @@ import com.nextcloud.talk.dagger.modules.BusModule;
import com.nextcloud.talk.dagger.modules.ContextModule; import com.nextcloud.talk.dagger.modules.ContextModule;
import com.nextcloud.talk.dagger.modules.DatabaseModule; import com.nextcloud.talk.dagger.modules.DatabaseModule;
import com.nextcloud.talk.dagger.modules.RestModule; import com.nextcloud.talk.dagger.modules.RestModule;
import com.nextcloud.talk.jobs.AccountRemovalJob;
import com.nextcloud.talk.jobs.PushRegistrationJob; import com.nextcloud.talk.jobs.PushRegistrationJob;
import com.nextcloud.talk.jobs.creator.MagicJobCreator; import com.nextcloud.talk.jobs.creator.MagicJobCreator;
import com.nextcloud.talk.utils.database.user.UserModule; import com.nextcloud.talk.utils.database.user.UserModule;
@ -96,7 +97,7 @@ public class NextcloudTalkApplication extends MultiDexApplication {
refWatcher = LeakCanary.install(this); refWatcher = LeakCanary.install(this);
new JobRequest.Builder(PushRegistrationJob.TAG).setUpdateCurrent(true).startNow().build().schedule(); new JobRequest.Builder(PushRegistrationJob.TAG).setUpdateCurrent(true).startNow().build().schedule();
new JobRequest.Builder(AccountRemovalJob.TAG).setUpdateCurrent(true).startNow().build().schedule();
} }

View File

@ -35,6 +35,7 @@ import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.api.helpers.api.ApiHelper; import com.nextcloud.talk.api.helpers.api.ApiHelper;
import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.controllers.base.BaseController; import com.nextcloud.talk.controllers.base.BaseController;
import com.nextcloud.talk.utils.ErrorMessageHolder;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
@ -170,6 +171,18 @@ public class ServerSelectionController extends BaseController {
}); });
} }
@Override
protected void onAttach(@NonNull View view) {
super.onAttach(view);
if (ErrorMessageHolder.getInstance().getMessageType() != null &&
ErrorMessageHolder.getInstance().getMessageType()
.equals(ErrorMessageHolder.ErrorMessageType.ACCOUNT_SCHEDULED_FOR_DELETION)) {
textFieldBoxes.setError(getResources().getString(R.string.nc_account_scheduled_for_deletion),
false);
ErrorMessageHolder.getInstance().setMessageType(null);
}
}
@Override @Override
protected void onDestroyView(@NonNull View view) { protected void onDestroyView(@NonNull View view) {
super.onDestroyView(view); super.onDestroyView(view);

View File

@ -33,18 +33,21 @@ import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import com.bluelinelabs.conductor.RouterTransaction; import com.bluelinelabs.conductor.RouterTransaction;
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler; import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler;
import com.bumptech.glide.load.model.GlideUrl; import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders; import com.bumptech.glide.load.model.LazyHeaders;
import com.evernote.android.job.JobRequest;
import com.nextcloud.talk.BuildConfig; import com.nextcloud.talk.BuildConfig;
import com.nextcloud.talk.R; import com.nextcloud.talk.R;
import com.nextcloud.talk.api.NcApi; import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.api.helpers.api.ApiHelper; import com.nextcloud.talk.api.helpers.api.ApiHelper;
import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.controllers.base.BaseController; import com.nextcloud.talk.controllers.base.BaseController;
import com.nextcloud.talk.jobs.AccountRemovalJob;
import com.nextcloud.talk.persistence.entities.UserEntity; import com.nextcloud.talk.persistence.entities.UserEntity;
import com.nextcloud.talk.utils.ColorUtils; import com.nextcloud.talk.utils.ColorUtils;
import com.nextcloud.talk.utils.SettingsMessageHolder; import com.nextcloud.talk.utils.ErrorMessageHolder;
import com.nextcloud.talk.utils.database.user.UserUtils; import com.nextcloud.talk.utils.database.user.UserUtils;
import com.nextcloud.talk.utils.glide.GlideApp; import com.nextcloud.talk.utils.glide.GlideApp;
import com.nextcloud.talk.utils.preferences.AppPreferences; import com.nextcloud.talk.utils.preferences.AppPreferences;
@ -306,14 +309,31 @@ public class SettingsController extends BaseController {
dispose(profileQueryDisposable); dispose(profileQueryDisposable);
}, () -> dispose(profileQueryDisposable)); }, () -> dispose(profileQueryDisposable));
removeAccountButton.setOnClickListener(view1 -> {
boolean otherUserExists = userUtils.scheduleUserForDeletionWithId(userEntity.getId());
if (otherUserExists && getView() != null) {
onViewBound(getView());
onAttach(getView());
} else if (!otherUserExists) {
getParentController().getRouter().setRoot(RouterTransaction.with(
new ServerSelectionController())
.pushChangeHandler(new HorizontalChangeHandler())
.popChangeHandler(new HorizontalChangeHandler()));
}
new JobRequest.Builder(AccountRemovalJob.TAG).setUpdateCurrent(true)
.startNow().build().schedule();
});
} }
if (userUtils.getUsers().size() <= 1) { if (userUtils.getUsers().size() <= 1) {
switchAccountButton.setVisibility(View.GONE); switchAccountButton.setVisibility(View.GONE);
} }
if (SettingsMessageHolder.getInstance().getMessageType() != null) { if (ErrorMessageHolder.getInstance().getMessageType() != null) {
switch (SettingsMessageHolder.getInstance().getMessageType()) { switch (ErrorMessageHolder.getInstance().getMessageType()) {
case ACCOUNT_UPDATED_NOT_ADDED: case ACCOUNT_UPDATED_NOT_ADDED:
messageText.setTextColor(getResources().getColor(R.color.colorPrimary)); messageText.setTextColor(getResources().getColor(R.color.colorPrimary));
messageText.setText(getResources().getString(R.string.nc_settings_account_updated)); messageText.setText(getResources().getString(R.string.nc_settings_account_updated));
@ -328,7 +348,7 @@ public class SettingsController extends BaseController {
messageView.setVisibility(View.GONE); messageView.setVisibility(View.GONE);
break; break;
} }
SettingsMessageHolder.getInstance().setMessageType(null); ErrorMessageHolder.getInstance().setMessageType(null);
messageView.animate() messageView.animate()
.translationY(0) .translationY(0)

View File

@ -45,7 +45,7 @@ import com.nextcloud.talk.controllers.base.BaseController;
import com.nextcloud.talk.events.CertificateEvent; import com.nextcloud.talk.events.CertificateEvent;
import com.nextcloud.talk.models.LoginData; import com.nextcloud.talk.models.LoginData;
import com.nextcloud.talk.persistence.entities.UserEntity; import com.nextcloud.talk.persistence.entities.UserEntity;
import com.nextcloud.talk.utils.SettingsMessageHolder; import com.nextcloud.talk.utils.ErrorMessageHolder;
import com.nextcloud.talk.utils.bundle.BundleBuilder; import com.nextcloud.talk.utils.bundle.BundleBuilder;
import com.nextcloud.talk.utils.bundle.BundleKeys; import com.nextcloud.talk.utils.bundle.BundleKeys;
import com.nextcloud.talk.utils.database.user.UserUtils; import com.nextcloud.talk.utils.database.user.UserUtils;
@ -221,24 +221,30 @@ public class WebViewLoginController extends BaseController {
UserEntity currentUser = userUtils.getCurrentUser(); UserEntity currentUser = userUtils.getCurrentUser();
SettingsMessageHolder.SettingsMessageType settingsMessageType = null; ErrorMessageHolder.ErrorMessageType errorMessageType = null;
if (currentUser != null && isPasswordUpdate && if (currentUser != null && isPasswordUpdate &&
!currentUser.getUsername().equals(loginData.getUsername())) { !currentUser.getUsername().equals(loginData.getUsername())) {
SettingsMessageHolder.getInstance().setMessageType( ErrorMessageHolder.getInstance().setMessageType(
SettingsMessageHolder.SettingsMessageType.WRONG_ACCOUNT); ErrorMessageHolder.ErrorMessageType.WRONG_ACCOUNT);
getRouter().popToRoot(); getRouter().popToRoot();
} else { } else {
if (!isPasswordUpdate && userUtils.getIfUserWithUsernameAndServer(loginData.getUsername(), baseUrl)) { if (!isPasswordUpdate && userUtils.getIfUserWithUsernameAndServer(loginData.getUsername(), baseUrl)) {
settingsMessageType = SettingsMessageHolder.SettingsMessageType.ACCOUNT_UPDATED_NOT_ADDED; errorMessageType = ErrorMessageHolder.ErrorMessageType.ACCOUNT_UPDATED_NOT_ADDED;
}
if (userUtils.checkIfUserIsScheduledForDeletion(loginData.getUsername(), baseUrl)) {
ErrorMessageHolder.getInstance().setMessageType(
ErrorMessageHolder.ErrorMessageType.ACCOUNT_SCHEDULED_FOR_DELETION);
getRouter().popToRoot();
} }
// We use the URL user entered because one provided by the server is NOT reliable // We use the URL user entered because one provided by the server is NOT reliable
SettingsMessageHolder.SettingsMessageType finalSettingsMessageType = settingsMessageType; ErrorMessageHolder.ErrorMessageType finalErrorMessageType = errorMessageType;
userQueryDisposable = userUtils.createOrUpdateUser(loginData.getUsername(), loginData.getToken(), userQueryDisposable = userUtils.createOrUpdateUser(loginData.getUsername(), loginData.getToken(),
baseUrl, null, null, true). baseUrl, null, null, true).
subscribe(userEntity -> { subscribe(userEntity -> {
if (!isPasswordUpdate && finalSettingsMessageType == null) { if (!isPasswordUpdate && finalErrorMessageType == null) {
BundleBuilder bundleBuilder = new BundleBuilder(new Bundle()); BundleBuilder bundleBuilder = new BundleBuilder(new Bundle());
bundleBuilder.putString(BundleKeys.KEY_USERNAME, userEntity.getUsername()); bundleBuilder.putString(BundleKeys.KEY_USERNAME, userEntity.getUsername());
bundleBuilder.putString(BundleKeys.KEY_TOKEN, userEntity.getToken()); bundleBuilder.putString(BundleKeys.KEY_TOKEN, userEntity.getToken());
@ -247,8 +253,8 @@ public class WebViewLoginController extends BaseController {
(bundleBuilder.build())).pushChangeHandler(new HorizontalChangeHandler()) (bundleBuilder.build())).pushChangeHandler(new HorizontalChangeHandler())
.popChangeHandler(new HorizontalChangeHandler())); .popChangeHandler(new HorizontalChangeHandler()));
} else { } else {
if (finalSettingsMessageType != null) { if (finalErrorMessageType != null) {
SettingsMessageHolder.getInstance().setMessageType(finalSettingsMessageType); ErrorMessageHolder.getInstance().setMessageType(finalErrorMessageType);
} }
getRouter().popToRoot(); getRouter().popToRoot();
} }

View File

@ -46,4 +46,6 @@ public interface User extends Parcelable, Persistable, Serializable {
String getPushConfigurationState(); String getPushConfigurationState();
boolean getCurrent(); boolean getCurrent();
boolean getScheduledForDeletion();
} }

View File

@ -22,24 +22,24 @@ package com.nextcloud.talk.utils;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
public class SettingsMessageHolder { public class ErrorMessageHolder {
public enum SettingsMessageType { public enum ErrorMessageType {
WRONG_ACCOUNT, ACCOUNT_UPDATED_NOT_ADDED WRONG_ACCOUNT, ACCOUNT_UPDATED_NOT_ADDED, ACCOUNT_SCHEDULED_FOR_DELETION
} }
private SettingsMessageType settingsMessageType; private ErrorMessageType errorMessageType;
private static final SettingsMessageHolder holder = new SettingsMessageHolder(); private static final ErrorMessageHolder holder = new ErrorMessageHolder();
public static SettingsMessageHolder getInstance() { public static ErrorMessageHolder getInstance() {
return holder; return holder;
} }
public SettingsMessageType getMessageType() { public ErrorMessageType getMessageType() {
return settingsMessageType; return errorMessageType;
} }
public void setMessageType(@Nullable SettingsMessageType settingsMessageType) { public void setMessageType(@Nullable ErrorMessageType errorMessageType) {
this.settingsMessageType = settingsMessageType; this.errorMessageType = errorMessageType;
} }

View File

@ -46,18 +46,36 @@ public class UserUtils {
} }
public boolean anyUserExists() { public boolean anyUserExists() {
return (dataStore.count(User.class).limit(1).get().value() > 0); return (dataStore.count(User.class).where(UserEntity.SCHEDULED_FOR_DELETION.eq(false)).
limit(1).get().value() > 0);
} }
public List getUsers() { public List getUsers() {
Result findUsersQueryResult = dataStore.select(User.class).get(); Result findUsersQueryResult = dataStore.select(User.class).where(UserEntity.SCHEDULED_FOR_DELETION.eq(false))
.get();
return findUsersQueryResult.toList(); return findUsersQueryResult.toList();
} }
// temporary method while we only support 1 user
public UserEntity getAnyUserAndSetAsActive() {
Result findUserQueryResult = dataStore.select(User.class)
.where(UserEntity.SCHEDULED_FOR_DELETION.eq(false))
.limit(1).get();
UserEntity userEntity;
if ((userEntity = (UserEntity) findUserQueryResult.firstOrNull()) != null) {
userEntity.setCurrent(true);
dataStore.update(userEntity).blockingGet();
return userEntity;
}
return null;
}
public UserEntity getCurrentUser() { public UserEntity getCurrentUser() {
Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.CURRENT.eq(true)) Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.CURRENT.eq(true)
.and(UserEntity.SCHEDULED_FOR_DELETION.eq(false)))
.limit(1).get(); .limit(1).get();
return (UserEntity) findUserQueryResult.firstOrNull(); return (UserEntity) findUserQueryResult.firstOrNull();
@ -86,6 +104,19 @@ public class UserUtils {
} }
} }
public boolean checkIfUserIsScheduledForDeletion(String username, String server) {
Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.USERNAME.eq(username))
.and(UserEntity.BASE_URL.eq(server))
.limit(1).get();
UserEntity userEntity;
if ((userEntity = (UserEntity) findUserQueryResult.firstOrNull()) != null) {
return userEntity.getScheduledForDeletion();
}
return false;
}
public boolean getIfUserWithUsernameAndServer(String username, String server) { public boolean getIfUserWithUsernameAndServer(String username, String server) {
Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.USERNAME.eq(username) Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.USERNAME.eq(username)
.and(UserEntity.BASE_URL.eq(server.toLowerCase()))) .and(UserEntity.BASE_URL.eq(server.toLowerCase())))
@ -94,6 +125,21 @@ public class UserUtils {
return findUserQueryResult.firstOrNull() != null; return findUserQueryResult.firstOrNull() != null;
} }
public boolean scheduleUserForDeletionWithId(long id) {
Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.ID.eq(id))
.limit(1).get();
UserEntity userEntity;
if ((userEntity = (UserEntity) findUserQueryResult.firstOrNull()) != null) {
userEntity.setScheduledForDeletion(true);
userEntity.setCurrent(false);
dataStore.update(userEntity).blockingGet();
}
return getAnyUserAndSetAsActive() != null;
}
public Observable<UserEntity> createOrUpdateUser(String username, String token, String serverUrl, public Observable<UserEntity> createOrUpdateUser(String username, String token, String serverUrl,
@Nullable String displayName, @Nullable String displayName,
@Nullable String pushConfigurationState, @Nullable String pushConfigurationState,

View File

@ -49,6 +49,7 @@
<string name="nc_settings_add_account">Add a new account</string> <string name="nc_settings_add_account">Add a new account</string>
<string name="nc_settings_wrong_account">Only current account can be reauthorized</string> <string name="nc_settings_wrong_account">Only current account can be reauthorized</string>
<string name="nc_settings_account_updated">We updated your existing account instead of adding a new one since it already exists</string> <string name="nc_settings_account_updated">We updated your existing account instead of adding a new one since it already exists</string>
<string name="nc_account_scheduled_for_deletion">Account is scheduled for deletion, and cannot be operated on</string>
<string name="nc_no_proxy">No proxy</string> <string name="nc_no_proxy">No proxy</string>
<string name="nc_username">Username</string> <string name="nc_username">Username</string>