diff --git a/owncloud-android-library b/owncloud-android-library index 21c329aa12..ddb8648809 160000 --- a/owncloud-android-library +++ b/owncloud-android-library @@ -1 +1 @@ -Subproject commit 21c329aa126833119f4bc6ed06a3f3881964246f +Subproject commit ddb8648809b7e5c91ec6d081ccdb0597dbebd520 diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index f26c02fbfe..5179fbbe03 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -168,7 +168,7 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq Connexion établie Test de connexion Configuration du serveur erronée - Un compte pour le même utilisateur et serveur existe déjà sur cet appareil + Un compte pour les même utilisateur et serveur existe déjà sur cet appareil L\'utilisateur entré ne correspond pas à l\'utilisateur de ce compte Une erreur inconnue s\'est produite. Impossible de trouver l\'hôte diff --git a/src/com/owncloud/android/authentication/AccountUtils.java b/src/com/owncloud/android/authentication/AccountUtils.java index bd3a8e79a7..a22164fb26 100644 --- a/src/com/owncloud/android/authentication/AccountUtils.java +++ b/src/com/owncloud/android/authentication/AccountUtils.java @@ -24,24 +24,28 @@ import java.util.Locale; import com.owncloud.android.MainApp; import com.owncloud.android.lib.common.accounts.AccountTypeUtils; +import com.owncloud.android.lib.common.accounts.AccountUtils.Constants; +import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.status.OwnCloudVersion; import android.accounts.Account; import android.accounts.AccountManager; import android.content.Context; import android.content.SharedPreferences; +import android.net.Uri; import android.preference.PreferenceManager; public class AccountUtils { - public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php"; - public static final String WEBDAV_PATH_2_0 = "/files/webdav.php"; - public static final String WEBDAV_PATH_4_0 = "/remote.php/webdav"; + + private static final String TAG = AccountUtils.class.getSimpleName(); + + public static final String WEBDAV_PATH_4_0_AND_LATER = "/remote.php/webdav"; private static final String ODAV_PATH = "/remote.php/odav"; private static final String SAML_SSO_PATH = "/remote.php/webdav"; - public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php"; - public static final String CARDDAV_PATH_4_0 = "/remote/carddav.php"; public static final String STATUS_PATH = "/status.php"; + public static final int ACCOUNT_VERSION = 1; + /** * Can be used to get the currently selected ownCloud {@link Account} in the * application preferences. @@ -105,19 +109,6 @@ public class AccountUtils { } - /** - * Checks, whether or not there are any ownCloud accounts setup. - * - * @return true, if there is at least one account. - */ - public static boolean accountsAreSetup(Context context) { - AccountManager accMan = AccountManager.get(context); - Account[] accounts = accMan - .getAccountsByType(MainApp.getAccountType()); - return accounts.length > 0; - } - - public static boolean setCurrentOwnCloudAccount(Context context, String accountName) { boolean result = false; if (accountName != null) { @@ -145,8 +136,10 @@ public class AccountUtils { * according to its version and the authorization method used. * * @param version Version of ownCloud server. - * @param authTokenType Authorization token type, matching some of the AUTH_TOKEN_TYPE_* constants in {@link AccountAuthenticator}. - * @return WebDAV path for given OC version and authorization method, null if OC version is unknown. + * @param authTokenType Authorization token type, matching some of the AUTH_TOKEN_TYPE_* constants in + * {@link AccountAuthenticator}. + * @return WebDAV path for given OC version and authorization method, null if OC version + * is unknown; versions prior to ownCloud 4 are not supported anymore */ public static String getWebdavPath(OwnCloudVersion version, String authTokenType) { if (version != null) { @@ -156,15 +149,103 @@ public class AccountUtils { if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(authTokenType)) { return SAML_SSO_PATH; } - if (version.compareTo(OwnCloudVersion.owncloud_v4) >= 0) - return WEBDAV_PATH_4_0; - if (version.compareTo(OwnCloudVersion.owncloud_v3) >= 0 - || version.compareTo(OwnCloudVersion.owncloud_v2) >= 0) - return WEBDAV_PATH_2_0; - if (version.compareTo(OwnCloudVersion.owncloud_v1) >= 0) - return WEBDAV_PATH_1_2; + return WEBDAV_PATH_4_0_AND_LATER; } return null; } - + + + /** + * Update the accounts in AccountManager to meet the current version of accounts expected by the app, if needed. + * + * Introduced to handle a change in the structure of stored account names needed to allow different OC servers + * in the same domain, but not in the same path. + * + * @param context Used to access the AccountManager. + */ + public static void updateAccountVersion(Context context) { + Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(context); + AccountManager accountMgr = AccountManager.get(context); + + String currentAccountVersion = accountMgr.getUserData(currentAccount, Constants.KEY_OC_ACCOUNT_VERSION); + + if (currentAccountVersion == null) { + Log_OC.i(TAG, "Upgrading accounts to account version #" + ACCOUNT_VERSION); + Account[] ocAccounts = accountMgr.getAccountsByType(MainApp.getAccountType()); + String serverUrl, username, newAccountName, password; + Account newAccount; + for (Account account : ocAccounts) { + // build new account name + serverUrl = accountMgr.getUserData(account, Constants.KEY_OC_BASE_URL); + username = account.name.substring(0, account.name.lastIndexOf('@')); + newAccountName = com.owncloud.android.lib.common.accounts.AccountUtils. + buildAccountName(Uri.parse(serverUrl), username); + + // migrate to a new account, if needed + if (!newAccountName.equals(account.name)) { + Log_OC.d(TAG, "Upgrading " + account.name + " to " + newAccountName ); + + // create the new account + newAccount = new Account(newAccountName, MainApp.getAccountType()); + password = accountMgr.getPassword(account); + accountMgr.addAccountExplicitly(newAccount, (password != null) ? password : "", null); + + // copy base URL + accountMgr.setUserData(newAccount, Constants.KEY_OC_BASE_URL, serverUrl); + + // copy server version + accountMgr.setUserData( + newAccount, + Constants.KEY_OC_VERSION, + accountMgr.getUserData(account, Constants.KEY_OC_VERSION) + ); + + // copy cookies + accountMgr.setUserData( + newAccount, + Constants.KEY_COOKIES, + accountMgr.getUserData(account, Constants.KEY_COOKIES) + ); + + // copy type of authentication + String isSamlStr = accountMgr.getUserData(account, Constants.KEY_SUPPORTS_SAML_WEB_SSO); + boolean isSaml = "TRUE".equals(isSamlStr); + if (isSaml) { + accountMgr.setUserData(newAccount, Constants.KEY_SUPPORTS_SAML_WEB_SSO, "TRUE"); + } + + String isOauthStr = accountMgr.getUserData(account, Constants.KEY_SUPPORTS_OAUTH2); + boolean isOAuth = "TRUE".equals(isOauthStr); + if (isOAuth) { + accountMgr.setUserData(newAccount, Constants.KEY_SUPPORTS_OAUTH2, "TRUE"); + } + /* TODO - study if it's possible to run this method in a background thread to copy the authToken + if (isOAuth || isSaml) { + accountMgr.setAuthToken(newAccount, mAuthTokenType, mAuthToken); + } + */ + + // don't forget the account saved in preferences as the current one + if (currentAccount != null && currentAccount.name.equals(account.name)) { + AccountUtils.setCurrentOwnCloudAccount(context, newAccountName); + } + + // remove the old account + accountMgr.removeAccount(account, null, null); // will assume it succeeds, not a big deal otherwise + + } else { + // servers which base URL is in the root of their domain need no change + Log_OC.d(TAG, account.name + " needs no upgrade "); + newAccount = account; + } + + // at least, upgrade account version + Log_OC.d(TAG, "Setting version " + ACCOUNT_VERSION + " to " + newAccountName); + accountMgr.setUserData(newAccount, Constants.KEY_OC_ACCOUNT_VERSION, Integer.toString(ACCOUNT_VERSION)); + + } + } + } + + } diff --git a/src/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/com/owncloud/android/authentication/AuthenticatorActivity.java index 1e4e8b4f69..f245900b72 100644 --- a/src/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/src/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -1119,13 +1119,9 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity // TODO remove, if possible private String trimUrlWebdav(String url){ - if(url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_4_0)){ - url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_4_0.length()); - } else if(url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_2_0)){ - url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_2_0.length()); - } else if (url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_1_2)){ - url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_1_2.length()); - } + if(url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_4_0_AND_LATER)){ + url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_4_0_AND_LATER.length()); + } return (url != null ? url : ""); } @@ -1487,6 +1483,13 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity ); } + // include account version with the new account + mAccountMgr.setUserData( + mAccount, + Constants.KEY_OC_ACCOUNT_VERSION, + Integer.toString(AccountUtils.ACCOUNT_VERSION) + ); + /// add the new account as default in preferences, if there is none already Account defaultAccount = AccountUtils.getCurrentOwnCloudAccount(this); if (defaultAccount == null) { diff --git a/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java b/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java index b52c36d9a6..47f7127b6c 100644 --- a/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java +++ b/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java @@ -89,7 +89,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver { Account account = AccountUtils.getCurrentOwnCloudAccount(context); if (account == null) { - Log_OC.w(TAG, "No owncloud account found for instant upload, aborting"); + Log_OC.w(TAG, "No ownCloud account found for instant upload, aborting"); return; } diff --git a/src/com/owncloud/android/operations/GetServerInfoOperation.java b/src/com/owncloud/android/operations/GetServerInfoOperation.java index 8e91100082..1b4b7a9bb4 100644 --- a/src/com/owncloud/android/operations/GetServerInfoOperation.java +++ b/src/com/owncloud/android/operations/GetServerInfoOperation.java @@ -23,7 +23,6 @@ package com.owncloud.android.operations; import java.util.ArrayList; -import com.owncloud.android.MainApp; import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; @@ -118,12 +117,8 @@ public class GetServerInfoOperation extends RemoteOperation { if (url.endsWith("/")) { url = url.substring(0, url.length() - 1); } - if(url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_4_0)){ - url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_4_0.length()); - } else if(url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_2_0)){ - url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_2_0.length()); - } else if (url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_1_2)){ - url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_1_2.length()); + if(url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_4_0_AND_LATER)){ + url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_4_0_AND_LATER.length()); } } return url; diff --git a/src/com/owncloud/android/providers/FileContentProvider.java b/src/com/owncloud/android/providers/FileContentProvider.java index bf1891e807..8c24c03af7 100644 --- a/src/com/owncloud/android/providers/FileContentProvider.java +++ b/src/com/owncloud/android/providers/FileContentProvider.java @@ -844,7 +844,7 @@ public class FileContentProvider extends ContentProvider { Account[] accounts = AccountManager.get(getContext()).getAccountsByType(MainApp.getAccountType()); String serverUrl, username, oldAccountName; for (Account account : accounts) { - // build new account name + // build old account name serverUrl = ama.getUserData(account, AccountUtils.Constants.KEY_OC_BASE_URL); username = account.name.substring(0, account.name.lastIndexOf('@')); oldAccountName = AccountUtils.buildAccountNameOld(Uri.parse(serverUrl), username); diff --git a/src/com/owncloud/android/syncadapter/ContactSyncAdapter.java b/src/com/owncloud/android/syncadapter/ContactSyncAdapter.java deleted file mode 100644 index d3ab06c1a4..0000000000 --- a/src/com/owncloud/android/syncadapter/ContactSyncAdapter.java +++ /dev/null @@ -1,125 +0,0 @@ -/** - * ownCloud Android client application - * - * Copyright (C) 2012 Bartek Przybylski - * Copyright (C) 2015 ownCloud Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package com.owncloud.android.syncadapter; - -import java.io.FileInputStream; -import java.io.IOException; - -import org.apache.http.client.methods.HttpPut; -import org.apache.http.entity.ByteArrayEntity; - -import com.owncloud.android.authentication.AccountUtils; -import com.owncloud.android.lib.common.accounts.AccountUtils.Constants; - - -import android.accounts.Account; -import android.accounts.AccountManager; -import android.accounts.AuthenticatorException; -import android.accounts.OperationCanceledException; -import android.content.ContentProviderClient; -import android.content.Context; -import android.content.SyncResult; -import android.content.res.AssetFileDescriptor; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.provider.ContactsContract; - -public class ContactSyncAdapter extends AbstractOwnCloudSyncAdapter { - private String mAddrBookUri; - - public ContactSyncAdapter(Context context, boolean autoInitialize) { - super(context, autoInitialize); - mAddrBookUri = null; - } - - @Override - public void onPerformSync(Account account, Bundle extras, String authority, - ContentProviderClient provider, SyncResult syncResult) { - setAccount(account); - setContentProviderClient(provider); - Cursor c = getLocalContacts(false); - if (c.moveToFirst()) { - do { - String lookup = c.getString(c - .getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)); - String a = getAddressBookUri(); - String uri = a + lookup + ".vcf"; - FileInputStream f; - try { - f = getContactVcard(lookup); - HttpPut query = new HttpPut(uri); - byte[] b = new byte[f.available()]; - f.read(b); - query.setEntity(new ByteArrayEntity(b)); - fireRawRequest(query); - } catch (IOException e) { - e.printStackTrace(); - return; - } catch (OperationCanceledException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (AuthenticatorException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } while (c.moveToNext()); - // } while (c.moveToNext()); - } - - } - - private String getAddressBookUri() { - if (mAddrBookUri != null) - return mAddrBookUri; - - AccountManager am = getAccountManager(); - @SuppressWarnings("deprecation") - String uri = am.getUserData(getAccount(), - Constants.KEY_OC_URL).replace( - AccountUtils.WEBDAV_PATH_2_0, AccountUtils.CARDDAV_PATH_2_0); - uri += "/addressbooks/" - + getAccount().name.substring(0, - getAccount().name.lastIndexOf('@')) + "/default/"; - mAddrBookUri = uri; - return uri; - } - - private FileInputStream getContactVcard(String lookupKey) - throws IOException { - Uri uri = Uri.withAppendedPath( - ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey); - AssetFileDescriptor fd = getContext().getContentResolver() - .openAssetFileDescriptor(uri, "r"); - return fd.createInputStream(); - } - - private Cursor getLocalContacts(boolean include_hidden_contacts) { - return getContext().getContentResolver().query( - ContactsContract.Contacts.CONTENT_URI, - new String[] { ContactsContract.Contacts._ID, - ContactsContract.Contacts.LOOKUP_KEY }, - ContactsContract.Contacts.IN_VISIBLE_GROUP + " = ?", - new String[] { (include_hidden_contacts ? "0" : "1") }, - ContactsContract.Contacts._ID + " DESC"); - } - -} diff --git a/src/com/owncloud/android/syncadapter/ContactSyncService.java b/src/com/owncloud/android/syncadapter/ContactSyncService.java deleted file mode 100644 index d907bb4912..0000000000 --- a/src/com/owncloud/android/syncadapter/ContactSyncService.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * ownCloud Android client application - * - * Copyright (C) 2012 Bartek Przybylski - * Copyright (C) 2015 ownCloud Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package com.owncloud.android.syncadapter; - -import android.app.Service; -import android.content.Intent; -import android.os.IBinder; - -public class ContactSyncService extends Service { - private static final Object syncAdapterLock = new Object(); - private static AbstractOwnCloudSyncAdapter mSyncAdapter = null; - - @Override - public void onCreate() { - synchronized (syncAdapterLock) { - if (mSyncAdapter == null) { - mSyncAdapter = new ContactSyncAdapter(getApplicationContext(), - true); - } - } - } - - @Override - public IBinder onBind(Intent arg0) { - return mSyncAdapter.getSyncAdapterBinder(); - } - -} diff --git a/src/com/owncloud/android/ui/activity/FileActivity.java b/src/com/owncloud/android/ui/activity/FileActivity.java index a566ccdbed..e3af83687c 100644 --- a/src/com/owncloud/android/ui/activity/FileActivity.java +++ b/src/com/owncloud/android/ui/activity/FileActivity.java @@ -61,7 +61,6 @@ import com.owncloud.android.operations.SynchronizeFolderOperation; import com.owncloud.android.operations.UnshareLinkOperation; import com.owncloud.android.services.OperationsService; import com.owncloud.android.services.OperationsService.OperationsServiceBinder; -import com.owncloud.android.ui.dialog.CreateFolderDialogFragment; import com.owncloud.android.ui.dialog.LoadingDialog; import com.owncloud.android.ui.dialog.SharePasswordDialogFragment; import com.owncloud.android.utils.ErrorMessageAdapter; @@ -152,6 +151,8 @@ public class FileActivity extends SherlockFragmentActivity mFromNotification = getIntent().getBooleanExtra(FileActivity.EXTRA_FROM_NOTIFICATION, false); } + AccountUtils.updateAccountVersion(this); // best place, before any access to AccountManager or database + setAccount(account, savedInstanceState != null); mOperationsServiceConnection = new OperationsServiceConnection(); @@ -168,7 +169,6 @@ public class FileActivity extends SherlockFragmentActivity } - /** * Since ownCloud {@link Account}s can be managed from the system setting menu, * the existence of the {@link Account} associated to the instance must be checked