diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml new file mode 100644 index 00000000..f365456a --- /dev/null +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -0,0 +1,10 @@ +name: "Validate Gradle Wrapper" +on: [pull_request] + +jobs: + validation: + name: "Validation" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: gradle/wrapper-validation-action@v1 diff --git a/.gitignore b/.gitignore index 491cdfc4..172bedd2 100644 --- a/.gitignore +++ b/.gitignore @@ -19,11 +19,6 @@ gen/ # Local configuration files (sdk path, etc) .gradle/ local.properties -sample_client/local.properties # Mac .DS_Store files .DS_Store - -# Proguard README -proguard-project.txt -sample_client/proguard-project.txt \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md index dd4c419d..d3a33d59 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -2,7 +2,7 @@ ownCloud Android Library is available under MIT license -Copyright (C) 2019 ownCloud GmbH. +Copyright (C) 2020 ownCloud GmbH. Copyright (C) 2012 Bartek Przybylski Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/build.gradle b/build.gradle index 8461dad5..6ce35582 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ buildscript { ext { - // Libraries - kotlinVersion = '1.3.50' + kotlinVersion = '1.3.72' + moshiVersion = "1.9.2" } repositories { @@ -9,7 +9,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' + classpath 'com.android.tools.build:gradle:3.6.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion" } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..946d709d --- /dev/null +++ b/gradle.properties @@ -0,0 +1,3 @@ +android.enableJetifier=true +android.useAndroidX=true +org.gradle.jvmargs=-Xmx1536M \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ce011295..2f02f8a6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index a00d52bb..97a1bbae 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -7,7 +7,14 @@ dependencies { api 'com.squareup.okhttp3:okhttp:3.12.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" api 'com.gitlab.ownclouders:dav4android:oc_support_1.0.1' - api 'com.github.hannesa2:Logcat:1.5.6' + api 'com.github.hannesa2:Logcat:1.6.0' + api 'net.openid:appauth:0.7.1' + + // Moshi + implementation ("com.squareup.moshi:moshi-kotlin:$moshiVersion") { + exclude module: "kotlin-reflect" + } + kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshiVersion" } allOpen { @@ -19,11 +26,15 @@ android { compileSdkVersion 28 defaultConfig { - minSdkVersion 19 + minSdkVersion 21 targetSdkVersion 28 - versionCode = 10000400 - versionName = "1.0.4" + versionCode = 10000500 + versionName = "1.0.5" + + // This is pretty ugly but manifest placeholders don't seem to work very well when using different modules + // See https://github.com/openid/AppAuth-Android/issues/325 + manifestPlaceholders = [appAuthRedirectScheme: ''] } lintOptions { diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/DynamicSessionManager.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/DynamicSessionManager.java deleted file mode 100644 index 38fb11e4..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/DynamicSessionManager.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.owncloud.android.lib.common; - -import android.accounts.AuthenticatorException; -import android.accounts.OperationCanceledException; -import android.content.Context; - -import com.owncloud.android.lib.common.accounts.AccountUtils; -import com.owncloud.android.lib.resources.status.OwnCloudVersion; - -import java.io.IOException; - -/** - * Dynamic implementation of {@link OwnCloudClientManager}. - * - * Wraps instances of {@link SingleSessionManager} and {@link SimpleFactoryManager} and delegates on one - * or the other depending on the known version of the server corresponding to the {@link OwnCloudAccount} - * - * @author David A. Velasco - */ - -public class DynamicSessionManager implements OwnCloudClientManager { - - private SimpleFactoryManager mSimpleFactoryManager = new SimpleFactoryManager(); - - private SingleSessionManager mSingleSessionManager = new SingleSessionManager(); - - @Override - public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) - throws AccountUtils.AccountNotFoundException, - OperationCanceledException, AuthenticatorException, IOException { - - OwnCloudVersion ownCloudVersion = null; - if (account.getSavedAccount() != null) { - ownCloudVersion = AccountUtils.getServerVersionForAccount( - account.getSavedAccount(), context - ); - } - - if (ownCloudVersion != null && ownCloudVersion.isSessionMonitoringSupported()) { - return mSingleSessionManager.getClientFor(account, context); - } else { - return mSimpleFactoryManager.getClientFor(account, context); - } - } - - @Override - public OwnCloudClient removeClientFor(OwnCloudAccount account) { - OwnCloudClient clientRemovedFromFactoryManager = mSimpleFactoryManager.removeClientFor(account); - OwnCloudClient clientRemovedFromSingleSessionManager = mSingleSessionManager.removeClientFor(account); - if (clientRemovedFromSingleSessionManager != null) { - return clientRemovedFromSingleSessionManager; - } else { - return clientRemovedFromFactoryManager; - } - // clientRemoved and clientRemoved2 should not be != null at the same time - } - - @Override - public void saveAllClients(Context context, String accountType) { - mSimpleFactoryManager.saveAllClients(context, accountType); - mSingleSessionManager.saveAllClients(context, accountType); - } -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java index d036214d..3ab812d4 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * Copyright (C) 2012 Bartek Przybylski * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -38,12 +38,11 @@ import com.owncloud.android.lib.common.http.HttpClient; import com.owncloud.android.lib.common.http.HttpConstants; import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; import com.owncloud.android.lib.common.network.RedirectionPath; -import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.common.utils.RandomUtils; import com.owncloud.android.lib.resources.status.OwnCloudVersion; import okhttp3.Cookie; -import okhttp3.Headers; import okhttp3.HttpUrl; +import timber.log.Timber; import java.io.IOException; import java.io.InputStream; @@ -54,11 +53,10 @@ import static com.owncloud.android.lib.common.http.HttpConstants.OC_X_REQUEST_ID public class OwnCloudClient extends HttpClient { public static final String WEBDAV_FILES_PATH_4_0 = "/remote.php/dav/files/"; - public static final String WEBDAV_UPLOADS_PATH_4_0 = "/remote.php/dav/uploads/"; + public static final String WEBDAV_PATH_4_0_AND_LATER = "/remote.php/dav"; + private static final String WEBDAV_UPLOADS_PATH_4_0 = "/remote.php/dav/uploads/"; public static final String STATUS_PATH = "/status.php"; - public static final String FILES_WEB_PATH = "/index.php/apps/files"; - private static final String TAG = OwnCloudClient.class.getSimpleName(); private static final int MAX_REDIRECTIONS_COUNT = 3; private static final int MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS = 1; @@ -70,13 +68,8 @@ public class OwnCloudClient extends HttpClient { private OwnCloudVersion mVersion = null; private OwnCloudAccount mAccount; - /** - * {@link @OwnCloudClientManager} holding a reference to this object and delivering it to callers; might be - * NULL - */ - private OwnCloudClientManager mOwnCloudClientManager = null; + private SingleSessionManager mSingleSessionManager = null; - private String mRedirectedLocation; private boolean mFollowRedirects; public OwnCloudClient(Uri baseUri) { @@ -86,7 +79,7 @@ public class OwnCloudClient extends HttpClient { mBaseUri = baseUri; mInstanceNumber = sIntanceCounter++; - Log_OC.d(TAG + " #" + mInstanceNumber, "Creating OwnCloudClient"); + Timber.d("#" + mInstanceNumber + "Creating OwnCloudClient"); clearCredentials(); clearCookies(); @@ -99,7 +92,7 @@ public class OwnCloudClient extends HttpClient { mCredentials.applyTo(this); } - public void applyCredentials() { + void applyCredentials() { mCredentials.applyTo(this); } @@ -112,7 +105,6 @@ public class OwnCloudClient extends HttpClient { setRequestId(method); status = method.execute(); - checkFirstRedirection(method); if (mFollowRedirects) { status = followRedirection(method).getLastStatus(); @@ -127,13 +119,6 @@ public class OwnCloudClient extends HttpClient { return status; } - private void checkFirstRedirection(HttpBaseMethod method) { - final String location = method.getResponseHeader(HttpConstants.LOCATION_HEADER_LOWER); - if (location != null && !location.isEmpty()) { - mRedirectedLocation = location; - } - } - private int executeRedirectedHttpMethod(HttpBaseMethod method) throws Exception { boolean repeatWithFreshCredentials; int repeatCounter = 0; @@ -163,7 +148,7 @@ public class OwnCloudClient extends HttpClient { // Header to allow tracing requests in apache and ownCloud logs addHeaderForAllRequests(OC_X_REQUEST_ID, requestId); - Log_OC.d(TAG, "Executing " + method.getClass().getSimpleName() + " in request with id " + requestId); + Timber.d("Executing in request with id %s", requestId); } public RedirectionPath followRedirection(HttpBaseMethod method) throws Exception { @@ -175,15 +160,14 @@ public class OwnCloudClient extends HttpClient { (status == HttpConstants.HTTP_MOVED_PERMANENTLY || status == HttpConstants.HTTP_MOVED_TEMPORARILY || status == HttpConstants.HTTP_TEMPORARY_REDIRECT) - ) { + ) { final String location = method.getResponseHeader(HttpConstants.LOCATION_HEADER) != null ? method.getResponseHeader(HttpConstants.LOCATION_HEADER) : method.getResponseHeader(HttpConstants.LOCATION_HEADER_LOWER); if (location != null) { - Log_OC.d(TAG + " #" + mInstanceNumber, - "Location to redirect: " + location); + Timber.d("#" + mInstanceNumber + "Location to redirect: " + location); redirectionPath.addLocation(location); @@ -216,7 +200,7 @@ public class OwnCloudClient extends HttpClient { redirectionsCount++; } else { - Log_OC.d(TAG + " #" + mInstanceNumber, "No location to redirect!"); + Timber.d(" #" + mInstanceNumber + "No location to redirect!"); status = HttpConstants.HTTP_NOT_FOUND; } } @@ -237,8 +221,7 @@ public class OwnCloudClient extends HttpClient { responseBodyAsStream.close(); } catch (IOException io) { - Log_OC.e(TAG, "Unexpected exception while exhausting not interesting HTTP response;" + - " will be IGNORED", io); + Timber.e(io, "Unexpected exception while exhausting not interesting HTTP response; will be IGNORED"); } } } @@ -248,7 +231,7 @@ public class OwnCloudClient extends HttpClient { } public Uri getUserFilesWebDavUri() { - return mCredentials instanceof OwnCloudAnonymousCredentials + return (mCredentials instanceof OwnCloudAnonymousCredentials || mAccount == null) ? Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0) : Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0 + AccountUtils.getUserId( mAccount.getSavedAccount(), getContext() @@ -296,38 +279,6 @@ public class OwnCloudClient extends HttpClient { } } - private void logCookie(Cookie cookie) { - Log_OC.d(TAG, "Cookie name: " + cookie.name()); - Log_OC.d(TAG, " value: " + cookie.value()); - Log_OC.d(TAG, " domain: " + cookie.domain()); - Log_OC.d(TAG, " path: " + cookie.path()); - Log_OC.d(TAG, " expiryDate: " + cookie.expiresAt()); - Log_OC.d(TAG, " secure: " + cookie.secure()); - } - - private void logCookiesAtRequest(Headers headers, String when) { - int counter = 0; - for (final String cookieHeader : headers.toMultimap().get("cookie")) { - Log_OC.d(TAG + " #" + mInstanceNumber, - "Cookies at request (" + when + ") (" + counter++ + "): " - + cookieHeader); - } - if (counter == 0) { - Log_OC.d(TAG + " #" + mInstanceNumber, "No cookie at request before"); - } - } - - private void logSetCookiesAtResponse(Headers headers) { - int counter = 0; - for (final String cookieHeader : headers.toMultimap().get("set-cookie")) { - Log_OC.d(TAG + " #" + mInstanceNumber, - "Set-Cookie (" + counter++ + "): " + cookieHeader); - } - if (counter == 0) { - Log_OC.d(TAG + " #" + mInstanceNumber, "No set-cookie"); - } - } - public String getCookiesString() { StringBuilder cookiesString = new StringBuilder(); List cookieList = getCookiesFromUrl(HttpUrl.parse(mBaseUri.toString())); @@ -384,7 +335,6 @@ public class OwnCloudClient extends HttpClient { if (invalidated) { if (getCredentials().authTokenCanBeRefreshed() && repeatCounter < MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS) { - try { mAccount.loadCredentials(getContext()); // if mAccount.getCredentials().length() == 0 --> refresh failed @@ -392,18 +342,16 @@ public class OwnCloudClient extends HttpClient { credentialsWereRefreshed = true; } catch (AccountsException | IOException e) { - Log_OC.e( - TAG, - "Error while trying to refresh auth token for " + mAccount.getSavedAccount().name, - e + Timber.e(e, "Error while trying to refresh auth token for %s", + mAccount.getSavedAccount().name ); } } - if (!credentialsWereRefreshed && mOwnCloudClientManager != null) { + if (!credentialsWereRefreshed && mSingleSessionManager != null) { // if credentials are not refreshed, client must be removed // from the OwnCloudClientManager to prevent it is reused once and again - mOwnCloudClientManager.removeClientFor(mAccount); + mSingleSessionManager.removeClientFor(mAccount); } } // else: onExecute will finish with status 401 @@ -421,21 +369,21 @@ public class OwnCloudClient extends HttpClient { * cannot be invalidated with the given arguments. */ private boolean shouldInvalidateAccountCredentials(int httpStatusCode) { + boolean shouldInvalidateAccountCredentials = + (httpStatusCode == HttpConstants.HTTP_UNAUTHORIZED); - boolean should = (httpStatusCode == HttpConstants.HTTP_UNAUTHORIZED); // invalid credentials - - should &= (mCredentials != null && // real credentials + shouldInvalidateAccountCredentials &= (mCredentials != null && // real credentials !(mCredentials instanceof OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials)); // test if have all the needed to effectively invalidate ... - should &= (mAccount != null && mAccount.getSavedAccount() != null && getContext() != null); + shouldInvalidateAccountCredentials &= (mAccount != null && mAccount.getSavedAccount() != null && getContext() != null); - return should; + return shouldInvalidateAccountCredentials; } /** * Invalidates credentials stored for the given account in the system {@link AccountManager} and in - * current {@link OwnCloudClientManagerFactory#getDefaultSingleton()} instance. + * current {@link SingleSessionManager#getDefaultSingleton()} instance. *

* {@link #shouldInvalidateAccountCredentials(int)} should be called first. * @@ -451,14 +399,6 @@ public class OwnCloudClient extends HttpClient { return true; } - public OwnCloudClientManager getOwnCloudClientManager() { - return mOwnCloudClientManager; - } - - void setOwnCloudClientManager(OwnCloudClientManager clientManager) { - mOwnCloudClientManager = clientManager; - } - public boolean followRedirects() { return mFollowRedirects; } @@ -466,4 +406,4 @@ public class OwnCloudClient extends HttpClient { public void setFollowRedirects(boolean followRedirects) { this.mFollowRedirects = followRedirects; } -} \ No newline at end of file +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClientFactory.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClientFactory.java index 6fb5345f..d78e4d6a 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClientFactory.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClientFactory.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,8 +29,6 @@ import android.net.Uri; public class OwnCloudClientFactory { - final private static String TAG = OwnCloudClientFactory.class.getSimpleName(); - /** * Creates a OwnCloudClient to access a URL and sets the desired parameters for ownCloud * client connections. @@ -39,8 +37,7 @@ public class OwnCloudClientFactory { * @param context Android context where the OwnCloudClient is being created. * @return A OwnCloudClient object ready to be used */ - public static OwnCloudClient createOwnCloudClient(Uri uri, Context context, - boolean followRedirects) { + public static OwnCloudClient createOwnCloudClient(Uri uri, Context context, boolean followRedirects) { OwnCloudClient client = new OwnCloudClient(uri); client.setFollowRedirects(followRedirects); @@ -49,4 +46,4 @@ public class OwnCloudClientFactory { return client; } -} \ No newline at end of file +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClientManagerFactory.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClientManagerFactory.java deleted file mode 100644 index 14944a15..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClientManagerFactory.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ -package com.owncloud.android.lib.common; - -public class OwnCloudClientManagerFactory { - - private static Policy sDefaultPolicy = Policy.ALWAYS_NEW_CLIENT; - private static OwnCloudClientManager sDefaultSingleton; - private static String sUserAgent; - - public static OwnCloudClientManager newDefaultOwnCloudClientManager() { - return newOwnCloudClientManager(sDefaultPolicy); - } - - public static OwnCloudClientManager newOwnCloudClientManager(Policy policy) { - switch (policy) { - case ALWAYS_NEW_CLIENT: - return new SimpleFactoryManager(); - - case SINGLE_SESSION_PER_ACCOUNT_IF_SERVER_SUPPORTS_SERVER_MONITORING: - return new DynamicSessionManager(); - - default: - throw new IllegalArgumentException("Unknown policy"); - } - } - - public static OwnCloudClientManager getDefaultSingleton() { - if (sDefaultSingleton == null) { - sDefaultSingleton = newDefaultOwnCloudClientManager(); - } - return sDefaultSingleton; - } - - public static Policy getDefaultPolicy() { - return sDefaultPolicy; - } - - public static void setDefaultPolicy(Policy policy) { - if (policy == null) { - throw new IllegalArgumentException("Default policy cannot be NULL"); - } - if (defaultSingletonMustBeUpdated(policy)) { - sDefaultSingleton = null; - } - sDefaultPolicy = policy; - } - - public static String getUserAgent() { - return sUserAgent; - } - - public static void setUserAgent(String userAgent) { - sUserAgent = userAgent; - } - - private static boolean defaultSingletonMustBeUpdated(Policy policy) { - if (sDefaultSingleton == null) { - return false; - } - return policy == Policy.ALWAYS_NEW_CLIENT && !(sDefaultSingleton instanceof SimpleFactoryManager); - } - - public enum Policy { - ALWAYS_NEW_CLIENT, - SINGLE_SESSION_PER_ACCOUNT_IF_SERVER_SUPPORTS_SERVER_MONITORING - } -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/SimpleFactoryManager.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/SimpleFactoryManager.java deleted file mode 100644 index 46f722e9..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/SimpleFactoryManager.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * Copyright (C) 2016 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common; - -import android.accounts.AuthenticatorException; -import android.accounts.OperationCanceledException; -import android.content.Context; - -import com.owncloud.android.lib.common.accounts.AccountUtils; -import com.owncloud.android.lib.common.utils.Log_OC; - -import java.io.IOException; - -public class SimpleFactoryManager implements OwnCloudClientManager { - - private static final String TAG = SimpleFactoryManager.class.getSimpleName(); - - @Override - public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) throws - OperationCanceledException, AuthenticatorException, IOException { - - Log_OC.d(TAG, "getClientFor(OwnCloudAccount ... : "); - - OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient( - account.getBaseUri(), - context.getApplicationContext(), - true); - - Log_OC.v(TAG, " new client {" + - (account.getName() != null ? - account.getName() : - AccountUtils.buildAccountName(account.getBaseUri(), "") - - ) + ", " + client.hashCode() + "}"); - - if (account.getCredentials() == null) { - account.loadCredentials(context); - } - client.setCredentials(account.getCredentials()); - client.setAccount(account); - client.setContext(context); - client.setOwnCloudClientManager(this); - return client; - } - - @Override - public OwnCloudClient removeClientFor(OwnCloudAccount account) { - // nothing to do - not taking care of tracking instances! - return null; - } - - @Override - public void saveAllClients(Context context, String accountType) { - // nothing to do - not taking care of tracking instances! - } - -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/SingleSessionManager.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/SingleSessionManager.java index 21bdf925..f448e45b 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/SingleSessionManager.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/SingleSessionManager.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,11 +30,10 @@ import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; import android.content.Context; import android.net.Uri; -import android.util.Log; import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.http.HttpClient; -import com.owncloud.android.lib.common.utils.Log_OC; +import timber.log.Timber; import java.io.IOException; import java.util.Iterator; @@ -42,31 +41,39 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** - * Implementation of {@link OwnCloudClientManager} - *

- * TODO check multithreading safety - * * @author David A. Velasco * @author masensio * @author Christian Schabesberger * @author David González Verdugo */ -public class SingleSessionManager implements OwnCloudClientManager { +public class SingleSessionManager { - private static final String TAG = SingleSessionManager.class.getSimpleName(); + private static SingleSessionManager sDefaultSingleton; + private static String sUserAgent; private ConcurrentMap mClientsWithKnownUsername = new ConcurrentHashMap<>(); - private ConcurrentMap mClientsWithUnknownUsername = new ConcurrentHashMap<>(); - @Override + public static SingleSessionManager getDefaultSingleton() { + if (sDefaultSingleton == null) { + sDefaultSingleton = new SingleSessionManager(); + } + return sDefaultSingleton; + } + + public static String getUserAgent() { + return sUserAgent; + } + + public static void setUserAgent(String userAgent) { + sUserAgent = userAgent; + } + public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) throws OperationCanceledException, AuthenticatorException, IOException { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log_OC.d(TAG, "getClientFor starting "); - } + Timber.d("getClientFor starting "); if (account == null) { throw new IllegalArgumentException("Cannot get an OwnCloudClient for a null account"); } @@ -84,21 +91,16 @@ public class SingleSessionManager implements OwnCloudClientManager { if (accountName != null) { client = mClientsWithUnknownUsername.remove(sessionName); if (client != null) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log_OC.v(TAG, "reusing client for session " + sessionName); - } + Timber.v("reusing client for session %s", sessionName); + mClientsWithKnownUsername.put(accountName, client); - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log_OC.v(TAG, "moved client to account " + accountName); - } + Timber.v("moved client to account %s", accountName); } } else { client = mClientsWithUnknownUsername.get(sessionName); } } else { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log_OC.v(TAG, "reusing client for account " + accountName); - } + Timber.v("reusing client for account %s", accountName); reusingKnown = true; } @@ -110,47 +112,36 @@ public class SingleSessionManager implements OwnCloudClientManager { true); // TODO remove dependency on OwnCloudClientFactory client.setAccount(account); HttpClient.setContext(context); - client.setOwnCloudClientManager(this); account.loadCredentials(context); client.setCredentials(account.getCredentials()); if (accountName != null) { mClientsWithKnownUsername.put(accountName, client); - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log_OC.v(TAG, "new client for account " + accountName); - } + Timber.v("new client for account %s", accountName); } else { mClientsWithUnknownUsername.put(sessionName, client); - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log_OC.v(TAG, "new client for session " + sessionName); - } + Timber.v("new client for session %s", sessionName); } } else { - if (!reusingKnown && Log.isLoggable(TAG, Log.VERBOSE)) { - Log_OC.v(TAG, "reusing client for session " + sessionName); + if (!reusingKnown) { + Timber.v("reusing client for session %s", sessionName); } keepCredentialsUpdated(client); keepCookiesUpdated(context, account, client); keepUriUpdated(account, client); } - - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log_OC.d(TAG, "getClientFor finishing "); - } + Timber.d("getClientFor finishing "); return client; } - @Override - public OwnCloudClient removeClientFor(OwnCloudAccount account) { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log_OC.d(TAG, "removeClientFor starting "); - } + public void removeClientFor(OwnCloudAccount account) { + Timber.d("removeClientFor starting "); if (account == null) { - return null; + return; } OwnCloudClient client; @@ -158,31 +149,20 @@ public class SingleSessionManager implements OwnCloudClientManager { if (accountName != null) { client = mClientsWithKnownUsername.remove(accountName); if (client != null) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log_OC.v(TAG, "Removed client for account " + accountName); - } - return client; + Timber.v("Removed client for account %s", accountName); + return; } else { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log_OC.v(TAG, "No client tracked for account " + accountName); - } + Timber.v("No client tracked for account %s", accountName); } } mClientsWithUnknownUsername.clear(); - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log_OC.d(TAG, "removeClientFor finishing "); - } - return null; + Timber.d("removeClientFor finishing "); } - @Override public void saveAllClients(Context context, String accountType) { - - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log_OC.d(TAG, "Saving sessions... "); - } + Timber.d("Saving sessions... "); Iterator accountNames = mClientsWithKnownUsername.keySet().iterator(); String accountName; @@ -193,9 +173,7 @@ public class SingleSessionManager implements OwnCloudClientManager { AccountUtils.saveClient(mClientsWithKnownUsername.get(accountName), account, context); } - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log_OC.d(TAG, "All sessions saved"); - } + Timber.d("All sessions saved"); } private void keepCredentialsUpdated(OwnCloudClient reusedClient) { diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/accounts/AccountTypeUtils.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/accounts/AccountTypeUtils.java index 1d40884e..2c2f2397 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/accounts/AccountTypeUtils.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/accounts/AccountTypeUtils.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/accounts/AccountUtils.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/accounts/AccountUtils.java index 2be339d8..40d1013a 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/accounts/AccountUtils.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/accounts/AccountUtils.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * Copyright (C) 2012 Bartek Przybylski * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -36,19 +36,16 @@ import android.net.Uri; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory; -import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.files.FileUtils; import com.owncloud.android.lib.resources.status.OwnCloudVersion; import okhttp3.Cookie; +import timber.log.Timber; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class AccountUtils { - - private static final String TAG = AccountUtils.class.getSimpleName(); - /** * Constructs full url to host and webdav resource basing on host version * @@ -66,7 +63,7 @@ public class AccountUtils { webDavUrlForAccount = getBaseUrlForAccount(context, account) + OwnCloudClient.WEBDAV_FILES_PATH_4_0 + ownCloudCredentials.getUsername(); } catch (OperationCanceledException | AuthenticatorException | IOException e) { - e.printStackTrace(); + Timber.e(e); } return webDavUrlForAccount; @@ -104,7 +101,7 @@ public class AccountUtils { try { username = account.name.substring(0, account.name.lastIndexOf('@')); } catch (Exception e) { - Log_OC.e(TAG, "Couldn't get a username for the given account", e); + Timber.e(e, "Couldn't get a username for the given account"); } return username; } @@ -124,7 +121,7 @@ public class AccountUtils { version = new OwnCloudVersion(versionString); } catch (Exception e) { - Log_OC.e(TAG, "Couldn't get a the server version for an account", e); + Timber.e(e, "Couldn't get a the server version for an account"); } return version; } @@ -142,10 +139,9 @@ public class AccountUtils { AccountManager am = AccountManager.get(context); String supportsOAuth2 = am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_OAUTH2); - boolean isOauth2 = supportsOAuth2 != null && supportsOAuth2.equals("TRUE"); + boolean isOauth2 = supportsOAuth2 != null && supportsOAuth2.equals(Constants.OAUTH_SUPPORTED_TRUE); String username = AccountUtils.getUsernameForAccount(account); - OwnCloudVersion version = new OwnCloudVersion(am.getUserData(account, Constants.KEY_OC_VERSION)); if (isOauth2) { String accessToken = am.blockingGetAuthToken( @@ -154,7 +150,6 @@ public class AccountUtils { false); credentials = OwnCloudCredentialsFactory.newBearerCredentials(username, accessToken); - } else { String password = am.blockingGetAuthToken( account, @@ -163,8 +158,7 @@ public class AccountUtils { credentials = OwnCloudCredentialsFactory.newBasicCredentials( username, - password, - version.isPreemptiveAuthenticationPreferred() + password ); } @@ -203,9 +197,8 @@ public class AccountUtils { if (url.contains("://")) { url = url.substring(serverBaseUrl.toString().indexOf("://") + 3); } - String accountName = username + "@" + url; - return accountName; + return username + "@" + url; } public static void saveClient(OwnCloudClient client, Account savedAccount, Context context) { @@ -216,7 +209,7 @@ public class AccountUtils { String cookiesString = client.getCookiesString(); if (!"".equals(cookiesString)) { ac.setUserData(savedAccount, Constants.KEY_COOKIES, cookiesString); - Log_OC.d(TAG, "Saving Cookies: " + cookiesString); + Timber.d("Saving Cookies: %s", cookiesString); } } } @@ -230,10 +223,10 @@ public class AccountUtils { */ public static void restoreCookies(Account account, OwnCloudClient client, Context context) { if (account == null) { - Log_OC.d(TAG, "Cannot restore cookie for null account"); + Timber.d("Cannot restore cookie for null account"); } else { - Log_OC.d(TAG, "Restoring cookies for " + account.name); + Timber.d("Restoring cookies for %s", account.name); // Account Manager AccountManager am = AccountManager.get(context.getApplicationContext()); @@ -299,8 +292,12 @@ public class AccountUtils { /** * Flag signaling if the ownCloud server can be accessed with OAuth2 access tokens. */ + + // TODO Please review this constants, move them out of the library, the rest of OAuth variables are in data layer public static final String KEY_SUPPORTS_OAUTH2 = "oc_supports_oauth2"; + public static final String OAUTH_SUPPORTED_TRUE = "TRUE"; + /** * OC account cookies */ @@ -321,9 +318,6 @@ public class AccountUtils { */ public static final String KEY_DISPLAY_NAME = "oc_display_name"; - /** - * OAuth2 refresh token - **/ - public static final String KEY_OAUTH2_REFRESH_TOKEN = "oc_oauth2_refresh_token"; + public static final int ACCOUNT_VERSION = 1; } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudBasicCredentials.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudBasicCredentials.java index ab1ba3ef..af3e9d75 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudBasicCredentials.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudBasicCredentials.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,8 +31,6 @@ import okhttp3.internal.Util; public class OwnCloudBasicCredentials implements OwnCloudCredentials { - private static final String TAG = OwnCloudCredentials.class.getSimpleName(); - private String mUsername; private String mPassword; diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudBearerCredentials.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudBearerCredentials.java index 573307a0..e455cb39 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudBearerCredentials.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudBearerCredentials.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudCredentialsFactory.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudCredentialsFactory.java index 822ef760..75b523cc 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudCredentialsFactory.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/OwnCloudCredentialsFactory.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,12 +38,6 @@ public class OwnCloudCredentialsFactory { return new OwnCloudBasicCredentials(username, password); } - public static OwnCloudCredentials newBasicCredentials( - String username, String password, boolean preemptiveMode - ) { - return new OwnCloudBasicCredentials(username, password, preemptiveMode); - } - public static OwnCloudCredentials newBearerCredentials(String username, String authToken) { return new OwnCloudBearerCredentials(username, authToken); } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/BearerCredentials.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/BearerCredentials.java deleted file mode 100644 index 6f7e9a6e..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/BearerCredentials.java +++ /dev/null @@ -1,95 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.authentication.oauth; - -/** - * @author David A. Velasco - * @author Christian Schabesberger - */ -public class BearerCredentials { - - public static final int HASH_SEED = 17; - public static final int HASH_OFFSET = 37; - - private String mAccessToken; - - /** - * The constructor with the bearer token - * - * @param token The bearer token - */ - public BearerCredentials(String token) { - mAccessToken = (token == null) ? "" : token; - } - - /** - * Returns the access token - * - * @return The access token - */ - public String getAccessToken() { - return mAccessToken; - } - - /** - * Get this object string. - * - * @return The access token - */ - public String toString() { - return mAccessToken; - } - - /** - * Does a hash of the access token. - * - * @return The hash code of the access token - */ - public int hashCode() { - return HASH_SEED * HASH_OFFSET + mAccessToken.hashCode(); - } - - /** - * These credentials are assumed equal if accessToken is the same. - * - * @param o The other object to compare with. - * @return 'True' if the object is equivalent. - */ - public boolean equals(Object o) { - if (o == null) { - return false; - } - if (this == o) { - return true; - } - if (this.getClass().equals(o.getClass())) { - BearerCredentials that = (BearerCredentials) o; - if (mAccessToken.equals(that.mAccessToken)) { - return true; - } - } - return false; - } -} \ No newline at end of file diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2Constants.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2Constants.java deleted file mode 100644 index 97dbfc41..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2Constants.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * - * @author David A. Velasco - * Copyright (C) 2017 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.authentication.oauth; - -/** - * Constant values for OAuth 2 protocol. - *

- * Includes required and optional parameter NAMES used in the 'authorization code' grant type. - */ - -public class OAuth2Constants { - - /// Parameters to send to the Authorization Endpoint - public static final String KEY_RESPONSE_TYPE = "response_type"; - public static final String KEY_REDIRECT_URI = "redirect_uri"; - public static final String KEY_CLIENT_ID = "client_id"; - public static final String KEY_SCOPE = "scope"; - public static final String KEY_STATE = "state"; - - /// Additional parameters to send to the Token Endpoint - public static final String KEY_GRANT_TYPE = "grant_type"; - public static final String KEY_CODE = "code"; - - // Used to get the Access Token using Refresh Token - public static final String OAUTH2_REFRESH_TOKEN_GRANT_TYPE = "refresh_token"; - - /// Parameters received in an OK response from the Token Endpoint - public static final String KEY_ACCESS_TOKEN = "access_token"; - public static final String KEY_TOKEN_TYPE = "token_type"; - public static final String KEY_EXPIRES_IN = "expires_in"; - public static final String KEY_REFRESH_TOKEN = "refresh_token"; - - /// Parameters in an ERROR response - public static final String KEY_ERROR = "error"; - public static final String KEY_ERROR_DESCRIPTION = "error_description"; - public static final String KEY_ERROR_URI = "error_uri"; - public static final String VALUE_ERROR_ACCESS_DENIED = "access_denied"; - - /// Extra not standard - public static final String KEY_USER_ID = "user_id"; - - /// Depends on oauth2 grant type - public static final String OAUTH2_RESPONSE_TYPE_CODE = "code"; -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2GetAccessTokenOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2GetAccessTokenOperation.java deleted file mode 100644 index c5273215..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2GetAccessTokenOperation.java +++ /dev/null @@ -1,141 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * - * @author David A. Velasco - * @author Christian Schabesberger - * Copyright (C) 2019 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.authentication.oauth; - -import android.net.Uri; - -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials; -import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; -import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; -import okhttp3.MultipartBody; -import okhttp3.RequestBody; -import org.json.JSONObject; - -import java.net.URL; -import java.util.Map; - -public class OAuth2GetAccessTokenOperation extends RemoteOperation> { - - private final String mAccessTokenEndpointPath; - private final OAuth2ResponseParser mResponseParser; - private String mGrantType; - private String mCode; - private String mClientId; - private String mClientSecret; - private String mRedirectUri; - - public OAuth2GetAccessTokenOperation( - String grantType, - String code, - String clientId, - String secretId, - String redirectUri, - String accessTokenEndpointPath - ) { - mClientId = clientId; - mClientSecret = secretId; - mRedirectUri = redirectUri; - mGrantType = grantType; - mCode = code; - - mAccessTokenEndpointPath = - accessTokenEndpointPath != null ? - accessTokenEndpointPath : - OwnCloudOAuth2Provider.ACCESS_TOKEN_ENDPOINT_PATH - ; - - mResponseParser = new OAuth2ResponseParser(); - } - - @Override - protected RemoteOperationResult run(OwnCloudClient client) { - RemoteOperationResult> result = null; - - try { - - final RequestBody requestBody = new MultipartBody.Builder() - .setType(MultipartBody.FORM) - .addFormDataPart(OAuth2Constants.KEY_GRANT_TYPE, mGrantType) - .addFormDataPart(OAuth2Constants.KEY_CODE, mCode) - .addFormDataPart(OAuth2Constants.KEY_REDIRECT_URI, mRedirectUri) - .addFormDataPart(OAuth2Constants.KEY_CLIENT_ID, mClientId) - .build(); - - Uri.Builder uriBuilder = client.getBaseUri().buildUpon(); - uriBuilder.appendEncodedPath(mAccessTokenEndpointPath); - - final PostMethod postMethod = new PostMethod(new URL( - client.getBaseUri().buildUpon() - .appendEncodedPath(mAccessTokenEndpointPath) - .build() - .toString())); - - postMethod.setRequestBody(requestBody); - - OwnCloudCredentials oauthCredentials = - new OwnCloudBasicCredentials(mClientId, mClientSecret); - OwnCloudCredentials oldCredentials = switchClientCredentials(oauthCredentials); - client.executeHttpMethod(postMethod); - switchClientCredentials(oldCredentials); - - String response = postMethod.getResponseBodyAsString(); - if (response != null && response.length() > 0) { - JSONObject tokenJson = new JSONObject(response); - Map accessTokenResult = - mResponseParser.parseAccessTokenResult(tokenJson); - if (accessTokenResult.get(OAuth2Constants.KEY_ERROR) != null || - accessTokenResult.get(OAuth2Constants.KEY_ACCESS_TOKEN) == null) { - result = new RemoteOperationResult<>(ResultCode.OAUTH2_ERROR); - - } else { - result = new RemoteOperationResult<>(ResultCode.OK); - result.setData(accessTokenResult); - } - - } else { - result = new RemoteOperationResult<>(ResultCode.OK); - client.exhaustResponse(postMethod.getResponseBodyAsStream()); - } - - } catch (Exception e) { - result = new RemoteOperationResult<>(e); - - } - return result; - } - - private OwnCloudCredentials switchClientCredentials(OwnCloudCredentials newCredentials) { - OwnCloudCredentials previousCredentials = getClient().getCredentials(); - getClient().setCredentials(newCredentials); - return previousCredentials; - } -} \ No newline at end of file diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2Provider.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2Provider.java deleted file mode 100644 index e8f598cd..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2Provider.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * - * @author David A. Velasco - * Copyright (C) 2017 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.authentication.oauth; - -public interface OAuth2Provider { - - /** - * {@link OAuth2RequestBuilder} implementation for this provider. - * - * @return {@link OAuth2RequestBuilder} implementation. - */ - OAuth2RequestBuilder getOperationBuilder(); - - /** - * Configuration of the client that is using this {@link OAuth2Provider} - * return Configuration of the client that is usinng this {@link OAuth2Provider} - */ - OAuth2ClientConfiguration getClientConfiguration(); - - /** - * Set configuration of the client that will use this {@link OAuth2Provider} - * - * @param oAuth2ClientConfiguration Configuration of the client that will use this {@link OAuth2Provider} - */ - void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration); - - /** - * base URI to authorization server. - * - * @return Base URL to authorization server. - */ - String getAuthorizationServerUri(); - - /** - * Set base URI to authorization server. - * - * @param authorizationServerUri Set base URL to authorization server. - */ - void setAuthorizationServerUri(String authorizationServerUri); - -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2ProvidersRegistry.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2ProvidersRegistry.java deleted file mode 100644 index 16e3b9ac..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2ProvidersRegistry.java +++ /dev/null @@ -1,121 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * - * @author David A. Velasco - * Copyright (C) 2017 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.authentication.oauth; - -import java.util.HashMap; -import java.util.Map; - -public class OAuth2ProvidersRegistry { - - private Map mProviders = new HashMap<>(); - - private OAuth2Provider mDefaultProvider = null; - - private OAuth2ProvidersRegistry() { - } - - /** - * Singleton accesor. - * - * @return Singleton isntance of {@link OAuth2ProvidersRegistry} - */ - public static OAuth2ProvidersRegistry getInstance() { - return LazyHolder.INSTANCE; - } - - /** - * Register an {@link OAuth2Provider} with the name passed as parameter. - * - * @param name Name to bind 'oAuthProvider' in the registry. - * @param oAuth2Provider An {@link OAuth2Provider} instance to keep in the registry. - * @throws IllegalArgumentException if 'name' or 'oAuthProvider' are null. - */ - public void registerProvider(String name, OAuth2Provider oAuth2Provider) { - if (name == null) { - throw new IllegalArgumentException("Name must not be NULL"); - } - if (oAuth2Provider == null) { - throw new IllegalArgumentException("oAuth2Provider must not be NULL"); - } - - mProviders.put(name, oAuth2Provider); - if (mProviders.size() == 1) { - mDefaultProvider = oAuth2Provider; - } - } - - public OAuth2Provider unregisterProvider(String name) { - OAuth2Provider unregisteredProvider = mProviders.remove(name); - if (mProviders.size() == 0) { - mDefaultProvider = null; - } else if (unregisteredProvider != null && unregisteredProvider == mDefaultProvider) { - mDefaultProvider = mProviders.values().iterator().next(); - } - return unregisteredProvider; - } - - /** - * Get default {@link OAuth2Provider}. - * - * @return Default provider, or NULL if there is no provider. - */ - public OAuth2Provider getProvider() { - return mDefaultProvider; - } - - /** - * Get {@link OAuth2Provider} registered with the name passed as parameter. - * - * @param name Name used to register the desired {@link OAuth2Provider} - * @return {@link OAuth2Provider} registered with the name 'name' - */ - public OAuth2Provider getProvider(String name) { - return mProviders.get(name); - } - - /** - * Sets the {@link OAuth2Provider} registered with the name passed as parameter as the default provider - * - * @param name Name used to register the {@link OAuth2Provider} to set as default. - * @return {@link OAuth2Provider} set as default, or NULL if no provider was registered with 'name'. - */ - public OAuth2Provider setDefaultProvider(String name) { - OAuth2Provider toDefault = mProviders.get(name); - if (toDefault != null) { - mDefaultProvider = toDefault; - } - return toDefault; - } - - /** - * See https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom - */ - private static class LazyHolder { - private static final OAuth2ProvidersRegistry INSTANCE = new OAuth2ProvidersRegistry(); - } - -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2QueryParser.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2QueryParser.java deleted file mode 100644 index aacd8bab..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2QueryParser.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * - * @author David A. Velasco - * Copyright (C) 2017 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.authentication.oauth; - -import com.owncloud.android.lib.common.utils.Log_OC; - -import java.util.HashMap; -import java.util.Map; - -public class OAuth2QueryParser { - - private static final String TAG = OAuth2QueryParser.class.getName(); - - private Map mOAuth2ParsedAuthorizationResponse; - - public OAuth2QueryParser() { - mOAuth2ParsedAuthorizationResponse = new HashMap<>(); - } - - public Map parse(String query) { - mOAuth2ParsedAuthorizationResponse.clear(); - - if (query != null) { - String[] pairs = query.split("&"); - int i = 0; - String key = ""; - String value; - while (pairs.length > i) { - int j = 0; - String[] part = pairs[i].split("="); - while (part.length > j) { - String p = part[j]; - if (j == 0) { - key = p; - } else if (j == 1) { - value = p; - mOAuth2ParsedAuthorizationResponse.put(key, value); - } - - Log_OC.v(TAG, "[" + i + "," + j + "] = " + p); - j++; - } - i++; - } - } - - return mOAuth2ParsedAuthorizationResponse; - } - -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2RefreshAccessTokenOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2RefreshAccessTokenOperation.java deleted file mode 100644 index 5f788831..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2RefreshAccessTokenOperation.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * ownCloud Android client application - * - * @author David González Verdugo - * @author Christian Schabesberger - *

- * Copyright (C) 2019 ownCloud GmbH. - *

- * 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.lib.common.authentication.oauth; - -import android.net.Uri; - -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials; -import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; -import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; -import com.owncloud.android.lib.common.utils.Log_OC; -import okhttp3.MultipartBody; -import okhttp3.RequestBody; -import org.json.JSONObject; - -import java.net.URL; -import java.util.Map; - -public class OAuth2RefreshAccessTokenOperation extends RemoteOperation> { - - private static final String TAG = OAuth2RefreshAccessTokenOperation.class.getSimpleName(); - private final String mAccessTokenEndpointPath; - private final OAuth2ResponseParser mResponseParser; - private String mClientId; - private String mClientSecret; - private String mRefreshToken; - - public OAuth2RefreshAccessTokenOperation( - String clientId, - String secretId, - String refreshToken, - String accessTokenEndpointPath - ) { - - mClientId = clientId; - mClientSecret = secretId; - mRefreshToken = refreshToken; - - mAccessTokenEndpointPath = - accessTokenEndpointPath != null ? - accessTokenEndpointPath : - OwnCloudOAuth2Provider.ACCESS_TOKEN_ENDPOINT_PATH - ; - - mResponseParser = new OAuth2ResponseParser(); - } - - @Override - protected RemoteOperationResult> run(OwnCloudClient client) { - - try { - final RequestBody requestBody = new MultipartBody.Builder() - .setType(MultipartBody.FORM) - .addFormDataPart(OAuth2Constants.KEY_GRANT_TYPE, - OAuth2GrantType.REFRESH_TOKEN.getValue()) - .addFormDataPart(OAuth2Constants.KEY_CLIENT_ID, mClientId) - .addFormDataPart(OAuth2Constants.KEY_REFRESH_TOKEN, mRefreshToken) - .build(); - - Uri.Builder uriBuilder = client.getBaseUri().buildUpon(); - uriBuilder.appendEncodedPath(mAccessTokenEndpointPath); - - final PostMethod postMethod = new PostMethod(new URL( - client.getBaseUri().buildUpon() - .appendEncodedPath(mAccessTokenEndpointPath) - .build() - .toString())); - postMethod.setRequestBody(requestBody); - - final OwnCloudCredentials oauthCredentials = new OwnCloudBasicCredentials(mClientId, mClientSecret); - - final OwnCloudCredentials oldCredentials = switchClientCredentials(oauthCredentials); - client.executeHttpMethod(postMethod); - switchClientCredentials(oldCredentials); - - final String responseData = postMethod.getResponseBodyAsString(); - Log_OC.d(TAG, "OAUTH2: raw response from POST TOKEN: " + responseData); - - if (responseData != null && responseData.length() > 0) { - final JSONObject tokenJson = new JSONObject(responseData); - - final Map accessTokenResult = - mResponseParser.parseAccessTokenResult(tokenJson); - - final RemoteOperationResult> result = new RemoteOperationResult<>(ResultCode.OK); - result.setData(accessTokenResult); - return (accessTokenResult.get(OAuth2Constants.KEY_ERROR) != null || - accessTokenResult.get(OAuth2Constants.KEY_ACCESS_TOKEN) == null) - ? new RemoteOperationResult<>(ResultCode.OAUTH2_ERROR) - : result; - } else { - return new RemoteOperationResult<>(postMethod); - } - - } catch (Exception e) { - return new RemoteOperationResult<>(e); - } - } - - private OwnCloudCredentials switchClientCredentials(OwnCloudCredentials newCredentials) { - OwnCloudCredentials previousCredentials = getClient().getCredentials(); - getClient().setCredentials(newCredentials); - return previousCredentials; - } -} \ No newline at end of file diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2ResponseParser.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2ResponseParser.java deleted file mode 100644 index 0d377c9e..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2ResponseParser.java +++ /dev/null @@ -1,75 +0,0 @@ -/** - * ownCloud Android client application - * - * @author David A. Velasco - *

- * Copyright (C) 2017 ownCloud GmbH. - *

- * 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.lib.common.authentication.oauth; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.HashMap; -import java.util.Map; - -class OAuth2ResponseParser { - - Map parseAccessTokenResult(JSONObject tokenJson) throws JSONException { - Map resultTokenMap = new HashMap<>(); - - if (tokenJson.has(OAuth2Constants.KEY_ACCESS_TOKEN)) { - resultTokenMap.put(OAuth2Constants.KEY_ACCESS_TOKEN, tokenJson. - getString(OAuth2Constants.KEY_ACCESS_TOKEN)); - } - if (tokenJson.has(OAuth2Constants.KEY_TOKEN_TYPE)) { - resultTokenMap.put(OAuth2Constants.KEY_TOKEN_TYPE, tokenJson. - getString(OAuth2Constants.KEY_TOKEN_TYPE)); - } - if (tokenJson.has(OAuth2Constants.KEY_EXPIRES_IN)) { - resultTokenMap.put(OAuth2Constants.KEY_EXPIRES_IN, tokenJson. - getString(OAuth2Constants.KEY_EXPIRES_IN)); - } - if (tokenJson.has(OAuth2Constants.KEY_REFRESH_TOKEN)) { - resultTokenMap.put(OAuth2Constants.KEY_REFRESH_TOKEN, tokenJson. - getString(OAuth2Constants.KEY_REFRESH_TOKEN)); - } - if (tokenJson.has(OAuth2Constants.KEY_SCOPE)) { - resultTokenMap.put(OAuth2Constants.KEY_SCOPE, tokenJson. - getString(OAuth2Constants.KEY_SCOPE)); - } - if (tokenJson.has(OAuth2Constants.KEY_ERROR)) { - resultTokenMap.put(OAuth2Constants.KEY_ERROR, tokenJson. - getString(OAuth2Constants.KEY_ERROR)); - } - if (tokenJson.has(OAuth2Constants.KEY_ERROR_DESCRIPTION)) { - resultTokenMap.put(OAuth2Constants.KEY_ERROR_DESCRIPTION, tokenJson. - getString(OAuth2Constants.KEY_ERROR_DESCRIPTION)); - } - if (tokenJson.has(OAuth2Constants.KEY_ERROR_URI)) { - resultTokenMap.put(OAuth2Constants.KEY_ERROR_URI, tokenJson. - getString(OAuth2Constants.KEY_ERROR_URI)); - } - - if (tokenJson.has(OAuth2Constants.KEY_USER_ID)) { // not standard - resultTokenMap.put(OAuth2Constants.KEY_USER_ID, tokenJson. - getString(OAuth2Constants.KEY_USER_ID)); - } - - return resultTokenMap; - } - -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OwnCloudOAuth2Provider.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OwnCloudOAuth2Provider.java deleted file mode 100644 index 58f149c7..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OwnCloudOAuth2Provider.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * - * @author David A. Velasco - * Copyright (C) 2017 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.authentication.oauth; - -import com.owncloud.android.lib.common.utils.Log_OC; - -public class OwnCloudOAuth2Provider implements OAuth2Provider { - - public static final String NAME = OAuth2Provider.class.getName(); - - public static final String ACCESS_TOKEN_ENDPOINT_PATH = "index.php/apps/oauth2/api/v1/token"; - private static final String AUTHORIZATION_CODE_ENDPOINT_PATH = "index.php/apps/oauth2/authorize"; - - private String mAuthorizationServerUrl = ""; - private String mAccessTokenEndpointPath = ACCESS_TOKEN_ENDPOINT_PATH; - private String mAuthorizationCodeEndpointPath = AUTHORIZATION_CODE_ENDPOINT_PATH; - - private OAuth2ClientConfiguration mClientConfiguration; - - @Override - public OAuth2RequestBuilder getOperationBuilder() { - return new OwnCloudOAuth2RequestBuilder(this); - } - - @Override - public OAuth2ClientConfiguration getClientConfiguration() { - return mClientConfiguration; - } - - @Override - public void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration) { - mClientConfiguration = oAuth2ClientConfiguration; - } - - @Override - public String getAuthorizationServerUri() { - return mAuthorizationServerUrl; - } - - @Override - public void setAuthorizationServerUri(String authorizationServerUri) { - mAuthorizationServerUrl = authorizationServerUri; - } - - public String getAccessTokenEndpointPath() { - return mAccessTokenEndpointPath; - } - - public void setAccessTokenEndpointPath(String accessTokenEndpointPath) { - if (accessTokenEndpointPath == null || accessTokenEndpointPath.length() <= 0) { - Log_OC.w(NAME, "Setting invalid access token endpoint path, going on with default"); - mAccessTokenEndpointPath = ACCESS_TOKEN_ENDPOINT_PATH; - } else { - mAccessTokenEndpointPath = accessTokenEndpointPath; - } - } - - public String getAuthorizationCodeEndpointPath() { - return mAuthorizationCodeEndpointPath; - } - - public void setAuthorizationCodeEndpointPath(String authorizationCodeEndpointPath) { - if (authorizationCodeEndpointPath == null || authorizationCodeEndpointPath.length() <= 0) { - Log_OC.w(NAME, "Setting invalid authorization code endpoint path, going on with default"); - mAuthorizationCodeEndpointPath = AUTHORIZATION_CODE_ENDPOINT_PATH; - } else { - mAuthorizationCodeEndpointPath = authorizationCodeEndpointPath; - } - } -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OwnCloudOAuth2RequestBuilder.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OwnCloudOAuth2RequestBuilder.java deleted file mode 100644 index 935004dd..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OwnCloudOAuth2RequestBuilder.java +++ /dev/null @@ -1,155 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * - * @author David A. Velasco - * Copyright (C) 2017 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.authentication.oauth; - -import android.net.Uri; - -import com.owncloud.android.lib.common.operations.RemoteOperation; - -public class OwnCloudOAuth2RequestBuilder implements OAuth2RequestBuilder { - - private OwnCloudOAuth2Provider mOAuth2Provider; - - private OAuthRequest mRequest; - private OAuth2GrantType mGrantType = OAuth2GrantType.AUTHORIZATION_CODE; - private String mCode; - private String mRefreshToken; - - public OwnCloudOAuth2RequestBuilder(OwnCloudOAuth2Provider ownCloudOAuth2Provider) { - mOAuth2Provider = ownCloudOAuth2Provider; - } - - @Override - public void setRequest(OAuthRequest request) { - mRequest = request; - } - - @Override - public void setGrantType(OAuth2GrantType grantType) { - mGrantType = grantType; - } - - @Override - public void setAuthorizationCode(String code) { - mCode = code; - } - - @Override - public void setRefreshToken(String refreshToken) { - mRefreshToken = refreshToken; - } - - @Override - public RemoteOperation buildOperation() { - if (mGrantType != OAuth2GrantType.AUTHORIZATION_CODE && - mGrantType != OAuth2GrantType.REFRESH_TOKEN) { - throw new UnsupportedOperationException( - "Unsupported grant type. Only " + - OAuth2GrantType.AUTHORIZATION_CODE.getValue() + " and " + - OAuth2GrantType.REFRESH_TOKEN + " are supported" - ); - } - OAuth2ClientConfiguration clientConfiguration = mOAuth2Provider.getClientConfiguration(); - - switch (mRequest) { - case CREATE_ACCESS_TOKEN: - return new OAuth2GetAccessTokenOperation( - mGrantType.getValue(), - mCode, - clientConfiguration.getClientId(), - clientConfiguration.getClientSecret(), - clientConfiguration.getRedirectUri(), - mOAuth2Provider.getAccessTokenEndpointPath() - ); - - case REFRESH_ACCESS_TOKEN: - return new OAuth2RefreshAccessTokenOperation( - clientConfiguration.getClientId(), - clientConfiguration.getClientSecret(), - mRefreshToken, - mOAuth2Provider.getAccessTokenEndpointPath() - ); - default: - throw new UnsupportedOperationException( - "Unsupported request" - ); - } - } - - @Override - public String buildUri() { - if (OAuth2GrantType.AUTHORIZATION_CODE != mGrantType) { - throw new UnsupportedOperationException( - "Unsupported grant type. Only " + - OAuth2GrantType.AUTHORIZATION_CODE.getValue() + " is supported by this provider" - ); - } - OAuth2ClientConfiguration clientConfiguration = mOAuth2Provider.getClientConfiguration(); - Uri uri; - Uri.Builder uriBuilder; - switch (mRequest) { - case GET_AUTHORIZATION_CODE: - uri = Uri.parse(mOAuth2Provider.getAuthorizationServerUri()); - uriBuilder = uri.buildUpon(); - uriBuilder.appendEncodedPath(mOAuth2Provider.getAuthorizationCodeEndpointPath()); - uriBuilder.appendQueryParameter( - OAuth2Constants.KEY_RESPONSE_TYPE, OAuth2Constants.OAUTH2_RESPONSE_TYPE_CODE - ); - uriBuilder.appendQueryParameter( - OAuth2Constants.KEY_REDIRECT_URI, clientConfiguration.getRedirectUri() - ); - uriBuilder.appendQueryParameter( - OAuth2Constants.KEY_CLIENT_ID, clientConfiguration.getClientId() - ); - - uri = uriBuilder.build(); - return uri.toString(); - - case CREATE_ACCESS_TOKEN: - uri = Uri.parse(mOAuth2Provider.getAuthorizationServerUri()); - uriBuilder = uri.buildUpon(); - uriBuilder.appendEncodedPath(mOAuth2Provider.getAccessTokenEndpointPath()); - uriBuilder.appendQueryParameter( - OAuth2Constants.KEY_RESPONSE_TYPE, OAuth2Constants.OAUTH2_RESPONSE_TYPE_CODE - ); - uriBuilder.appendQueryParameter( - OAuth2Constants.KEY_REDIRECT_URI, clientConfiguration.getRedirectUri() - ); - uriBuilder.appendQueryParameter( - OAuth2Constants.KEY_CLIENT_ID, clientConfiguration.getClientId() - ); - - uri = uriBuilder.build(); - return uri.toString(); - - default: - throw new UnsupportedOperationException( - "Unsupported request" - ); - } - } -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/HttpClient.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/HttpClient.java index 9564922d..27e83e62 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/HttpClient.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/HttpClient.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,18 +26,17 @@ package com.owncloud.android.lib.common.http; import android.content.Context; -import android.os.Build; -import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; +import com.owncloud.android.lib.common.SingleSessionManager; import com.owncloud.android.lib.common.http.interceptors.HttpInterceptor; import com.owncloud.android.lib.common.http.interceptors.RequestHeaderInterceptor; import com.owncloud.android.lib.common.network.AdvancedX509TrustManager; import com.owncloud.android.lib.common.network.NetworkUtils; -import com.owncloud.android.lib.common.utils.Log_OC; import okhttp3.Cookie; import okhttp3.CookieJar; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.Protocol; +import timber.log.Timber; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; @@ -58,8 +57,6 @@ import java.util.concurrent.TimeUnit; * @author David González Verdugo */ public class HttpClient { - private static final String TAG = HttpClient.class.toString(); - private static OkHttpClient sOkHttpClient; private static HttpInterceptor sOkHttpInterceptor; private static Context sContext; @@ -77,10 +74,10 @@ public class HttpClient { sslContext = SSLContext.getInstance("TLSv1.2"); } catch (NoSuchAlgorithmException tlsv12Exception) { try { - Log_OC.w(TAG, "TLSv1.2 is not supported in this device; falling through TLSv1.1"); + Timber.w("TLSv1.2 is not supported in this device; falling through TLSv1.1"); sslContext = SSLContext.getInstance("TLSv1.1"); } catch (NoSuchAlgorithmException tlsv11Exception) { - Log_OC.w(TAG, "TLSv1.1 is not supported in this device; falling through TLSv1.0"); + Timber.w("TLSv1.1 is not supported in this device; falling through TLSv1.0"); sslContext = SSLContext.getInstance("TLSv1"); // should be available in any device; see reference of supported protocols in // http://developer.android.com/reference/javax/net/ssl/SSLSocket.html @@ -91,22 +88,15 @@ public class HttpClient { SSLSocketFactory sslSocketFactory; - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { - // TLS v1.2 is disabled by default in API 19, use custom SSLSocketFactory to enable it - sslSocketFactory = new TLSSocketFactory(sslContext.getSocketFactory()); - } else { - sslSocketFactory = sslContext.getSocketFactory(); - } + sslSocketFactory = sslContext.getSocketFactory(); // Automatic cookie handling, NOT PERSISTENT CookieJar cookieJar = new CookieJar() { @Override public void saveFromResponse(HttpUrl url, List cookies) { // Avoid duplicated cookies - Set nonDuplicatedCookiesSet = new HashSet<>(); - nonDuplicatedCookiesSet.addAll(cookies); - List nonDuplicatedCookiesList = new ArrayList<>(); - nonDuplicatedCookiesList.addAll(nonDuplicatedCookiesSet); + Set nonDuplicatedCookiesSet = new HashSet<>(cookies); + List nonDuplicatedCookiesList = new ArrayList<>(nonDuplicatedCookiesSet); sCookieStore.put(url.host(), nonDuplicatedCookiesList); } @@ -133,7 +123,7 @@ public class HttpClient { sOkHttpClient = clientBuilder.build(); } catch (Exception e) { - Log_OC.e(TAG, "Could not setup SSL system.", e); + Timber.e(e, "Could not setup SSL system."); } } return sOkHttpClient; @@ -142,7 +132,7 @@ public class HttpClient { private static HttpInterceptor getOkHttpInterceptor() { if (sOkHttpInterceptor == null) { sOkHttpInterceptor = new HttpInterceptor(); - addHeaderForAllRequests(HttpConstants.USER_AGENT_HEADER, OwnCloudClientManagerFactory.getUserAgent()); + addHeaderForAllRequests(HttpConstants.USER_AGENT_HEADER, SingleSessionManager.getUserAgent()); addHeaderForAllRequests(HttpConstants.PARAM_SINGLE_COOKIE_HEADER, "true"); addHeaderForAllRequests(HttpConstants.ACCEPT_ENCODING_HEADER, HttpConstants.ACCEPT_ENCODING_IDENTITY); } @@ -158,7 +148,7 @@ public class HttpClient { public static void addHeaderForAllRequests(String headerName, String headerValue) { HttpInterceptor httpInterceptor = getOkHttpInterceptor(); - if(getOkHttpInterceptor() != null) { + if (getOkHttpInterceptor() != null) { httpInterceptor.addRequestInterceptor( new RequestHeaderInterceptor(headerName, headerValue) ); @@ -177,22 +167,6 @@ public class HttpClient { sContext = context; } - public void disableAutomaticCookiesHandling() { - OkHttpClient.Builder clientBuilder = getOkHttpClient().newBuilder(); - clientBuilder.cookieJar(new CookieJar() { - @Override - public void saveFromResponse(HttpUrl url, List cookies) { - // DO NOTHING - } - - @Override - public List loadForRequest(HttpUrl url) { - return new ArrayList<>(); - } - }); - sOkHttpClient = clientBuilder.build(); - } - public List getCookiesFromUrl(HttpUrl httpUrl) { return sCookieStore.get(httpUrl.host()); } @@ -200,4 +174,4 @@ public class HttpClient { public void clearCookies() { sCookieStore.clear(); } -} \ No newline at end of file +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/HttpConstants.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/HttpConstants.java index 2cd4df0d..aa00a797 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/HttpConstants.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/HttpConstants.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/TLSSocketFactory.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/TLSSocketFactory.java index 9ec8815e..5cff6b43 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/TLSSocketFactory.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/TLSSocketFactory.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/interceptors/HttpInterceptor.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/interceptors/HttpInterceptor.java index 55abe84d..b9965548 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/interceptors/HttpInterceptor.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/interceptors/HttpInterceptor.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/interceptors/RequestHeaderInterceptor.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/interceptors/RequestHeaderInterceptor.java index 5066d607..d7cb6dc4 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/interceptors/RequestHeaderInterceptor.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/interceptors/RequestHeaderInterceptor.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/HttpBaseMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/HttpBaseMethod.java index 1d12c6e1..9dc8de97 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/HttpBaseMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/HttpBaseMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/DeleteMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/DeleteMethod.java index 2d7153f9..42039dde 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/DeleteMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/DeleteMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/GetMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/GetMethod.java index afcf45e5..55022bbe 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/GetMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/GetMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/HttpMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/HttpMethod.java index 30e8c52c..971923b7 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/HttpMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/HttpMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/PostMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/PostMethod.java index a6cc7fc9..1efb26d0 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/PostMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/PostMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/PutMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/PutMethod.java index 67eb4f00..c51a1958 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/PutMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/nonwebdav/PutMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/CopyMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/CopyMethod.java index a3daeba3..718f948c 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/CopyMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/CopyMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavConstants.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavConstants.java index c1ceacd9..67fd90ba 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavConstants.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavConstants.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavMethod.java index a132f528..4255e1a6 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -78,14 +78,18 @@ public abstract class DavMethod extends HttpBaseMethod { .build(); } else if (mResponse != null) { - ResponseBody responseBody = ResponseBody.create( - mResponse.body().contentType(), - httpException.getResponseBody() - ); + // The check below should be included in okhttp library, method ResponseBody.create( + // TODO check most recent versions of okhttp to see if this is already fixed and try to update if so + if (mResponse.body().contentType() != null) { + ResponseBody responseBody = ResponseBody.create( + mResponse.body().contentType(), + httpException.getResponseBody() + ); - mResponse = mResponse.newBuilder() - .body(responseBody) - .build(); + mResponse = mResponse.newBuilder() + .body(responseBody) + .build(); + } } return httpException.getCode(); diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/MkColMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/MkColMethod.java index 07b6fbfb..9c4a3e34 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/MkColMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/MkColMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/MoveMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/MoveMethod.java index c6e281c1..a57a86b1 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/MoveMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/MoveMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/PropfindMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/PropfindMethod.java index 3e5bb087..6a48fc80 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/PropfindMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/PropfindMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/PutMethod.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/PutMethod.java index 52e33c75..243a4d5a 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/PutMethod.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/PutMethod.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/AdvancedX509TrustManager.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/AdvancedX509TrustManager.java index f70dabd8..d76ecbca 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/AdvancedX509TrustManager.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/AdvancedX509TrustManager.java @@ -24,7 +24,7 @@ package com.owncloud.android.lib.common.network; -import com.owncloud.android.lib.common.utils.Log_OC; +import timber.log.Timber; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; @@ -43,11 +43,8 @@ import java.security.cert.X509Certificate; */ public class AdvancedX509TrustManager implements X509TrustManager { - private static final String TAG = AdvancedX509TrustManager.class.getSimpleName(); - private X509TrustManager mStandardTrustManager; private KeyStore mKnownServersKeyStore; - /** * Constructor for AdvancedX509TrustManager * @@ -136,7 +133,7 @@ public class AdvancedX509TrustManager implements X509TrustManager { try { return (mKnownServersKeyStore.getCertificateAlias(cert) != null); } catch (KeyStoreException e) { - Log_OC.d(TAG, "Fail while checking certificate in the known-servers store"); + Timber.e(e, "Fail while checking certificate in the known-servers store"); return false; } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.java index 776bce2a..53abaf9a 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ChunkFromFileRequestBody.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,11 +24,9 @@ package com.owncloud.android.lib.common.network; -import android.util.Log; - -import com.owncloud.android.lib.common.utils.Log_OC; import okhttp3.MediaType; import okio.BufferedSink; +import timber.log.Timber; import java.io.File; import java.io.IOException; @@ -43,9 +41,6 @@ import java.util.Iterator; */ public class ChunkFromFileRequestBody extends FileRequestBody { - private static final String TAG = ChunkFromFileRequestBody.class.getSimpleName(); - - //private final File mFile; private final FileChannel mChannel; private final long mChunkSize; private long mOffset; @@ -89,17 +84,17 @@ public class ChunkFromFileRequestBody extends FileRequestBody { long maxCount = Math.min(mOffset + mChunkSize, mChannel.size()); while (mChannel.position() < maxCount) { - Log_OC.d(TAG, "Sink buffer size: " + sink.buffer().size()); + Timber.v("Sink buffer size: %s", sink.buffer().size()); readCount = mChannel.read(mBuffer); - Log_OC.d(TAG, "Read " + readCount + " bytes from file channel to " + mBuffer.toString()); + Timber.v("Read " + readCount + " bytes from file channel to " + mBuffer.toString()); sink.buffer().write(mBuffer.array(), 0, readCount); sink.flush(); - Log_OC.d(TAG, "Write " + readCount + " bytes to sink buffer with size " + sink.buffer().size()); + Timber.v("Write " + readCount + " bytes to sink buffer with size " + sink.buffer().size()); mBuffer.clear(); if (mTransferred < maxCount) { // condition to avoid accumulate progress for repeated chunks @@ -113,19 +108,10 @@ public class ChunkFromFileRequestBody extends FileRequestBody { } } - Log.d(TAG, "Chunk with size " + mChunkSize + " written in request body"); + Timber.v("Chunk with size " + mChunkSize + " written in request body"); } catch (Exception exception) { - - Log.e(TAG, exception.toString()); - // // any read problem will be handled as if the file is not there - // if (io instanceof FileNotFoundException) { - // throw io; - // } else { - // FileNotFoundException fnf = new FileNotFoundException("Exception reading source file"); - // fnf.initCause(io); - // throw fnf; - // } + Timber.e(exception); } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.java index 21934a2b..63d07bec 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/FileRequestBody.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,13 +24,12 @@ package com.owncloud.android.lib.common.network; -import android.util.Log; - import okhttp3.MediaType; import okhttp3.RequestBody; import okio.BufferedSink; import okio.Okio; import okio.Source; +import timber.log.Timber; import java.io.File; import java.util.Collection; @@ -45,11 +44,9 @@ import java.util.Set; */ public class FileRequestBody extends RequestBody implements ProgressiveDataTransferer { - private static final String TAG = FileRequestBody.class.getSimpleName(); - protected File mFile; private MediaType mContentType; - Set mDataTransferListeners = new HashSet<>(); + final Set mDataTransferListeners = new HashSet<>(); public FileRequestBody(File file, MediaType contentType) { mFile = file; @@ -87,11 +84,10 @@ public class FileRequestBody extends RequestBody implements ProgressiveDataTrans } } - Log.d(TAG, "File with name " + mFile.getName() + " and size " + mFile.length() + - " written in request body"); + Timber.d("File with name " + mFile.getName() + " and size " + mFile.length() + " written in request body"); } catch (Exception e) { - e.printStackTrace(); + Timber.e(e); } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/NetworkUtils.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/NetworkUtils.java index e4461341..f6013cb8 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/NetworkUtils.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/NetworkUtils.java @@ -26,8 +26,7 @@ package com.owncloud.android.lib.common.network; import android.content.Context; -import com.owncloud.android.lib.common.utils.Log_OC; -import org.apache.http.conn.ssl.X509HostnameVerifier; +import timber.log.Timber; import java.io.File; import java.io.FileInputStream; @@ -42,25 +41,6 @@ import java.security.cert.CertificateException; public class NetworkUtils { - /** - * Default timeout for waiting data from the server - */ - public static final int DEFAULT_DATA_TIMEOUT = 60000; - /** - * Default timeout for establishing a connection - */ - public static final int DEFAULT_CONNECTION_TIMEOUT = 60000; - /** - * Standard name for protocol TLS version 1.2 in Java Secure Socket Extension (JSSE) API - */ - public static final String PROTOCOL_TLSv1_2 = "TLSv1.2"; - /** - * Standard name for protocol TLS version 1.0 in JSSE API - */ - public static final String PROTOCOL_TLSv1_0 = "TLSv1"; - final private static String TAG = NetworkUtils.class.getSimpleName(); - private static X509HostnameVerifier mHostnameVerifier = null; - private static String LOCAL_TRUSTSTORE_FILENAME = "knownServers.bks"; private static String LOCAL_TRUSTSTORE_PASSWORD = "password"; @@ -88,7 +68,7 @@ public class NetworkUtils { //mKnownServersStore = KeyStore.getInstance("BKS"); mKnownServersStore = KeyStore.getInstance(KeyStore.getDefaultType()); File localTrustStoreFile = new File(context.getFilesDir(), LOCAL_TRUSTSTORE_FILENAME); - Log_OC.d(TAG, "Searching known-servers store at " + localTrustStoreFile.getAbsolutePath()); + Timber.d("Searching known-servers store at %s", localTrustStoreFile.getAbsolutePath()); if (localTrustStoreFile.exists()) { InputStream in = new FileInputStream(localTrustStoreFile); try { @@ -109,22 +89,9 @@ public class NetworkUtils { KeyStore knownServers = getKnownServersStore(context); knownServers.setCertificateEntry(Integer.toString(cert.hashCode()), cert); - FileOutputStream fos = null; - try { - fos = context.openFileOutput(LOCAL_TRUSTSTORE_FILENAME, Context.MODE_PRIVATE); + try (FileOutputStream fos = context.openFileOutput(LOCAL_TRUSTSTORE_FILENAME, Context.MODE_PRIVATE)) { knownServers.store(fos, LOCAL_TRUSTSTORE_PASSWORD.toCharArray()); - } finally { - fos.close(); } } - public static boolean isCertInKnownServersStore(Certificate cert, Context context) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { - - KeyStore knownServers = getKnownServersStore(context); - Log_OC.d(TAG, "Certificate - HashCode: " + cert.hashCode() + " " - + Boolean.toString(knownServers.isCertificateEntry(Integer.toString(cert.hashCode())))); - return knownServers.isCertificateEntry(Integer.toString(cert.hashCode())); - } - } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ServerNameIndicator.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ServerNameIndicator.java deleted file mode 100644 index e0dabae9..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ServerNameIndicator.java +++ /dev/null @@ -1,145 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * Copyright (C) 2016 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.network; - -import com.owncloud.android.lib.common.utils.Log_OC; - -import javax.net.ssl.SSLSocket; -import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Enables the support of Server Name Indication if existing - * in the underlying network implementation. - *

- * Build as a singleton. - * - * @author David A. Velasco - */ -public class ServerNameIndicator { - - private static final String TAG = ServerNameIndicator.class.getSimpleName(); - - private static final AtomicReference mSingleInstance = new AtomicReference(); - - private static final String METHOD_NAME = "setHostname"; - - private final WeakReference> mSSLSocketClassRef; - private final WeakReference mSetHostnameMethodRef; - - /** - * Private constructor, class is a singleton. - * - * @param sslSocketClass Underlying implementation class of {@link SSLSocket} used to connect with the server. - * @param setHostnameMethod Name of the method to call to enable the SNI support. - */ - private ServerNameIndicator(Class sslSocketClass, Method setHostnameMethod) { - mSSLSocketClassRef = new WeakReference>(sslSocketClass); - mSetHostnameMethodRef = (setHostnameMethod == null) ? null : new WeakReference(setHostnameMethod); - } - - /** - * Calls the {@code #setHostname(String)} method of the underlying implementation - * of {@link SSLSocket} if exists. - *

- * Creates and initializes the single instance of the class when needed - * - * @param hostname The name of the server host of interest. - * @param sslSocket Client socket to connect with the server. - */ - public static void setServerNameIndication(String hostname, SSLSocket sslSocket) { - final Method setHostnameMethod = getMethod(sslSocket); - if (setHostnameMethod != null) { - try { - setHostnameMethod.invoke(sslSocket, hostname); - Log_OC.i(TAG, "SNI done, hostname: " + hostname); - - } catch (IllegalArgumentException e) { - Log_OC.e(TAG, "Call to SSLSocket#setHost(String) failed ", e); - - } catch (IllegalAccessException e) { - Log_OC.e(TAG, "Call to SSLSocket#setHost(String) failed ", e); - - } catch (InvocationTargetException e) { - Log_OC.e(TAG, "Call to SSLSocket#setHost(String) failed ", e); - } - } else { - Log_OC.i(TAG, "SNI not supported"); - } - } - - /** - * Gets the method to invoke trying to minimize the effective - * application of reflection. - * - * @param sslSocket Instance of the SSL socket to use in connection with server. - * @return Method to call to indicate the server name of interest to the server. - */ - private static Method getMethod(SSLSocket sslSocket) { - final Class sslSocketClass = sslSocket.getClass(); - final ServerNameIndicator instance = mSingleInstance.get(); - if (instance == null) { - return initFrom(sslSocketClass); - - } else if (instance.mSSLSocketClassRef.get() != sslSocketClass) { - // the underlying class changed - return initFrom(sslSocketClass); - - } else if (instance.mSetHostnameMethodRef == null) { - // SNI not supported - return null; - - } else { - final Method cachedSetHostnameMethod = instance.mSetHostnameMethodRef.get(); - return (cachedSetHostnameMethod == null) ? initFrom(sslSocketClass) : cachedSetHostnameMethod; - } - } - - /** - * Singleton initializer. - *

- * Uses reflection to extract and 'cache' the method to invoke to indicate the desited host name to the server side. - * - * @param sslSocketClass Underlying class providing the implementation of {@link SSLSocket}. - * @return Method to call to indicate the server name of interest to the server. - */ - private static Method initFrom(Class sslSocketClass) { - Log_OC.i(TAG, "SSLSocket implementation: " + sslSocketClass.getCanonicalName()); - Method setHostnameMethod = null; - try { - setHostnameMethod = sslSocketClass.getMethod(METHOD_NAME, String.class); - } catch (SecurityException e) { - Log_OC.e(TAG, "Could not access to SSLSocket#setHostname(String) method ", e); - - } catch (NoSuchMethodException e) { - Log_OC.i(TAG, "Could not find SSLSocket#setHostname(String) method - SNI not supported"); - } - mSingleInstance.set(new ServerNameIndicator(sslSocketClass, setHostnameMethod)); - return setHostnameMethod; - } - -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/WebdavUtils.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/WebdavUtils.java index 45b7f35f..5647dec4 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/WebdavUtils.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/WebdavUtils.java @@ -34,11 +34,12 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; -public class WebdavUtils { - public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat( - "dd.MM.yyyy hh:mm"); +import static com.owncloud.android.lib.common.OwnCloudClient.WEBDAV_FILES_PATH_4_0; +import static com.owncloud.android.lib.common.OwnCloudClient.WEBDAV_PATH_4_0_AND_LATER; - private static final SimpleDateFormat DATETIME_FORMATS[] = { +public class WebdavUtils { + + private static final SimpleDateFormat[] DATETIME_FORMATS = { new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US), new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US), new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US), @@ -50,11 +51,11 @@ public class WebdavUtils { }; public static Date parseResponseDate(String date) { - Date returnDate = null; - SimpleDateFormat format = null; - for (int i = 0; i < DATETIME_FORMATS.length; ++i) { + Date returnDate; + SimpleDateFormat format; + for (SimpleDateFormat datetimeFormat : DATETIME_FORMATS) { try { - format = DATETIME_FORMATS[i]; + format = datetimeFormat; synchronized (format) { returnDate = format.parse(date); } @@ -82,23 +83,6 @@ public class WebdavUtils { return encodedPath; } - /** - * @param rawEtag - * @return - */ - public static String parseEtag(String rawEtag) { - if (rawEtag == null || rawEtag.length() == 0) { - return ""; - } - if (rawEtag.endsWith("-gzip")) { - rawEtag = rawEtag.substring(0, rawEtag.length() - 5); - } - if (rawEtag.length() >= 2 && rawEtag.startsWith("\"") && rawEtag.endsWith("\"")) { - rawEtag = rawEtag.substring(1, rawEtag.length() - 1); - } - return rawEtag; - } - /** * @param httpBaseMethod from which to get the etag * @return etag from response @@ -120,4 +104,17 @@ public class WebdavUtils { } return result; } + + public static String normalizeProtocolPrefix(String url, boolean isSslConn) { + if (!url.toLowerCase().startsWith("http://") && + !url.toLowerCase().startsWith("https://")) { + if (isSslConn) { + return "https://" + url; + } else { + return "http://" + url; + } + } + return url; + } + } \ No newline at end of file diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/WriteTimeoutEnforcer.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/WriteTimeoutEnforcer.java deleted file mode 100644 index 19b4a797..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/WriteTimeoutEnforcer.java +++ /dev/null @@ -1,167 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * Copyright (C) 2017 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.common.network; - -import com.owncloud.android.lib.common.utils.Log_OC; - -import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.Socket; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Enforces, if possible, a write timeout for a socket. - *

- * Built as a singleton. - *

- * Tries to hit something like this: - * https://android.googlesource.com/platform/external/conscrypt/+/lollipop-release/src/main/java/org/conscrypt/OpenSSLSocketImpl.java#1005 - *

- * Minimizes the chances of getting stalled in PUT/POST request if the network interface is lost while - * writing the entity into the outwards sockect. - *

- * It happens. See https://github.com/owncloud/android/issues/1684#issuecomment-295306015 - * - * @author David A. Velasco - */ -public class WriteTimeoutEnforcer { - - private static final String TAG = WriteTimeoutEnforcer.class.getSimpleName(); - - private static final AtomicReference mSingleInstance = new AtomicReference<>(); - - private static final String METHOD_NAME = "setSoWriteTimeout"; - - private final WeakReference> mSocketClassRef; - private final WeakReference mSetSoWriteTimeoutMethodRef; - - /** - * Private constructor, class is a singleton. - * - * @param socketClass Underlying implementation class of {@link Socket} used to connect - * with the server. - * @param setSoWriteTimeoutMethod Name of the method to call to set a write timeout in the socket. - */ - private WriteTimeoutEnforcer(Class socketClass, Method setSoWriteTimeoutMethod) { - mSocketClassRef = new WeakReference>(socketClass); - mSetSoWriteTimeoutMethodRef = - (setSoWriteTimeoutMethod == null) ? - null : - new WeakReference<>(setSoWriteTimeoutMethod) - ; - } - - /** - * Calls the {@code #setSoWrite(int)} method of the underlying implementation - * of {@link Socket} if exists. - *

- * Creates and initializes the single instance of the class when needed - * - * @param writeTimeoutMilliseconds Write timeout to set, in milliseconds. - * @param socket Client socket to connect with the server. - */ - public static void setSoWriteTimeout(int writeTimeoutMilliseconds, Socket socket) { - final Method setSoWriteTimeoutMethod = getMethod(socket); - if (setSoWriteTimeoutMethod != null) { - try { - setSoWriteTimeoutMethod.invoke(socket, writeTimeoutMilliseconds); - Log_OC.i( - TAG, - "Write timeout set in socket, writeTimeoutMilliseconds: " - + writeTimeoutMilliseconds - ); - - } catch (IllegalArgumentException e) { - Log_OC.e(TAG, "Call to (SocketImpl)#setSoWriteTimeout(int) failed ", e); - - } catch (IllegalAccessException e) { - Log_OC.e(TAG, "Call to (SocketImpl)#setSoWriteTimeout(int) failed ", e); - - } catch (InvocationTargetException e) { - Log_OC.e(TAG, "Call to (SocketImpl)#setSoWriteTimeout(int) failed ", e); - } - } else { - Log_OC.i(TAG, "Write timeout for socket not supported"); - } - } - - /** - * Gets the method to invoke trying to minimize the cost of reflection reusing objects cached - * in static members. - * - * @param socket Instance of the socket to use in connection with server. - * @return Method to call to set a write timeout in the socket. - */ - private static Method getMethod(Socket socket) { - final Class socketClass = socket.getClass(); - final WriteTimeoutEnforcer instance = mSingleInstance.get(); - if (instance == null) { - return initFrom(socketClass); - - } else if (instance.mSocketClassRef.get() != socketClass) { - // the underlying class changed - return initFrom(socketClass); - - } else if (instance.mSetSoWriteTimeoutMethodRef == null) { - // method not supported - return null; - - } else { - final Method cachedSetSoWriteTimeoutMethod = instance.mSetSoWriteTimeoutMethodRef.get(); - return (cachedSetSoWriteTimeoutMethod == null) ? - initFrom(socketClass) : - cachedSetSoWriteTimeoutMethod - ; - } - } - - /** - * Singleton initializer. - *

- * Uses reflection to extract and 'cache' the method to invoke to set a write timouet in a socket. - * - * @param socketClass Underlying class providing the implementation of {@link Socket}. - * @return Method to call to set a write timeout in the socket. - */ - private static Method initFrom(Class socketClass) { - Log_OC.i(TAG, "Socket implementation: " + socketClass.getCanonicalName()); - Method setSoWriteTimeoutMethod = null; - try { - setSoWriteTimeoutMethod = socketClass.getMethod(METHOD_NAME, int.class); - } catch (SecurityException e) { - Log_OC.e(TAG, "Could not access to (SocketImpl)#setSoWriteTimeout(int) method ", e); - - } catch (NoSuchMethodException e) { - Log_OC.i( - TAG, - "Could not find (SocketImpl)#setSoWriteTimeout(int) method - write timeout not supported" - ); - } - mSingleInstance.set(new WriteTimeoutEnforcer(socketClass, setSoWriteTimeoutMethod)); - return setSoWriteTimeoutMethod; - } - -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/operations/RemoteOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/operations/RemoteOperation.java index 9f009bbd..321907b6 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/operations/RemoteOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/operations/RemoteOperation.java @@ -9,13 +9,14 @@ import android.os.Handler; 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.SingleSessionManager; import com.owncloud.android.lib.common.accounts.AccountUtils; -import com.owncloud.android.lib.common.utils.Log_OC; import okhttp3.OkHttpClient; +import timber.log.Timber; import java.io.IOException; +@SuppressWarnings("WeakerAccess") public abstract class RemoteOperation implements Runnable { /** @@ -26,7 +27,6 @@ public abstract class RemoteOperation implements Runnable { * OCS API header value */ public static final String OCS_API_HEADER_VALUE = "true"; - private static final String TAG = RemoteOperation.class.getSimpleName(); /** * ownCloud account in the remote ownCloud server to operate */ @@ -40,22 +40,22 @@ public abstract class RemoteOperation implements Runnable { /** * Object to interact with the remote server */ - protected OwnCloudClient mClient = null; + private OwnCloudClient mClient = null; /** * Object to interact with the remote server */ - protected OkHttpClient mHttpClient = null; + private OkHttpClient mHttpClient = null; /** * Callback object to notify about the execution of the remote operation */ - protected OnRemoteOperationListener mListener = null; + private OnRemoteOperationListener mListener = null; /** * Handler to the thread where mListener methods will be called */ - protected Handler mListenerHandler = null; + private Handler mListenerHandler = null; /** * Asynchronously executes the remote operation @@ -75,12 +75,10 @@ public abstract class RemoteOperation implements Runnable { OnRemoteOperationListener listener, Handler listenerHandler) { if (account == null) { - throw new IllegalArgumentException - ("Trying to execute a remote operation with a NULL Account"); + throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Account"); } if (context == null) { - throw new IllegalArgumentException - ("Trying to execute a remote operation with a NULL Context"); + throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Context"); } // mAccount and mContext in the runnerThread to create below mAccount = account; @@ -106,11 +104,9 @@ public abstract class RemoteOperation implements Runnable { * the listener objects must be called. * @return Thread were the remote operation is executed. */ - public Thread execute(OwnCloudClient client, - OnRemoteOperationListener listener, Handler listenerHandler) { + public Thread execute(OwnCloudClient client, OnRemoteOperationListener listener, Handler listenerHandler) { if (client == null) { - throw new IllegalArgumentException - ("Trying to execute a remote operation with a NULL OwnCloudClient"); + throw new IllegalArgumentException("Trying to execute a remote operation with a NULL OwnCloudClient"); } mClient = client; if (client.getAccount() != null) { @@ -120,8 +116,7 @@ public abstract class RemoteOperation implements Runnable { if (listener == null) { throw new IllegalArgumentException - ("Trying to execute a remote operation asynchronously " + - "without a listener to notiy the result"); + ("Trying to execute a remote operation asynchronously without a listener to notify the result"); } mListener = listener; @@ -134,12 +129,12 @@ public abstract class RemoteOperation implements Runnable { return runnerThread; } - protected void grantOwnCloudClient() throws + private void grantOwnCloudClient() throws AccountUtils.AccountNotFoundException, OperationCanceledException, AuthenticatorException, IOException { if (mClient == null) { if (mAccount != null && mContext != null) { OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext); - mClient = OwnCloudClientManagerFactory.getDefaultSingleton(). + mClient = SingleSessionManager.getDefaultSingleton(). getClientFor(ocAccount, mContext); } else { throw new IllegalStateException("Trying to run a remote operation " + @@ -177,12 +172,10 @@ public abstract class RemoteOperation implements Runnable { */ public RemoteOperationResult execute(Account account, Context context) { if (account == null) { - throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + - "Account"); + throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Account"); } if (context == null) { - throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + - "Context"); + throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Context"); } mAccount = account; mContext = context.getApplicationContext(); @@ -192,7 +185,7 @@ public abstract class RemoteOperation implements Runnable { /** * Synchronously executes the remote operation - * + *

* Do not call this method from the main thread. * * @param client Client object to reach an ownCloud server during the execution of @@ -201,8 +194,7 @@ public abstract class RemoteOperation implements Runnable { */ public RemoteOperationResult execute(OwnCloudClient client) { if (client == null) { - throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + - "OwnCloudClient"); + throw new IllegalArgumentException("Trying to execute a remote operation with a NULL OwnCloudClient"); } mClient = client; if (client.getAccount() != null) { @@ -224,8 +216,7 @@ public abstract class RemoteOperation implements Runnable { */ public RemoteOperationResult execute(OkHttpClient client, Context context) { if (client == null) { - throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + - "OwnCloudClient"); + throw new IllegalArgumentException("Trying to execute a remote operation with a NULL OwnCloudClient"); } mHttpClient = client; mContext = context; @@ -236,9 +227,7 @@ public abstract class RemoteOperation implements Runnable { /** * Run operation for asynchronous or synchronous 'onExecute' method. *

- * Considers and performs silent refresh of account credentials if possible, and if - * {@link RemoteOperation#setSilentRefreshOfAccountCredentials(boolean)} was called with - * parameter 'true' before the execution. + * Considers and performs silent refresh of account credentials if possible * * @return Remote operation result */ @@ -251,7 +240,7 @@ public abstract class RemoteOperation implements Runnable { result = run(mClient); } catch (AccountsException | IOException e) { - Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, e); + Timber.e(e, "Error while trying to access to %s", mAccount.name); result = new RemoteOperationResult<>(e); } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/operations/RemoteOperationResult.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/operations/RemoteOperationResult.java index b58d1b73..715ed32c 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/operations/RemoteOperationResult.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,9 +33,9 @@ import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.http.HttpConstants; import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; import com.owncloud.android.lib.common.network.CertificateCombinedException; -import com.owncloud.android.lib.common.utils.Log_OC; import okhttp3.Headers; import org.json.JSONException; +import timber.log.Timber; import javax.net.ssl.SSLException; import javax.net.ssl.SSLPeerUnverifiedException; @@ -60,14 +60,13 @@ public class RemoteOperationResult */ private static final long serialVersionUID = 4968939884332372230L; - private static final String TAG = RemoteOperationResult.class.getSimpleName(); private boolean mSuccess = false; private int mHttpCode = -1; private String mHttpPhrase = null; private Exception mException = null; private ResultCode mCode = ResultCode.UNKNOWN_ERROR; private String mRedirectedLocation; - private ArrayList mAuthenticate = new ArrayList<>(); + private List mAuthenticate = new ArrayList<>(); private String mLastPermanentLocation = null; private T mData = null; @@ -189,10 +188,14 @@ public class RemoteOperationResult try { if (xmlParser.parseXMLResponse(is)) { mCode = ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER; + } else { + parseErrorMessageAndSetCode( + httpMethod.getResponseBodyAsString(), + ResultCode.SPECIFIC_BAD_REQUEST + ); } - } catch (Exception e) { - Log_OC.w(TAG, "Error reading exception from server: " + e.getMessage()); + Timber.w("Error reading exception from server: %s", e.getMessage()); // mCode stays as set in this(success, httpCode, headers) } } @@ -250,7 +253,9 @@ public class RemoteOperationResult continue; } if ("www-authenticate".equals(header.getKey().toLowerCase())) { - mAuthenticate.add(header.getValue().get(0).toLowerCase()); + for (String value: header.getValue()) { + mAuthenticate.add(value.toLowerCase()); + } } } } @@ -293,11 +298,7 @@ public class RemoteOperationResult break; default: mCode = ResultCode.UNHANDLED_HTTP_CODE; // UNKNOWN ERROR - Log_OC.d(TAG, - "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + - - mHttpCode + " " + mHttpPhrase - ); + Timber.d("RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + mHttpCode + " " + mHttpPhrase); } } } @@ -308,21 +309,19 @@ public class RemoteOperationResult * * @param bodyResponse okHttp response body * @param resultCode our own custom result code - * @throws IOException */ private void parseErrorMessageAndSetCode(String bodyResponse, ResultCode resultCode) { - if (bodyResponse != null && bodyResponse.length() > 0) { InputStream is = new ByteArrayInputStream(bodyResponse.getBytes()); ErrorMessageParser xmlParser = new ErrorMessageParser(); try { String errorMessage = xmlParser.parseXMLResponse(is); - if (errorMessage != "" && errorMessage != null) { + if (!errorMessage.equals("")) { mCode = resultCode; mHttpPhrase = errorMessage; } } catch (Exception e) { - Log_OC.w(TAG, "Error reading exception from server: " + e.getMessage()); + Timber.w("Error reading exception from server: %s", e.getMessage()); // mCode stays as set in this(success, httpCode, headers) } } @@ -376,7 +375,7 @@ public class RemoteOperationResult previousCause = cause; cause = cause.getCause(); } - if (cause != null && cause instanceof CertificateCombinedException) { + if (cause instanceof CertificateCombinedException) { result = (CertificateCombinedException) cause; } return result; @@ -497,7 +496,7 @@ public class RemoteOperationResult return (mRedirectedLocation != null && !(mRedirectedLocation.toLowerCase().startsWith("https://"))); } - public ArrayList getAuthenticateHeaders() { + public List getAuthenticateHeaders() { return mAuthenticate; } @@ -572,6 +571,7 @@ public class RemoteOperationResult SERVICE_UNAVAILABLE, SPECIFIC_SERVICE_UNAVAILABLE, SPECIFIC_UNSUPPORTED_MEDIA_TYPE, - SPECIFIC_METHOD_NOT_ALLOWED + SPECIFIC_METHOD_NOT_ALLOWED, + SPECIFIC_BAD_REQUEST } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/Log_OC.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/Log_OC.java deleted file mode 100644 index 831076b6..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/Log_OC.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.owncloud.android.lib.common.utils; - -import timber.log.Timber; - -import java.io.File; - -public class Log_OC { - - private static String mOwncloudDataFolderLog; - - public static void setLogDataFolder(String logFolder) { - mOwncloudDataFolderLog = logFolder; - } - - public static void i(String message) { - Timber.i(message); - } - - public static void d(String message) { - Timber.d(message); - } - - public static void d(String message, Exception e) { - Timber.d(e, message); - } - - public static void e(String message) { - Timber.e(message); - } - - public static void e(String message, Throwable e) { - Timber.e(e, message); - } - - public static void v(String message) { - Timber.v(message); - } - - public static void w(String message) { - Timber.w(message); - } - - @Deprecated - public static void i(String tag, String message) { - Timber.i(message); - } - - @Deprecated - public static void d(String TAG, String message) { - Timber.d(message); - } - - @Deprecated - public static void d(String TAG, String message, Exception e) { - Timber.d(e, message); - } - - @Deprecated - public static void e(String TAG, String message) { - Timber.e(message); - } - - @Deprecated - public static void e(String TAG, String message, Throwable e) { - Timber.e(e, message); - } - - @Deprecated - public static void v(String TAG, String message) { - Timber.v(message); - } - - @Deprecated - public static void w(String TAG, String message) { - Timber.w(message); - } - - public static void startLogging(String storagePath) { - LoggingHelper.INSTANCE.startLogging( - new File(storagePath+ File.separator + mOwncloudDataFolderLog), mOwncloudDataFolderLog); - } - - public static void stopLogging() { - LoggingHelper.INSTANCE.stopLogging(); - } - -} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/LoggingHelper.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/LoggingHelper.kt index edb93b66..1418f500 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/LoggingHelper.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/LoggingHelper.kt @@ -13,7 +13,7 @@ object LoggingHelper { } if (!directory.exists()) directory.mkdirs() - Timber.plant(FileLoggingTree(directory, filename = storagePath, delegator = Log_OC::class.java)) + Timber.plant(FileLoggingTree(directory, filename = storagePath)) } fun stopLogging() { diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/RandomUtils.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/RandomUtils.java index be6cd880..f98aad7f 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/RandomUtils.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/utils/RandomUtils.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/Service.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/Service.kt index 0fa90756..7b4a62df 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/Service.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/Service.kt @@ -3,7 +3,7 @@ * * @author David González Verdugo * - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CheckPathExistenceRemoteOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CheckPathExistenceRemoteOperation.kt new file mode 100644 index 00000000..aafa5fc7 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CheckPathExistenceRemoteOperation.kt @@ -0,0 +1,115 @@ +/* ownCloud Android Library is available under MIT license +* Copyright (C) 2020 ownCloud GmbH. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +*/ +package com.owncloud.android.lib.resources.files + +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.http.HttpConstants +import com.owncloud.android.lib.common.http.methods.webdav.DavUtils +import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod +import com.owncloud.android.lib.common.network.RedirectionPath +import com.owncloud.android.lib.common.network.WebdavUtils +import com.owncloud.android.lib.common.operations.RemoteOperation +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode +import timber.log.Timber +import java.net.URL +import java.util.concurrent.TimeUnit + +/** + * Operation to check the existence of a path in a remote server. + * + * @author David A. Velasco + * @author David González Verdugo + * @author Abel García de Prada + * + * @param remotePath Path to append to the URL owned by the client instance. + * @param isUserLogged When `true`, the username won't be added at the end of the PROPFIND url since is not + * needed to check user credentials + */ +class CheckPathExistenceRemoteOperation( + val remotePath: String? = "", + val isUserLogged: Boolean +) : RemoteOperation() { + /** + * Gets the sequence of redirections followed during the execution of the operation. + * + * @return Sequence of redirections followed, if any, or NULL if the operation was not executed. + */ + var redirectionPath: RedirectionPath? = null + private set + + override fun run(client: OwnCloudClient): RemoteOperationResult { + val previousFollowRedirects = client.followRedirects() + return try { + val stringUrl = + if (isUserLogged) client.baseFilesWebDavUri.toString() + else client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(remotePath) + + val propFindMethod = PropfindMethod(URL(stringUrl), 0, DavUtils.getAllPropset()).apply { + setReadTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS) + setConnectionTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS) + } + + client.setFollowRedirects(false) + var status = client.executeHttpMethod(propFindMethod) + if (previousFollowRedirects) { + redirectionPath = client.followRedirection(propFindMethod) + status = redirectionPath?.lastStatus!! + } + /* PROPFIND method + * 404 NOT FOUND: path doesn't exist, + * 207 MULTI_STATUS: path exists. + */ + Timber.d( + "Existence check for $stringUrl finished with HTTP status $status${if (!isSuccess(status)) "(FAIL)" else ""}" + ) + if (isSuccess(status)) RemoteOperationResult(ResultCode.OK).apply { data = true } + else RemoteOperationResult(propFindMethod).apply { data = false } + + } catch (e: Exception) { + val result = RemoteOperationResult(e) + Timber.e( + e, + "Existence check for ${client.userFilesWebDavUri}${WebdavUtils.encodePath(remotePath)} : ${result.logMessage}" + ) + result + } finally { + client.setFollowRedirects(previousFollowRedirects) + } + } + + /** + * @return 'True' if the operation was executed and at least one redirection was followed. + */ + fun wasRedirected() = redirectionPath?.redirectionsCount ?: 0 > 0 + + private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_MULTI_STATUS + + companion object { + /** + * Maximum time to wait for a response from the server in milliseconds. + */ + private const val TIMEOUT = 10000 + } +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java index 79852444..2f9e5431 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,8 +24,6 @@ package com.owncloud.android.lib.resources.files; -import android.util.Log; - import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.http.HttpConstants; import com.owncloud.android.lib.common.http.methods.webdav.CopyMethod; @@ -33,7 +31,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; -import com.owncloud.android.lib.resources.status.OwnCloudVersion; +import timber.log.Timber; import java.net.URL; import java.util.concurrent.TimeUnit; @@ -41,16 +39,15 @@ import java.util.concurrent.TimeUnit; /** * Remote operation moving a remote file or folder in the ownCloud server to a different folder * in the same account. - *

+ * * Allows renaming the moving file/folder at the same time. * * @author David A. Velasco * @author Christian Schabesberger + * @author David González V. */ public class CopyRemoteFileOperation extends RemoteOperation { - private static final String TAG = CopyRemoteFileOperation.class.getSimpleName(); - private static final int COPY_READ_TIMEOUT = 600000; private static final int COPY_CONNECTION_TIMEOUT = 5000; @@ -81,14 +78,6 @@ public class CopyRemoteFileOperation extends RemoteOperation { */ @Override protected RemoteOperationResult run(OwnCloudClient client) { - OwnCloudVersion version = client.getOwnCloudVersion(); - boolean versionWithForbiddenChars = - (version != null && version.isVersionWithForbiddenCharacters()); - - /// check parameters - if (!FileUtils.isValidPath(mTargetRemotePath, versionWithForbiddenChars)) { - return new RemoteOperationResult<>(ResultCode.INVALID_CHARACTER_IN_NAME); - } if (mTargetRemotePath.equals(mSrcRemotePath)) { // nothing to do! @@ -100,7 +89,7 @@ public class CopyRemoteFileOperation extends RemoteOperation { } /// perform remote operation - RemoteOperationResult result; + RemoteOperationResult result; try { CopyMethod copyMethod = new CopyMethod(new URL(client.getUserFilesWebDavUri() + WebdavUtils.encodePath(mSrcRemotePath)), @@ -128,13 +117,11 @@ public class CopyRemoteFileOperation extends RemoteOperation { client.exhaustResponse(copyMethod.getResponseBodyAsStream()); } - Log.i(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + - result.getLogMessage()); + Timber.i("Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage()); } catch (Exception e) { result = new RemoteOperationResult<>(e); - Log.e(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + - result.getLogMessage(), e); + Timber.e(e, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage()); } return result; diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java index 04a1c4bb..3985ab2c 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2016 ownCloud GmbH. + * Copyright (C) 2019 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,8 +33,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; -import com.owncloud.android.lib.common.utils.Log_OC; -import com.owncloud.android.lib.resources.status.OwnCloudVersion; +import timber.log.Timber; import java.net.URL; import java.util.concurrent.TimeUnit; @@ -47,8 +46,6 @@ import java.util.concurrent.TimeUnit; */ public class CreateRemoteFolderOperation extends RemoteOperation { - private static final String TAG = CreateRemoteFolderOperation.class.getSimpleName(); - private static final int READ_TIMEOUT = 30000; private static final int CONNECTION_TIMEOUT = 5000; @@ -75,24 +72,14 @@ public class CreateRemoteFolderOperation extends RemoteOperation { */ @Override protected RemoteOperationResult run(OwnCloudClient client) { - RemoteOperationResult result; - OwnCloudVersion version = client.getOwnCloudVersion(); - boolean versionWithForbiddenChars = - (version != null && version.isVersionWithForbiddenCharacters()); - boolean noInvalidChars = FileUtils.isValidPath(mRemotePath, versionWithForbiddenChars); - if (noInvalidChars) { - result = createFolder(client); - if (!result.isSuccess() && mCreateFullPath && - RemoteOperationResult.ResultCode.CONFLICT == result.getCode()) { - result = createParentFolder(FileUtils.getParentPath(mRemotePath), client); - if (result.isSuccess()) { - result = createFolder(client); // second (and last) try - } + RemoteOperationResult result = createFolder(client); + if (!result.isSuccess() && mCreateFullPath && + RemoteOperationResult.ResultCode.CONFLICT == result.getCode()) { + result = createParentFolder(FileUtils.getParentPath(mRemotePath), client); + if (result.isSuccess()) { + result = createFolder(client); // second (and last) try } - } else { - result = new RemoteOperationResult<>(ResultCode.INVALID_CHARACTER_IN_NAME); } - return result; } @@ -108,12 +95,12 @@ public class CreateRemoteFolderOperation extends RemoteOperation { result = (status == HttpConstants.HTTP_CREATED) ? new RemoteOperationResult<>(ResultCode.OK) : new RemoteOperationResult<>(mkcol); - Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage()); + Timber.d("Create directory " + mRemotePath + ": " + result.getLogMessage()); client.exhaustResponse(mkcol.getResponseBodyAsStream()); } catch (Exception e) { result = new RemoteOperationResult<>(e); - Log_OC.e(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage(), e); + Timber.e(e, "Create directory " + mRemotePath + ": " + result.getLogMessage()); } return result; @@ -123,4 +110,4 @@ public class CreateRemoteFolderOperation extends RemoteOperation { RemoteOperation operation = new CreateRemoteFolderOperation(parentPath, mCreateFullPath); return operation.execute(client); } -} \ No newline at end of file +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java index 16699e3b..0201dac7 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.java @@ -32,7 +32,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; +import timber.log.Timber; import java.io.BufferedInputStream; import java.io.File; @@ -53,7 +53,6 @@ import java.util.concurrent.atomic.AtomicBoolean; public class DownloadRemoteFileOperation extends RemoteOperation { - private static final String TAG = DownloadRemoteFileOperation.class.getSimpleName(); private static final int FORBIDDEN_ERROR = 403; private static final int SERVICE_UNAVAILABLE_ERROR = 503; private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); @@ -81,13 +80,11 @@ public class DownloadRemoteFileOperation extends RemoteOperation { try { tmpFile.getParentFile().mkdirs(); result = downloadFile(client, tmpFile); - Log_OC.i(TAG, "Download of " + mRemotePath + " to " + getTmpPath() + ": " + - result.getLogMessage()); + Timber.i("Download of " + mRemotePath + " to " + getTmpPath() + ": " + result.getLogMessage()); } catch (Exception e) { result = new RemoteOperationResult<>(e); - Log_OC.e(TAG, "Download of " + mRemotePath + " to " + getTmpPath() + ": " + - result.getLogMessage(), e); + Timber.e(e, "Download of " + mRemotePath + " to " + getTmpPath() + ": " + result.getLogMessage()); } return result; @@ -149,7 +146,7 @@ public class DownloadRemoteFileOperation extends RemoteOperation { final Date d = WebdavUtils.parseResponseDate(modificationTime); mModificationTimestamp = (d != null) ? d.getTime() : 0; } else { - Log_OC.e(TAG, "Could not read modification time from response downloading " + mRemotePath); + Timber.e("Could not read modification time from response downloading %s", mRemotePath); } mEtag = WebdavUtils.getEtagFromResponse(mGet); @@ -158,7 +155,7 @@ public class DownloadRemoteFileOperation extends RemoteOperation { mEtag = mEtag.replace("\"", ""); if (mEtag.length() == 0) { - Log_OC.e(TAG, "Could not read eTag from response downloading " + mRemotePath); + Timber.e("Could not read eTag from response downloading %s", mRemotePath); } } else { diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java deleted file mode 100644 index 4bb2e760..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ExistenceCheckRemoteOperation.java +++ /dev/null @@ -1,153 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.resources.files; - -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.http.HttpConstants; -import com.owncloud.android.lib.common.http.methods.webdav.DavUtils; -import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod; -import com.owncloud.android.lib.common.network.RedirectionPath; -import com.owncloud.android.lib.common.network.WebdavUtils; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; - -import java.net.URL; -import java.util.concurrent.TimeUnit; - -import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; - -/** - * Operation to check the existence or absence of a path in a remote server. - * - * @author David A. Velasco - * @author David González Verdugo - */ -public class ExistenceCheckRemoteOperation extends RemoteOperation { - - /** - * Maximum time to wait for a response from the server in MILLISECONDs. - */ - public static final int TIMEOUT = 10000; - - private static final String TAG = ExistenceCheckRemoteOperation.class.getSimpleName(); - - private String mPath; - private boolean mSuccessIfAbsent; - private boolean mIsLogin; - - /** - * Sequence of redirections followed. Available only after executing the operation - */ - private RedirectionPath mRedirectionPath = null; - - /** - * Full constructor. Success of the operation will depend upon the value of successIfAbsent. - * - * @param remotePath Path to append to the URL owned by the client instance. - * @param successIfAbsent When 'true', the operation finishes in success if the path does - * NOT exist in the remote server (HTTP 404). - * @param isLogin When `true`, the username won't be added at the end of the PROPFIND url since is not - * needed to check user credentials - */ - public ExistenceCheckRemoteOperation(String remotePath, boolean successIfAbsent, boolean isLogin) { - mPath = (remotePath != null) ? remotePath : ""; - mSuccessIfAbsent = successIfAbsent; - mIsLogin = isLogin; - } - - @Override - protected RemoteOperationResult run(OwnCloudClient client) { - - boolean previousFollowRedirects = client.followRedirects(); - - try { - String stringUrl = mIsLogin ? - client.getBaseFilesWebDavUri().toString() : - client.getUserFilesWebDavUri() + WebdavUtils.encodePath(mPath); - PropfindMethod propfindMethod = new PropfindMethod( - new URL(stringUrl), - 0, - DavUtils.getAllPropset() - ); - propfindMethod.setReadTimeout(TIMEOUT, TimeUnit.SECONDS); - propfindMethod.setConnectionTimeout(TIMEOUT, TimeUnit.SECONDS); - - client.setFollowRedirects(false); - int status = client.executeHttpMethod(propfindMethod); - - if (previousFollowRedirects) { - mRedirectionPath = client.followRedirection(propfindMethod); - status = mRedirectionPath.getLastStatus(); - } - - /** - * PROPFIND method - * 404 NOT FOUND: path doesn't exist, - * 207 MULTI_STATUS: path exists. - */ - - Log_OC.d(TAG, "Existence check for " + stringUrl + WebdavUtils.encodePath(mPath) + - " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + - "finished with HTTP status " + status + (!isSuccess(status) ? "(FAIL)" : "")); - - return isSuccess(status) - ? new RemoteOperationResult<>(OK) - : new RemoteOperationResult<>(propfindMethod); - - } catch (Exception e) { - final RemoteOperationResult result = new RemoteOperationResult<>(e); - Log_OC.e(TAG, "Existence check for " + client.getUserFilesWebDavUri() + - WebdavUtils.encodePath(mPath) + " targeting for " + - (mSuccessIfAbsent ? " absence " : " existence ") + ": " + - result.getLogMessage(), result.getException()); - return result; - } finally { - client.setFollowRedirects(previousFollowRedirects); - } - } - - /** - * Gets the sequence of redirections followed during the execution of the operation. - * - * @return Sequence of redirections followed, if any, or NULL if the operation was not executed. - */ - public RedirectionPath getRedirectionPath() { - return mRedirectionPath; - } - - /** - * @return 'True' if the operation was executed and at least one redirection was followed. - */ - public boolean wasRedirected() { - return (mRedirectionPath != null && mRedirectionPath.getRedirectionsCount() > 0); - } - - private boolean isSuccess(int status) { - return ((status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_MULTI_STATUS) && !mSuccessIfAbsent) - || (status == HttpConstants.HTTP_MULTI_STATUS && !mSuccessIfAbsent) - || (status == HttpConstants.HTTP_NOT_FOUND && mSuccessIfAbsent); - } -} \ No newline at end of file diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/FileUtils.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/FileUtils.java index c9c424d3..0843783f 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/FileUtils.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/FileUtils.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,17 +24,15 @@ package com.owncloud.android.lib.resources.files; -import com.owncloud.android.lib.common.utils.Log_OC; +import timber.log.Timber; import java.io.File; public class FileUtils { - public static final String PATH_SEPARATOR = "/"; public static final String FINAL_CHUNKS_FILE = ".file"; - private static final String TAG = FileUtils.class.getSimpleName(); - public static String getParentPath(String remotePath) { + static String getParentPath(String remotePath) { String parentPath = new File(remotePath).getParent(); parentPath = parentPath.endsWith(PATH_SEPARATOR) ? parentPath : parentPath + PATH_SEPARATOR; return parentPath; @@ -45,40 +43,13 @@ public class FileUtils { * : , " , | , ? , * * * @param fileName - * @param versionSupportsForbiddenChars * @return */ - public static boolean isValidName(String fileName, boolean versionSupportsForbiddenChars) { + public static boolean isValidName(String fileName) { boolean result = true; - Log_OC.d(TAG, "fileName =======" + fileName); - if ((versionSupportsForbiddenChars && fileName.contains(PATH_SEPARATOR)) || - (!versionSupportsForbiddenChars && (fileName.contains(PATH_SEPARATOR) || - fileName.contains("\\") || fileName.contains("<") || fileName.contains(">") || - fileName.contains(":") || fileName.contains("\"") || fileName.contains("|") || - fileName.contains("?") || fileName.contains("*")))) { - - result = false; - } - return result; - } - - /** - * Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | , - * ? , * - * - * @param path - * @return - */ - public static boolean isValidPath(String path, boolean versionSupportsForbidenChars) { - boolean result = true; - - Log_OC.d(TAG, "path ....... " + path); - if (!versionSupportsForbidenChars && - (path.contains("\\") || path.contains("<") || path.contains(">") || - path.contains(":") || path.contains("\"") || path.contains("|") || - path.contains("?") || path.contains("*"))) { - + Timber.d("fileName =======%s", fileName); + if (fileName.contains(PATH_SEPARATOR)) { result = false; } return result; diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java index 2bebe540..46181e8f 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,7 +25,6 @@ package com.owncloud.android.lib.resources.files; import android.net.Uri; -import android.util.Log; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.http.HttpConstants; @@ -34,7 +33,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; -import com.owncloud.android.lib.resources.status.OwnCloudVersion; +import timber.log.Timber; import java.net.URL; import java.util.concurrent.TimeUnit; @@ -50,8 +49,6 @@ import java.util.concurrent.TimeUnit; */ public class MoveRemoteFileOperation extends RemoteOperation { - private static final String TAG = MoveRemoteFileOperation.class.getSimpleName(); - private static final int MOVE_READ_TIMEOUT = 600000; private static final int MOVE_CONNECTION_TIMEOUT = 5000; @@ -87,16 +84,6 @@ public class MoveRemoteFileOperation extends RemoteOperation { */ @Override protected RemoteOperationResult run(OwnCloudClient client) { - - OwnCloudVersion version = client.getOwnCloudVersion(); - boolean versionWithForbiddenChars = - (version != null && version.isVersionWithForbiddenCharacters()); - - /// check parameters - if (!FileUtils.isValidPath(mTargetRemotePath, versionWithForbiddenChars)) { - return new RemoteOperationResult<>(ResultCode.INVALID_CHARACTER_IN_NAME); - } - if (mTargetRemotePath.equals(mSrcRemotePath)) { // nothing to do! return new RemoteOperationResult<>(ResultCode.OK); @@ -143,13 +130,11 @@ public class MoveRemoteFileOperation extends RemoteOperation { client.exhaustResponse(move.getResponseBodyAsStream()); } - Log.i(TAG, "Move " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + - result.getLogMessage()); + Timber.i("Move " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage()); } catch (Exception e) { result = new RemoteOperationResult<>(e); - Log.e(TAG, "Move " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + - result.getLogMessage(), e); + Timber.e(e, "Move " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage()); } return result; @@ -158,4 +143,4 @@ public class MoveRemoteFileOperation extends RemoteOperation { protected boolean isSuccess(int status) { return status == HttpConstants.HTTP_CREATED || status == HttpConstants.HTTP_NO_CONTENT; } -} \ No newline at end of file +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.java index d3dfcb83..9149e6d3 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.java @@ -31,7 +31,7 @@ import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; +import timber.log.Timber; import java.net.URL; import java.util.concurrent.TimeUnit; @@ -49,7 +49,6 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R public class ReadRemoteFileOperation extends RemoteOperation { - private static final String TAG = ReadRemoteFileOperation.class.getSimpleName(); private static final int SYNC_READ_TIMEOUT = 40000; private static final int SYNC_CONNECTION_TIMEOUT = 5000; @@ -100,9 +99,7 @@ public class ReadRemoteFileOperation extends RemoteOperation { } catch (Exception e) { result = new RemoteOperationResult<>(e); - e.printStackTrace(); - Log_OC.e(TAG, "Synchronizing file " + mRemotePath + ": " + result.getLogMessage(), - result.getException()); + Timber.e(e, "Synchronizing file %s", mRemotePath); } return result; diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java index 3aee5d40..730bd86b 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,7 +34,7 @@ import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; +import timber.log.Timber; import java.net.URL; import java.util.ArrayList; @@ -51,8 +51,6 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R public class ReadRemoteFolderOperation extends RemoteOperation> { - private static final String TAG = ReadRemoteFolderOperation.class.getSimpleName(); - private String mRemotePath; /** @@ -108,14 +106,15 @@ public class ReadRemoteFolderOperation extends RemoteOperation(e); } finally { - if (result.isSuccess()) { - Log_OC.i(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage()); + if (result == null) { + Timber.e("Synchronized " + mRemotePath + ": result is null"); + } else if (result.isSuccess()) { + Timber.i("Synchronized " + mRemotePath + ": " + result.getLogMessage()); } else { if (result.isException()) { - Log_OC.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage(), - result.getException()); + Timber.e(result.getException(), "Synchronized " + mRemotePath + ": " + result.getLogMessage()); } else { - Log_OC.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage()); + Timber.e("Synchronized " + mRemotePath + ": " + result.getLogMessage()); } } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.java index e8892e6e..740641aa 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,7 +24,6 @@ package com.owncloud.android.lib.resources.files; -import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; @@ -41,14 +40,11 @@ import at.bitfire.dav4android.property.owncloud.OCId; import at.bitfire.dav4android.property.owncloud.OCPermissions; import at.bitfire.dav4android.property.owncloud.OCPrivatelink; import at.bitfire.dav4android.property.owncloud.OCSize; -import okhttp3.HttpUrl; import java.io.Serializable; import java.math.BigDecimal; import java.util.List; -import static com.owncloud.android.lib.common.OwnCloudClient.WEBDAV_FILES_PATH_4_0; - /** * Contains the data of a Remote File from a WebDavEntry * @@ -115,7 +111,7 @@ public class RemoteFile implements Parcelable, Serializable { } public RemoteFile(final Response davResource, String userId) { - this(getRemotePathFromUrl(davResource.getHref(), userId)); + this(RemoteFileUtil.Companion.getRemotePathFromUrl(davResource.getHref(), userId)); final List properties = davResource.getProperties(); for (Property property : properties) { @@ -167,21 +163,6 @@ public class RemoteFile implements Parcelable, Serializable { readFromParcel(source); } - /** - * Retrieves a relative path from a remote file url - *

- * Example: url:port/remote.php/dav/files/username/Documents/text.txt => /Documents/text.txt - * - * @param url remote file url - * @param userId file owner - * @return remote relative path of the file - */ - private static String getRemotePathFromUrl(HttpUrl url, String userId) { - final String davFilesPath = WEBDAV_FILES_PATH_4_0 + userId; - final String absoluteDavPath = Uri.decode(url.encodedPath()); - final String pathToOc = absoluteDavPath.split(davFilesPath)[0]; - return absoluteDavPath.replace(pathToOc + davFilesPath, ""); - } /** * Getters and Setters diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2ClientConfiguration.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFileUtil.kt similarity index 50% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2ClientConfiguration.java rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFileUtil.kt index 24814167..ace0675b 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2ClientConfiguration.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFileUtil.kt @@ -1,7 +1,5 @@ /* ownCloud Android Library is available under MIT license - * - * @author David A. Velasco - * Copyright (C) 2017 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,44 +21,29 @@ * THE SOFTWARE. * */ +package com.owncloud.android.lib.resources.files -package com.owncloud.android.lib.common.authentication.oauth; +import android.net.Uri +import com.owncloud.android.lib.common.OwnCloudClient +import okhttp3.HttpUrl -public class OAuth2ClientConfiguration { - - private String mClientId; - - private String mClientSecret; - - private String mRedirectUri; - - public OAuth2ClientConfiguration(String clientId, String clientSecret, String redirectUri) { - mClientId = (clientId == null) ? "" : clientId; - mClientSecret = (clientSecret == null) ? "" : clientSecret; - mRedirectUri = (redirectUri == null) ? "" : redirectUri; - } - - public String getClientId() { - return mClientId; - } - - public void setClientId(String clientId) { - mClientId = (clientId == null) ? "" : clientId; - } - - public String getClientSecret() { - return mClientSecret; - } - - public void setClientSecret(String clientSecret) { - mClientSecret = (clientSecret == null) ? "" : clientSecret; - } - - public String getRedirectUri() { - return mRedirectUri; - } - - public void setRedirectUri(String redirectUri) { - this.mRedirectUri = (redirectUri == null) ? "" : redirectUri; +class RemoteFileUtil { + companion object { + /** + * Retrieves a relative path from a remote file url + * + * + * Example: url:port/remote.php/dav/files/username/Documents/text.txt => /Documents/text.txt + * + * @param url remote file url + * @param userId file owner + * @return remote relative path of the file + */ + fun getRemotePathFromUrl(url: HttpUrl, userId: String): String? { + val davFilesPath = OwnCloudClient.WEBDAV_FILES_PATH_4_0 + userId + val absoluteDavPath = Uri.decode(url.encodedPath()) + val pathToOc = absoluteDavPath.split(davFilesPath)[0] + return absoluteDavPath.replace(pathToOc + davFilesPath, "") + } } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoveRemoteFileOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoveRemoteFileOperation.java index 20ba44ca..4789d015 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoveRemoteFileOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoveRemoteFileOperation.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,7 +32,7 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.DeleteMethod; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; +import timber.log.Timber; import java.net.URL; @@ -46,7 +46,6 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R * @author David González Verdugo */ public class RemoveRemoteFileOperation extends RemoteOperation { - private static final String TAG = RemoveRemoteFileOperation.class.getSimpleName(); private String mRemotePath; protected boolean removeChunksFolder = false; @@ -81,11 +80,11 @@ public class RemoveRemoteFileOperation extends RemoteOperation { new RemoteOperationResult<>(OK) : new RemoteOperationResult<>(deleteMethod); - Log_OC.i(TAG, "Remove " + mRemotePath + ": " + result.getLogMessage()); + Timber.i("Remove " + mRemotePath + ": " + result.getLogMessage()); } catch (Exception e) { result = new RemoteOperationResult<>(e); - Log_OC.e(TAG, "Remove " + mRemotePath + ": " + result.getLogMessage(), e); + Timber.e(e, "Remove " + mRemotePath + ": " + result.getLogMessage()); } return result; diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java index 56f137ff..90a9c469 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2016 ownCloud GmbH. + * Copyright (C) 2019 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,8 +31,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; -import com.owncloud.android.lib.common.utils.Log_OC; -import com.owncloud.android.lib.resources.status.OwnCloudVersion; +import timber.log.Timber; import java.io.File; import java.net.URL; @@ -46,8 +45,6 @@ import java.util.concurrent.TimeUnit; */ public class RenameRemoteFileOperation extends RemoteOperation { - private static final String TAG = RenameRemoteFileOperation.class.getSimpleName(); - private static final int RENAME_READ_TIMEOUT = 600000; private static final int RENAME_CONNECTION_TIMEOUT = 5000; @@ -86,15 +83,6 @@ public class RenameRemoteFileOperation extends RemoteOperation { */ @Override protected RemoteOperationResult run(OwnCloudClient client) { - - final OwnCloudVersion version = client.getOwnCloudVersion(); - final boolean versionWithForbiddenChars = - (version != null && version.isVersionWithForbiddenCharacters()); - - if (!FileUtils.isValidPath(mNewRemotePath, versionWithForbiddenChars)) { - return new RemoteOperationResult<>(ResultCode.INVALID_CHARACTER_IN_NAME); - } - try { if (mNewName.equals(mOldName)) { return new RemoteOperationResult<>(ResultCode.OK); @@ -117,16 +105,14 @@ public class RenameRemoteFileOperation extends RemoteOperation { ? new RemoteOperationResult<>(ResultCode.OK) : new RemoteOperationResult<>(move); - Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " + - result.getLogMessage() - ); + Timber.i("Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " + result.getLogMessage()); client.exhaustResponse(move.getResponseBodyAsStream()); return result; } catch (Exception e) { final RemoteOperationResult result = new RemoteOperationResult<>(e); - Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " + - ((mNewRemotePath == null) ? mNewName : mNewRemotePath) + ": " + - result.getLogMessage(), e); + Timber.e(e, + "Rename " + mOldRemotePath + " to " + ((mNewRemotePath == null) ? mNewName : mNewRemotePath) + ":" + + " " + result.getLogMessage()); return result; } } @@ -137,9 +123,9 @@ public class RenameRemoteFileOperation extends RemoteOperation { * @return 'True' if the target path is already used by an existing file. */ private boolean targetPathIsUsed(OwnCloudClient client) { - ExistenceCheckRemoteOperation existenceCheckRemoteOperation = - new ExistenceCheckRemoteOperation(mNewRemotePath, false, false); - RemoteOperationResult exists = existenceCheckRemoteOperation.run(client); + CheckPathExistenceRemoteOperation checkPathExistenceRemoteOperation = + new CheckPathExistenceRemoteOperation(mNewRemotePath, false); + RemoteOperationResult exists = checkPathExistenceRemoteOperation.execute(client); return exists.isSuccess(); } } \ No newline at end of file diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index 46738f8b..939eafee 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,8 +33,8 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; import okhttp3.MediaType; +import timber.log.Timber; import java.io.File; import java.net.URL; @@ -54,7 +54,6 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R public class UploadRemoteFileOperation extends RemoteOperation { - private static final String TAG = UploadRemoteFileOperation.class.getSimpleName(); protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); protected String mLocalPath; protected String mRemotePath; @@ -62,7 +61,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { protected String mFileLastModifTimestamp; protected PutMethod mPutMethod = null; protected String mRequiredEtag = null; - protected Set mDataTransferListeners = new HashSet(); + protected Set mDataTransferListeners = new HashSet<>(); protected FileRequestBody mFileRequestBody = null; @@ -96,27 +95,25 @@ public class UploadRemoteFileOperation extends RemoteOperation { } else { // perform the upload result = uploadFile(client); - Log_OC.i(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ": " + - result.getLogMessage()); + Timber.i("Upload of " + mLocalPath + " to " + mRemotePath + ": " + result.getLogMessage()); } } catch (Exception e) { if (mPutMethod != null && mPutMethod.isAborted()) { result = new RemoteOperationResult<>(new OperationCancelledException()); - Log_OC.e(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ": " + - result.getLogMessage(), new OperationCancelledException()); + Timber.e(result.getException(), + "Upload of " + mLocalPath + " to " + mRemotePath + ": " + result.getLogMessage()); } else { result = new RemoteOperationResult<>(e); - Log_OC.e(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ": " + - result.getLogMessage(), e); + Timber.e(e, "Upload of " + mLocalPath + " to " + mRemotePath + ": " + result.getLogMessage()); } } return result; } - protected RemoteOperationResult uploadFile(OwnCloudClient client) throws Exception { + protected RemoteOperationResult uploadFile(OwnCloudClient client) throws Exception { File fileToUpload = new File(mLocalPath); diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/ChunkedUploadRemoteFileOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/ChunkedUploadRemoteFileOperation.java index 2282767c..bbc297c8 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/ChunkedUploadRemoteFileOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/ChunkedUploadRemoteFileOperation.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,10 +29,10 @@ import com.owncloud.android.lib.common.http.methods.webdav.PutMethod; import com.owncloud.android.lib.common.network.ChunkFromFileRequestBody; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.files.FileUtils; import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation; import okhttp3.MediaType; +import timber.log.Timber; import java.io.File; import java.io.RandomAccessFile; @@ -53,7 +53,6 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation public static final long CHUNK_SIZE = 1024000; private static final int LAST_CHUNK_TIMEOUT = 900000; //15 mins. - private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName(); private String mTransferId; @@ -113,7 +112,7 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation status = client.executeHttpMethod(mPutMethod); - Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + + Timber.d("Upload of " + mLocalPath + " to " + mRemotePath + ", chunk index " + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status); diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/CreateRemoteChunkFolderOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/CreateRemoteChunkFolderOperation.java index 2c9557e1..fc2d797f 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/CreateRemoteChunkFolderOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/CreateRemoteChunkFolderOperation.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/MoveRemoteChunksFileOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/MoveRemoteChunksFileOperation.java index c60ec12f..767a20b8 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/MoveRemoteChunksFileOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/MoveRemoteChunksFileOperation.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/RemoveRemoteChunksFolderOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/RemoveRemoteChunksFolderOperation.java index e515cd04..16d2b8bd 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/RemoveRemoteChunksFolderOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/RemoveRemoteChunksFolderOperation.java @@ -1,6 +1,6 @@ /* ownCloud Android Library is available under MIT license * @author David González Verdugo - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/services/FileService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/services/FileService.kt new file mode 100644 index 00000000..aa69d505 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/services/FileService.kt @@ -0,0 +1,31 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2020 ownCloud GmbH. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package com.owncloud.android.lib.resources.files.services + +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.Service + +interface FileService: Service { + fun checkPathExistence(path: String, isUserLogged: Boolean): RemoteOperationResult +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/services/implementation/OCFileService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/services/implementation/OCFileService.kt new file mode 100644 index 00000000..abe1e2e6 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/services/implementation/OCFileService.kt @@ -0,0 +1,34 @@ +/** + * ownCloud Android client application + * + * @author Abel García de Prada + * Copyright (C) 2020 ownCloud GmbH. + * + * 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.lib.resources.files.services.implementation + +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.files.CheckPathExistenceRemoteOperation +import com.owncloud.android.lib.resources.files.services.FileService + +class OCFileService(override val client: OwnCloudClient) : + FileService { + override fun checkPathExistence(path: String, isUserLogged: Boolean): RemoteOperationResult = + CheckPathExistenceRemoteOperation( + remotePath = path, + isUserLogged = isUserLogged + ).execute(client) +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/response/CapabilityResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/response/CapabilityResponse.kt new file mode 100644 index 00000000..49efaea9 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/response/CapabilityResponse.kt @@ -0,0 +1,169 @@ +/* ownCloud Android Library is available under MIT license + * @author Abel García de Prada + * Copyright (C) 2020 ownCloud GmbH. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package com.owncloud.android.lib.resources.response + +import com.owncloud.android.lib.resources.status.RemoteCapability +import com.owncloud.android.lib.resources.status.RemoteCapability.CapabilityBooleanType +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class CapabilityResponse( + @Json(name = "version") + val serverVersion: ServerVersion?, + val capabilities: Capabilities? +) { + fun toRemoteCapability(): RemoteCapability = RemoteCapability( + versionMayor = serverVersion?.major ?: 0, + versionMinor = serverVersion?.minor ?: 0, + versionMicro = serverVersion?.micro ?: 0, + versionString = serverVersion?.string ?: "", + versionEdition = serverVersion?.edition ?: "", + corePollinterval = capabilities?.coreCapabilities?.pollinterval ?: 0, + chunkingVersion = capabilities?.davCapabilities?.chunking ?: "", + filesSharingApiEnabled = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingApiEnabled), + filesSharingResharing = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingReSharing), + filesSharingPublicEnabled = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.enabled), + filesSharingPublicUpload = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicUpload), + filesSharingPublicSupportsUploadOnly = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicUploadOnly), + filesSharingPublicMultiple = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicMultiple), + filesSharingPublicPasswordEnforced = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicPassword?.enforced), + filesSharingPublicPasswordEnforcedReadOnly = CapabilityBooleanType.fromBooleanValue( + capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicPassword?.enforcedFor?.enforcedReadOnly + ), + filesSharingPublicPasswordEnforcedReadWrite = CapabilityBooleanType.fromBooleanValue( + capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicPassword?.enforcedFor?.enforcedReadWrite + ), + filesSharingPublicPasswordEnforcedUploadOnly = CapabilityBooleanType.fromBooleanValue( + capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicPassword?.enforcedFor?.enforcedUploadOnly + ), + filesSharingPublicExpireDateEnabled = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicExpireDate?.enabled), + filesSharingPublicExpireDateDays = capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicExpireDate?.days + ?: 0, + filesSharingPublicExpireDateEnforced = CapabilityBooleanType.fromBooleanValue( + capabilities?.fileSharingCapabilities?.fileSharingPublic?.fileSharingPublicExpireDate?.enforced + ), + filesBigFileChunking = CapabilityBooleanType.fromBooleanValue(capabilities?.fileCapabilities?.bigfilechunking), + filesUndelete = CapabilityBooleanType.fromBooleanValue(capabilities?.fileCapabilities?.undelete), + filesVersioning = CapabilityBooleanType.fromBooleanValue(capabilities?.fileCapabilities?.versioning), + filesSharingFederationIncoming = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingFederation?.incoming), + filesSharingFederationOutgoing = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingFederation?.outgoing) + ) +} + +@JsonClass(generateAdapter = true) +data class Capabilities( + @Json(name = "core") + val coreCapabilities: CoreCapabilities?, + @Json(name = "files_sharing") + val fileSharingCapabilities: FileSharingCapabilities?, + @Json(name = "files") + val fileCapabilities: FileCapabilities?, + @Json(name = "dav") + val davCapabilities: DavCapabilities? +) + +@JsonClass(generateAdapter = true) +data class CoreCapabilities( + val pollinterval: Int? +) + +@JsonClass(generateAdapter = true) +data class FileSharingCapabilities( + @Json(name = "api_enabled") + val fileSharingApiEnabled: Boolean?, + @Json(name = "public") + val fileSharingPublic: FileSharingPublic?, + @Json(name = "resharing") + val fileSharingReSharing: Boolean?, + @Json(name = "federation") + val fileSharingFederation: FileSharingFederation? +) + +@JsonClass(generateAdapter = true) +data class FileSharingPublic( + val enabled: Boolean?, + @Json(name = "upload") + val fileSharingPublicUpload: Boolean?, + @Json(name = "supports_upload_only") + val fileSharingPublicUploadOnly: Boolean?, + @Json(name = "multiple") + val fileSharingPublicMultiple: Boolean?, + @Json(name = "password") + val fileSharingPublicPassword: FileSharingPublicPassword?, + @Json(name = "expire_date") + val fileSharingPublicExpireDate: FileSharingPublicExpireDate? +) + +@JsonClass(generateAdapter = true) +data class FileSharingPublicPassword( + val enforced: Boolean?, + @Json(name = "enforced_for") + val enforcedFor: FileSharingPublicPasswordEnforced? +) + +@JsonClass(generateAdapter = true) +data class FileSharingPublicPasswordEnforced( + @Json(name = "read_only") + val enforcedReadOnly: Boolean?, + @Json(name = "read_write") + val enforcedReadWrite: Boolean?, + @Json(name = "upload_only") + val enforcedUploadOnly: Boolean? +) + +@JsonClass(generateAdapter = true) +data class FileSharingPublicExpireDate( + val enabled: Boolean?, + val days: Int?, + val enforced: Boolean? +) + +@JsonClass(generateAdapter = true) +data class FileSharingFederation( + val incoming: Boolean?, + val outgoing: Boolean? +) + +@JsonClass(generateAdapter = true) +data class FileCapabilities( + val bigfilechunking: Boolean?, + val undelete: Boolean?, + val versioning: Boolean? +) + +@JsonClass(generateAdapter = true) +data class DavCapabilities( + val chunking: String? +) + +@JsonClass(generateAdapter = true) +data class ServerVersion( + var major: Int?, + var minor: Int?, + var micro: Int?, + var string: String?, + var edition: String? +) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClientManager.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/response/CommonOcsResponse.kt similarity index 54% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClientManager.java rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/response/CommonOcsResponse.kt index fe793863..d8402eb9 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClientManager.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/response/CommonOcsResponse.kt @@ -1,5 +1,6 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -19,34 +20,27 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * */ +package com.owncloud.android.lib.resources.response -package com.owncloud.android.lib.common; +import com.squareup.moshi.JsonClass -import android.accounts.AuthenticatorException; -import android.accounts.OperationCanceledException; -import android.content.Context; +// Response retrieved by OCS Rest API, used to obtain capabilities, shares and user info among others. +// More info: https://doc.owncloud.com/server/developer_manual/core/apis/ocs-capabilities.html +@JsonClass(generateAdapter = true) +data class CommonOcsResponse( + val ocs: OCSResponse +) -import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; +@JsonClass(generateAdapter = true) +data class OCSResponse( + val meta: MetaData, + val data: T +) -import java.io.IOException; - -/** - * Manager to create and reuse OwnCloudClient instances to access remote OC servers. - * - * @author David A. Velasco - * @author masensio - * @author Christian Schabesberger - */ - -public interface OwnCloudClientManager { - - OwnCloudClient getClientFor(OwnCloudAccount account, Context context) throws AccountNotFoundException, - OperationCanceledException, AuthenticatorException, IOException; - - OwnCloudClient removeClientFor(OwnCloudAccount account); - - void saveAllClients(Context context, String accountType) throws AccountNotFoundException, AuthenticatorException, IOException, - OperationCanceledException; -} \ No newline at end of file +@JsonClass(generateAdapter = true) +data class MetaData( + val status: String, + val statuscode: Int, + val message: String? +) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/response/UserInfoResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/response/UserInfoResponse.kt new file mode 100644 index 00000000..1ff3b94e --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/response/UserInfoResponse.kt @@ -0,0 +1,42 @@ +/* ownCloud Android Library is available under MIT license + * + * Copyright (C) 2020 ownCloud GmbH. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.owncloud.android.lib.resources.response + +import com.owncloud.android.lib.resources.users.RemoteUserInfo +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class UserInfoResponse( + val id: String, + @Json(name = "display-name") + val displayName: String, + val email: String? +) { + fun toRemoteUserInfo() = RemoteUserInfo( + id = id, + displayName = displayName, + email = email + ) +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.kt index b7080c4d..5d5eeb39 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/CreateRemoteShareOperation.kt @@ -2,7 +2,7 @@ * @author masensio * @author David A. Velasco * @author David González Verdugo - * Copyright (C) 2019 ownCloud GmbH + * Copyright (C) 2020 ownCloud GmbH * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,9 +32,9 @@ import com.owncloud.android.lib.common.http.HttpConstants import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult -import com.owncloud.android.lib.common.utils.Log_OC import com.owncloud.android.lib.resources.shares.RemoteShare.Companion.INIT_EXPIRATION_DATE_IN_MILLIS import okhttp3.FormBody +import timber.log.Timber import java.net.URL import java.text.SimpleDateFormat import java.util.Calendar @@ -150,7 +150,7 @@ class CreateRemoteShareOperation( } catch (e: Exception) { result = RemoteOperationResult(e) - Log_OC.e(TAG, "Exception while Creating New Share", e) + Timber.e(e, "Exception while Creating New Share") } return result @@ -159,8 +159,6 @@ class CreateRemoteShareOperation( private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK companion object { - private val TAG = CreateRemoteShareOperation::class.java.simpleName - private const val PARAM_NAME = "name" private const val PARAM_PASSWORD = "password" private const val PARAM_EXPIRATION_DATE = "expireDate" diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java index e4d4972e..4b815df1 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteShareOperation.java @@ -1,7 +1,7 @@ /* ownCloud Android Library is available under MIT license * @author David A. Velasco * @author David González Verdugo - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,7 +33,7 @@ import com.owncloud.android.lib.common.http.HttpConstants; import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; +import timber.log.Timber; import java.net.URL; @@ -46,8 +46,6 @@ import java.net.URL; public class GetRemoteShareOperation extends RemoteOperation { - private static final String TAG = GetRemoteShareOperation.class.getSimpleName(); - private long mRemoteId; public GetRemoteShareOperation(long remoteId) { @@ -85,7 +83,7 @@ public class GetRemoteShareOperation extends RemoteOperation } catch (Exception e) { result = new RemoteOperationResult<>(e); - Log_OC.e(TAG, "Exception while getting remote shares ", e); + Timber.e(e, "Exception while getting remote shares"); } return result; } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.kt index 1419ff7e..11449fb0 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteShareesOperation.kt @@ -3,7 +3,7 @@ * @author masensio * @author David A. Velasco * @author David González Verdugo - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,8 +34,8 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK -import com.owncloud.android.lib.common.utils.Log_OC import org.json.JSONObject +import timber.log.Timber import java.net.URL import java.util.ArrayList @@ -95,13 +95,13 @@ class GetRemoteShareesOperation val getMethod = GetMethod(URL(uriBuilder.build().toString())) - getMethod.addRequestHeader(RemoteOperation.OCS_API_HEADER, RemoteOperation.OCS_API_HEADER_VALUE) + getMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE) val status = client.executeHttpMethod(getMethod) val response = getMethod.responseBodyAsString if (isSuccess(status)) { - Log_OC.d(TAG, "Successful response: " + response!!) + Timber.d("Successful response: $response") // Parse the response val respJSON = JSONObject(response) @@ -128,65 +128,61 @@ class GetRemoteShareesOperation for (j in 0 until jsonResults[i].length()) { val jsonResult = jsonResults[i].getJSONObject(j) data.add(jsonResult) - Log_OC.d(TAG, "*** Added item: " + jsonResult.getString(PROPERTY_LABEL)) + Timber.d("*** Added item: ${jsonResult.getString(PROPERTY_LABEL)}") } } result = RemoteOperationResult(OK) result.data = data - Log_OC.d(TAG, "*** Get Users or groups completed ") + Timber.d("*** Get Users or groups completed ") } else { result = RemoteOperationResult(getMethod) - Log_OC.e(TAG, "Failed response while getting users/groups from the server ") + Timber.e("Failed response while getting users/groups from the server ") if (response != null) { - Log_OC.e(TAG, "*** status code: $status; response message: $response") + Timber.e("*** status code: $status; response message: $response") } else { - Log_OC.e(TAG, "*** status code: $status") + Timber.e("*** status code: $status") } } } catch (e: Exception) { result = RemoteOperationResult(e) - Log_OC.e(TAG, "Exception while getting users/groups", e) + Timber.e(e, "Exception while getting users/groups") } return result } - private fun isSuccess(status: Int): Boolean { - return status == HttpConstants.HTTP_OK - } + private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK companion object { - private val TAG = GetRemoteShareesOperation::class.java.simpleName - // OCS Routes - private val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/sharees" // from OC 8.2 + private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/sharees" // from OC 8.2 // Arguments - names - private val PARAM_FORMAT = "format" - private val PARAM_ITEM_TYPE = "itemType" - private val PARAM_SEARCH = "search" - private val PARAM_PAGE = "page" // default = 1 - private val PARAM_PER_PAGE = "perPage" // default = 200 + private const val PARAM_FORMAT = "format" + private const val PARAM_ITEM_TYPE = "itemType" + private const val PARAM_SEARCH = "search" + private const val PARAM_PAGE = "page" // default = 1 + private const val PARAM_PER_PAGE = "perPage" // default = 200 // Arguments - constant values - private val VALUE_FORMAT = "json" - private val VALUE_ITEM_TYPE = "file" // to get the server search for users / groups + private const val VALUE_FORMAT = "json" + private const val VALUE_ITEM_TYPE = "file" // to get the server search for users / groups // JSON Node names - private val NODE_OCS = "ocs" - private val NODE_DATA = "data" - private val NODE_EXACT = "exact" - private val NODE_USERS = "users" - private val NODE_GROUPS = "groups" - private val NODE_REMOTES = "remotes" - val NODE_VALUE = "value" - val PROPERTY_LABEL = "label" - val PROPERTY_SHARE_TYPE = "shareType" - val PROPERTY_SHARE_WITH = "shareWith" - val PROPERTY_SHARE_WITH_ADDITIONAL_INFO = "shareWithAdditionalInfo" + private const val NODE_OCS = "ocs" + private const val NODE_DATA = "data" + private const val NODE_EXACT = "exact" + private const val NODE_USERS = "users" + private const val NODE_GROUPS = "groups" + private const val NODE_REMOTES = "remotes" + const val NODE_VALUE = "value" + const val PROPERTY_LABEL = "label" + const val PROPERTY_SHARE_TYPE = "shareType" + const val PROPERTY_SHARE_WITH = "shareWith" + const val PROPERTY_SHARE_WITH_ADDITIONAL_INFO = "shareWithAdditionalInfo" } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.kt index f74a7e75..ae09166b 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/GetRemoteSharesForFileOperation.kt @@ -2,7 +2,7 @@ * @author masensio * @author David A. Velasco * @author David González Verdugo - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,7 +32,7 @@ import com.owncloud.android.lib.common.http.HttpConstants import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult -import com.owncloud.android.lib.common.utils.Log_OC +import timber.log.Timber import java.net.URL /** @@ -89,14 +89,14 @@ class GetRemoteSharesForFileOperation( result = parser.parse(getMethod.responseBodyAsString) if (result.isSuccess) { - Log_OC.d(TAG, "Got " + result.data.shares.size + " shares") + Timber.d("Got " + result.data.shares.size + " shares") } } else { result = RemoteOperationResult(getMethod) } } catch (e: Exception) { result = RemoteOperationResult(e) - Log_OC.e(TAG, "Exception while getting shares", e) + Timber.e(e, "Exception while getting shares") } return result @@ -105,11 +105,8 @@ class GetRemoteSharesForFileOperation( private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK companion object { - - private val TAG = GetRemoteSharesForFileOperation::class.java.simpleName - private const val PARAM_PATH = "path" private const val PARAM_RESHARES = "reshares" private const val PARAM_SUBFILES = "subfiles" } -} \ No newline at end of file +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/RemoteShare.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/RemoteShare.kt index a0a4afea..12032316 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/RemoteShare.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/RemoteShare.kt @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -42,8 +42,8 @@ data class RemoteShare( var sharedWithAdditionalInfo: String = "", var name: String = "", var shareLink: String = "", - var fileSource: Long = 0, - var itemSource: Long = 0, + var fileSource: String = "0", + var itemSource: String = "0", var shareType: ShareType? = ShareType.UNKNOWN, var permissions: Int = DEFAULT_PERMISSION, var sharedDate: Long = INIT_SHARED_DATE, @@ -66,16 +66,14 @@ data class RemoteShare( const val MAXIMUM_PERMISSIONS_FOR_FOLDER = MAXIMUM_PERMISSIONS_FOR_FILE + CREATE_PERMISSION_FLAG + DELETE_PERMISSION_FLAG - const val FEDERATED_PERMISSIONS_FOR_FILE_UP_TO_OC9 = READ_PERMISSION_FLAG + UPDATE_PERMISSION_FLAG - const val FEDERATED_PERMISSIONS_FOR_FILE_AFTER_OC9 = READ_PERMISSION_FLAG + + const val FEDERATED_PERMISSIONS_FOR_FILE = READ_PERMISSION_FLAG + UPDATE_PERMISSION_FLAG + SHARE_PERMISSION_FLAG - const val FEDERATED_PERMISSIONS_FOR_FOLDER_UP_TO_OC9 = READ_PERMISSION_FLAG + + const val FEDERATED_PERMISSIONS_FOR_FOLDER = READ_PERMISSION_FLAG + UPDATE_PERMISSION_FLAG + CREATE_PERMISSION_FLAG + - DELETE_PERMISSION_FLAG - const val FEDERATED_PERMISSIONS_FOR_FOLDER_AFTER_OC9 = - FEDERATED_PERMISSIONS_FOR_FOLDER_UP_TO_OC9 + SHARE_PERMISSION_FLAG + DELETE_PERMISSION_FLAG + + SHARE_PERMISSION_FLAG const val INIT_EXPIRATION_DATE_IN_MILLIS: Long = 0 const val INIT_SHARED_DATE: Long = 0 diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.kt index d4deda06..034be286 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/RemoveRemoteShareOperation.kt @@ -2,7 +2,7 @@ * @author masensio * @author David A. Velasco * @author David González Verdugo - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,7 +32,7 @@ import com.owncloud.android.lib.common.http.HttpConstants import com.owncloud.android.lib.common.http.methods.nonwebdav.DeleteMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult -import com.owncloud.android.lib.common.utils.Log_OC +import timber.log.Timber import java.net.URL /** @@ -75,7 +75,7 @@ class RemoveRemoteShareOperation(private val remoteShareId: Long) : RemoteOperat ) result = parser.parse(deleteMethod.responseBodyAsString) - Log_OC.d(TAG, "Unshare " + remoteShareId + ": " + result.logMessage) + Timber.d("Unshare " + remoteShareId + ": " + result.logMessage) } else { result = RemoteOperationResult(deleteMethod) @@ -83,16 +83,11 @@ class RemoveRemoteShareOperation(private val remoteShareId: Long) : RemoteOperat } catch (e: Exception) { result = RemoteOperationResult(e) - Log_OC.e(TAG, "Unshare Link Exception " + result.logMessage, e) + Timber.e(e, "Unshare Link Exception " + result.logMessage) } return result } private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK - - companion object { - - private val TAG = RemoveRemoteShareOperation::class.java.simpleName - } -} \ No newline at end of file +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareParserResult.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareParserResult.kt index bd0920a6..dd5f19df 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareParserResult.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareParserResult.kt @@ -1,6 +1,6 @@ /* ownCloud Android Library is available under MIT license * @author Christian Schabesberger - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/SharePermissionsBuilder.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/SharePermissionsBuilder.kt index 2f503ac1..ec166134 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/SharePermissionsBuilder.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/SharePermissionsBuilder.kt @@ -1,6 +1,6 @@ /* ownCloud Android Library is available under MIT license * @author David A. Velasco - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.kt index 09fc03ab..6e55fd51 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareToRemoteOperationResultParser.kt @@ -2,7 +2,7 @@ * @author David A. Velasco * @author David González Verdugo * @author Christian Schabesberger - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,9 +29,9 @@ package com.owncloud.android.lib.resources.shares import android.net.Uri import com.owncloud.android.lib.common.operations.RemoteOperationResult -import com.owncloud.android.lib.common.utils.Log_OC import com.owncloud.android.lib.resources.status.OwnCloudVersion import org.xmlpull.v1.XmlPullParserException +import timber.log.Timber import java.io.ByteArrayInputStream import java.io.IOException import java.util.ArrayList @@ -53,7 +53,7 @@ class ShareToRemoteOperationResultParser(private var shareXmlParser: ShareXMLPar // Parse xml response and obtain the list of shares val byteArrayServerResponse = ByteArrayInputStream(serverResponse.toByteArray()) if (shareXmlParser == null) { - Log_OC.w(TAG, "No ShareXmlParser provided, creating new instance ") + Timber.w("No ShareXmlParser provided, creating new instance") shareXmlParser = ShareXMLParser() } val shares = shareXmlParser?.parseXMLResponse(byteArrayServerResponse) @@ -72,10 +72,10 @@ class ShareToRemoteOperationResultParser(private var shareXmlParser: ShareXMLPar } if (serverBaseUri != null) { - val sharingLinkPath = ShareUtils.getSharingLinkPath(ownCloudVersion) + val sharingLinkPath = ShareUtils.SHARING_LINK_PATH share.shareLink = serverBaseUri.toString() + sharingLinkPath + share.token } else { - Log_OC.e(TAG, "Couldn't build link for public share :(") + Timber.e("Couldn't build link for public share :(") } share @@ -87,7 +87,7 @@ class ShareToRemoteOperationResultParser(private var shareXmlParser: ShareXMLPar } else { result = RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE) - Log_OC.e(TAG, "Successful status with no share in the response") + Timber.e("Successful status with no share in the response") } } shareXmlParser?.isWrongParameter!! -> { @@ -107,18 +107,14 @@ class ShareToRemoteOperationResultParser(private var shareXmlParser: ShareXMLPar } } } catch (e: XmlPullParserException) { - Log_OC.e(TAG, "Error parsing response from server ", e) + Timber.e(e, "Error parsing response from server") result = RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE) } catch (e: IOException) { - Log_OC.e(TAG, "Error reading response from server ", e) + Timber.e(e, "Error reading response from server") result = RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE) } return result } - - companion object { - private val TAG = ShareToRemoteOperationResultParser::class.java.simpleName - } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareUtils.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareUtils.java index 4d4b80ae..518666a1 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareUtils.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareUtils.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,8 +24,6 @@ package com.owncloud.android.lib.resources.shares; -import com.owncloud.android.lib.resources.status.OwnCloudVersion; - /** * Contains Constants for Share Operation * @@ -39,14 +37,5 @@ public class ShareUtils { public static final String SHARING_API_PATH = "ocs/v2.php/apps/files_sharing/api/v1/shares"; // String to build the link with the token of a share: - public static final String SHARING_LINK_PATH_BEFORE_VERSION_8 = "/public.php?service=files&t="; - public static final String SHARING_LINK_PATH_AFTER_VERSION_8 = "/index.php/s/"; - - public static String getSharingLinkPath(OwnCloudVersion version) { - if (version != null && version.isAfter8Version()) { - return SHARING_LINK_PATH_AFTER_VERSION_8; - } else { - return SHARING_LINK_PATH_BEFORE_VERSION_8; - } - } -} \ No newline at end of file + public static final String SHARING_LINK_PATH = "/index.php/s/"; +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareXMLParser.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareXMLParser.kt index df634321..0fa93482 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareXMLParser.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareXMLParser.kt @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -110,12 +110,16 @@ class ShareXMLParser { } val name = parser.name // read NODE_META and NODE_DATA - if (name.equals(NODE_META, ignoreCase = true)) { - readMeta(parser) - } else if (name.equals(NODE_DATA, ignoreCase = true)) { - shares = readData(parser) - } else { - skip(parser) + when { + name.equals(NODE_META, ignoreCase = true) -> { + readMeta(parser) + } + name.equals(NODE_DATA, ignoreCase = true) -> { + shares = readData(parser) + } + else -> { + skip(parser) + } } } return shares @@ -130,24 +134,25 @@ class ShareXMLParser { @Throws(XmlPullParserException::class, IOException::class) private fun readMeta(parser: XmlPullParser) { parser.require(XmlPullParser.START_TAG, ns, NODE_META) - //Log_OC.d(TAG, "---- NODE META ---"); while (parser.next() != XmlPullParser.END_TAG) { if (parser.eventType != XmlPullParser.START_TAG) { continue } val name = parser.name - if (name.equals(NODE_STATUS, ignoreCase = true)) { - status = readNode(parser, NODE_STATUS) - - } else if (name.equals(NODE_STATUS_CODE, ignoreCase = true)) { - statusCode = Integer.parseInt(readNode(parser, NODE_STATUS_CODE)) - - } else if (name.equals(NODE_MESSAGE, ignoreCase = true)) { - message = readNode(parser, NODE_MESSAGE) - - } else { - skip(parser) + when { + name.equals(NODE_STATUS, ignoreCase = true) -> { + status = readNode(parser, NODE_STATUS) + } + name.equals(NODE_STATUS_CODE, ignoreCase = true) -> { + statusCode = Integer.parseInt(readNode(parser, NODE_STATUS_CODE)) + } + name.equals(NODE_MESSAGE, ignoreCase = true) -> { + message = readNode(parser, NODE_MESSAGE) + } + else -> { + skip(parser) + } } } } @@ -165,33 +170,34 @@ class ShareXMLParser { var share: RemoteShare? = null parser.require(XmlPullParser.START_TAG, ns, NODE_DATA) - //Log_OC.d(TAG, "---- NODE DATA ---"); while (parser.next() != XmlPullParser.END_TAG) { if (parser.eventType != XmlPullParser.START_TAG) { continue } val name = parser.name - if (name.equals(NODE_ELEMENT, ignoreCase = true)) { - readElement(parser, shares) - - } else if (name.equals(NODE_ID, ignoreCase = true)) {// Parse Create XML Response - share = RemoteShare() - val value = readNode(parser, NODE_ID) - share.id = Integer.parseInt(value).toLong() - - } else if (name.equals(NODE_URL, ignoreCase = true)) { - // NOTE: this field is received in all the public shares from OC 9.0.0 - // in previous versions, it's received in the result of POST requests, but not - // in GET requests - share!!.shareType = ShareType.PUBLIC_LINK - val value = readNode(parser, NODE_URL) - share.shareLink = value - - } else if (name.equals(NODE_TOKEN, ignoreCase = true)) { - share!!.token = readNode(parser, NODE_TOKEN) - - } else { - skip(parser) + when { + name.equals(NODE_ELEMENT, ignoreCase = true) -> { + readElement(parser, shares) + } + name.equals(NODE_ID, ignoreCase = true) -> {// Parse Create XML Response + share = RemoteShare() + val value = readNode(parser, NODE_ID) + share.id = Integer.parseInt(value).toLong() + } + name.equals(NODE_URL, ignoreCase = true) -> { + // NOTE: this field is received in all the public shares from OC 9.0.0 + // in previous versions, it's received in the result of POST requests, but not + // in GET requests + share!!.shareType = ShareType.PUBLIC_LINK + val value = readNode(parser, NODE_URL) + share.shareLink = value + } + name.equals(NODE_TOKEN, ignoreCase = true) -> { + share!!.token = readNode(parser, NODE_TOKEN) + } + else -> { + skip(parser) + } } } @@ -217,7 +223,6 @@ class ShareXMLParser { val remoteShare = RemoteShare() - //Log_OC.d(TAG, "---- NODE ELEMENT ---"); while (parser.next() != XmlPullParser.END_TAG) { if (parser.eventType != XmlPullParser.START_TAG) { continue @@ -243,7 +248,7 @@ class ShareXMLParser { } name.equals(NODE_ITEM_SOURCE, ignoreCase = true) -> { - remoteShare.itemSource = java.lang.Long.parseLong(readNode(parser, NODE_ITEM_SOURCE)) + remoteShare.itemSource = readNode(parser, NODE_ITEM_SOURCE) } name.equals(NODE_PARENT, ignoreCase = true) -> { @@ -260,7 +265,7 @@ class ShareXMLParser { } name.equals(NODE_FILE_SOURCE, ignoreCase = true) -> { - remoteShare.fileSource = java.lang.Long.parseLong(readNode(parser, NODE_FILE_SOURCE)) + remoteShare.fileSource = readNode(parser, NODE_FILE_SOURCE) } name.equals(NODE_PATH, ignoreCase = true) -> { @@ -343,7 +348,6 @@ class ShareXMLParser { private fun readNode(parser: XmlPullParser, node: String): String { parser.require(XmlPullParser.START_TAG, ns, node) val value = readText(parser) - //Log_OC.d(TAG, "node= " + node + ", value= " + value); parser.require(XmlPullParser.END_TAG, ns, node) return value } @@ -387,8 +391,6 @@ class ShareXMLParser { companion object { - //private static final String TAG = ShareXMLParser.class.getSimpleName(); - // No namespaces private val ns: String? = null diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.kt index 16f34e2d..0b4a08e5 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/UpdateRemoteShareOperation.kt @@ -1,6 +1,6 @@ /* ownCloud Android Library is available under MIT license * - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,9 +30,9 @@ import com.owncloud.android.lib.common.http.HttpConstants import com.owncloud.android.lib.common.http.methods.nonwebdav.PutMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult -import com.owncloud.android.lib.common.utils.Log_OC import com.owncloud.android.lib.resources.shares.RemoteShare.Companion.DEFAULT_PERMISSION import okhttp3.FormBody +import timber.log.Timber import java.net.URL import java.text.SimpleDateFormat import java.util.Calendar @@ -61,7 +61,6 @@ class UpdateRemoteShareOperation /** * Name to update in Share resource. Ignored by servers previous to version 10.0.0 * - * @param name Name to set to the target share. * Empty string clears the current name. * Null results in no update applied to the name. */ @@ -70,7 +69,6 @@ class UpdateRemoteShareOperation /** * Password to update in Share resource. * - * @param password Password to set to the target share. * Empty string clears the current password. * Null results in no update applied to the password. */ @@ -79,7 +77,6 @@ class UpdateRemoteShareOperation /** * Expiration date to update in Share resource. * - * @param expirationDateInMillis Expiration date to set to the target share. * A negative value clears the current expiration date. * Zero value (start-of-epoch) results in no update done on * the expiration date. @@ -89,7 +86,6 @@ class UpdateRemoteShareOperation /** * Permissions to update in Share resource. * - * @param permissions Permissions to set to the target share. * Values <= 0 result in no update applied to the permissions. */ var permissions: Int = DEFAULT_PERMISSION @@ -97,7 +93,6 @@ class UpdateRemoteShareOperation /** * Enable upload permissions to update in Share resource. * - * @param publicUpload Upload permission to set to the target share. * Null results in no update applied to the upload permission. */ var publicUpload: Boolean? = null @@ -181,7 +176,7 @@ class UpdateRemoteShareOperation } catch (e: Exception) { result = RemoteOperationResult(e) - Log_OC.e(TAG, "Exception while Creating New Share", e) + Timber.e(e, "Exception while Creating New Share") } return result @@ -190,7 +185,6 @@ class UpdateRemoteShareOperation private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK companion object { - private val TAG = GetRemoteShareOperation::class.java.simpleName private const val PARAM_NAME = "name" private const val PARAM_PASSWORD = "password" diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareService.kt similarity index 87% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareService.kt rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareService.kt index e8b728b3..38980256 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareService.kt @@ -3,7 +3,7 @@ * * @author David González Verdugo * - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -18,10 +18,12 @@ * along with this program. If not, see . */ -package com.owncloud.android.lib.resources.shares +package com.owncloud.android.lib.resources.shares.services import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.resources.Service +import com.owncloud.android.lib.resources.shares.ShareParserResult +import com.owncloud.android.lib.resources.shares.ShareType interface ShareService : Service { fun getShares( diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareeService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareeService.kt similarity index 91% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareeService.kt rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareeService.kt index ba6426dc..ab6d9e83 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/ShareeService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareeService.kt @@ -3,7 +3,7 @@ * * @author David González Verdugo * - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package com.owncloud.android.lib.resources.shares +package com.owncloud.android.lib.resources.shares.services import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.resources.Service diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/implementation/OCShareService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/implementation/OCShareService.kt new file mode 100644 index 00000000..a22919bf --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/implementation/OCShareService.kt @@ -0,0 +1,91 @@ +/** + * ownCloud Android client application + * + * @author David González Verdugo + * + * Copyright (C) 2020 ownCloud GmbH. + * + * 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.lib.resources.shares.services.implementation + +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.shares.CreateRemoteShareOperation +import com.owncloud.android.lib.resources.shares.GetRemoteSharesForFileOperation +import com.owncloud.android.lib.resources.shares.RemoveRemoteShareOperation +import com.owncloud.android.lib.resources.shares.ShareParserResult +import com.owncloud.android.lib.resources.shares.ShareType +import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation +import com.owncloud.android.lib.resources.shares.services.ShareService + +class OCShareService(override val client: OwnCloudClient) : + ShareService { + override fun getShares( + remoteFilePath: String, + reshares: Boolean, + subfiles: Boolean + ): RemoteOperationResult = GetRemoteSharesForFileOperation( + remoteFilePath, + reshares, + subfiles + ).execute(client) + + override fun insertShare( + remoteFilePath: String, + shareType: ShareType, + shareWith: String, + permissions: Int, + name: String, + password: String, + expirationDate: Long, + publicUpload: Boolean + ): RemoteOperationResult = + CreateRemoteShareOperation( + remoteFilePath, + shareType, + shareWith, + permissions + ).apply { + this.name = name + this.password = password + this.expirationDateInMillis = expirationDate + this.publicUpload = publicUpload + this.retrieveShareDetails = true + }.execute(client) + + override fun updateShare( + remoteId: Long, + name: String, + password: String?, + expirationDate: Long, + permissions: Int, + publicUpload: Boolean + ): RemoteOperationResult = + UpdateRemoteShareOperation( + remoteId + ).apply { + this.name = name + this.password = password + this.expirationDateInMillis = expirationDate + this.permissions = permissions + this.publicUpload = publicUpload + this.retrieveShareDetails = true + }.execute(client) + + override fun deleteShare(remoteId: Long): RemoteOperationResult = + RemoveRemoteShareOperation( + remoteId + ).execute(client) +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/implementation/OCShareeService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/implementation/OCShareeService.kt new file mode 100644 index 00000000..370ef34b --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/implementation/OCShareeService.kt @@ -0,0 +1,42 @@ +/** + * ownCloud Android client application + * + * @author David González Verdugo + * + * Copyright (C) 2020 ownCloud GmbH. + * + * 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.lib.resources.shares.services.implementation + +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.shares.GetRemoteShareesOperation +import com.owncloud.android.lib.resources.shares.services.ShareeService +import org.json.JSONObject +import java.util.ArrayList + +class OCShareeService(override val client: OwnCloudClient) : + ShareeService { + override fun getSharees( + searchString: String, + page: Int, + perPage: Int + ): RemoteOperationResult> = + GetRemoteShareesOperation( + searchString, + page, + perPage + ).execute(client) +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/GetRemoteCapabilitiesOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/GetRemoteCapabilitiesOperation.kt index e5cd965b..256e03b6 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/GetRemoteCapabilitiesOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/GetRemoteCapabilitiesOperation.kt @@ -2,7 +2,9 @@ * @author masensio * @author Semih Serhat Karakaya * @author David González Verdugo - * Copyright (C) 2019 ownCloud GmbH. + * @author Abel García de Prada + * + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,7 +26,6 @@ * THE SOFTWARE. * */ - package com.owncloud.android.lib.resources.status import com.owncloud.android.lib.common.OwnCloudClient @@ -33,10 +34,14 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK -import com.owncloud.android.lib.common.utils.Log_OC -import org.json.JSONObject +import com.owncloud.android.lib.resources.response.CapabilityResponse +import com.owncloud.android.lib.resources.response.CommonOcsResponse +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import timber.log.Timber +import java.lang.reflect.Type import java.net.URL -import com.owncloud.android.lib.resources.status.RemoteCapability.CapabilityBooleanType /** * Get the Capabilities from the server @@ -45,228 +50,51 @@ import com.owncloud.android.lib.resources.status.RemoteCapability.CapabilityBool * @author masensio * @author David González Verdugo */ -/** - * Constructor - */ class GetRemoteCapabilitiesOperation : RemoteOperation() { override fun run(client: OwnCloudClient): RemoteOperationResult { var result: RemoteOperationResult try { - val requestUri = client.baseUri - val uriBuilder = requestUri.buildUpon() - uriBuilder.appendEncodedPath(OCS_ROUTE) // avoid starting "/" in this method - uriBuilder.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT) - - val getMethod = GetMethod(URL(uriBuilder.build().toString())) - - getMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE) - + val uriBuilder = client.baseUri.buildUpon().apply { + appendEncodedPath(OCS_ROUTE) // avoid starting "/" in this method + appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT) + } + val getMethod = GetMethod(URL(uriBuilder.build().toString())).apply { + addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE) + } val status = client.executeHttpMethod(getMethod) val response = getMethod.responseBodyAsString - if (!isSuccess(status)) { - result = RemoteOperationResult(getMethod) - Log_OC.e(TAG, "Failed response while getting capabilities from the server ") - if (response != null) { - Log_OC.e(TAG, "*** status code: $status; response message: $response") - } else { - Log_OC.e(TAG, "*** status code: $status") - } + if (status == HttpConstants.HTTP_OK) { + Timber.d("Successful response $response") - return result - } + // Parse the response + val moshi: Moshi = Moshi.Builder().build() + val type: Type = Types.newParameterizedType(CommonOcsResponse::class.java, CapabilityResponse::class.java) + val adapter: JsonAdapter> = moshi.adapter(type) + val commonResponse: CommonOcsResponse? = adapter.fromJson(response) - Log_OC.d(TAG, "Successful response: " + response!!) - - // Parse the response - val respJSON = JSONObject(response) - val respOCS = respJSON.getJSONObject(NODE_OCS) - val respMeta = respOCS.getJSONObject(NODE_META) - val respData = respOCS.getJSONObject(NODE_DATA) - - // Read meta - val statusProp = respMeta.getString(PROPERTY_STATUS).equals(PROPERTY_STATUS_OK, ignoreCase = true) - val statuscode = respMeta.getInt(PROPERTY_STATUSCODE) - val message = respMeta.getString(PROPERTY_MESSAGE) - - if (statusProp) { - val capability = RemoteCapability() - // Add Version - if (respData.has(NODE_VERSION)) { - val respVersion = respData.getJSONObject(NODE_VERSION) - capability.versionMayor = respVersion.getInt(PROPERTY_MAJOR) - capability.versionMinor = respVersion.getInt(PROPERTY_MINOR) - capability.versionMicro = respVersion.getInt(PROPERTY_MICRO) - capability.versionString = respVersion.getString(PROPERTY_STRING) - capability.versionEdition = respVersion.getString(PROPERTY_EDITION) - Log_OC.d(TAG, "*** Added $NODE_VERSION") - } - - // Capabilities Object - if (respData.has(NODE_CAPABILITIES)) { - val respCapabilities = respData.getJSONObject(NODE_CAPABILITIES) - - // Add Core: pollinterval - if (respCapabilities.has(NODE_CORE)) { - val respCore = respCapabilities.getJSONObject(NODE_CORE) - capability.corePollinterval = respCore.getInt(PROPERTY_POLLINTERVAL) - Log_OC.d(TAG, "*** Added $NODE_CORE") - } - - // Add files_sharing: public, user, resharing - if (respCapabilities.has(NODE_FILES_SHARING)) { - val respFilesSharing = respCapabilities.getJSONObject(NODE_FILES_SHARING) - if (respFilesSharing.has(PROPERTY_API_ENABLED)) { - capability.filesSharingApiEnabled = CapabilityBooleanType.fromBooleanValue( - respFilesSharing.getBoolean(PROPERTY_API_ENABLED) - ) - } - if (respFilesSharing.has(PROPERTY_SEARCH_MIN_LENGTH)){ - capability.filesSharingSearchMinLength = respFilesSharing.getInt( - PROPERTY_SEARCH_MIN_LENGTH) - } - - if (respFilesSharing.has(NODE_PUBLIC)) { - val respPublic = respFilesSharing.getJSONObject(NODE_PUBLIC) - capability.filesSharingPublicEnabled = CapabilityBooleanType.fromBooleanValue( - respPublic.getBoolean(PROPERTY_ENABLED) - ) - - if (respPublic.has(NODE_PASSWORD)) { - val respPassword = respPublic.getJSONObject(NODE_PASSWORD) - capability.filesSharingPublicPasswordEnforced = - CapabilityBooleanType.fromBooleanValue( - respPublic.getJSONObject(NODE_PASSWORD).getBoolean(PROPERTY_ENFORCED) - ) - - if (respPassword.has(NODE_ENFORCED_FOR)) { - capability.filesSharingPublicPasswordEnforcedReadOnly = - CapabilityBooleanType.fromBooleanValue( - respPassword.getJSONObject(NODE_ENFORCED_FOR).getBoolean( - PROPERTY_ENFORCED_READ_ONLY - ) - ) - - capability.filesSharingPublicPasswordEnforcedReadWrite = - CapabilityBooleanType.fromBooleanValue( - respPassword.getJSONObject(NODE_ENFORCED_FOR).getBoolean( - PROPERTY_ENFORCED_READ_WRITE - ) - ) - - capability.filesSharingPublicPasswordEnforcedUploadOnly = - CapabilityBooleanType.fromBooleanValue( - respPassword.getJSONObject(NODE_ENFORCED_FOR).getBoolean( - PROPERTY_ENFORCED_UPLOAD_ONLY - ) - ) - } - } - if (respPublic.has(NODE_EXPIRE_DATE)) { - val respExpireDate = respPublic.getJSONObject(NODE_EXPIRE_DATE) - capability.filesSharingPublicExpireDateEnabled = - CapabilityBooleanType.fromBooleanValue( - respExpireDate.getBoolean(PROPERTY_ENABLED) - ) - if (respExpireDate.has(PROPERTY_DAYS)) { - capability.filesSharingPublicExpireDateDays = - respExpireDate.getInt(PROPERTY_DAYS) - } - if (respExpireDate.has(PROPERTY_ENFORCED)) { - capability.filesSharingPublicExpireDateEnforced = - CapabilityBooleanType.fromBooleanValue( - respExpireDate.getBoolean(PROPERTY_ENFORCED) - ) - } - } - if (respPublic.has(PROPERTY_UPLOAD)) { - capability.filesSharingPublicUpload = CapabilityBooleanType.fromBooleanValue( - respPublic.getBoolean(PROPERTY_UPLOAD) - ) - } - if (respPublic.has(PROPERTY_UPLOAD_ONLY)) { - capability.filesSharingPublicSupportsUploadOnly = - CapabilityBooleanType.fromBooleanValue( - respPublic.getBoolean(PROPERTY_UPLOAD_ONLY) - ) - } - if (respPublic.has(PROPERTY_MULTIPLE)) { - capability.filesSharingPublicMultiple = CapabilityBooleanType.fromBooleanValue( - respPublic.getBoolean(PROPERTY_MULTIPLE) - ) - } - } - - if (respFilesSharing.has(NODE_USER)) { - val respUser = respFilesSharing.getJSONObject(NODE_USER) - capability.filesSharingUserSendMail = CapabilityBooleanType.fromBooleanValue( - respUser.getBoolean(PROPERTY_SEND_MAIL) - ) - } - - capability.filesSharingResharing = CapabilityBooleanType.fromBooleanValue( - respFilesSharing.getBoolean(PROPERTY_RESHARING) - ) - if (respFilesSharing.has(NODE_FEDERATION)) { - val respFederation = respFilesSharing.getJSONObject(NODE_FEDERATION) - capability.filesSharingFederationOutgoing = - CapabilityBooleanType.fromBooleanValue(respFederation.getBoolean(PROPERTY_OUTGOING)) - capability.filesSharingFederationIncoming = CapabilityBooleanType.fromBooleanValue( - respFederation.getBoolean(PROPERTY_INCOMING) - ) - } - Log_OC.d(TAG, "*** Added $NODE_FILES_SHARING") - } - - if (respCapabilities.has(NODE_FILES)) { - val respFiles = respCapabilities.getJSONObject(NODE_FILES) - // Add files - capability.filesBigFileChunking = CapabilityBooleanType.fromBooleanValue( - respFiles.getBoolean(PROPERTY_BIGFILECHUNKING) - ) - if (respFiles.has(PROPERTY_UNDELETE)) { - capability.filesUndelete = CapabilityBooleanType.fromBooleanValue( - respFiles.getBoolean(PROPERTY_UNDELETE) - ) - } - if (respFiles.has(PROPERTY_VERSIONING)) { - capability.filesVersioning = CapabilityBooleanType.fromBooleanValue( - respFiles.getBoolean(PROPERTY_VERSIONING) - ) - } - Log_OC.d(TAG, "*** Added $NODE_FILES") - } - } - // Result result = RemoteOperationResult(OK) - result.data = capability + result.data = commonResponse?.ocs?.data?.toRemoteCapability() - Log_OC.d(TAG, "*** Get Capabilities completed ") + Timber.d("Get Capabilities completed and parsed to ${result.data}") } else { - result = RemoteOperationResult(statuscode, message, null) - Log_OC.e(TAG, "Failed response while getting capabilities from the server ") - Log_OC.e(TAG, "*** status: $statusProp; message: $message") + result = RemoteOperationResult(getMethod) + Timber.e("Failed response while getting capabilities from the server status code: $status; response message: $response") } } catch (e: Exception) { result = RemoteOperationResult(e) - Log_OC.e(TAG, "Exception while getting capabilities", e) + Timber.e(e, "Exception while getting capabilities") } return result } - private fun isSuccess(status: Int): Boolean { - return status == HttpConstants.HTTP_OK - } - companion object { - private val TAG = GetRemoteCapabilitiesOperation::class.java.simpleName - // OCS Routes private const val OCS_ROUTE = "ocs/v2.php/cloud/capabilities" @@ -275,58 +103,5 @@ class GetRemoteCapabilitiesOperation : RemoteOperation() { // Arguments - constant values private const val VALUE_FORMAT = "json" - - // JSON Node names - private const val NODE_OCS = "ocs" - - private const val NODE_META = "meta" - - private const val NODE_DATA = "data" - private const val NODE_VERSION = "version" - - private const val NODE_CAPABILITIES = "capabilities" - private const val NODE_CORE = "core" - - private const val NODE_FILES_SHARING = "files_sharing" - private const val NODE_PUBLIC = "public" - private const val NODE_PASSWORD = "password" - private const val NODE_ENFORCED_FOR = "enforced_for" - private const val NODE_EXPIRE_DATE = "expire_date" - private const val NODE_USER = "user" - private const val NODE_FEDERATION = "federation" - private const val NODE_FILES = "files" - - private const val PROPERTY_STATUS = "status" - private const val PROPERTY_STATUS_OK = "ok" - private const val PROPERTY_STATUSCODE = "statuscode" - private const val PROPERTY_MESSAGE = "message" - - private const val PROPERTY_POLLINTERVAL = "pollinterval" - - private const val PROPERTY_MAJOR = "major" - private const val PROPERTY_MINOR = "minor" - private const val PROPERTY_MICRO = "micro" - private const val PROPERTY_STRING = "string" - private const val PROPERTY_EDITION = "edition" - - private const val PROPERTY_API_ENABLED = "api_enabled" - private const val PROPERTY_ENABLED = "enabled" - private const val PROPERTY_ENFORCED = "enforced" - private const val PROPERTY_ENFORCED_READ_ONLY = "read_only" - private const val PROPERTY_ENFORCED_READ_WRITE = "read_write" - private const val PROPERTY_ENFORCED_UPLOAD_ONLY = "upload_only" - private const val PROPERTY_DAYS = "days" - private const val PROPERTY_SEARCH_MIN_LENGTH = "search_min_length" - private const val PROPERTY_SEND_MAIL = "send_mail" - private const val PROPERTY_UPLOAD = "upload" - private const val PROPERTY_UPLOAD_ONLY = "supports_upload_only" - private const val PROPERTY_MULTIPLE = "multiple" - private const val PROPERTY_RESHARING = "resharing" - private const val PROPERTY_OUTGOING = "outgoing" - private const val PROPERTY_INCOMING = "incoming" - - private const val PROPERTY_BIGFILECHUNKING = "bigfilechunking" - private const val PROPERTY_UNDELETE = "undelete" - private const val PROPERTY_VERSIONING = "versioning" } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java deleted file mode 100644 index 9917186a..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java +++ /dev/null @@ -1,200 +0,0 @@ -/* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -package com.owncloud.android.lib.resources.status; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.Uri; - -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.http.HttpConstants; -import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; -import org.json.JSONException; -import org.json.JSONObject; - -import javax.net.ssl.SSLException; -import java.net.URL; -import java.util.concurrent.TimeUnit; - -import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; - -/** - * Checks if the server is valid and if the server supports the Share API - * - * @author David A. Velasco - * @author masensio - * @author David González Verdugo - */ - -public class GetRemoteStatusOperation extends RemoteOperation { - - /** - * Maximum time to wait for a response from the server when the connection is being tested, - * in MILLISECONDs. - */ - public static final long TRY_CONNECTION_TIMEOUT = 5000; - - private static final String TAG = GetRemoteStatusOperation.class.getSimpleName(); - - private static final String NODE_INSTALLED = "installed"; - private static final String NODE_VERSION = "version"; - private static final String HTTPS_PREFIX = "https://"; - private static final String HTTP_PREFIX = "http://"; - - private RemoteOperationResult mLatestResult; - private Context mContext; - - public GetRemoteStatusOperation(Context context) { - mContext = context; - } - - private boolean tryConnection(OwnCloudClient client) { - boolean retval = false; - String baseUrlSt = client.getBaseUri().toString(); - try { - GetMethod getMethod = new GetMethod(new URL(baseUrlSt + OwnCloudClient.STATUS_PATH)); - - getMethod.setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS); - getMethod.setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS); - - client.setFollowRedirects(false); - boolean isRedirectToNonSecureConnection = false; - int status; - try { - status = client.executeHttpMethod(getMethod); - mLatestResult = isSuccess(status) - ? new RemoteOperationResult<>(OK) - : new RemoteOperationResult<>(getMethod); - } catch (SSLException sslE) { - mLatestResult = new RemoteOperationResult(sslE); - return false; - } - - String redirectedLocation = mLatestResult.getRedirectedLocation(); - while (redirectedLocation != null && redirectedLocation.length() > 0 - && !mLatestResult.isSuccess()) { - - isRedirectToNonSecureConnection |= ( - baseUrlSt.startsWith(HTTPS_PREFIX) && - redirectedLocation.startsWith(HTTP_PREFIX) - ); - - getMethod = new GetMethod(new URL(redirectedLocation)); - getMethod.setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS); - getMethod.setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS); - - status = client.executeHttpMethod(getMethod); - mLatestResult = new RemoteOperationResult<>(getMethod); - redirectedLocation = mLatestResult.getRedirectedLocation(); - } - - if (isSuccess(status)) { - - JSONObject respJSON = new JSONObject(getMethod.getResponseBodyAsString()); - if (!respJSON.getBoolean(NODE_INSTALLED)) { - mLatestResult = new RemoteOperationResult( - RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED); - } else { - String version = respJSON.getString(NODE_VERSION); - OwnCloudVersion ocVersion = new OwnCloudVersion(version); - /// the version object will be returned even if the version is invalid, no error code; - /// every app will decide how to act if (ocVersion.isVersionValid() == false) - - if (isRedirectToNonSecureConnection) { - mLatestResult = new RemoteOperationResult<>( - RemoteOperationResult.ResultCode. - OK_REDIRECT_TO_NON_SECURE_CONNECTION); - } else { - mLatestResult = new RemoteOperationResult<>( - baseUrlSt.startsWith(HTTPS_PREFIX) ? - RemoteOperationResult.ResultCode.OK_SSL : - RemoteOperationResult.ResultCode.OK_NO_SSL); - } - - mLatestResult.setData(ocVersion); - retval = true; - } - - } else { - mLatestResult = new RemoteOperationResult<>(getMethod); - } - - } catch (JSONException e) { - mLatestResult = new RemoteOperationResult<>( - RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED); - - } catch (Exception e) { - mLatestResult = new RemoteOperationResult<>(e); - } - - if (mLatestResult.isSuccess()) { - Log_OC.i(TAG, "Connection check at " + baseUrlSt + ": " + mLatestResult.getLogMessage()); - - } else if (mLatestResult.getException() != null) { - Log_OC.e(TAG, "Connection check at " + baseUrlSt + ": " + mLatestResult.getLogMessage(), - mLatestResult.getException()); - - } else { - Log_OC.e(TAG, "Connection check at " + baseUrlSt + ": " + mLatestResult.getLogMessage()); - } - - return retval; - } - - private boolean isOnline() { - ConnectivityManager cm = (ConnectivityManager) mContext - .getSystemService(Context.CONNECTIVITY_SERVICE); - return cm != null && cm.getActiveNetworkInfo() != null - && cm.getActiveNetworkInfo().isConnectedOrConnecting(); - } - - @Override - protected RemoteOperationResult run(OwnCloudClient client) { - if (!isOnline()) { - return new RemoteOperationResult<>(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION); - } - String baseUriStr = client.getBaseUri().toString(); - if (baseUriStr.startsWith(HTTP_PREFIX) || baseUriStr.startsWith(HTTPS_PREFIX)) { - tryConnection(client); - - } else { - client.setBaseUri(Uri.parse(HTTPS_PREFIX + baseUriStr)); - boolean httpsSuccess = tryConnection(client); - if (!httpsSuccess && !mLatestResult.isSslRecoverableException()) { - Log_OC.d(TAG, "establishing secure connection failed, trying non secure connection"); - client.setBaseUri(Uri.parse(HTTP_PREFIX + baseUriStr)); - tryConnection(client); - } - } - return mLatestResult; - } - - private boolean isSuccess(int status) { - return (status == HttpConstants.HTTP_OK); - } -} \ No newline at end of file diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.kt new file mode 100644 index 00000000..b6fd1b39 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.kt @@ -0,0 +1,160 @@ +/* ownCloud Android Library is available under MIT license +* Copyright (C) 2020 ownCloud GmbH. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +*/ +package com.owncloud.android.lib.resources.status + +import android.net.Uri +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.http.HttpConstants +import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod +import com.owncloud.android.lib.common.operations.RemoteOperation +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode +import org.json.JSONException +import org.json.JSONObject +import timber.log.Timber +import java.net.URL +import java.util.concurrent.TimeUnit +import javax.net.ssl.SSLException + +/** + * Checks if the server is valid + * + * @author David A. Velasco + * @author masensio + * @author David González Verdugo + * @author Abel García de Prada + */ +class GetRemoteStatusOperation : RemoteOperation() { + private lateinit var latestResult: RemoteOperationResult + + override fun run(client: OwnCloudClient): RemoteOperationResult { + + val baseUriStr = client.baseUri.toString() + if (baseUriStr.startsWith(HTTP_PREFIX) || baseUriStr.startsWith( + HTTPS_PREFIX + )) { + tryConnection(client) + } else { + client.baseUri = Uri.parse(HTTPS_PREFIX + baseUriStr) + val httpsSuccess = tryConnection(client) + if (!httpsSuccess && !latestResult.isSslRecoverableException) { + Timber.d("Establishing secure connection failed, trying non secure connection") + client.baseUri = Uri.parse(HTTP_PREFIX + baseUriStr) + tryConnection(client) + } + } + return latestResult + } + + private fun tryConnection(client: OwnCloudClient): Boolean { + var successfulConnection = false + val baseUrlSt = client.baseUri.toString() + try { + var getMethod = GetMethod(URL(baseUrlSt + OwnCloudClient.STATUS_PATH)).apply { + setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS) + setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS) + } + client.setFollowRedirects(false) + var isRedirectToNonSecureConnection = false + var status: Int + try { + status = client.executeHttpMethod(getMethod) + latestResult = + if (isSuccess(status)) RemoteOperationResult(ResultCode.OK) + else RemoteOperationResult(getMethod) + + } catch (sslE: SSLException) { + latestResult = RemoteOperationResult(sslE) + return successfulConnection + } + + var redirectedLocation = latestResult.redirectedLocation + while (!redirectedLocation.isNullOrEmpty() && !latestResult.isSuccess) { + isRedirectToNonSecureConnection = + isRedirectToNonSecureConnection || + (baseUrlSt.startsWith(HTTPS_PREFIX) && redirectedLocation.startsWith( + HTTP_PREFIX + )) + + getMethod = GetMethod(URL(redirectedLocation)).apply { + setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS) + setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS) + } + + status = client.executeHttpMethod(getMethod) + latestResult = RemoteOperationResult(getMethod) + redirectedLocation = latestResult.redirectedLocation + } + + if (isSuccess(status)) { + val respJSON = JSONObject(getMethod.responseBodyAsString) + if (!respJSON.getBoolean(NODE_INSTALLED)) { + latestResult = RemoteOperationResult(ResultCode.INSTANCE_NOT_CONFIGURED) + } else { + val version = respJSON.getString(NODE_VERSION) + val ocVersion = OwnCloudVersion(version) + // the version object will be returned even if the version is invalid, no error code; + // every app will decide how to act if (ocVersion.isVersionValid() == false) + latestResult = if (isRedirectToNonSecureConnection) { + RemoteOperationResult(ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION) + } else { + if (baseUrlSt.startsWith(HTTPS_PREFIX)) RemoteOperationResult(ResultCode.OK_SSL) + else RemoteOperationResult(ResultCode.OK_NO_SSL) + } + latestResult.data = ocVersion + successfulConnection = true + } + } else { + latestResult = RemoteOperationResult(getMethod) + } + } catch (e: JSONException) { + latestResult = RemoteOperationResult(ResultCode.INSTANCE_NOT_CONFIGURED) + } catch (e: Exception) { + latestResult = RemoteOperationResult(e) + } + when { + latestResult.isSuccess -> Timber.i("Connection check at $baseUrlSt successful: ${latestResult.logMessage}") + + latestResult.isException -> + Timber.e(latestResult.exception, "Connection check at $baseUrlSt: ${latestResult.logMessage}") + + else -> Timber.e("Connection check at $baseUrlSt failed: ${latestResult.logMessage}") + } + return successfulConnection + } + + private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK + + companion object { + /** + * Maximum time to wait for a response from the server when the connection is being tested, + * in MILLISECONDs. + */ + private const val TRY_CONNECTION_TIMEOUT: Long = 5000 + private const val NODE_INSTALLED = "installed" + private const val NODE_VERSION = "version" + private const val HTTPS_PREFIX = "https://" + private const val HTTP_PREFIX = "http://" + } +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/OwnCloudVersion.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/OwnCloudVersion.kt index dae5b91a..c8c75653 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/OwnCloudVersion.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/OwnCloudVersion.kt @@ -45,63 +45,24 @@ class OwnCloudVersion(version: String) : Comparable, Parcelable INVALID_ZERO_VERSION } - val isChunkedUploadSupported: Boolean - get() = mVersion >= MINIMUN_VERSION_FOR_CHUNKED_UPLOADS - - val isSharedSupported: Boolean - get() = mVersion >= MINIMUM_VERSION_FOR_SHARING_API - - val isVersionWithForbiddenCharacters: Boolean - get() = mVersion >= MINIMUM_VERSION_WITH_FORBIDDEN_CHARS - - val isAfter8Version: Boolean - get() = mVersion >= VERSION_8 - - val isSearchUsersSupported: Boolean - get() = mVersion >= MINIMUM_VERSION_FOR_SEARCHING_USERS - - val isVersionWithCapabilitiesAPI: Boolean - get() = mVersion >= MINIMUM_VERSION_CAPABILITIES_API - - val isNotReshareableFederatedSupported: Boolean - get() = mVersion >= MINIMUM_VERSION_WITH_NOT_RESHAREABLE_FEDERATED - - val isSessionMonitoringSupported: Boolean - get() = mVersion >= MINIMUM_VERSION_WITH_SESSION_MONITORING - - /** - * From OC 9.1 session tracking is a feature, but to get it working in the OC app we need the preemptive - * mode of basic authentication is disabled. This changes in OC 9.1.3, where preemptive mode is compatible - * with session tracking again. - * - * @return True for every version before 9.1 and from 9.1.3, false otherwise - */ - val isPreemptiveAuthenticationPreferred: Boolean - get() = mVersion < MINIMUM_VERSION_WITH_SESSION_MONITORING || mVersion >= MINIMUM_VERSION_WITH_SESSION_MONITORING_WORKING_IN_PREEMPTIVE_MODE - - val isMultiplePublicSharingSupported: Boolean - get() = mVersion >= MINIMUM_VERSION_WITH_MULTIPLE_PUBLIC_SHARING + val isServerVersionSupported: Boolean + get() = mVersion >= MINIMUN_VERSION_SUPPORTED val isPublicSharingWriteOnlySupported: Boolean get() = mVersion >= MINIMUM_VERSION_WITH_WRITE_ONLY_PUBLIC_SHARING - val isPublicUploadPermissionNeeded: Boolean - get() = mVersion >= MINIMUN_MAJOR_VERSION_WITHOUT_PUBLIC_UPLOAD_PERMISSION && - (mVersion > MINIMUN_MINOR_VERSION_WITHOUT_PUBLIC_UPLOAD_PERMISSION || - mVersion > MINIMUN_MICRO_VERSION_WITHOUT_PUBLIC_UPLOAD_PERMISSION) - init { - var version = version + var versionToParse = version mVersion = 0 isVersionValid = false - val countDots = version.length - version.replace(".", "").length + val countDots = versionToParse.length - versionToParse.replace(".", "").length // Complete the version. Version must have 3 dots for (i in countDots until MAX_DOTS) { - version = "$version.0" + versionToParse = "$versionToParse.0" } - parseVersion(version) + parseVersion(versionToParse) } @@ -119,10 +80,10 @@ class OwnCloudVersion(version: String) : Comparable, Parcelable return versionToString } - override fun compareTo(another: OwnCloudVersion): Int { - return if (another.mVersion == mVersion) + override fun compareTo(other: OwnCloudVersion): Int { + return if (other.mVersion == mVersion) 0 - else if (another.mVersion < mVersion) 1 else -1 + else if (other.mVersion < mVersion) 1 else -1 } private fun parseVersion(version: String) { @@ -134,20 +95,18 @@ class OwnCloudVersion(version: String) : Comparable, Parcelable isVersionValid = false // if invalid, the instance will respond as if server is 8.1, minimum with capabilities API, // and "dead" : https://github.com/owncloud/core/wiki/Maintenance-and-Release-Schedule - mVersion = MINIMUM_VERSION_CAPABILITIES_API } - } @Throws(NumberFormatException::class) private fun getParsedVersion(version: String): Int { - var version = version + var versionToParse = version var versionValue = 0 // get only numeric part - version = version.replace("[^\\d.]".toRegex(), "") + versionToParse = versionToParse.replace("[^\\d.]".toRegex(), "") - val nums = version.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + val nums = versionToParse.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() var i = 0 while (i < nums.size && i <= MAX_DOTS) { versionValue += Integer.parseInt(nums[i]) @@ -160,10 +119,6 @@ class OwnCloudVersion(version: String) : Comparable, Parcelable return versionValue } - fun supportsRemoteThumbnails(): Boolean { - return mVersion >= MINIMUM_SERVER_VERSION_FOR_REMOTE_THUMBNAILS - } - override fun describeContents(): Int { return super.hashCode() } @@ -174,34 +129,7 @@ class OwnCloudVersion(version: String) : Comparable, Parcelable } companion object { - private const val MINIMUN_MINOR_VERSION_WITHOUT_PUBLIC_UPLOAD_PERMISSION = 0x01000000 // 1.0.0 - - private const val MINIMUN_MICRO_VERSION_WITHOUT_PUBLIC_UPLOAD_PERMISSION = 0x03000000 // 3.0.0 - - const val MINIMUN_VERSION_FOR_CHUNKED_UPLOADS = 0x04050000 // 4.5 - - const val MINIMUM_VERSION_FOR_SHARING_API = 0x05001B00 // 5.0.27 - - const val MINIMUM_VERSION_WITH_FORBIDDEN_CHARS = 0x08010000 // 8.1 - - const val MINIMUM_SERVER_VERSION_FOR_REMOTE_THUMBNAILS = 0x07080000 // 7.8.0 - - const val MINIMUM_VERSION_FOR_SEARCHING_USERS = 0x08020000 //8.2 - - const val VERSION_8 = 0x08000000 // 8.0 - - const val MINIMUM_VERSION_CAPABILITIES_API = 0x08010000 // 8.1 - - private const val MINIMUM_VERSION_WITH_NOT_RESHAREABLE_FEDERATED = 0x09010000 // 9.1 - - private const val MINIMUM_VERSION_WITH_SESSION_MONITORING = 0x09010000 // 9.1 - - private const val MINIMUM_VERSION_WITH_SESSION_MONITORING_WORKING_IN_PREEMPTIVE_MODE = 0x09010301 - // 9.1.3.1, final 9.1.3: https://github.com/owncloud/core/commit/f9a867b70c217463289a741d4d26079eb2a80dfd - - private const val MINIMUM_VERSION_WITH_MULTIPLE_PUBLIC_SHARING = 0xA000000 // 10.0.0 - - private const val MINIMUN_MAJOR_VERSION_WITHOUT_PUBLIC_UPLOAD_PERMISSION = 0xA000000 // 10.0.0 + private const val MINIMUN_VERSION_SUPPORTED = 0xA000000 // 10.0.0 private const val MINIMUM_VERSION_WITH_WRITE_ONLY_PUBLIC_SHARING = 0xA000100 // 10.0.1 diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/RemoteCapability.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/RemoteCapability.kt index 6bd51efe..6e97ba0c 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/RemoteCapability.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/RemoteCapability.kt @@ -2,7 +2,7 @@ * @author masensio * @author David González Verdugo * @author Abel García de Prada - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -42,9 +42,11 @@ data class RemoteCapability( // Core PollInterval var corePollinterval: Int = 0, + // Dav Capabilities + val chunkingVersion: String = "", + // Files Sharing var filesSharingApiEnabled: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, - var filesSharingSearchMinLength: Int? = DEFAULT_MIN_CHARACTERS_TO_SEARCH, var filesSharingPublicEnabled: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, var filesSharingPublicPasswordEnforced: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, var filesSharingPublicPasswordEnforcedReadOnly: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, @@ -53,11 +55,9 @@ data class RemoteCapability( var filesSharingPublicExpireDateEnabled: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, var filesSharingPublicExpireDateDays: Int = 0, var filesSharingPublicExpireDateEnforced: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, - var filesSharingPublicSendMail: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, var filesSharingPublicUpload: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, var filesSharingPublicMultiple: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, var filesSharingPublicSupportsUploadOnly: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, - var filesSharingUserSendMail: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, var filesSharingResharing: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, var filesSharingFederationOutgoing: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, var filesSharingFederationIncoming: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, @@ -88,8 +88,8 @@ data class RemoteCapability( } } - fun fromBooleanValue(boolValue: Boolean): CapabilityBooleanType { - return if (boolValue) { + fun fromBooleanValue(boolValue: Boolean?): CapabilityBooleanType { + return if (boolValue != null && boolValue) { TRUE } else { FALSE @@ -97,8 +97,4 @@ data class RemoteCapability( } } } - - companion object { - private const val DEFAULT_MIN_CHARACTERS_TO_SEARCH = 2 - } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/CapabilityService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/CapabilityService.kt similarity index 84% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/CapabilityService.kt rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/CapabilityService.kt index 1253f9ca..0ad809c8 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/CapabilityService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/CapabilityService.kt @@ -3,7 +3,7 @@ * * @author David González Verdugo * - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -18,10 +18,11 @@ * along with this program. If not, see . */ -package com.owncloud.android.lib.resources.status +package com.owncloud.android.lib.resources.status.services import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.resources.Service +import com.owncloud.android.lib.resources.status.RemoteCapability interface CapabilityService: Service { fun getCapabilities() : RemoteOperationResult diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2RequestBuilder.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/ServerInfoService.kt similarity index 69% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2RequestBuilder.java rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/ServerInfoService.kt index edda5d6b..1efa7f1b 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/authentication/oauth/OAuth2RequestBuilder.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/ServerInfoService.kt @@ -1,7 +1,5 @@ /* ownCloud Android Library is available under MIT license - * - * @author David A. Velasco - * Copyright (C) 2017 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,26 +21,13 @@ * THE SOFTWARE. * */ +package com.owncloud.android.lib.resources.status.services -package com.owncloud.android.lib.common.authentication.oauth; +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.status.OwnCloudVersion -import com.owncloud.android.lib.common.operations.RemoteOperation; +interface ServerInfoService { + fun checkPathExistence(path: String, isUserLogged: Boolean): RemoteOperationResult -public interface OAuth2RequestBuilder { - - void setRequest(OAuthRequest operation); - - void setGrantType(OAuth2GrantType grantType); - - void setAuthorizationCode(String code); - - void setRefreshToken(String refreshToken); - - RemoteOperation buildOperation(); - - String buildUri(); - - enum OAuthRequest { - GET_AUTHORIZATION_CODE, CREATE_ACCESS_TOKEN, REFRESH_ACCESS_TOKEN - } -} \ No newline at end of file + fun getRemoteStatus(path: String): RemoteOperationResult +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/implementation/OCCapabilityService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/implementation/OCCapabilityService.kt new file mode 100644 index 00000000..d2161b05 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/implementation/OCCapabilityService.kt @@ -0,0 +1,33 @@ +/** + * ownCloud Android client application + * + * @author David González Verdugo + * + * Copyright (C) 2020 ownCloud GmbH. + * + * 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.lib.resources.status.services.implementation + +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.status.services.CapabilityService +import com.owncloud.android.lib.resources.status.GetRemoteCapabilitiesOperation +import com.owncloud.android.lib.resources.status.RemoteCapability + +class OCCapabilityService(override val client: OwnCloudClient) : + CapabilityService { + override fun getCapabilities(): RemoteOperationResult = + GetRemoteCapabilitiesOperation().execute(client) +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/implementation/OCServerInfoService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/implementation/OCServerInfoService.kt new file mode 100644 index 00000000..8efd9def --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/services/implementation/OCServerInfoService.kt @@ -0,0 +1,43 @@ +/** + * ownCloud Android client application + * + * @author Abel García de Prada + * Copyright (C) 2020 ownCloud GmbH. + * + * 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.lib.resources.status.services.implementation + +import android.net.Uri +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.status.services.ServerInfoService +import com.owncloud.android.lib.resources.files.CheckPathExistenceRemoteOperation +import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation +import com.owncloud.android.lib.resources.status.OwnCloudVersion + +class OCServerInfoService : ServerInfoService { + override fun checkPathExistence(path: String, isUserLogged: Boolean): RemoteOperationResult = + CheckPathExistenceRemoteOperation( + remotePath = path, + isUserLogged = true + ).execute(createClientFromPath(path)) + + override fun getRemoteStatus(path: String): RemoteOperationResult = + GetRemoteStatusOperation().execute(createClientFromPath(path)) + + private fun createClientFromPath(path: String): OwnCloudClient { + return OwnCloudClient(Uri.parse(path)) + } +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/GetRemoteUserAvatarOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/GetRemoteUserAvatarOperation.java index 06b0e120..e9e78df6 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/GetRemoteUserAvatarOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/GetRemoteUserAvatarOperation.java @@ -1,6 +1,6 @@ /* ownCloud Android Library is available under MIT license * - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,7 +31,7 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; +import timber.log.Timber; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; @@ -49,8 +49,6 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R */ public class GetRemoteUserAvatarOperation extends RemoteOperation { - private static final String TAG = GetRemoteUserAvatarOperation.class.getSimpleName(); - private static final String NON_OFFICIAL_AVATAR_PATH = "/index.php/avatar/"; /** @@ -58,11 +56,6 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation(RemoteOperationResult.ResultCode.FILE_NOT_FOUND); return result; } @@ -119,7 +112,7 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation(e); - Log_OC.e(TAG, "Exception while getting OC user avatar", e); + Timber.e(e, "Exception while getting OC user avatar"); } finally { if (getMethod != null) { @@ -147,14 +140,14 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation { - - private static final String TAG = GetRemoteUserInfoOperation.class.getSimpleName(); - - // OCS Route - private static final String OCS_ROUTE = "/ocs/v2.php/cloud/user?format=json"; - - // JSON Node names - private static final String NODE_OCS = "ocs"; - private static final String NODE_DATA = "data"; - private static final String NODE_ID = "id"; - private static final String NODE_DISPLAY_NAME = "display-name"; - private static final String NODE_EMAIL = "email"; - - public GetRemoteUserInfoOperation() { - } - - @Override - protected RemoteOperationResult run(OwnCloudClient client) { - RemoteOperationResult result; - - //Get the user - try { - GetMethod getMethod = new GetMethod(new URL(client.getBaseUri() + OCS_ROUTE)); - - int status = client.executeHttpMethod(getMethod); - - if (isSuccess(status)) { - Log_OC.d(TAG, "Successful response"); - - JSONObject respJSON = new JSONObject(getMethod.getResponseBodyAsString()); - JSONObject respOCS = respJSON.getJSONObject(NODE_OCS); - JSONObject respData = respOCS.getJSONObject(NODE_DATA); - - UserInfo userInfo = new UserInfo(); - userInfo.mId = respData.getString(NODE_ID); - userInfo.mDisplayName = respData.getString(NODE_DISPLAY_NAME); - userInfo.mEmail = respData.getString(NODE_EMAIL); - - result = new RemoteOperationResult<>(OK); - - result.setData(userInfo); - - } else { - result = new RemoteOperationResult<>(getMethod); - String response = getMethod.getResponseBodyAsString(); - Log_OC.e(TAG, "Failed response while getting user information "); - if (getMethod != null) { - Log_OC.e(TAG, "*** status code: " + status + " ; response message: " + response); - } else { - Log_OC.e(TAG, "*** status code: " + status); - } - } - } catch (Exception e) { - result = new RemoteOperationResult<>(e); - Log_OC.e(TAG, "Exception while getting OC user information", e); - } - - return result; - } - - private boolean isSuccess(int status) { - return (status == HttpConstants.HTTP_OK); - } - - public static class UserInfo { - public String mId = ""; - public String mDisplayName = ""; - public String mEmail = ""; - } -} \ No newline at end of file diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/GetRemoteUserInfoOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/GetRemoteUserInfoOperation.kt new file mode 100644 index 00000000..7ea63c69 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/GetRemoteUserInfoOperation.kt @@ -0,0 +1,85 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2020 ownCloud GmbH. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package com.owncloud.android.lib.resources.users + +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.http.HttpConstants +import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod +import com.owncloud.android.lib.common.operations.RemoteOperation +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode +import com.owncloud.android.lib.resources.response.CommonOcsResponse +import com.owncloud.android.lib.resources.response.UserInfoResponse +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import timber.log.Timber +import java.lang.reflect.Type +import java.net.URL + +/** + * Gets information (id, display name, and e-mail address) about the user logged in. + * + * @author masensio + * @author David A. Velasco + * @author David González Verdugo + * @author Abel García de Prada + */ +class GetRemoteUserInfoOperation : RemoteOperation() { + override fun run(client: OwnCloudClient): RemoteOperationResult { + var result: RemoteOperationResult + //Get the user + try { + val getMethod = GetMethod(URL(client.baseUri.toString() + OCS_ROUTE)) + val status = client.executeHttpMethod(getMethod) + val response = getMethod.responseBodyAsString + if (status == HttpConstants.HTTP_OK) { + Timber.d("Successful response $response") + + val moshi: Moshi = Moshi.Builder().build() + val type: Type = Types.newParameterizedType(CommonOcsResponse::class.java, UserInfoResponse::class.java) + val adapter: JsonAdapter> = moshi.adapter(type) + val commonResponse: CommonOcsResponse? = adapter.fromJson(response) + + result = RemoteOperationResult(ResultCode.OK) + result.data = commonResponse?.ocs?.data?.toRemoteUserInfo() + + Timber.d("Get User Info completed and parsed to ${result.data}") + + } else { + result = RemoteOperationResult(getMethod) + Timber.e("Failed response while getting user information status code: $status, response: $response") + } + } catch (e: Exception) { + result = RemoteOperationResult(e) + Timber.e(e, "Exception while getting OC user information") + } + return result + } + + companion object { + // OCS Route + private const val OCS_ROUTE = "/ocs/v2.php/cloud/user?format=json" + } +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/GetRemoteUserQuotaOperation.java b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/GetRemoteUserQuotaOperation.java index 49c313be..e4d834d8 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/GetRemoteUserQuotaOperation.java +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/GetRemoteUserQuotaOperation.java @@ -1,6 +1,6 @@ /* ownCloud Android Library is available under MIT license * - * Copyright (C) 2019 ownCloud Inc. + * Copyright (C) 2020 ownCloud Inc. * Copyright (C) 2015 Bartosz Przybylski * Copyright (C) 2014 Marcello Steiner * @@ -37,7 +37,7 @@ import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; +import timber.log.Timber; import java.net.URL; import java.util.List; @@ -51,7 +51,6 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R */ public class GetRemoteUserQuotaOperation extends RemoteOperation { - private static final String TAG = GetRemoteUserQuotaOperation.class.getSimpleName(); private String mRemotePath; /** @@ -94,13 +93,12 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/services/implementation/OCUserService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/services/implementation/OCUserService.kt new file mode 100644 index 00000000..6b07b25e --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/users/services/implementation/OCUserService.kt @@ -0,0 +1,32 @@ +/** + * ownCloud Android client application + * + * @author Abel García de Prada + * Copyright (C) 2020 ownCloud GmbH. + * + * 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.lib.resources.users.services.implementation + +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation +import com.owncloud.android.lib.resources.users.RemoteUserInfo +import com.owncloud.android.lib.resources.users.services.UserService + +class OCUserService(override val client: OwnCloudClient) : + UserService { + override fun getUserInfo(): RemoteOperationResult = + GetRemoteUserInfoOperation().execute(client) +} diff --git a/pom.xml b/pom.xml deleted file mode 100644 index a72688d2..00000000 --- a/pom.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - 4.0.0 - com.owncloud.android - owncloud-android-library - ${owncloud.version} - jar - owncloud-android-library for Owncloud Android - - - 1.5.1-SNAPSHOT - 1.6 - - 4.4.2_r4 - - 19 - - - owncloud-android-library for Owncloud for Android - - - - - android - android - ${google.android-version} - provided - - - - - - ${project.artifactId} - - src - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.0 - - ${java-version} - ${java-version} - - - - - com.jayway.maven.plugins.android.generation2 - android-maven-plugin - 3.8.0 - - - ${env.ANDROID_HOME} - ${google.android-api} - - - true - - - - - - - - diff --git a/sample_client/build.gradle b/sample_client/build.gradle index 7f865ceb..4d0c1d4b 100644 --- a/sample_client/build.gradle +++ b/sample_client/build.gradle @@ -8,8 +8,12 @@ android { compileSdkVersion 28 defaultConfig { - minSdkVersion 19 + minSdkVersion 21 targetSdkVersion 28 + + // This is pretty ugly but manifest placeholders don't seem to work very well when using different modules + // See https://github.com/openid/AppAuth-Android/issues/325 + manifestPlaceholders = [appAuthRedirectScheme: ''] } lintOptions { diff --git a/sample_client/src/main/java/com/owncloud/android/lib/sampleclient/FilesArrayAdapter.java b/sample_client/src/main/java/com/owncloud/android/lib/sampleclient/FilesArrayAdapter.java index 4e942719..29219f21 100644 --- a/sample_client/src/main/java/com/owncloud/android/lib/sampleclient/FilesArrayAdapter.java +++ b/sample_client/src/main/java/com/owncloud/android/lib/sampleclient/FilesArrayAdapter.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2016 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/sample_client/src/main/java/com/owncloud/android/lib/sampleclient/MainActivity.java b/sample_client/src/main/java/com/owncloud/android/lib/sampleclient/MainActivity.java index 953699ab..bff10fed 100644 --- a/sample_client/src/main/java/com/owncloud/android/lib/sampleclient/MainActivity.java +++ b/sample_client/src/main/java/com/owncloud/android/lib/sampleclient/MainActivity.java @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2019 ownCloud GmbH. + * Copyright (C) 2020 ownCloud GmbH. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,7 +33,6 @@ import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Bundle; import android.os.Handler; -import android.util.Log; import android.view.View; import android.widget.ListView; import android.widget.TextView; @@ -41,34 +40,30 @@ import android.widget.Toast; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.OwnCloudClientFactory; -import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; +import com.owncloud.android.lib.common.SingleSessionManager; import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; import com.owncloud.android.lib.common.operations.OnRemoteOperationListener; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.files.DownloadRemoteFileOperation; import com.owncloud.android.lib.resources.files.FileUtils; import com.owncloud.android.lib.resources.files.ReadRemoteFolderOperation; import com.owncloud.android.lib.resources.files.RemoteFile; import com.owncloud.android.lib.resources.files.RemoveRemoteFileOperation; import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation; +import info.hannes.timber.DebugTree; +import timber.log.Timber; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; -import static android.content.ContentValues.TAG; - public class MainActivity extends Activity implements OnRemoteOperationListener, OnDatatransferProgressListener { - private static String LOG_TAG = MainActivity.class.getCanonicalName(); - private Handler mHandler; private OwnCloudClient mClient; private FilesArrayAdapter mFilesAdapter; @@ -82,11 +77,12 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, super.onCreate(savedInstanceState); setContentView(R.layout.main); + Timber.plant(new DebugTree()); mHandler = new Handler(); final Uri serverUri = Uri.parse(getString(R.string.server_base_url)); - OwnCloudClientManagerFactory.setUserAgent(getUserAgent()); + SingleSessionManager.setUserAgent(getUserAgent()); mClient = OwnCloudClientFactory.createOwnCloudClient(serverUri, this, true); mClient.setCredentials( @@ -108,7 +104,7 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, File upFile = new File(upFolder, sampleFileName); FileOutputStream fos = new FileOutputStream(upFile); InputStream is = assets.open(sampleFileName); - int count = 0; + int count; byte[] buffer = new byte[1024]; while ((count = is.read(buffer, 0, buffer.length)) >= 0) { fos.write(buffer, 0, count); @@ -117,7 +113,7 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, fos.close(); } catch (IOException e) { Toast.makeText(this, R.string.error_copying_sample_file, Toast.LENGTH_SHORT).show(); - Log.e(LOG_TAG, getString(R.string.error_copying_sample_file), e); + Timber.e(e, getString(R.string.error_copying_sample_file)); } mFrame = findViewById(R.id.frame); @@ -166,8 +162,8 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, String mimeType = getString(R.string.sample_file_mimetype); // Get the last modification date of the file from the file system - Long timeStampLong = fileToUpload.lastModified() / 1000; - String timeStamp = timeStampLong.toString(); + long timeStampLong = fileToUpload.lastModified() / 1000; + String timeStamp = Long.toString(timeStampLong); UploadRemoteFileOperation uploadOperation = new UploadRemoteFileOperation(fileToUpload.getAbsolutePath(), remotePath, mimeType, timeStamp); @@ -212,16 +208,16 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { if (!result.isSuccess()) { Toast.makeText(this, R.string.todo_operation_finished_in_fail, Toast.LENGTH_SHORT).show(); - Log.e(LOG_TAG, result.getLogMessage(), result.getException()); + Timber.e(result.getException(), result.getLogMessage()); } else if (operation instanceof ReadRemoteFolderOperation) { - onSuccessfulRefresh((ReadRemoteFolderOperation) operation, result); + onSuccessfulRefresh(result); } else if (operation instanceof com.owncloud.android.lib.resources.files.UploadRemoteFileOperation) { - onSuccessfulUpload((com.owncloud.android.lib.resources.files.UploadRemoteFileOperation) operation, result); + onSuccessfulUpload(); } else if (operation instanceof RemoveRemoteFileOperation) { - onSuccessfulRemoteDeletion((RemoveRemoteFileOperation) operation, result); + onSuccessfulRemoteDeletion(); } else if (operation instanceof DownloadRemoteFileOperation) { onSuccessfulDownload(); @@ -231,29 +227,26 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, } } - private void onSuccessfulRefresh(ReadRemoteFolderOperation operation, RemoteOperationResult result) { + private void onSuccessfulRefresh(RemoteOperationResult result) { mFilesAdapter.clear(); List files = new ArrayList<>(); for (RemoteFile remoteFile : (List) result.getData()) { files.add(remoteFile); } - if (files != null) { - Iterator it = files.iterator(); - while (it.hasNext()) { - mFilesAdapter.add(it.next()); - } - mFilesAdapter.remove(mFilesAdapter.getItem(0)); + for (RemoteFile file : files) { + mFilesAdapter.add(file); } + mFilesAdapter.remove(mFilesAdapter.getItem(0)); mFilesAdapter.notifyDataSetChanged(); } - private void onSuccessfulUpload(com.owncloud.android.lib.resources.files.UploadRemoteFileOperation operation, RemoteOperationResult result) { + private void onSuccessfulUpload() { startRefresh(); } - private void onSuccessfulRemoteDeletion(RemoveRemoteFileOperation operation, RemoteOperationResult result) { + private void onSuccessfulRemoteDeletion() { startRefresh(); - TextView progressView = (TextView) findViewById(R.id.upload_progress); + TextView progressView = findViewById(R.id.upload_progress); if (progressView != null) { progressView.setText("0%"); } @@ -266,23 +259,21 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, mFrame.setBackgroundDrawable(bDraw); } + @SuppressLint("SetTextI18n") @Override public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String fileName) { final long percentage = (totalToTransfer > 0 ? totalTransferredSoFar * 100 / totalToTransfer : 0); final boolean upload = fileName.contains(getString(R.string.upload_folder_path)); - Log.d(LOG_TAG, "progressRate " + percentage); - mHandler.post(new Runnable() { - @Override - public void run() { - TextView progressView = null; - if (upload) { - progressView = findViewById(R.id.upload_progress); - } else { - progressView = findViewById(R.id.download_progress); - } - if (progressView != null) { - progressView.setText(Long.toString(percentage) + "%"); - } + Timber.d("progressRate %s", percentage); + mHandler.post(() -> { + TextView progressView; + if (upload) { + progressView = findViewById(R.id.upload_progress); + } else { + progressView = findViewById(R.id.download_progress); + } + if (progressView != null) { + progressView.setText(percentage + "%"); } }); } @@ -301,7 +292,7 @@ public class MainActivity extends Activity implements OnRemoteOperationListener, version = pInfo.versionName; } } catch (PackageManager.NameNotFoundException e) { - Log_OC.e(TAG, "Trying to get packageName", e.getCause()); + Timber.e(e); } // Mozilla/5.0 (Android) ownCloud-android/1.7.0 diff --git a/sample_client/src/main/res/values/setup.xml b/sample_client/src/main/res/values/setup.xml index 1acc5d6e..44734305 100644 --- a/sample_client/src/main/res/values/setup.xml +++ b/sample_client/src/main/res/values/setup.xml @@ -1,6 +1,6 @@