Remote wipe

Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
This commit is contained in:
tobiasKaminsky 2019-04-04 14:38:13 +01:00
parent c09b116fc3
commit 0b26aa7755
No known key found for this signature in database
GPG key ID: 0E00D4D47D0C5AF7
8 changed files with 219 additions and 105 deletions

View file

@ -179,4 +179,4 @@
</arrangement> </arrangement>
</codeStyleSettings> </codeStyleSettings>
</code_scheme> </code_scheme>
</component> </component>

View file

@ -2278,15 +2278,15 @@ public class FileDataStorageManager {
} }
public void deleteAllFiles() { public void deleteAllFiles() {
String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?"; String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "= ? AND " +
String[] whereArgs = new String[]{account.name}; ProviderTableMeta.FILE_PATH + "= ?";
String[] whereArgs = new String[]{account.name, OCFile.ROOT_PATH};
if (getContentResolver() != null) { if (getContentResolver() != null) {
getContentResolver().delete(ProviderTableMeta.CONTENT_URI_FILE, where, whereArgs); getContentResolver().delete(ProviderTableMeta.CONTENT_URI_DIR, where, whereArgs);
} else { } else {
try { try {
getContentProviderClient().delete(ProviderTableMeta.CONTENT_URI_FILE, where, whereArgs); getContentProviderClient().delete(ProviderTableMeta.CONTENT_URI_DIR, where, whereArgs);
} catch (RemoteException e) { } catch (RemoteException e) {
Log_OC.e(TAG, "Exception in deleteAllFiles for account " + account.name + ": " + e.getMessage(), e); Log_OC.e(TAG, "Exception in deleteAllFiles for account " + account.name + ": " + e.getMessage(), e);
} }

View file

@ -28,26 +28,38 @@ import android.accounts.Account;
import android.accounts.AccountManager; import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback; import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture; import android.accounts.AccountManagerFuture;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.text.TextUtils;
import com.evernote.android.job.Job; import com.evernote.android.job.Job;
import com.evernote.android.job.util.support.PersistableBundleCompat; import com.evernote.android.job.util.support.PersistableBundleCompat;
import com.google.gson.Gson;
import com.nextcloud.client.account.UserAccountManager; import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.preferences.AppPreferencesImpl; import com.nextcloud.client.preferences.AppPreferencesImpl;
import com.owncloud.android.MainApp; import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.datamodel.ArbitraryDataProvider;
import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.FilesystemDataProvider; import com.owncloud.android.datamodel.FilesystemDataProvider;
import com.owncloud.android.datamodel.PushConfigurationState;
import com.owncloud.android.datamodel.SyncedFolder; import com.owncloud.android.datamodel.SyncedFolder;
import com.owncloud.android.datamodel.SyncedFolderProvider; import com.owncloud.android.datamodel.SyncedFolderProvider;
import com.owncloud.android.datamodel.UploadsStorageManager; import com.owncloud.android.datamodel.UploadsStorageManager;
import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.resources.users.RemoteWipeSuccessRemoteOperation;
import com.owncloud.android.ui.activity.ContactsPreferenceActivity; import com.owncloud.android.ui.activity.ContactsPreferenceActivity;
import com.owncloud.android.ui.events.AccountRemovedEvent; import com.owncloud.android.ui.events.AccountRemovedEvent;
import com.owncloud.android.utils.EncryptionUtils; import com.owncloud.android.utils.EncryptionUtils;
import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.utils.FilesSyncHelper; import com.owncloud.android.utils.FilesSyncHelper;
import com.owncloud.android.utils.PushUtils;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import org.jetbrains.annotations.NotNull;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -65,28 +77,48 @@ import static com.owncloud.android.ui.activity.ManageAccountsActivity.PENDING_FO
public class AccountRemovalJob extends Job implements AccountManagerCallback<Boolean> { public class AccountRemovalJob extends Job implements AccountManagerCallback<Boolean> {
public static final String TAG = "AccountRemovalJob"; public static final String TAG = "AccountRemovalJob";
public static final String ACCOUNT = "account"; public static final String ACCOUNT = "account";
public static final String REMOTE_WIPE = "remote_wipe";
private UploadsStorageManager uploadsStorageManager; private UploadsStorageManager uploadsStorageManager;
private UserAccountManager accountManager; private UserAccountManager userAccountManager;
public AccountRemovalJob(UploadsStorageManager uploadStorageManager, UserAccountManager accountManager) { public AccountRemovalJob(UploadsStorageManager uploadStorageManager, UserAccountManager accountManager) {
this.uploadsStorageManager = uploadStorageManager; this.uploadsStorageManager = uploadStorageManager;
this.accountManager = accountManager; this.userAccountManager = accountManager;
} }
@NonNull @NonNull
@Override @Override
protected Result onRunJob(Params params) { protected Result onRunJob(@NotNull Params params) {
Context context = MainApp.getAppContext(); Context context = MainApp.getAppContext();
PersistableBundleCompat bundle = params.getExtras(); PersistableBundleCompat bundle = params.getExtras();
Account account = accountManager.getAccountByName(bundle.getString(ACCOUNT, "")); Account account = userAccountManager.getAccountByName(bundle.getString(ACCOUNT, ""));
AccountManager am = (AccountManager) context.getSystemService(ACCOUNT_SERVICE); AccountManager accountManager = (AccountManager) context.getSystemService(ACCOUNT_SERVICE);
boolean remoteWipe = bundle.getBoolean(REMOTE_WIPE, false);
if (account != null && am != null) { if (account != null && accountManager != null) {
// disable contact backup job // disable contact backup job
ContactsPreferenceActivity.cancelContactBackupJobForAccount(context, account); ContactsPreferenceActivity.cancelContactBackupJobForAccount(context, account);
am.removeAccount(account, this, null); OwnCloudClient client = null;
try {
OwnCloudAccount ocAccount = new OwnCloudAccount(account, MainApp.getAppContext());
client = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount,
MainApp.getAppContext());
} catch (Exception e) {
Log_OC.e(this, "Could not create client", e);
}
try {
AccountManagerFuture<Boolean> accountRemoval = accountManager.removeAccount(account, this, null);
boolean removal = accountRemoval.getResult();
if (!removal) {
Log_OC.e(this, "Account removal of " + account.name + " failed!");
}
} catch (Exception e) {
Log_OC.e(this, "Account removal of " + account.name + " failed!", e);
}
FileDataStorageManager storageManager = new FileDataStorageManager(account, context.getContentResolver()); FileDataStorageManager storageManager = new FileDataStorageManager(account, context.getContentResolver());
@ -99,8 +131,34 @@ public class AccountRemovalJob extends Job implements AccountManagerCallback<Boo
// delete all database entries // delete all database entries
storageManager.deleteAllFiles(); storageManager.deleteAllFiles();
// remove contact backup job
ContactsPreferenceActivity.cancelContactBackupJobForAccount(context, account);
ContentResolver contentResolver = context.getContentResolver();
// disable daily backup
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(contentResolver);
arbitraryDataProvider.storeOrUpdateKeyValue(account.name,
ContactsPreferenceActivity.PREFERENCE_CONTACTS_AUTOMATIC_BACKUP,
"false");
String arbitraryDataPushString;
if (!TextUtils.isEmpty(arbitraryDataPushString = arbitraryDataProvider.getValue(
account, PushUtils.KEY_PUSH)) &&
!TextUtils.isEmpty(context.getResources().getString(R.string.push_server_url))) {
Gson gson = new Gson();
PushConfigurationState pushArbitraryData = gson.fromJson(arbitraryDataPushString,
PushConfigurationState.class);
pushArbitraryData.setShouldBeDeleted(true);
arbitraryDataProvider.storeOrUpdateKeyValue(account.name, PushUtils.KEY_PUSH,
gson.toJson(pushArbitraryData));
PushUtils.pushRegistrationToServer(userAccountManager, pushArbitraryData.getPushToken());
}
// remove pending account removal // remove pending account removal
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
arbitraryDataProvider.deleteKeyForAccount(account.name, PENDING_FOR_REMOVAL); arbitraryDataProvider.deleteKeyForAccount(account.name, PENDING_FOR_REMOVAL);
// remove synced folders set for account // remove synced folders set for account
@ -113,7 +171,7 @@ public class AccountRemovalJob extends Job implements AccountManagerCallback<Boo
for (SyncedFolder syncedFolder : syncedFolders) { for (SyncedFolder syncedFolder : syncedFolders) {
if (syncedFolder.getAccount().equals(account.name)) { if (syncedFolder.getAccount().equals(account.name)) {
arbitraryDataProvider.deleteKeyForAccount(FilesSyncHelper.GLOBAL, arbitraryDataProvider.deleteKeyForAccount(FilesSyncHelper.GLOBAL,
FilesSyncHelper.SYNCEDFOLDERINITIATED + syncedFolder.getId()); FilesSyncHelper.SYNCEDFOLDERINITIATED + syncedFolder.getId());
syncedFolderIds.add(syncedFolder.getId()); syncedFolderIds.add(syncedFolder.getId());
} }
} }
@ -132,6 +190,11 @@ public class AccountRemovalJob extends Job implements AccountManagerCallback<Boo
arbitraryDataProvider.deleteKeyForAccount(account.name, EncryptionUtils.PRIVATE_KEY); arbitraryDataProvider.deleteKeyForAccount(account.name, EncryptionUtils.PRIVATE_KEY);
arbitraryDataProvider.deleteKeyForAccount(account.name, EncryptionUtils.PUBLIC_KEY); arbitraryDataProvider.deleteKeyForAccount(account.name, EncryptionUtils.PUBLIC_KEY);
if (remoteWipe && client != null) {
String authToken = client.getCredentials().getAuthToken();
new RemoteWipeSuccessRemoteOperation(authToken).execute(client);
}
return Result.SUCCESS; return Result.SUCCESS;
} else { } else {
return Result.FAILURE; return Result.FAILURE;

View file

@ -186,9 +186,11 @@ public class FileContentProvider extends ContentProvider {
children.close(); children.close();
} }
count += db.delete(ProviderTableMeta.FILE_TABLE_NAME, if (uri.getPathSegments().size() > 1) {
ProviderTableMeta._ID + "=" + uri.getPathSegments().get(1) count += db.delete(ProviderTableMeta.FILE_TABLE_NAME,
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs); ProviderTableMeta._ID + "=" + uri.getPathSegments().get(1)
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}
return count; return count;
} }
@ -203,9 +205,13 @@ public class FileContentProvider extends ContentProvider {
} }
Log_OC.d(TAG, "Removing FILE " + remoteId); Log_OC.d(TAG, "Removing FILE " + remoteId);
count = db.delete(ProviderTableMeta.FILE_TABLE_NAME, if (remoteId == null) {
ProviderTableMeta._ID + "=" + uri.getPathSegments().get(1) return 0;
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs); } else {
count = db.delete(ProviderTableMeta.FILE_TABLE_NAME,
ProviderTableMeta._ID + "=" + uri.getPathSegments().get(1)
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}
} catch (Exception e) { } catch (Exception e) {
Log_OC.d(TAG, "DB-Error removing file!", e); Log_OC.d(TAG, "DB-Error removing file!", e);
} finally { } finally {
@ -476,7 +482,9 @@ public class FileContentProvider extends ContentProvider {
case ROOT_DIRECTORY: case ROOT_DIRECTORY:
break; break;
case DIRECTORY: case DIRECTORY:
sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "=" + uri.getPathSegments().get(1)); if (uri.getPathSegments().size() > 1) {
sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "=" + uri.getPathSegments().get(1));
}
break; break;
case SINGLE_FILE: case SINGLE_FILE:
if (uri.getPathSegments().size() > SINGLE_PATH_SEGMENT) { if (uri.getPathSegments().size() > SINGLE_PATH_SEGMENT) {

View file

@ -463,7 +463,7 @@ public abstract class DrawerActivity extends ToolbarActivity
case R.id.nav_logout: case R.id.nav_logout:
mCheckedMenuItem = -1; mCheckedMenuItem = -1;
menuItem.setChecked(false); menuItem.setChecked(false);
UserInfoActivity.openAccountRemovalConfirmationDialog(getAccount(), getSupportFragmentManager(), true); UserInfoActivity.openAccountRemovalConfirmationDialog(getAccount(), getSupportFragmentManager());
break; break;
case R.id.nav_shared: case R.id.nav_shared:
handleSearchEvents(new SearchEvent("", handleSearchEvents(new SearchEvent("",
@ -1430,6 +1430,8 @@ public abstract class DrawerActivity extends ToolbarActivity
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
public void onAccountRemovedEvent(AccountRemovedEvent event) { public void onAccountRemovedEvent(AccountRemovedEvent event) {
updateAccountList(); updateAccountList();
restart();
} }
/** /**

View file

@ -69,6 +69,7 @@ import com.owncloud.android.operations.UpdateSharePermissionsOperation;
import com.owncloud.android.operations.UpdateShareViaLinkOperation; import com.owncloud.android.operations.UpdateShareViaLinkOperation;
import com.owncloud.android.services.OperationsService; import com.owncloud.android.services.OperationsService;
import com.owncloud.android.services.OperationsService.OperationsServiceBinder; import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
import com.owncloud.android.ui.asynctasks.CheckRemoteWipeTask;
import com.owncloud.android.ui.asynctasks.LoadingVersionNumberTask; import com.owncloud.android.ui.asynctasks.LoadingVersionNumberTask;
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment; import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
import com.owncloud.android.ui.dialog.LoadingDialog; import com.owncloud.android.ui.dialog.LoadingDialog;
@ -81,6 +82,8 @@ import com.owncloud.android.utils.ErrorMessageAdapter;
import com.owncloud.android.utils.FilesSyncHelper; import com.owncloud.android.utils.FilesSyncHelper;
import com.owncloud.android.utils.ThemeUtils; import com.owncloud.android.utils.ThemeUtils;
import java.lang.ref.WeakReference;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
@ -394,43 +397,48 @@ public abstract class FileActivity extends DrawerActivity
* be used. * be used.
*/ */
protected void requestCredentialsUpdate(Context context, Account account) { protected void requestCredentialsUpdate(Context context, Account account) {
if (account == null) {
account = getAccount();
}
boolean remoteWipeSupported = accountManager.getServerVersion(account).isRemoteWipeSupported();
if (remoteWipeSupported) {
new CheckRemoteWipeTask(account, new WeakReference<>(this)).execute();
} else {
performCredentialsUpdate(account, context);
}
}
public void performCredentialsUpdate(Account account, Context context) {
try { try {
/// step 1 - invalidate credentials of current account /// step 1 - invalidate credentials of current account
if (account == null) {
account = getAccount();
}
OwnCloudClient client;
OwnCloudAccount ocAccount = new OwnCloudAccount(account, context); OwnCloudAccount ocAccount = new OwnCloudAccount(account, context);
client = OwnCloudClientManagerFactory.getDefaultSingleton().removeClientFor(ocAccount); OwnCloudClient client = OwnCloudClientManagerFactory.getDefaultSingleton().removeClientFor(ocAccount);
if (client != null) { if (client != null) {
OwnCloudCredentials cred = client.getCredentials(); OwnCloudCredentials credentials = client.getCredentials();
if (cred != null) { if (credentials != null) {
AccountManager am = AccountManager.get(context); AccountManager accountManager = AccountManager.get(context);
if (cred.authTokenExpires()) { if (credentials.authTokenExpires()) {
am.invalidateAuthToken( accountManager.invalidateAuthToken(account.type, credentials.getAuthToken());
account.type,
cred.getAuthToken()
);
} else { } else {
am.clearPassword(account); accountManager.clearPassword(account);
} }
} }
} }
/// step 2 - request credentials to user /// step 2 - request credentials to user
Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class); Intent updateAccountCredentials = new Intent(context, AuthenticatorActivity.class);
updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, account); updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, account);
updateAccountCredentials.putExtra( updateAccountCredentials.putExtra(
AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.EXTRA_ACTION,
AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN); AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN);
updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivityForResult(updateAccountCredentials, REQUEST_CODE__UPDATE_CREDENTIALS); startActivityForResult(updateAccountCredentials, REQUEST_CODE__UPDATE_CREDENTIALS);
} catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) { } catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
DisplayUtils.showSnackMessage(this, R.string.auth_account_does_not_exist); DisplayUtils.showSnackMessage(this, R.string.auth_account_does_not_exist);
} }
} }
/** /**

View file

@ -26,11 +26,8 @@
package com.owncloud.android.ui.activity; package com.owncloud.android.ui.activity;
import android.accounts.Account; import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@ -52,12 +49,12 @@ import android.widget.TextView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation; import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget; import com.bumptech.glide.request.target.SimpleTarget;
import com.google.gson.Gson; import com.evernote.android.job.JobRequest;
import com.evernote.android.job.util.support.PersistableBundleCompat;
import com.nextcloud.client.di.Injectable; import com.nextcloud.client.di.Injectable;
import com.nextcloud.client.preferences.AppPreferences; import com.nextcloud.client.preferences.AppPreferences;
import com.owncloud.android.R; import com.owncloud.android.R;
import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.jobs.AccountRemovalJob;
import com.owncloud.android.datamodel.PushConfigurationState;
import com.owncloud.android.lib.common.UserInfo; import com.owncloud.android.lib.common.UserInfo;
import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@ -68,7 +65,6 @@ import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.PushUtils; import com.owncloud.android.utils.PushUtils;
import com.owncloud.android.utils.ThemeUtils; import com.owncloud.android.utils.ThemeUtils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode; import org.greenrobot.eventbus.ThreadMode;
import org.parceler.Parcels; import org.parceler.Parcels;
@ -100,9 +96,6 @@ public class UserInfoActivity extends FileActivity implements Injectable {
private static final String TAG = UserInfoActivity.class.getSimpleName(); private static final String TAG = UserInfoActivity.class.getSimpleName();
private static final String KEY_USER_DATA = "USER_DATA"; private static final String KEY_USER_DATA = "USER_DATA";
private static final String KEY_DIRECT_REMOVE = "DIRECT_REMOVE";
private static final int KEY_DELETE_CODE = 101;
@BindView(R.id.empty_list_view) protected LinearLayout emptyContentContainer; @BindView(R.id.empty_list_view) protected LinearLayout emptyContentContainer;
@BindView(R.id.empty_list_view_text) protected TextView emptyContentMessage; @BindView(R.id.empty_list_view_text) protected TextView emptyContentMessage;
@ -179,7 +172,7 @@ public class UserInfoActivity extends FileActivity implements Injectable {
onBackPressed(); onBackPressed();
break; break;
case R.id.delete_account: case R.id.delete_account:
openAccountRemovalConfirmationDialog(account, getSupportFragmentManager(), false); openAccountRemovalConfirmationDialog(account, getSupportFragmentManager());
break; break;
default: default:
retval = super.onOptionsItemSelected(item); retval = super.onOptionsItemSelected(item);
@ -309,10 +302,9 @@ public class UserInfoActivity extends FileActivity implements Injectable {
} }
} }
public static void openAccountRemovalConfirmationDialog(Account account, FragmentManager fragmentManager, public static void openAccountRemovalConfirmationDialog(Account account, FragmentManager fragmentManager) {
boolean removeDirectly) {
UserInfoActivity.AccountRemovalConfirmationDialog dialog = UserInfoActivity.AccountRemovalConfirmationDialog dialog =
UserInfoActivity.AccountRemovalConfirmationDialog.newInstance(account, removeDirectly); UserInfoActivity.AccountRemovalConfirmationDialog.newInstance(account);
dialog.show(fragmentManager, "dialog"); dialog.show(fragmentManager, "dialog");
} }
@ -320,11 +312,9 @@ public class UserInfoActivity extends FileActivity implements Injectable {
private Account account; private Account account;
public static UserInfoActivity.AccountRemovalConfirmationDialog newInstance(Account account, public static UserInfoActivity.AccountRemovalConfirmationDialog newInstance(Account account) {
boolean removeDirectly) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putParcelable(KEY_ACCOUNT, account); bundle.putParcelable(KEY_ACCOUNT, account);
bundle.putBoolean(KEY_DIRECT_REMOVE, removeDirectly);
UserInfoActivity.AccountRemovalConfirmationDialog dialog = new UserInfoActivity.AccountRemovalConfirmationDialog dialog = new
UserInfoActivity.AccountRemovalConfirmationDialog(); UserInfoActivity.AccountRemovalConfirmationDialog();
@ -354,59 +344,22 @@ public class UserInfoActivity extends FileActivity implements Injectable {
@NonNull @NonNull
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
final boolean removeDirectly = getArguments().getBoolean(KEY_DIRECT_REMOVE);
return new AlertDialog.Builder(getActivity(), R.style.Theme_ownCloud_Dialog) return new AlertDialog.Builder(getActivity(), R.style.Theme_ownCloud_Dialog)
.setTitle(R.string.delete_account) .setTitle(R.string.delete_account)
.setMessage(getResources().getString(R.string.delete_account_warning, account.name)) .setMessage(getResources().getString(R.string.delete_account_warning, account.name))
.setIcon(R.drawable.ic_warning) .setIcon(R.drawable.ic_warning)
.setPositiveButton(R.string.common_ok, .setPositiveButton(R.string.common_ok,
(dialogInterface, i) -> { (dialogInterface, i) -> {
// remove contact backup job // schedule job
ContactsPreferenceActivity.cancelContactBackupJobForAccount(getActivity(), account); PersistableBundleCompat bundle = new PersistableBundleCompat();
bundle.putString(AccountRemovalJob.ACCOUNT, account.name);
ContentResolver contentResolver = getActivity().getContentResolver();
// disable daily backup
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(
contentResolver);
arbitraryDataProvider.storeOrUpdateKeyValue(account.name,
ContactsPreferenceActivity.PREFERENCE_CONTACTS_AUTOMATIC_BACKUP,
"false");
String arbitraryDataPushString;
if (!TextUtils.isEmpty(arbitraryDataPushString = arbitraryDataProvider.getValue(
account, PushUtils.KEY_PUSH)) &&
!TextUtils.isEmpty(getResources().getString(R.string.push_server_url))) {
Gson gson = new Gson();
PushConfigurationState pushArbitraryData = gson.fromJson(arbitraryDataPushString,
PushConfigurationState.class);
pushArbitraryData.setShouldBeDeleted(true);
arbitraryDataProvider.storeOrUpdateKeyValue(account.name, PushUtils.KEY_PUSH,
gson.toJson(pushArbitraryData));
EventBus.getDefault().post(new TokenPushEvent());
}
if (getActivity() != null && !removeDirectly) {
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_ACCOUNT, Parcels.wrap(account));
Intent intent = new Intent();
intent.putExtras(bundle);
getActivity().setResult(KEY_DELETE_CODE, intent);
getActivity().finish();
} else {
AccountManager am = (AccountManager) getActivity()
.getSystemService(ACCOUNT_SERVICE);
am.removeAccount(account, null, null);
Intent start = new Intent(getActivity(), FileDisplayActivity.class);
start.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(start);
}
new JobRequest.Builder(AccountRemovalJob.TAG)
.startNow()
.setExtras(bundle)
.setUpdateCurrent(false)
.build()
.schedule();
}) })
.setNegativeButton(R.string.common_cancel, null) .setNegativeButton(R.string.common_cancel, null)
.create(); .create();

View file

@ -0,0 +1,80 @@
/*
*
* * Nextcloud Android client application
* *
* * @author Tobias Kaminsky
* * Copyright (C) 2019 Tobias Kaminsky
* * Copyright (C) 2019 Nextcloud GmbH
* *
* * This program is free software: you can redistribute it and/or modify
* * it under the terms of the GNU Affero General Public License as published by
* * the Free Software Foundation, either version 3 of the License, or
* * (at your option) any later version.
* *
* * This program is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* * GNU Affero General Public License for more details.
* *
* * You should have received a copy of the GNU Affero General Public License
* * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.ui.asynctasks;
import android.accounts.Account;
import android.os.AsyncTask;
import com.evernote.android.job.JobRequest;
import com.evernote.android.job.util.support.PersistableBundleCompat;
import com.owncloud.android.jobs.AccountRemovalJob;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.resources.users.CheckRemoteWipeRemoteOperation;
import com.owncloud.android.ui.activity.FileActivity;
import java.lang.ref.WeakReference;
public class CheckRemoteWipeTask extends AsyncTask<Void, Void, Boolean> {
private Account account;
private WeakReference<FileActivity> fileActivityWeakReference;
public CheckRemoteWipeTask(Account account, WeakReference<FileActivity> fileActivityWeakReference) {
this.account = account;
this.fileActivityWeakReference = fileActivityWeakReference;
}
@Override
protected Boolean doInBackground(Void... voids) {
FileActivity fileActivity = fileActivityWeakReference.get();
if (fileActivity == null) {
Log_OC.e(this, "Check for remote wipe: no context available");
return false;
}
RemoteOperationResult checkWipeResult = new CheckRemoteWipeRemoteOperation().execute(account, fileActivity);
if (checkWipeResult.isSuccess()) {
// schedule job
PersistableBundleCompat bundle = new PersistableBundleCompat();
bundle.putString(AccountRemovalJob.ACCOUNT, account.name);
bundle.putBoolean(AccountRemovalJob.REMOTE_WIPE, true);
new JobRequest.Builder(AccountRemovalJob.TAG)
.startNow()
.setExtras(bundle)
.setUpdateCurrent(false)
.build()
.schedule();
} else {
Log_OC.e(this, "Check for remote wipe not needed -> update credentials");
fileActivity.performCredentialsUpdate(account, fileActivity);
}
return true;
}
}