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.DatabaseModule;
import com.nextcloud.talk.dagger.modules.RestModule;
import com.nextcloud.talk.jobs.AccountRemovalJob;
import com.nextcloud.talk.jobs.PushRegistrationJob;
import com.nextcloud.talk.jobs.creator.MagicJobCreator;
import com.nextcloud.talk.utils.database.user.UserModule;
@ -96,7 +97,7 @@ public class NextcloudTalkApplication extends MultiDexApplication {
refWatcher = LeakCanary.install(this);
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.application.NextcloudTalkApplication;
import com.nextcloud.talk.controllers.base.BaseController;
import com.nextcloud.talk.utils.ErrorMessageHolder;
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
protected void onDestroyView(@NonNull View view) {
super.onDestroyView(view);

View File

@ -33,18 +33,21 @@ import android.view.ViewGroup;
import android.widget.TextView;
import com.bluelinelabs.conductor.RouterTransaction;
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.evernote.android.job.JobRequest;
import com.nextcloud.talk.BuildConfig;
import com.nextcloud.talk.R;
import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.api.helpers.api.ApiHelper;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.controllers.base.BaseController;
import com.nextcloud.talk.jobs.AccountRemovalJob;
import com.nextcloud.talk.persistence.entities.UserEntity;
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.glide.GlideApp;
import com.nextcloud.talk.utils.preferences.AppPreferences;
@ -306,14 +309,31 @@ public class SettingsController extends BaseController {
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) {
switchAccountButton.setVisibility(View.GONE);
}
if (SettingsMessageHolder.getInstance().getMessageType() != null) {
switch (SettingsMessageHolder.getInstance().getMessageType()) {
if (ErrorMessageHolder.getInstance().getMessageType() != null) {
switch (ErrorMessageHolder.getInstance().getMessageType()) {
case ACCOUNT_UPDATED_NOT_ADDED:
messageText.setTextColor(getResources().getColor(R.color.colorPrimary));
messageText.setText(getResources().getString(R.string.nc_settings_account_updated));
@ -328,7 +348,7 @@ public class SettingsController extends BaseController {
messageView.setVisibility(View.GONE);
break;
}
SettingsMessageHolder.getInstance().setMessageType(null);
ErrorMessageHolder.getInstance().setMessageType(null);
messageView.animate()
.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.models.LoginData;
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.BundleKeys;
import com.nextcloud.talk.utils.database.user.UserUtils;
@ -221,24 +221,30 @@ public class WebViewLoginController extends BaseController {
UserEntity currentUser = userUtils.getCurrentUser();
SettingsMessageHolder.SettingsMessageType settingsMessageType = null;
ErrorMessageHolder.ErrorMessageType errorMessageType = null;
if (currentUser != null && isPasswordUpdate &&
!currentUser.getUsername().equals(loginData.getUsername())) {
SettingsMessageHolder.getInstance().setMessageType(
SettingsMessageHolder.SettingsMessageType.WRONG_ACCOUNT);
ErrorMessageHolder.getInstance().setMessageType(
ErrorMessageHolder.ErrorMessageType.WRONG_ACCOUNT);
getRouter().popToRoot();
} else {
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
SettingsMessageHolder.SettingsMessageType finalSettingsMessageType = settingsMessageType;
ErrorMessageHolder.ErrorMessageType finalErrorMessageType = errorMessageType;
userQueryDisposable = userUtils.createOrUpdateUser(loginData.getUsername(), loginData.getToken(),
baseUrl, null, null, true).
subscribe(userEntity -> {
if (!isPasswordUpdate && finalSettingsMessageType == null) {
if (!isPasswordUpdate && finalErrorMessageType == null) {
BundleBuilder bundleBuilder = new BundleBuilder(new Bundle());
bundleBuilder.putString(BundleKeys.KEY_USERNAME, userEntity.getUsername());
bundleBuilder.putString(BundleKeys.KEY_TOKEN, userEntity.getToken());
@ -247,8 +253,8 @@ public class WebViewLoginController extends BaseController {
(bundleBuilder.build())).pushChangeHandler(new HorizontalChangeHandler())
.popChangeHandler(new HorizontalChangeHandler()));
} else {
if (finalSettingsMessageType != null) {
SettingsMessageHolder.getInstance().setMessageType(finalSettingsMessageType);
if (finalErrorMessageType != null) {
ErrorMessageHolder.getInstance().setMessageType(finalErrorMessageType);
}
getRouter().popToRoot();
}

View File

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

View File

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

View File

@ -46,18 +46,36 @@ public class UserUtils {
}
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() {
Result findUsersQueryResult = dataStore.select(User.class).get();
Result findUsersQueryResult = dataStore.select(User.class).where(UserEntity.SCHEDULED_FOR_DELETION.eq(false))
.get();
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() {
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();
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) {
Result findUserQueryResult = dataStore.select(User.class).where(UserEntity.USERNAME.eq(username)
.and(UserEntity.BASE_URL.eq(server.toLowerCase())))
@ -94,6 +125,21 @@ public class UserUtils {
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,
@Nullable String displayName,
@Nullable String pushConfigurationState,

View File

@ -49,6 +49,7 @@
<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_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_username">Username</string>