From a877612fca2a5034b77c33600b1c247fff2d0757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Tue, 13 Dec 2022 14:51:57 +0100 Subject: [PATCH 01/49] Bump several dependencies at the same time --- build.gradle | 10 +++++----- owncloudComLibrary/build.gradle | 8 ++++---- .../services/implementation/OCCapabilityService.kt | 5 +---- .../services/implementation/OCServerInfoService.kt | 9 +++------ 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/build.gradle b/build.gradle index aa8824db..8e1455fa 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ buildscript { ext { - kotlinVersion = '1.6.21' - moshiVersion = "1.13.0" + orgJetbrainsKotlin = '1.7.20' + comSquareupMoshi = '1.14.0' } repositories { @@ -10,9 +10,9 @@ buildscript { maven { url "https://plugins.gradle.org/m2/" } } dependencies { - classpath "org.jlleitschuh.gradle:ktlint-gradle:10.3.0" + classpath "org.jlleitschuh.gradle:ktlint-gradle:11.0.0" classpath 'com.android.tools.build:gradle:7.1.3' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$orgJetbrainsKotlin" } } @@ -26,4 +26,4 @@ allprojects { subprojects { apply plugin: "org.jlleitschuh.gradle.ktlint" -} \ No newline at end of file +} diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index 34391930..bcba8217 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -5,16 +5,16 @@ apply plugin: 'kotlin-parcelize' dependencies { api 'com.squareup.okhttp3:okhttp:4.6.0' - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$orgJetbrainsKotlin" api 'com.gitlab.ownclouders:dav4android:oc_support_2.1.5' api 'com.github.AppDevNext.Logcat:LogcatCore:2.2.2' // Moshi - implementation("com.squareup.moshi:moshi-kotlin:$moshiVersion") { + implementation("com.squareup.moshi:moshi-kotlin:$comSquareupMoshi") { exclude module: "kotlin-reflect" } implementation 'org.apache.commons:commons-lang3:3.12.0' - kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshiVersion" + kapt "com.squareup.moshi:moshi-kotlin-codegen:$comSquareupMoshi" testImplementation 'junit:junit:4.13.2' testImplementation 'org.robolectric:robolectric:4.9' @@ -22,7 +22,7 @@ dependencies { } android { - compileSdkVersion 31 + compileSdkVersion 33 defaultConfig { minSdkVersion 21 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 index e211475f..01c9c628 100644 --- 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 @@ -1,8 +1,6 @@ /* ownCloud Android Library is available under MIT license * Copyright (C) 2022 ownCloud GmbH. * - * @author David González Verdugo - * * 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 @@ -32,8 +30,7 @@ import com.owncloud.android.lib.resources.status.GetRemoteCapabilitiesOperation import com.owncloud.android.lib.resources.status.RemoteCapability import com.owncloud.android.lib.resources.status.services.CapabilityService -class OCCapabilityService(override val client: OwnCloudClient) : - CapabilityService { +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 index d2c891f0..0997f712 100644 --- 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 @@ -1,8 +1,6 @@ /* ownCloud Android Library is available under MIT license * Copyright (C) 2022 ownCloud GmbH. * - * @author Abel García de Prada - * * 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 @@ -26,7 +24,6 @@ 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.files.CheckPathExistenceRemoteOperation @@ -39,16 +36,16 @@ class OCServerInfoService : ServerInfoService { override fun checkPathExistence( path: String, isUserLoggedIn: Boolean, - client: OwnCloudClient + client: OwnCloudClient, ): RemoteOperationResult = CheckPathExistenceRemoteOperation( remotePath = path, - isUserLoggedIn = true + isUserLoggedIn = true, ).execute(client) override fun getRemoteStatus( path: String, - client: OwnCloudClient + client: OwnCloudClient, ): RemoteOperationResult = GetRemoteStatusOperation().execute(client) } From 7ceef58382e77d72a49dd18118fbc0561414a3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Tue, 13 Dec 2022 19:00:10 +0100 Subject: [PATCH 02/49] Bump gradle plugin to 7.3.1 and move package name fro manifest to gradle namespace --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- owncloudComLibrary/build.gradle | 1 + owncloudComLibrary/src/main/AndroidManifest.xml | 3 +-- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 8e1455fa..2baca957 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { } dependencies { classpath "org.jlleitschuh.gradle:ktlint-gradle:11.0.0" - classpath 'com.android.tools.build:gradle:7.1.3' + classpath 'com.android.tools.build:gradle:7.3.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$orgJetbrainsKotlin" } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2e6e5897..41dfb879 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index bcba8217..6b71177d 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -39,4 +39,5 @@ android { includeAndroidResources = true } } + namespace 'com.owncloud.android.lib' } diff --git a/owncloudComLibrary/src/main/AndroidManifest.xml b/owncloudComLibrary/src/main/AndroidManifest.xml index 4561b3f5..baef71f2 100644 --- a/owncloudComLibrary/src/main/AndroidManifest.xml +++ b/owncloudComLibrary/src/main/AndroidManifest.xml @@ -23,8 +23,7 @@ --> - + From fa7bfdd597063e5415768f32cd904f0983d87a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Thu, 15 Dec 2022 15:26:37 +0100 Subject: [PATCH 03/49] Unsharing wont return anything anymore since result object was not used --- .../shares/RemoveRemoteShareOperation.kt | 39 ++++--------------- .../resources/shares/services/ShareService.kt | 2 +- .../services/implementation/OCShareService.kt | 5 +-- 3 files changed, 10 insertions(+), 36 deletions(-) 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 304ead67..54280604 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 @@ -36,13 +36,7 @@ import com.owncloud.android.lib.common.http.HttpConstants.VALUE_FORMAT 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.resources.CommonOcsResponse -import com.owncloud.android.lib.resources.shares.responses.ShareItem -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 /** @@ -52,14 +46,10 @@ import java.net.URL * @author David A. Velasco * @author David González Verdugo * @author Fernando Sanz Velasco - */ - -/** - * Constructor * * @param remoteShareId Share ID */ -class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOperation() { +class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOperation() { private fun buildRequestUri(baseUri: Uri) = baseUri.buildUpon() @@ -68,24 +58,12 @@ class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOper .appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT) .build() - private fun parseResponse(response: String): ShareResponse? { - val moshi = Moshi.Builder().build() - val listOfShareItemType: Type = Types.newParameterizedType(List::class.java, ShareItem::class.java) - val commonOcsType: Type = Types.newParameterizedType(CommonOcsResponse::class.java, listOfShareItemType) - val adapter: JsonAdapter>> = moshi.adapter(commonOcsType) - return adapter.fromJson(response)?.ocs?.data?.let { listOfShareItems -> - ShareResponse(listOfShareItems.map { shareItem -> - shareItem.toRemoteShare() - }) - } - } - private fun onResultUnsuccessful( method: DeleteMethod, response: String?, status: Int - ): RemoteOperationResult { - Timber.e("Failed response while unshare link ") + ): RemoteOperationResult { + Timber.e("Failed response while removing share ") if (response != null) { Timber.e("*** status code: $status; response message: $response") } else { @@ -94,17 +72,14 @@ class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOper return RemoteOperationResult(method) } - private fun onRequestSuccessful(response: String?): RemoteOperationResult { - val result = RemoteOperationResult(RemoteOperationResult.ResultCode.OK) + private fun onRequestSuccessful(response: String?): RemoteOperationResult { + val result = RemoteOperationResult(RemoteOperationResult.ResultCode.OK) Timber.d("Successful response: $response") - result.data = parseResponse(response!!) Timber.d("*** Unshare link completed ") return result } - override fun run(client: OwnCloudClient): RemoteOperationResult { - - + override fun run(client: OwnCloudClient): RemoteOperationResult { val requestUri = buildRequestUri(client.baseUri) val deleteMethod = DeleteMethod(URL(requestUri.toString())).apply { @@ -129,7 +104,7 @@ class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOper private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK companion object { - //OCS Route + // OCS Route private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/shares" } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareService.kt index 9774ca38..7e77c62b 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareService.kt @@ -58,5 +58,5 @@ interface ShareService : Service { publicUpload: Boolean ): RemoteOperationResult - fun deleteShare(remoteId: String): RemoteOperationResult + fun deleteShare(remoteId: String): RemoteOperationResult } 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 index f8bcd1ea..68a22654 100644 --- 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 @@ -36,8 +36,7 @@ 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 { +class OCShareService(override val client: OwnCloudClient) : ShareService { override fun getShares( remoteFilePath: String, reshares: Boolean, @@ -90,7 +89,7 @@ class OCShareService(override val client: OwnCloudClient) : this.retrieveShareDetails = true }.execute(client) - override fun deleteShare(remoteId: String): RemoteOperationResult = + override fun deleteShare(remoteId: String): RemoteOperationResult = RemoveRemoteShareOperation( remoteId ).execute(client) From a0750c613a69f5fb60a06edd2a3335fc1797d68a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Dec 2022 02:01:28 +0000 Subject: [PATCH 04/49] Bump robolectric from 4.9 to 4.9.1 Bumps [robolectric](https://github.com/robolectric/robolectric) from 4.9 to 4.9.1. - [Release notes](https://github.com/robolectric/robolectric/releases) - [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.9...robolectric-4.9.1) --- updated-dependencies: - dependency-name: org.robolectric:robolectric dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- owncloudComLibrary/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index 6b71177d..b4c626b1 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -17,7 +17,7 @@ dependencies { kapt "com.squareup.moshi:moshi-kotlin-codegen:$comSquareupMoshi" testImplementation 'junit:junit:4.13.2' - testImplementation 'org.robolectric:robolectric:4.9' + testImplementation 'org.robolectric:robolectric:4.9.1' debugImplementation 'com.facebook.stetho:stetho-okhttp3:1.6.0' } From 3545686a31eabc72c4a7800111977d5f1b21fde2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Tue, 20 Dec 2022 13:53:46 +0100 Subject: [PATCH 05/49] Add several logs to try to debug potential errors related to oAuth --- .../android/lib/common/ConnectionValidator.kt | 22 ++++++++++++------- .../lib/common/accounts/AccountUtils.java | 1 + 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/ConnectionValidator.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/ConnectionValidator.kt index 23a5a92f..258c514c 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/ConnectionValidator.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/ConnectionValidator.kt @@ -37,7 +37,6 @@ import com.owncloud.android.lib.resources.status.RemoteServerInfo import org.apache.commons.lang3.exception.ExceptionUtils import timber.log.Timber import java.io.IOException -import java.lang.Exception /** * ConnectionValidator @@ -46,7 +45,7 @@ import java.lang.Exception */ class ConnectionValidator( val context: Context, - val clearCookiesOnValidation: Boolean + private val clearCookiesOnValidation: Boolean ) { fun validate(baseClient: OwnCloudClient, singleSessionManager: SingleSessionManager, context: Context): Boolean { try { @@ -61,12 +60,12 @@ class ConnectionValidator( client.account = baseClient.account client.credentials = baseClient.credentials while (validationRetryCount < VALIDATION_RETRY_COUNT) { - Timber.d("validationRetryCout %d", validationRetryCount) + Timber.d("validationRetryCount %d", validationRetryCount) var successCounter = 0 var failCounter = 0 client.setFollowRedirects(true) - if (isOnwCloudStatusOk(client)) { + if (isOwnCloudStatusOk(client)) { successCounter++ } else { failCounter++ @@ -103,7 +102,7 @@ class ConnectionValidator( return false } - private fun isOnwCloudStatusOk(client: OwnCloudClient): Boolean { + private fun isOwnCloudStatusOk(client: OwnCloudClient): Boolean { val reply = getOwnCloudStatus(client) // dont check status code. It currently relais on the broken redirect code of the owncloud client // TODO: Use okhttp redirect and add this check again @@ -138,6 +137,12 @@ class ConnectionValidator( // test if have all the needed to effectively invalidate ... shouldInvalidateAccountCredentials = shouldInvalidateAccountCredentials and (account.savedAccount != null) + Timber.d( + """Received error: $httpStatusCode, + account: ${account.name} + credentials are real: ${credentials !is OwnCloudAnonymousCredentials}, + so we need to invalidate credentials for account ${account.name} : $shouldInvalidateAccountCredentials""" + ) return shouldInvalidateAccountCredentials } @@ -150,6 +155,7 @@ class ConnectionValidator( * */ private fun invalidateAccountCredentials(account: OwnCloudAccount, credentials: OwnCloudCredentials) { + Timber.i("Invalidating account credentials for account $account") val am = AccountManager.get(context) am.invalidateAuthToken( account.savedAccount.type, @@ -167,8 +173,6 @@ class ConnectionValidator( * * Refresh current credentials if possible, and marks a retry. * - * @param status - * @param repeatCounter * @return */ private fun checkUnauthorizedAccess(client: OwnCloudClient, singleSessionManager: SingleSessionManager, status: Int): Boolean { @@ -181,6 +185,7 @@ class ConnectionValidator( if (credentials.authTokenCanBeRefreshed()) { try { // This command does the actual refresh + Timber.i("Trying to refresh auth token for account $account") account.loadCredentials(context) // if mAccount.getCredentials().length() == 0 --> refresh failed client.credentials = account.credentials @@ -201,6 +206,7 @@ class ConnectionValidator( if (!credentialsWereRefreshed) { // if credentials are not refreshed, client must be removed // from the OwnCloudClientManager to prevent it is reused once and again + Timber.w("Credentials were not refreshed, client will be removed from the Session Manager to prevent using it over and over") singleSessionManager.removeClientFor(account) } } @@ -210,6 +216,6 @@ class ConnectionValidator( } companion object { - private val VALIDATION_RETRY_COUNT = 3 + private const val VALIDATION_RETRY_COUNT = 3 } } 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 535104df..224d647b 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 @@ -112,6 +112,7 @@ public class AccountUtils { String username = AccountUtils.getUsernameForAccount(account); if (isOauth2) { + Timber.i("Trying to retrieve credentials for oAuth account" + account.name); String accessToken = am.blockingGetAuthToken( account, AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), From 118646290d5ba34b28921a3fa60a644e06529f51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Dec 2022 02:01:23 +0000 Subject: [PATCH 06/49] Bump robolectric from 4.9.1 to 4.9.2 Bumps [robolectric](https://github.com/robolectric/robolectric) from 4.9.1 to 4.9.2. - [Release notes](https://github.com/robolectric/robolectric/releases) - [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.9.1...robolectric-4.9.2) --- updated-dependencies: - dependency-name: org.robolectric:robolectric dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- owncloudComLibrary/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index b4c626b1..897474da 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -17,7 +17,7 @@ dependencies { kapt "com.squareup.moshi:moshi-kotlin-codegen:$comSquareupMoshi" testImplementation 'junit:junit:4.13.2' - testImplementation 'org.robolectric:robolectric:4.9.1' + testImplementation 'org.robolectric:robolectric:4.9.2' debugImplementation 'com.facebook.stetho:stetho-okhttp3:1.6.0' } From 148a97cd32619c8868923f8473c11e5ff7b73b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Mon, 23 Jan 2023 13:58:02 +0100 Subject: [PATCH 07/49] Potential fix to oauth error after logging in for first time that makes user to reauthenticate --- .../lib/common/SingleSessionManager.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) 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 7e40c16f..9a7925ed 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 @@ -31,7 +31,6 @@ import android.net.Uri; import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; -import com.owncloud.android.lib.common.http.HttpClient; import timber.log.Timber; import java.io.IOException; @@ -124,6 +123,24 @@ public class SingleSessionManager { } } else { Timber.v("reusing client for account %s", accountName); + if (client.getAccount() != null && + client.getAccount().getCredentials() != null && + (client.getAccount().getCredentials().getAuthToken() == null || client.getAccount().getCredentials().getAuthToken().isEmpty()) + ) { + Timber.i("Client " + client.getAccount().getName() + " needs to refresh credentials"); + + //the next two lines are a hack because okHttpclient is used as a singleton instead of being an + //injected instance that can be deleted when required + client.clearCookies(); + client.clearCredentials(); + + client.setAccount(account); + + account.loadCredentials(context); + client.setCredentials(account.getCredentials()); + + Timber.i("Client " + account.getName() + " with credentials size" + client.getAccount().getCredentials().getAuthToken().length()); + } reusingKnown = true; } From b5cd4a1df2aee52382a73b3a6247581e8a9cf5f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 02:11:34 +0000 Subject: [PATCH 08/49] Bump ktlint-gradle from 11.0.0 to 11.1.0 Bumps ktlint-gradle from 11.0.0 to 11.1.0. --- updated-dependencies: - dependency-name: org.jlleitschuh.gradle:ktlint-gradle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2baca957..67eb420a 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { maven { url "https://plugins.gradle.org/m2/" } } dependencies { - classpath "org.jlleitschuh.gradle:ktlint-gradle:11.0.0" + classpath "org.jlleitschuh.gradle:ktlint-gradle:11.1.0" classpath 'com.android.tools.build:gradle:7.3.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$orgJetbrainsKotlin" } From 4200ed324c5b0ac5c73a2541110d9311cb2c34ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Tue, 14 Feb 2023 09:45:29 +0100 Subject: [PATCH 09/49] Bump kotlin version to 1.8.10 --- build.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- owncloudComLibrary/build.gradle | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 67eb420a..0825f3eb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ buildscript { ext { - orgJetbrainsKotlin = '1.7.20' + orgJetbrainsKotlin = '1.8.10' comSquareupMoshi = '1.14.0' } @@ -11,7 +11,7 @@ buildscript { } dependencies { classpath "org.jlleitschuh.gradle:ktlint-gradle:11.1.0" - classpath 'com.android.tools.build:gradle:7.3.1' + classpath 'com.android.tools.build:gradle:7.4.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$orgJetbrainsKotlin" } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 41dfb879..8049c684 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index 897474da..1df5440b 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -5,7 +5,7 @@ apply plugin: 'kotlin-parcelize' dependencies { api 'com.squareup.okhttp3:okhttp:4.6.0' - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$orgJetbrainsKotlin" + implementation "org.jetbrains.kotlin:kotlin-stdlib:$orgJetbrainsKotlin" api 'com.gitlab.ownclouders:dav4android:oc_support_2.1.5' api 'com.github.AppDevNext.Logcat:LogcatCore:2.2.2' From 763005b05167eefd66a7c490bf3899531cc58372 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 02:57:18 +0000 Subject: [PATCH 10/49] Bump com.android.tools.build:gradle from 7.4.1 to 7.4.2 Bumps com.android.tools.build:gradle from 7.4.1 to 7.4.2. --- updated-dependencies: - dependency-name: com.android.tools.build:gradle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0825f3eb..28bdd05b 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { } dependencies { classpath "org.jlleitschuh.gradle:ktlint-gradle:11.1.0" - classpath 'com.android.tools.build:gradle:7.4.1' + classpath 'com.android.tools.build:gradle:7.4.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$orgJetbrainsKotlin" } } From 602b7e75480e8db7996e4316e77805911c8d48da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Mon, 6 Mar 2023 14:53:33 +0100 Subject: [PATCH 11/49] Show the url in the response http log too --- .../com/owncloud/android/lib/common/http/LogInterceptor.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/LogInterceptor.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/LogInterceptor.kt index 0ca90a47..eea604d9 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/LogInterceptor.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/LogInterceptor.kt @@ -51,7 +51,7 @@ class LogInterceptor : Interceptor { val request = chain.request().also { val requestId = it.headers[OC_X_REQUEST_ID] - logHttp(REQUEST, INFO, requestId, "Type: ${it.method} URL: ${it.url}") + logHttp(REQUEST, INFO, requestId, "Method: ${it.method} URL: ${it.url}") logHeaders(requestId, it.headers, REQUEST) logRequestBody(requestId, it.body) } @@ -64,7 +64,7 @@ class LogInterceptor : Interceptor { RESPONSE, INFO, requestId, - "Code: ${it.code} Message: ${it.message} IsSuccessful: ${it.isSuccessful}" + "Method: ${request.method} URL: ${request.url} Code: ${it.code} Message: ${it.message}" ) logHeaders(requestId, it.headers, RESPONSE) logResponseBody(requestId, it.body) From 4f001550f9cd8194d7662bbc18c76c53a85e6cdf Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 21 Dec 2022 17:34:23 +0100 Subject: [PATCH 12/49] Save spaces-related capabilities in database --- .../status/GetRemoteCapabilitiesOperation.kt | 2 +- .../lib/resources/status/RemoteCapability.kt | 61 ++++++++++------- .../status/responses/CapabilityResponse.kt | 66 ++++++++++++------- 3 files changed, 79 insertions(+), 50 deletions(-) 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 8591a68a..dd48376e 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 @@ -45,7 +45,7 @@ import java.net.URL /** * Get the Capabilities from the server - * Save in Result.getData in a RemoteCapability object + * Save Result.getData in a RemoteCapability object * * @author masensio * @author David González Verdugo 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 ff7f5b4f..fe4c26f0 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 @@ -1,29 +1,33 @@ -/* ownCloud Android Library is available under MIT license - * @author masensio - * @author David González Verdugo - * @author Abel García de Prada - * Copyright (C) 2020 ownCloud GmbH. +/** + * ownCloud Android Library is available under MIT license * - * 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: + * @author masensio + * @author David González Verdugo + * @author Abel García de Prada + * @author Juan Carlos Garrote Gascón * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * Copyright (C) 2022 ownCloud GmbH. * - * 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. + * 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 /** @@ -33,7 +37,7 @@ data class RemoteCapability( var accountName: String = "", // Server version - var versionMayor: Int = 0, + var versionMajor: Int = 0, var versionMinor: Int = 0, var versionMicro: Int = 0, var versionString: String = "", @@ -68,7 +72,10 @@ data class RemoteCapability( var filesUndelete: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, var filesVersioning: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, val filesPrivateLinks: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN, - val filesAppProviders: List?, + val filesAppProviders: List?, + + // Spaces + val spaces: RemoteSpaces?, ) { /** * Enum for Boolean Type in capabilities, with values: @@ -101,7 +108,7 @@ data class RemoteCapability( } } - data class RemoteOCISProvider( + data class RemoteAppProviders( val enabled: Boolean, val version: String, val appsUrl: String?, @@ -109,4 +116,10 @@ data class RemoteCapability( val openWebUrl: String?, val newUrl: String?, ) + + data class RemoteSpaces( + val enabled: Boolean, + val projects: Boolean, + val shareJail: Boolean, + ) } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt index d4000b93..3c281b70 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt @@ -1,32 +1,35 @@ -/* ownCloud Android Library is available under MIT license - * @author Abel García de Prada - * Copyright (C) 2020 ownCloud GmbH. +/** + * ownCloud Android Library is available under MIT license * - * 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: + * @author Abel García de Prada + * @author Juan Carlos Garrote Gascón * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * Copyright (C) 2022 ownCloud GmbH. * - * 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. + * 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.responses import com.owncloud.android.lib.resources.status.RemoteCapability -import com.owncloud.android.lib.resources.status.RemoteCapability.CapabilityBooleanType -import com.owncloud.android.lib.resources.status.RemoteCapability.RemoteOCISProvider +import com.owncloud.android.lib.resources.status.RemoteCapability.* import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -37,7 +40,7 @@ data class CapabilityResponse( val capabilities: Capabilities? ) { fun toRemoteCapability(): RemoteCapability = RemoteCapability( - versionMayor = serverVersion?.major ?: 0, + versionMajor = serverVersion?.major ?: 0, versionMinor = serverVersion?.minor ?: 0, versionMicro = serverVersion?.micro ?: 0, versionString = serverVersion?.string ?: "", @@ -70,10 +73,11 @@ data class CapabilityResponse( filesUndelete = CapabilityBooleanType.fromBooleanValue(capabilities?.fileCapabilities?.undelete), filesVersioning = CapabilityBooleanType.fromBooleanValue(capabilities?.fileCapabilities?.versioning), filesPrivateLinks = capabilities?.fileCapabilities?.privateLinks?.let { CapabilityBooleanType.fromBooleanValue(it) } ?: CapabilityBooleanType.UNKNOWN, - filesAppProviders = capabilities?.fileCapabilities?.appProviders?.map { it.toOCISProvider() }, + filesAppProviders = capabilities?.fileCapabilities?.appProviders?.map { it.toAppProviders() }, filesSharingFederationIncoming = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingFederation?.incoming), filesSharingFederationOutgoing = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingFederation?.outgoing), filesSharingUserProfilePicture = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingUser?.profilePicture), + spaces = capabilities?.spacesCapabilities?.toSpaces(), ) } @@ -86,7 +90,9 @@ data class Capabilities( @Json(name = "files") val fileCapabilities: FileCapabilities?, @Json(name = "dav") - val davCapabilities: DavCapabilities? + val davCapabilities: DavCapabilities?, + @Json(name = "spaces") + val spacesCapabilities: SpacesCapabilities? ) @JsonClass(generateAdapter = true) @@ -182,7 +188,7 @@ data class AppProvider( @Json(name = "new_url") val newUrl: String?, ) { - fun toOCISProvider() = RemoteOCISProvider(enabled, version, appsUrl, openUrl, openWebUrl, newUrl) + fun toAppProviders() = RemoteAppProviders(enabled, version, appsUrl, openUrl, openWebUrl, newUrl) } @JsonClass(generateAdapter = true) @@ -190,6 +196,16 @@ data class DavCapabilities( val chunking: String? ) +@JsonClass(generateAdapter = true) +data class SpacesCapabilities( + val enabled: Boolean, + val projects: Boolean, + @Json(name = "share_jail") + val shareJail: Boolean, +) { + fun toSpaces() = RemoteSpaces(enabled, projects, shareJail) +} + @JsonClass(generateAdapter = true) data class ServerVersion( var major: Int?, From f0dda9eb8bbc6265dad69357ac9b5c40c03e0333 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Mon, 9 Jan 2023 13:27:33 +0100 Subject: [PATCH 13/49] Added trailing comma --- .../lib/resources/status/responses/CapabilityResponse.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt index 3c281b70..31673541 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/responses/CapabilityResponse.kt @@ -92,7 +92,7 @@ data class Capabilities( @Json(name = "dav") val davCapabilities: DavCapabilities?, @Json(name = "spaces") - val spacesCapabilities: SpacesCapabilities? + val spacesCapabilities: SpacesCapabilities?, ) @JsonClass(generateAdapter = true) From b1a3402656534e87b71e9014434d9afeddab1626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Wed, 21 Dec 2022 19:13:31 +0100 Subject: [PATCH 14/49] Create spaces fetch operation and spaces service --- .../spaces/GetRemoteSpacesOperation.kt | 103 +++++++++++++++++ .../spaces/responses/SpacesResponse.kt | 104 ++++++++++++++++++ .../spaces/services/OCSpacesService.kt | 34 ++++++ .../spaces/services/SpacesService.kt | 31 ++++++ 4 files changed, 272 insertions(+) create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/GetRemoteSpacesOperation.kt create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/services/OCSpacesService.kt create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/services/SpacesService.kt diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/GetRemoteSpacesOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/GetRemoteSpacesOperation.kt new file mode 100644 index 00000000..46e36a10 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/GetRemoteSpacesOperation.kt @@ -0,0 +1,103 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2022 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.spaces + +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.resources.CommonOcsResponse +import com.owncloud.android.lib.resources.shares.responses.ShareeOcsResponse +import com.owncloud.android.lib.resources.spaces.responses.SpaceResponse +import com.owncloud.android.lib.resources.spaces.responses.SpacesResponseWrapper +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 + +class GetRemoteSpacesOperation : RemoteOperation>() { + override fun run(client: OwnCloudClient): RemoteOperationResult> { + val requestUri = buildRequestUri(client.baseUri) + + val getMethod = GetMethod(URL(requestUri.toString())) + + return try { + val status = client.executeHttpMethod(getMethod) + val response = getMethod.getResponseBodyAsString() + + if (isSuccess(status)) { + onRequestSuccessful(response) + } else { + onResultUnsuccessful(getMethod, response, status) + } + } catch (e: Exception) { + Timber.e(e, "Exception while getting remote shares") + RemoteOperationResult(e) + } + } + + private fun buildRequestUri(baseUri: Uri) = + baseUri.buildUpon() + .appendEncodedPath(GRAPH_API_PATH) + .appendEncodedPath(ENDPOINT_SPACES_LIST) + .build() + + private fun parseResponse(response: String): List { + val moshi = Moshi.Builder().build() + val adapter: JsonAdapter = moshi.adapter(SpacesResponseWrapper::class.java) + return adapter.fromJson(response)?.value ?: listOf() + } + + private fun onResultUnsuccessful( + method: GetMethod, + response: String?, + status: Int + ): RemoteOperationResult> { + Timber.e("Failed response while getting spaces for user") + if (response != null) { + Timber.e("*** status code: $status; response message: $response") + } else { + Timber.e("*** status code: $status") + } + return RemoteOperationResult(method) + } + + private fun onRequestSuccessful(response: String?): RemoteOperationResult> { + val result = RemoteOperationResult>(RemoteOperationResult.ResultCode.OK) + Timber.d("Successful response: $response") + result.data = response?.let { parseResponse(it) } ?: listOf() + Timber.d("*** Fetch of spaces completed and parsed to ${result.data}") + return result + } + + private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK + + companion object { + private const val GRAPH_API_PATH = "graph/v1.0" + private const val ENDPOINT_SPACES_LIST = "me/drives" + } +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt new file mode 100644 index 00000000..8ccca7cc --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt @@ -0,0 +1,104 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2022 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.spaces.responses + +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class SpacesResponseWrapper( + val value: List +) + +@JsonClass(generateAdapter = true) +data class SpaceResponse( + val description: String?, + val driveAlias: String, + val driveType: String, + val id: String, + val lastModifiedDateTime: String, + val name: String, + val owner: OwnerResponse, + val quota: QuotaResponse, + val root: RootResponse, + val special: List?, + val webUrl: String +) + +@JsonClass(generateAdapter = true) +data class OwnerResponse( + val user: UserResponse +) + +@JsonClass(generateAdapter = true) +data class QuotaResponse( + val remaining: Long, + val state: String, + val total: Int, + val used: Int +) + +@JsonClass(generateAdapter = true) +data class RootResponse( + val eTag: String, + val id: String, + val permissions: List?, + val webDavUrl: String +) + +@JsonClass(generateAdapter = true) +data class SpecialResponse( + val eTag: String, + val file: FileResponse, + val id: String, + val lastModifiedDateTime: String, + val name: String, + val size: Int, + val specialFolder: SpecialFolderResponse, + val webDavUrl: String +) + +@JsonClass(generateAdapter = true) +data class UserResponse( + val id: String +) + +@JsonClass(generateAdapter = true) +data class FileResponse( + val mimeType: String +) + +@JsonClass(generateAdapter = true) +data class GrantedToResponse( + val user: UserResponse +) + +@JsonClass(generateAdapter = true) +data class PermissionResponse( + val grantedTo: List, + val roles: List +) + +@JsonClass(generateAdapter = true) +data class SpecialFolderResponse( + val name: String +) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/services/OCSpacesService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/services/OCSpacesService.kt new file mode 100644 index 00000000..2f29601d --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/services/OCSpacesService.kt @@ -0,0 +1,34 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2022 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.spaces.services + +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.spaces.GetRemoteSpacesOperation +import com.owncloud.android.lib.resources.spaces.responses.SpaceResponse + +class OCSpacesService(override val client: OwnCloudClient) : SpacesService { + override fun getSpaces(): RemoteOperationResult> { + return GetRemoteSpacesOperation().execute(client) + } +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/services/SpacesService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/services/SpacesService.kt new file mode 100644 index 00000000..2384769c --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/services/SpacesService.kt @@ -0,0 +1,31 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2022 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.spaces.services + +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.Service +import com.owncloud.android.lib.resources.spaces.responses.SpaceResponse + +interface SpacesService : Service { + fun getSpaces(): RemoteOperationResult> +} From 7bb94cf2896cbec5f95da5e7760523def7a44a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Fri, 23 Dec 2022 11:49:54 +0100 Subject: [PATCH 15/49] Make quota attribute nullable. Its not mandatory --- .../android/lib/resources/spaces/GetRemoteSpacesOperation.kt | 4 ---- .../android/lib/resources/spaces/responses/SpacesResponse.kt | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/GetRemoteSpacesOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/GetRemoteSpacesOperation.kt index 46e36a10..35a6727b 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/GetRemoteSpacesOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/GetRemoteSpacesOperation.kt @@ -28,15 +28,11 @@ 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.resources.CommonOcsResponse -import com.owncloud.android.lib.resources.shares.responses.ShareeOcsResponse import com.owncloud.android.lib.resources.spaces.responses.SpaceResponse import com.owncloud.android.lib.resources.spaces.responses.SpacesResponseWrapper 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 class GetRemoteSpacesOperation : RemoteOperation>() { diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt index 8ccca7cc..7100b552 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt @@ -38,7 +38,7 @@ data class SpaceResponse( val lastModifiedDateTime: String, val name: String, val owner: OwnerResponse, - val quota: QuotaResponse, + val quota: QuotaResponse?, val root: RootResponse, val special: List?, val webUrl: String From 0d7a49b3ff6c1a87a4791c6440d52002d5d57c15 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Tue, 27 Dec 2022 15:17:44 +0100 Subject: [PATCH 16/49] Some type changes and renamings --- .../android/lib/resources/spaces/responses/SpacesResponse.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt index 7100b552..81bdaa21 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt @@ -53,8 +53,8 @@ data class OwnerResponse( data class QuotaResponse( val remaining: Long, val state: String, - val total: Int, - val used: Int + val total: Long, + val used: Long ) @JsonClass(generateAdapter = true) From 31ccf56e9759a2257287b5ed6c0bfbe997c77643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Tue, 10 Jan 2023 14:37:48 +0100 Subject: [PATCH 17/49] Fix parsing when space is disabled --- .../resources/spaces/responses/SpacesResponse.kt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt index 81bdaa21..09235d6e 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt @@ -51,10 +51,10 @@ data class OwnerResponse( @JsonClass(generateAdapter = true) data class QuotaResponse( - val remaining: Long, - val state: String, + val remaining: Long?, + val state: String?, val total: Long, - val used: Long + val used: Long?, ) @JsonClass(generateAdapter = true) @@ -62,7 +62,8 @@ data class RootResponse( val eTag: String, val id: String, val permissions: List?, - val webDavUrl: String + val webDavUrl: String, + val deleted: DeleteResponse?, ) @JsonClass(generateAdapter = true) @@ -92,6 +93,11 @@ data class GrantedToResponse( val user: UserResponse ) +@JsonClass(generateAdapter = true) +data class DeleteResponse( + val state: String, +) + @JsonClass(generateAdapter = true) data class PermissionResponse( val grantedTo: List, From 8a4fcb6550c91b1a96ccc23896733f0b39837d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Fri, 13 Jan 2023 08:53:13 +0100 Subject: [PATCH 18/49] Support shares space --- .../lib/resources/spaces/responses/SpacesResponse.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt index 09235d6e..a6f08a5f 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt @@ -35,13 +35,13 @@ data class SpaceResponse( val driveAlias: String, val driveType: String, val id: String, - val lastModifiedDateTime: String, + val lastModifiedDateTime: String?, val name: String, - val owner: OwnerResponse, + val owner: OwnerResponse?, val quota: QuotaResponse?, val root: RootResponse, val special: List?, - val webUrl: String + val webUrl: String, ) @JsonClass(generateAdapter = true) @@ -59,7 +59,7 @@ data class QuotaResponse( @JsonClass(generateAdapter = true) data class RootResponse( - val eTag: String, + val eTag: String?, val id: String, val permissions: List?, val webDavUrl: String, From 45f53656ba989c44c0bc7b5ce1aa261c72cf7a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Fri, 13 Jan 2023 11:27:20 +0100 Subject: [PATCH 19/49] Update permissions parsing to latest api changes Supports api renaming from grantedTo to grantedToIdentities on v1.0.1 https://github.com/owncloud/libre-graph-api/releases/tag/v1.0.1 --- .../spaces/responses/SpacesResponse.kt | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt index a6f08a5f..6ce50498 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt @@ -89,8 +89,15 @@ data class FileResponse( ) @JsonClass(generateAdapter = true) -data class GrantedToResponse( - val user: UserResponse +data class IdentityPermissionResponse( + val id: String, + val displayName: String?, +) + +@JsonClass(generateAdapter = true) +data class GrantedToIdentitiesResponse( + val user: IdentityPermissionResponse?, + val group: IdentityPermissionResponse?, ) @JsonClass(generateAdapter = true) @@ -100,9 +107,18 @@ data class DeleteResponse( @JsonClass(generateAdapter = true) data class PermissionResponse( - val grantedTo: List, - val roles: List -) + val grantedTo: List?, + val grantedToIdentities: List?, + val roles: List, +) { + /** + * Supports api renaming from grantedTo to grantedToIdentities on v1.0.1 + * https://github.com/owncloud/libre-graph-api/releases/tag/v1.0.1 + */ + fun getGrantedToIdentitiesResponse(): List { + return grantedToIdentities ?: grantedTo ?: throw IllegalArgumentException("Permissions not granted to anyone") + } +} @JsonClass(generateAdapter = true) data class SpecialFolderResponse( From a65a82cae0499dfba2e0edbbfdbd71a53b8974a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Mon, 16 Jan 2023 15:32:44 +0100 Subject: [PATCH 20/49] Adapt the propfind to work with specific webdavurl from the space --- .../lib/resources/files/ReadRemoteFolderOperation.kt | 11 +++++++++-- .../lib/resources/files/services/FileService.kt | 3 ++- .../files/services/implementation/OCFileService.kt | 6 ++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt index 40747ace..ee0b0a03 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt @@ -48,7 +48,8 @@ import java.net.URL * @author David González Verdugo */ class ReadRemoteFolderOperation( - val remotePath: String + val remotePath: String, + val spaceWebDavUrl: String? = null, ) : RemoteOperation>() { /** @@ -61,7 +62,7 @@ class ReadRemoteFolderOperation( PropertyRegistry.register(OCShareTypes.Factory()) val propfindMethod = PropfindMethod( - URL(client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(remotePath)), + getFinalWebDavUrl(), DavConstants.DEPTH_1, DavUtils.allPropset ) @@ -107,5 +108,11 @@ class ReadRemoteFolderOperation( } } + private fun getFinalWebDavUrl(): URL { + val baseWebDavUrl = spaceWebDavUrl ?: client.userFilesWebDavUri.toString() + + return URL(baseWebDavUrl + WebdavUtils.encodePath(remotePath)) + } + private fun isSuccess(status: Int): Boolean = status.isOneOf(HTTP_OK, HTTP_MULTI_STATUS) } 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 index 51a85c46..4798f234 100644 --- 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 @@ -61,7 +61,8 @@ interface FileService : Service { ): RemoteOperationResult fun refreshFolder( - remotePath: String + remotePath: String, + spaceWebDavUrl: String? = null, ): RemoteOperationResult> fun removeFile( 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 index 32ac22ca..037e5ef2 100644 --- 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 @@ -98,10 +98,12 @@ class OCFileService(override val client: OwnCloudClient) : FileService { ).execute(client) override fun refreshFolder( - remotePath: String + remotePath: String, + spaceWebDavUrl: String?, ): RemoteOperationResult> = ReadRemoteFolderOperation( - remotePath = remotePath + remotePath = remotePath, + spaceWebDavUrl = spaceWebDavUrl, ).execute(client) override fun removeFile( From 8e4f243031f90174c17417ad1bc8c31eef1e586b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Tue, 17 Jan 2023 16:25:09 +0100 Subject: [PATCH 21/49] Fix remote path retrieval. Now it depends on webdav url to support spaces --- .../files/ReadRemoteFolderOperation.kt | 8 +-- .../android/lib/resources/files/RemoteFile.kt | 28 +++++++-- .../owncloud/android/lib/RemoteFileTest.kt | 59 +++++++++++++++++++ 3 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 owncloudComLibrary/src/test/java/com/owncloud/android/lib/RemoteFileTest.kt diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt index ee0b0a03..16600fe1 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt @@ -72,12 +72,11 @@ class ReadRemoteFolderOperation( if (isSuccess(status)) { val mFolderAndFiles = ArrayList() - // parse data from remote folder - // TODO: Remove that !! val remoteFolder = RemoteFile.getRemoteFileFromDav( davResource = propfindMethod.root!!, userId = AccountUtils.getUserId(mAccount, mContext), - userName = mAccount.name + userName = mAccount.name, + spaceWebDavUrl = spaceWebDavUrl, ) mFolderAndFiles.add(remoteFolder) @@ -86,7 +85,8 @@ class ReadRemoteFolderOperation( val remoteFile = RemoteFile.getRemoteFileFromDav( davResource = resource, userId = AccountUtils.getUserId(mAccount, mContext), - userName = mAccount.name + userName = mAccount.name, + spaceWebDavUrl = spaceWebDavUrl, ) mFolderAndFiles.add(remoteFile) } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.kt index 87a6663e..791a0765 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.kt @@ -26,6 +26,7 @@ package com.owncloud.android.lib.resources.files import android.net.Uri import android.os.Parcelable +import androidx.annotation.VisibleForTesting import at.bitfire.dav4jvm.PropStat import at.bitfire.dav4jvm.Property import at.bitfire.dav4jvm.Response @@ -100,8 +101,13 @@ data class RemoteFile( const val MIME_DIR = "DIR" const val MIME_DIR_UNIX = "httpd/unix-directory" - fun getRemoteFileFromDav(davResource: Response, userId: String, userName: String): RemoteFile { - val remotePath = getRemotePathFromUrl(davResource.href, userId) + fun getRemoteFileFromDav( + davResource: Response, + userId: String, + userName: String, + spaceWebDavUrl: String? = null + ): RemoteFile { + val remotePath = getRemotePathFromUrl(davResource.href, userId, spaceWebDavUrl) val remoteFile = RemoteFile(remotePath = remotePath, owner = userName) val properties = getPropertiesEvenIfPostProcessing(davResource) @@ -164,15 +170,25 @@ data class RemoteFile( * Retrieves a relative path from a remote file url * * - * Example: url:port/remote.php/dav/files/username/Documents/text.txt => /Documents/text.txt + * Example legacy: + * /remote.php/dav/files/username/Documents/text.txt => /Documents/text.txt + * + * Example spaces: + * /dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$05bca744-d89f-4e9c-a990-25a0d7f03fe9/Documents/text.txt => /Documents/text.txt * * @param url remote file url * @param userId file owner + * @param spaceWebDavUrl custom web dav url for space * @return remote relative path of the file */ - private fun getRemotePathFromUrl(url: HttpUrl, userId: String): String { - val davFilesPath = OwnCloudClient.WEBDAV_FILES_PATH_4_0 + userId - val absoluteDavPath = Uri.decode(url.encodedPath) + @VisibleForTesting + fun getRemotePathFromUrl( + url: HttpUrl, + userId: String, + spaceWebDavUrl: String? = null, + ): String { + val davFilesPath = spaceWebDavUrl ?: (OwnCloudClient.WEBDAV_FILES_PATH_4_0 + userId) + val absoluteDavPath = if (spaceWebDavUrl != null) Uri.decode(url.toString()) else Uri.decode(url.encodedPath) val pathToOc = absoluteDavPath.split(davFilesPath).first() return absoluteDavPath.replace(pathToOc + davFilesPath, "") } diff --git a/owncloudComLibrary/src/test/java/com/owncloud/android/lib/RemoteFileTest.kt b/owncloudComLibrary/src/test/java/com/owncloud/android/lib/RemoteFileTest.kt new file mode 100644 index 00000000..6cd8febe --- /dev/null +++ b/owncloudComLibrary/src/test/java/com/owncloud/android/lib/RemoteFileTest.kt @@ -0,0 +1,59 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2023 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 + +import android.os.Build +import com.owncloud.android.lib.resources.files.RemoteFile +import okhttp3.HttpUrl.Companion.toHttpUrl +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [Build.VERSION_CODES.O], manifest = Config.NONE) +class RemoteFileTest { + + @Test + fun getRemotePathFromUrl_legacyWebDav() { + val httpUrlToTest = "https://server.url/remote.php/dav/files/username/Documents/text.txt".toHttpUrl() + val expectedRemotePath = "/Documents/text.txt" + + val actualRemotePath = RemoteFile.Companion.getRemotePathFromUrl(httpUrlToTest, "username") + assertEquals(expectedRemotePath, actualRemotePath) + } + + @Test + fun getRemotePathFromUrl_spacesWebDav() { + val spaceWebDavUrl = "https://server.url/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$05bca744-d89f-4e9c-a990-25a0d7f03fe9" + + val httpUrlToTest = + "https://server.url/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$05bca744-d89f-4e9c-a990-25a0d7f03fe9/Documents/text.txt".toHttpUrl() + val expectedRemotePath = "/Documents/text.txt" + + val actualRemotePath = RemoteFile.Companion.getRemotePathFromUrl(httpUrlToTest, "username", spaceWebDavUrl) + assertEquals(expectedRemotePath, actualRemotePath) + } +} From cb73d537e4b616b8aa94e85b4b6a8fbb151381ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Tue, 17 Jan 2023 18:55:35 +0100 Subject: [PATCH 22/49] Allow support to read specific file from a space --- .../files/ReadRemoteFileOperation.kt | 20 ++++++++++++++----- .../resources/files/services/FileService.kt | 3 ++- .../services/implementation/OCFileService.kt | 6 ++++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.kt index 539ea92c..cf29b60e 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.kt @@ -46,7 +46,10 @@ import java.util.concurrent.TimeUnit * @author David González Verdugo */ -class ReadRemoteFileOperation(val remotePath: String) : RemoteOperation() { +class ReadRemoteFileOperation( + val remotePath: String, + val spaceWebDavUrl: String? = null, +) : RemoteOperation() { /** * Performs the read operation. @@ -57,7 +60,7 @@ class ReadRemoteFileOperation(val remotePath: String) : RemoteOperation { try { val propFind = PropfindMethod( - url = URL("${client.userFilesWebDavUri}${WebdavUtils.encodePath(remotePath)}"), + url = getFinalWebDavUrl(), depth = DEPTH_0, propertiesToRequest = DavUtils.allPropset ).apply { @@ -69,10 +72,11 @@ class ReadRemoteFileOperation(val remotePath: String) : RemoteOperation(RemoteOperationResult.ResultCode.OK).apply { @@ -88,6 +92,12 @@ class ReadRemoteFileOperation(val remotePath: String) : RemoteOperation fun readFile( - remotePath: String + remotePath: String, + spaceWebDavUrl: String? = null, ): RemoteOperationResult fun refreshFolder( 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 index 037e5ef2..e2affc8a 100644 --- 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 @@ -91,10 +91,12 @@ class OCFileService(override val client: OwnCloudClient) : FileService { ).execute(client) override fun readFile( - remotePath: String + remotePath: String, + spaceWebDavUrl: String?, ): RemoteOperationResult = ReadRemoteFileOperation( - remotePath = remotePath + remotePath = remotePath, + spaceWebDavUrl = spaceWebDavUrl, ).execute(client) override fun refreshFolder( From 2c18e7b679069d434bf329ad482e8dc31a68eeee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Tue, 17 Jan 2023 19:07:42 +0100 Subject: [PATCH 23/49] Added create folder operation support for specific space --- .../lib/resources/files/CreateRemoteFolderOperation.kt | 3 ++- .../android/lib/resources/files/services/FileService.kt | 3 ++- .../files/services/implementation/OCFileService.kt | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.kt index 372c8f21..22757409 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.kt @@ -46,7 +46,8 @@ import java.util.concurrent.TimeUnit class CreateRemoteFolderOperation( val remotePath: String, private val createFullPath: Boolean, - private val isChunksFolder: Boolean = false + private val isChunksFolder: Boolean = false, + val spaceWebDavUrl: String? = null, ) : RemoteOperation() { override fun run(client: OwnCloudClient): RemoteOperationResult { 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 index 9ebe1994..50f4407f 100644 --- 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 @@ -43,7 +43,8 @@ interface FileService : Service { fun createFolder( remotePath: String, createFullPath: Boolean, - isChunkFolder: Boolean = false + isChunkFolder: Boolean = false, + spaceWebDavUrl: String? = null, ): RemoteOperationResult fun downloadFile( 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 index e2affc8a..54113b81 100644 --- 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 @@ -64,12 +64,14 @@ class OCFileService(override val client: OwnCloudClient) : FileService { override fun createFolder( remotePath: String, createFullPath: Boolean, - isChunkFolder: Boolean + isChunkFolder: Boolean, + spaceWebDavUrl: String?, ): RemoteOperationResult = CreateRemoteFolderOperation( remotePath = remotePath, createFullPath = createFullPath, - isChunksFolder = isChunkFolder + isChunksFolder = isChunkFolder, + spaceWebDavUrl = spaceWebDavUrl, ).execute(client) override fun downloadFile( From 9c844aae7e32a7e900ca79359866a8818d33123d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Wed, 18 Jan 2023 13:15:19 +0100 Subject: [PATCH 24/49] Support removal of files from specific space --- .../lib/resources/files/CreateRemoteFolderOperation.kt | 6 +++--- .../lib/resources/files/RemoveRemoteFileOperation.kt | 8 ++++---- .../files/chunks/RemoveRemoteChunksFolderOperation.kt | 3 +-- .../android/lib/resources/files/services/FileService.kt | 3 ++- .../files/services/implementation/OCFileService.kt | 6 ++++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.kt index 22757409..15a9e8bc 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.kt @@ -68,13 +68,13 @@ class CreateRemoteFolderOperation( var result: RemoteOperationResult try { val webDavUri = if (isChunksFolder) { - client.uploadsWebDavUri + client.uploadsWebDavUri.toString() } else { - client.userFilesWebDavUri + spaceWebDavUrl ?: client.userFilesWebDavUri.toString() } val mkCol = MkColMethod( - URL(webDavUri.toString() + WebdavUtils.encodePath(remotePath)) + URL(webDavUri + WebdavUtils.encodePath(remotePath)) ).apply { setReadTimeout(READ_TIMEOUT, TimeUnit.SECONDS) setConnectionTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoveRemoteFileOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoveRemoteFileOperation.kt index a451256a..b97b3d78 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoveRemoteFileOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoveRemoteFileOperation.kt @@ -24,7 +24,6 @@ package com.owncloud.android.lib.resources.files -import android.net.Uri import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.http.HttpConstants.HTTP_NO_CONTENT import com.owncloud.android.lib.common.http.HttpConstants.HTTP_OK @@ -46,7 +45,8 @@ import java.net.URL * @author Abel García de Prada */ open class RemoveRemoteFileOperation( - private val remotePath: String + private val remotePath: String, + val spaceWebDavUrl: String? = null, ) : RemoteOperation() { override fun run(client: OwnCloudClient): RemoteOperationResult { @@ -54,7 +54,7 @@ open class RemoveRemoteFileOperation( try { val srcWebDavUri = getSrcWebDavUriForClient(client) val deleteMethod = DeleteMethod( - URL(srcWebDavUri.toString() + WebdavUtils.encodePath(remotePath)) + URL(srcWebDavUri + WebdavUtils.encodePath(remotePath)) ) val status = client.executeHttpMethod(deleteMethod) @@ -75,7 +75,7 @@ open class RemoveRemoteFileOperation( * For standard removals, we will use [OwnCloudClient.getUserFilesWebDavUri]. * In case we need a different source Uri, override this method. */ - open fun getSrcWebDavUriForClient(client: OwnCloudClient): Uri = client.userFilesWebDavUri + open fun getSrcWebDavUriForClient(client: OwnCloudClient): String = spaceWebDavUrl ?: client.userFilesWebDavUri.toString() private fun isSuccess(status: Int) = status.isOneOf(HTTP_OK, HTTP_NO_CONTENT) } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/RemoveRemoteChunksFolderOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/RemoveRemoteChunksFolderOperation.kt index 150a4dd1..b738dfbf 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/RemoveRemoteChunksFolderOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/chunks/RemoveRemoteChunksFolderOperation.kt @@ -24,10 +24,9 @@ */ package com.owncloud.android.lib.resources.files.chunks -import android.net.Uri import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.resources.files.RemoveRemoteFileOperation class RemoveRemoteChunksFolderOperation(remotePath: String) : RemoveRemoteFileOperation(remotePath) { - override fun getSrcWebDavUriForClient(client: OwnCloudClient): Uri = client.uploadsWebDavUri + override fun getSrcWebDavUriForClient(client: OwnCloudClient): String = client.uploadsWebDavUri.toString() } 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 index 50f4407f..2fd3c0e8 100644 --- 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 @@ -68,7 +68,8 @@ interface FileService : Service { ): RemoteOperationResult> fun removeFile( - remotePath: String + remotePath: String, + spaceWebDavUrl: String? = null, ): RemoteOperationResult fun renameFile( 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 index 54113b81..8bbbc074 100644 --- 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 @@ -111,10 +111,12 @@ class OCFileService(override val client: OwnCloudClient) : FileService { ).execute(client) override fun removeFile( - remotePath: String + remotePath: String, + spaceWebDavUrl: String?, ): RemoteOperationResult = RemoveRemoteFileOperation( - remotePath = remotePath + remotePath = remotePath, + spaceWebDavUrl = spaceWebDavUrl, ).execute(client) override fun renameFile( From 78665e8cb048aed8830de266c8a788bedec1e648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Thu, 19 Jan 2023 08:19:34 +0100 Subject: [PATCH 25/49] Add support for spaces web dav specific urls to the rename operation --- .../lib/resources/files/RenameRemoteFileOperation.kt | 5 +++-- .../android/lib/resources/files/services/FileService.kt | 1 + .../files/services/implementation/OCFileService.kt | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.kt index 8f669c69..9a0a4b30 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.kt @@ -48,6 +48,7 @@ class RenameRemoteFileOperation( private val oldRemotePath: String, private val newName: String, isFolder: Boolean, + val spaceWebDavUrl: String? = null, ) : RemoteOperation() { private var newRemotePath: String @@ -75,8 +76,8 @@ class RenameRemoteFileOperation( } val moveMethod: MoveMethod = MoveMethod( - url = URL(client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(oldRemotePath)), - destinationUrl = client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(newRemotePath), + url = URL((spaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(oldRemotePath)), + destinationUrl = (spaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(newRemotePath), ).apply { setReadTimeout(RENAME_READ_TIMEOUT, TimeUnit.MILLISECONDS) setConnectionTimeout(RENAME_CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS) 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 index 2fd3c0e8..89407585 100644 --- 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 @@ -77,5 +77,6 @@ interface FileService : Service { oldRemotePath: String, newName: String, isFolder: Boolean, + spaceWebDavUrl: String? = null, ): 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 index 8bbbc074..e0c6a2f6 100644 --- 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 @@ -123,12 +123,14 @@ class OCFileService(override val client: OwnCloudClient) : FileService { oldName: String, oldRemotePath: String, newName: String, - isFolder: Boolean + isFolder: Boolean, + spaceWebDavUrl: String?, ): RemoteOperationResult = RenameRemoteFileOperation( oldName = oldName, oldRemotePath = oldRemotePath, newName = newName, - isFolder = isFolder + isFolder = isFolder, + spaceWebDavUrl = spaceWebDavUrl, ).execute(client) } From b65efc2b691dd1fe77a7d60c134a7447f8e47d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Thu, 2 Feb 2023 14:30:34 +0100 Subject: [PATCH 26/49] Allow downloads from specific WebDav urls --- .../lib/resources/files/DownloadRemoteFileOperation.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.kt index 80b9adc7..86fcde46 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/DownloadRemoteFileOperation.kt @@ -36,7 +36,6 @@ import java.io.BufferedInputStream import java.io.File import java.io.FileOutputStream import java.net.URL -import java.util.HashSet import java.util.concurrent.atomic.AtomicBoolean /** @@ -47,7 +46,8 @@ import java.util.concurrent.atomic.AtomicBoolean */ class DownloadRemoteFileOperation( private val remotePath: String, - localFolderPath: String + localFolderPath: String, + private val spaceWebDavUrl: String? = null, ) : RemoteOperation() { private val cancellationRequested = AtomicBoolean(false) @@ -84,7 +84,8 @@ class DownloadRemoteFileOperation( var bis: BufferedInputStream? = null var savedFile = false - val getMethod = GetMethod(URL(client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(remotePath))) + val webDavUri = spaceWebDavUrl ?: client.userFilesWebDavUri.toString() + val getMethod = GetMethod(URL(webDavUri + WebdavUtils.encodePath(remotePath))) try { val status = client.executeHttpMethod(getMethod) From e9f291371dbe69e2784749972e159b3e2a3e33c9 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Tue, 7 Feb 2023 17:02:10 +0100 Subject: [PATCH 27/49] Move network operation adapted to spaces --- .../CheckPathExistenceRemoteOperation.kt | 19 +++++++++++-------- .../files/MoveRemoteFileOperation.kt | 13 +++++++++---- .../resources/files/services/FileService.kt | 6 ++++-- .../services/implementation/OCFileService.kt | 10 +++++++--- 4 files changed, 31 insertions(+), 17 deletions(-) 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 index e59388bd..d7e927be 100644 --- 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 @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license -* Copyright (C) 2020 ownCloud GmbH. +* Copyright (C) 2023 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 @@ -41,6 +41,7 @@ import java.util.concurrent.TimeUnit * @author David A. Velasco * @author David González Verdugo * @author Abel García de Prada + * @author Juan Carlos Garrote Gascón * * @param remotePath Path to append to the URL owned by the client instance. * @param isUserLoggedIn When `true`, the username won't be added at the end of the PROPFIND url since is not @@ -48,21 +49,23 @@ import java.util.concurrent.TimeUnit */ class CheckPathExistenceRemoteOperation( val remotePath: String? = "", - val isUserLoggedIn: Boolean + val isUserLoggedIn: Boolean, + val spaceWebDavUrl: String? = null, ) : RemoteOperation() { override fun run(client: OwnCloudClient): RemoteOperationResult { - return try { - val stringUrl = - if (isUserLoggedIn) client.baseFilesWebDavUri.toString() - else client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(remotePath) + val baseStringUrl = spaceWebDavUrl ?: + if (isUserLoggedIn) client.baseFilesWebDavUri.toString() + else client.userFilesWebDavUri.toString() + val stringUrl = baseStringUrl + WebdavUtils.encodePath(remotePath) + return try { val propFindMethod = PropfindMethod(URL(stringUrl), 0, allPropset).apply { setReadTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS) setConnectionTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS) } - var status = client.executeHttpMethod(propFindMethod) + val status = client.executeHttpMethod(propFindMethod) /* PROPFIND method * 404 NOT FOUND: path doesn't exist, * 207 MULTI_STATUS: path exists. @@ -77,7 +80,7 @@ class CheckPathExistenceRemoteOperation( val result = RemoteOperationResult(e) Timber.e( e, - "Existence check for ${client.userFilesWebDavUri}${WebdavUtils.encodePath(remotePath)} : ${result.logMessage}" + "Existence check for $stringUrl : ${result.logMessage}" ) result } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.kt index 5741766a..6689c5f9 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.kt @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2021 ownCloud GmbH. + * Copyright (C) 2023 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,17 +38,22 @@ 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. + * in the same account and space. * * Allows renaming the moving file/folder at the same time. * * @author David A. Velasco * @author David González Verdugo * @author Abel García de Prada + * @author Juan Carlos Garrote Gascón + * + * @param sourceRemotePath Remote path of the file/folder to copy. + * @param targetRemotePath Remote path desired for the file/folder to copy it. */ open class MoveRemoteFileOperation( private val sourceRemotePath: String, private val targetRemotePath: String, + private val spaceWebDavUrl: String? = null, ) : RemoteOperation() { /** @@ -73,8 +78,8 @@ open class MoveRemoteFileOperation( // so this uri has to be customizable val srcWebDavUri = getSrcWebDavUriForClient(client) val moveMethod = MoveMethod( - url = URL(srcWebDavUri.toString() + WebdavUtils.encodePath(sourceRemotePath)), - destinationUrl = client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(targetRemotePath), + url = URL((spaceWebDavUrl ?: srcWebDavUri.toString()) + WebdavUtils.encodePath(sourceRemotePath)), + destinationUrl = (spaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(targetRemotePath), ).apply { addRequestHeaders(this) setReadTimeout(MOVE_READ_TIMEOUT, TimeUnit.SECONDS) 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 index 89407585..25365301 100644 --- 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 @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2020 ownCloud GmbH. + * Copyright (C) 2023 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,8 @@ interface FileService : Service { fun checkPathExistence( path: String, - isUserLogged: Boolean + isUserLogged: Boolean, + spaceWebDavUrl: String? = null, ): RemoteOperationResult fun copyFile( @@ -55,6 +56,7 @@ interface FileService : Service { fun moveFile( sourceRemotePath: String, targetRemotePath: String, + spaceWebDavUrl: String?, ): RemoteOperationResult fun readFile( 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 index e0c6a2f6..0a7b6e1f 100644 --- 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 @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2022 ownCloud GmbH. + * Copyright (C) 2023 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,11 +42,13 @@ class OCFileService(override val client: OwnCloudClient) : FileService { override fun checkPathExistence( path: String, - isUserLogged: Boolean + isUserLogged: Boolean, + spaceWebDavUrl: String?, ): RemoteOperationResult = CheckPathExistenceRemoteOperation( remotePath = path, - isUserLoggedIn = isUserLogged + isUserLoggedIn = isUserLogged, + spaceWebDavUrl = spaceWebDavUrl, ).execute(client) override fun getUrlToOpenInWeb(openWebEndpoint: String, fileId: String): RemoteOperationResult = @@ -86,10 +88,12 @@ class OCFileService(override val client: OwnCloudClient) : FileService { override fun moveFile( sourceRemotePath: String, targetRemotePath: String, + spaceWebDavUrl: String?, ): RemoteOperationResult = MoveRemoteFileOperation( sourceRemotePath = sourceRemotePath, targetRemotePath = targetRemotePath, + spaceWebDavUrl = spaceWebDavUrl, ).execute(client) override fun readFile( From a395787e0b1de4c06760f24b7e103e860b748c01 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 8 Feb 2023 13:30:22 +0100 Subject: [PATCH 28/49] Adapted copy operation for spaces --- .../files/CopyRemoteFileOperation.kt | 22 +++++++++++-------- .../resources/files/services/FileService.kt | 2 ++ .../services/implementation/OCFileService.kt | 10 ++++++--- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.kt index ce47a4fd..949d72e9 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.kt @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2022 ownCloud GmbH. + * Copyright (C) 2023 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 @@ -44,25 +44,29 @@ import java.util.concurrent.TimeUnit * @author David A. Velasco * @author Christian Schabesberger * @author David González V. + * @author Juan Carlos Garrote Gascón * - * @param srcRemotePath Remote path of the file/folder to copy. + * @param sourceRemotePath Remote path of the file/folder to copy. * @param targetRemotePath Remote path desired for the file/folder to copy it. */ class CopyRemoteFileOperation( - private val srcRemotePath: String, + private val sourceRemotePath: String, private val targetRemotePath: String, + private val sourceSpaceWebDavUrl: String? = null, + private val targetSpaceWebDavUrl: String? = null, ) : RemoteOperation() { + /** * Performs the rename operation. * * @param client Client object to communicate with the remote ownCloud server. */ override fun run(client: OwnCloudClient): RemoteOperationResult { - if (targetRemotePath == srcRemotePath) { + if (targetRemotePath == sourceRemotePath && sourceSpaceWebDavUrl == targetSpaceWebDavUrl) { // nothing to do! return RemoteOperationResult(ResultCode.OK) } - if (targetRemotePath.startsWith(srcRemotePath)) { + if (targetRemotePath.startsWith(sourceRemotePath) && sourceSpaceWebDavUrl == targetSpaceWebDavUrl) { return RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT) } @@ -70,8 +74,8 @@ class CopyRemoteFileOperation( var result: RemoteOperationResult try { val copyMethod = CopyMethod( - URL(client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(srcRemotePath)), - client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(targetRemotePath), + URL((sourceSpaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(sourceRemotePath)), + (targetSpaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(targetRemotePath), ).apply { setReadTimeout(COPY_READ_TIMEOUT, TimeUnit.SECONDS) setConnectionTimeout(COPY_CONNECTION_TIMEOUT, TimeUnit.SECONDS) @@ -95,10 +99,10 @@ class CopyRemoteFileOperation( client.exhaustResponse(copyMethod.getResponseBodyAsStream()) } } - Timber.i("Copy $srcRemotePath to $targetRemotePath: ${result.logMessage}") + Timber.i("Copy $sourceRemotePath to $targetRemotePath: ${result.logMessage}") } catch (e: Exception) { result = RemoteOperationResult(e) - Timber.e(e, "Copy $srcRemotePath to $targetRemotePath: ${result.logMessage}") + Timber.e(e, "Copy $sourceRemotePath to $targetRemotePath: ${result.logMessage}") } return result } 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 index 25365301..1421648b 100644 --- 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 @@ -39,6 +39,8 @@ interface FileService : Service { fun copyFile( sourceRemotePath: String, targetRemotePath: String, + sourceSpaceWebDavUrl: String?, + targetSpaceWebDavUrl: String?, ): RemoteOperationResult fun createFolder( 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 index 0a7b6e1f..8ec44d46 100644 --- 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 @@ -56,11 +56,15 @@ class OCFileService(override val client: OwnCloudClient) : FileService { override fun copyFile( sourceRemotePath: String, - targetRemotePath: String + targetRemotePath: String, + sourceSpaceWebDavUrl: String?, + targetSpaceWebDavUrl: String?, ): RemoteOperationResult = CopyRemoteFileOperation( - srcRemotePath = sourceRemotePath, - targetRemotePath = targetRemotePath + sourceRemotePath = sourceRemotePath, + targetRemotePath = targetRemotePath, + sourceSpaceWebDavUrl = sourceSpaceWebDavUrl, + targetSpaceWebDavUrl = targetSpaceWebDavUrl, ).execute(client) override fun createFolder( From e6f3fd2e1650877722684606239b7901f87ee6b4 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 15 Feb 2023 14:54:59 +0100 Subject: [PATCH 29/49] Upload workers and network operations adapted to spaces --- .../resources/files/UploadFileFromFileSystemOperation.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadFileFromFileSystemOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadFileFromFileSystemOperation.kt index 93a2357a..a863a37b 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadFileFromFileSystemOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/UploadFileFromFileSystemOperation.kt @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license - * Copyright (C) 2022 ownCloud GmbH. + * Copyright (C) 2023 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 @@ -48,6 +48,7 @@ import java.util.concurrent.atomic.AtomicBoolean * @author masensio * @author David González Verdugo * @author Abel García de Prada + * @author Juan Carlos Garrote Gascón */ open class UploadFileFromFileSystemOperation( val localPath: String, @@ -55,6 +56,7 @@ open class UploadFileFromFileSystemOperation( val mimeType: String, val lastModifiedTimestamp: String, val requiredEtag: String?, + val spaceWebDavUrl: String? = null, ) : RemoteOperation() { protected val cancellationRequested = AtomicBoolean(false) @@ -97,7 +99,8 @@ open class UploadFileFromFileSystemOperation( synchronized(dataTransferListener) { it.addDatatransferProgressListeners(dataTransferListener) } } - putMethod = PutMethod(URL(client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(remotePath)), fileRequestBody!!).apply { + val baseStringUrl = spaceWebDavUrl ?: client.userFilesWebDavUri.toString() + putMethod = PutMethod(URL(baseStringUrl + WebdavUtils.encodePath(remotePath)), fileRequestBody!!).apply { retryOnConnectionFailure = false if (!requiredEtag.isNullOrBlank()) { addRequestHeader(HttpConstants.IF_MATCH_HEADER, requiredEtag) From 2458db1828082bbbb4be71b2800862998681e9a9 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Wed, 15 Feb 2023 15:02:08 +0100 Subject: [PATCH 30/49] Fix to KtLint report --- .../lib/resources/files/CheckPathExistenceRemoteOperation.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 index d7e927be..dd7d0a56 100644 --- 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 @@ -54,9 +54,8 @@ class CheckPathExistenceRemoteOperation( ) : RemoteOperation() { override fun run(client: OwnCloudClient): RemoteOperationResult { - val baseStringUrl = spaceWebDavUrl ?: - if (isUserLoggedIn) client.baseFilesWebDavUri.toString() - else client.userFilesWebDavUri.toString() + val baseStringUrl = spaceWebDavUrl ?: if (isUserLoggedIn) client.baseFilesWebDavUri.toString() + else client.userFilesWebDavUri.toString() val stringUrl = baseStringUrl + WebdavUtils.encodePath(remotePath) return try { From 0017079a6921c88bc8ea11d512b488bba8d0bda1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Wed, 1 Mar 2023 13:36:29 +0100 Subject: [PATCH 31/49] Allow retrieval of several instances from webfinger --- ...t => GetInstancesViaWebfingerOperation.kt} | 27 ++++++++----------- .../webfinger/services/WebfingerService.kt | 5 ++-- .../implementation/OCWebfingerService.kt | 14 ++++------ 3 files changed, 19 insertions(+), 27 deletions(-) rename owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/{GetOCInstanceViaWebfingerOperation.kt => GetInstancesViaWebfingerOperation.kt} (83%) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetOCInstanceViaWebfingerOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebfingerOperation.kt similarity index 83% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetOCInstanceViaWebfingerOperation.kt rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebfingerOperation.kt index 42ee4b12..8439d0d0 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetOCInstanceViaWebfingerOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebfingerOperation.kt @@ -36,11 +36,11 @@ import com.squareup.moshi.Moshi import timber.log.Timber import java.net.URL -class GetOCInstanceViaWebfingerOperation( +class GetInstancesViaWebfingerOperation( private val lockupServerDomain: String, private val rel: String, private val resource: String, -) : RemoteOperation() { +) : RemoteOperation>() { private fun buildRequestUri() = Uri.parse(lockupServerDomain).buildUpon() @@ -61,30 +61,25 @@ class GetOCInstanceViaWebfingerOperation( method: HttpMethod, response: String?, status: Int - ): RemoteOperationResult { + ): RemoteOperationResult> { Timber.e("Failed requesting webfinger info") if (response != null) { Timber.e("*** status code: $status; response message: $response") } else { Timber.e("*** status code: $status") } - return RemoteOperationResult(method) + return RemoteOperationResult>(method) } - private fun onRequestSuccessful(rawResponse: String): RemoteOperationResult { + private fun onRequestSuccessful(rawResponse: String): RemoteOperationResult> { val response = parseResponse(rawResponse) - for (i in response.links) { - if (i.rel == rel) { - val operationResult = RemoteOperationResult(RemoteOperationResult.ResultCode.OK) - operationResult.data = i.href - return operationResult - } - } - Timber.e("Could not find ownCloud relevant information in webfinger response: $rawResponse") - throw java.lang.Exception("Could not find ownCloud relevant information in webfinger response") + Timber.d("Successful Webfinger request: $response") + val operationResult = RemoteOperationResult>(RemoteOperationResult.ResultCode.OK) + operationResult.data = response.links.map { it.href } + return operationResult } - override fun run(client: OwnCloudClient): RemoteOperationResult { + override fun run(client: OwnCloudClient): RemoteOperationResult> { val requestUri = buildRequestUri() val getMethod = GetMethod(URL(requestUri.toString())) return try { @@ -98,7 +93,7 @@ class GetOCInstanceViaWebfingerOperation( } } catch (e: Exception) { Timber.e(e, "Requesting webfinger info failed") - RemoteOperationResult(e) + RemoteOperationResult>(e) } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebfingerService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebfingerService.kt index 4e057beb..ada5c6d0 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebfingerService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebfingerService.kt @@ -21,9 +21,10 @@ import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.operations.RemoteOperationResult interface WebfingerService { - fun getInstanceFromWebfinger( + fun getInstancesFromWebfinger( lookupServer: String, username: String, + rel: String, client: OwnCloudClient, - ): RemoteOperationResult + ): RemoteOperationResult> } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebfingerService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebfingerService.kt index 3eab83d4..9ea1147b 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebfingerService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebfingerService.kt @@ -19,20 +19,16 @@ package com.owncloud.android.lib.resources.webfinger.services.implementation import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.operations.RemoteOperationResult -import com.owncloud.android.lib.resources.webfinger.GetOCInstanceViaWebfingerOperation +import com.owncloud.android.lib.resources.webfinger.GetInstancesViaWebfingerOperation import com.owncloud.android.lib.resources.webfinger.services.WebfingerService class OCWebfingerService : WebfingerService { - override fun getInstanceFromWebfinger( + override fun getInstancesFromWebfinger( lookupServer: String, username: String, + rel: String, client: OwnCloudClient, - ): RemoteOperationResult = - GetOCInstanceViaWebfingerOperation(lookupServer, OWNCLOUD_REL, username).execute(client) - - companion object { - private const val OWNCLOUD_REL = "http://webfinger.owncloud/rel/server-instance" - } - + ): RemoteOperationResult> = + GetInstancesViaWebfingerOperation(lookupServer, rel, username).execute(client) } From ff90598a2d0fba2b6e6782286bbad179fdc22f7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Wed, 8 Mar 2023 16:38:46 +0100 Subject: [PATCH 32/49] Rename WebFinger classes to make them consistent --- .../webfinger/GetInstancesViaWebfingerOperation.kt | 14 +++++++------- .../webfinger/responses/WebfingerResponse.kt | 4 ++-- .../webfinger/services/WebfingerService.kt | 6 +++--- .../services/implementation/OCWebfingerService.kt | 12 ++++++------ .../webfinger/responses/WebfingerResponseTest.kt | 6 +++--- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebfingerOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebfingerOperation.kt index 8439d0d0..2517b14b 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebfingerOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebfingerOperation.kt @@ -31,12 +31,12 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod import com.owncloud.android.lib.common.http.methods.nonwebdav.HttpMethod import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult -import com.owncloud.android.lib.resources.webfinger.responses.WebfingerJrdResponse +import com.owncloud.android.lib.resources.webfinger.responses.WebFingerResponse import com.squareup.moshi.Moshi import timber.log.Timber import java.net.URL -class GetInstancesViaWebfingerOperation( +class GetInstancesViaWebFingerOperation( private val lockupServerDomain: String, private val rel: String, private val resource: String, @@ -51,9 +51,9 @@ class GetInstancesViaWebfingerOperation( private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK - private fun parseResponse(response: String): WebfingerJrdResponse { + private fun parseResponse(response: String): WebFingerResponse { val moshi = Moshi.Builder().build() - val adapter = moshi.adapter(WebfingerJrdResponse::class.java) + val adapter = moshi.adapter(WebFingerResponse::class.java) return adapter.fromJson(response)!! } @@ -62,7 +62,7 @@ class GetInstancesViaWebfingerOperation( response: String?, status: Int ): RemoteOperationResult> { - Timber.e("Failed requesting webfinger info") + Timber.e("Failed requesting WebFinger info") if (response != null) { Timber.e("*** status code: $status; response message: $response") } else { @@ -73,7 +73,7 @@ class GetInstancesViaWebfingerOperation( private fun onRequestSuccessful(rawResponse: String): RemoteOperationResult> { val response = parseResponse(rawResponse) - Timber.d("Successful Webfinger request: $response") + Timber.d("Successful WebFinger request: $response") val operationResult = RemoteOperationResult>(RemoteOperationResult.ResultCode.OK) operationResult.data = response.links.map { it.href } return operationResult @@ -92,7 +92,7 @@ class GetInstancesViaWebfingerOperation( onResultUnsuccessful(getMethod, response, status) } } catch (e: Exception) { - Timber.e(e, "Requesting webfinger info failed") + Timber.e(e, "Requesting WebFinger info failed") RemoteOperationResult>(e) } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponse.kt index 45e85a75..d7e5a6bb 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponse.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponse.kt @@ -27,13 +27,13 @@ package com.owncloud.android.lib.resources.webfinger.responses import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -data class WebfingerJrdResponse( +data class WebFingerResponse( val subject: String, val links: List ) @JsonClass(generateAdapter = true) data class LinkItem( + val rel: String, val href: String, - val rel: String ) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebfingerService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebfingerService.kt index ada5c6d0..f12e87fa 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebfingerService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebfingerService.kt @@ -20,10 +20,10 @@ package com.owncloud.android.lib.resources.webfinger.services import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.operations.RemoteOperationResult -interface WebfingerService { - fun getInstancesFromWebfinger( +interface WebFingerService { + fun getInstancesFromWebFinger( lookupServer: String, - username: String, + resource: String, rel: String, client: OwnCloudClient, ): RemoteOperationResult> diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebfingerService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebfingerService.kt index 9ea1147b..3f0ac4d9 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebfingerService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebfingerService.kt @@ -19,16 +19,16 @@ package com.owncloud.android.lib.resources.webfinger.services.implementation import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.operations.RemoteOperationResult -import com.owncloud.android.lib.resources.webfinger.GetInstancesViaWebfingerOperation -import com.owncloud.android.lib.resources.webfinger.services.WebfingerService +import com.owncloud.android.lib.resources.webfinger.GetInstancesViaWebFingerOperation +import com.owncloud.android.lib.resources.webfinger.services.WebFingerService -class OCWebfingerService : WebfingerService { +class OCWebFingerService : WebFingerService { - override fun getInstancesFromWebfinger( + override fun getInstancesFromWebFinger( lookupServer: String, - username: String, + resource: String, rel: String, client: OwnCloudClient, ): RemoteOperationResult> = - GetInstancesViaWebfingerOperation(lookupServer, rel, username).execute(client) + GetInstancesViaWebFingerOperation(lookupServer, rel, resource).execute(client) } diff --git a/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponseTest.kt b/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponseTest.kt index 2d0c6235..bed95002 100644 --- a/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponseTest.kt +++ b/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponseTest.kt @@ -8,15 +8,15 @@ import org.junit.Before import org.junit.Test import java.io.File -class WebfingerResponseTest { - lateinit var adapter: JsonAdapter +class WebFingerResponseTest { + lateinit var adapter: JsonAdapter private fun loadResponses(fileName: String) = adapter.fromJson(File(fileName).readText()) @Before fun prepare() { val moshi = Moshi.Builder().build() - adapter = moshi.adapter(WebfingerJrdResponse::class.java) + adapter = moshi.adapter(WebFingerResponse::class.java) } @Test From b660ee98fd3e667d283a6004022435aa1be95c61 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Thu, 9 Mar 2023 09:37:09 +0100 Subject: [PATCH 33/49] Rename files to be the same as the classes they contain --- .../responses/{WebfingerResponse.kt => WebFingerResponse.kt} | 0 .../services/{WebfingerService.kt => WebFingerService.kt} | 0 .../{OCWebfingerService.kt => OCWebFingerService.kt} | 0 .../{WebfingerResponseTest.kt => WebFingerResponseTest.kt} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/{WebfingerResponse.kt => WebFingerResponse.kt} (100%) rename owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/{WebfingerService.kt => WebFingerService.kt} (100%) rename owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/{OCWebfingerService.kt => OCWebFingerService.kt} (100%) rename owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/{WebfingerResponseTest.kt => WebFingerResponseTest.kt} (100%) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponse.kt similarity index 100% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponse.kt rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponse.kt diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebfingerService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebFingerService.kt similarity index 100% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebfingerService.kt rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/WebFingerService.kt diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebfingerService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebFingerService.kt similarity index 100% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebfingerService.kt rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/services/implementation/OCWebFingerService.kt diff --git a/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponseTest.kt b/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponseTest.kt similarity index 100% rename from owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebfingerResponseTest.kt rename to owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponseTest.kt From 159dcd6d68983ba63db235819061531f29558e62 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Thu, 9 Mar 2023 09:43:07 +0100 Subject: [PATCH 34/49] Rename file to be the same as the class it contains --- ...WebfingerOperation.kt => GetInstancesViaWebFingerOperation.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/{GetInstancesViaWebfingerOperation.kt => GetInstancesViaWebFingerOperation.kt} (100%) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebfingerOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebFingerOperation.kt similarity index 100% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebfingerOperation.kt rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebFingerOperation.kt From 6846e25fa31b44a54dabd10262e66d5d99e32980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Thu, 9 Mar 2023 11:50:54 +0100 Subject: [PATCH 35/49] Replace kapt with ksp --- build.gradle | 5 +++++ owncloudComLibrary/build.gradle | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 28bdd05b..29330f17 100644 --- a/build.gradle +++ b/build.gradle @@ -16,6 +16,10 @@ buildscript { } } +plugins { + id 'com.google.devtools.ksp' version '1.8.10-1.0.9' apply false +} + allprojects { repositories { google() @@ -26,4 +30,5 @@ allprojects { subprojects { apply plugin: "org.jlleitschuh.gradle.ktlint" + apply plugin: "com.google.devtools.ksp" } diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index 1df5440b..40bb8c6d 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -1,6 +1,6 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-kapt' +apply plugin: 'com.google.devtools.ksp' apply plugin: 'kotlin-parcelize' dependencies { @@ -14,7 +14,7 @@ dependencies { exclude module: "kotlin-reflect" } implementation 'org.apache.commons:commons-lang3:3.12.0' - kapt "com.squareup.moshi:moshi-kotlin-codegen:$comSquareupMoshi" + ksp "com.squareup.moshi:moshi-kotlin-codegen:$comSquareupMoshi" testImplementation 'junit:junit:4.13.2' testImplementation 'org.robolectric:robolectric:4.9.2' From c53475da37d15271d45604df65f3e3fc67e69021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Fri, 10 Mar 2023 12:47:35 +0100 Subject: [PATCH 36/49] Removing quotas from webdav properties in regular propfinds --- .../common/http/methods/webdav/DavUtils.kt | 29 +++++++++++++++++-- .../CheckPathExistenceRemoteOperation.kt | 4 +-- .../files/GetBaseUrlRemoteOperation.kt | 2 +- .../files/ReadRemoteFileOperation.kt | 2 +- .../files/ReadRemoteFolderOperation.kt | 2 +- .../android/lib/resources/files/RemoteFile.kt | 11 ------- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavUtils.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavUtils.kt index a48626d3..ce772609 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavUtils.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavUtils.kt @@ -24,13 +24,36 @@ package com.owncloud.android.lib.common.http.methods.webdav import at.bitfire.dav4jvm.Property -import at.bitfire.dav4jvm.PropertyUtils.getAllPropSet import at.bitfire.dav4jvm.PropertyUtils.getQuotaPropset +import at.bitfire.dav4jvm.property.CreationDate +import at.bitfire.dav4jvm.property.DisplayName +import at.bitfire.dav4jvm.property.GetContentLength +import at.bitfire.dav4jvm.property.GetContentType +import at.bitfire.dav4jvm.property.GetETag +import at.bitfire.dav4jvm.property.GetLastModified +import at.bitfire.dav4jvm.property.OCId +import at.bitfire.dav4jvm.property.OCPermissions +import at.bitfire.dav4jvm.property.OCPrivatelink +import at.bitfire.dav4jvm.property.OCSize +import at.bitfire.dav4jvm.property.ResourceType import com.owncloud.android.lib.common.http.methods.webdav.properties.OCShareTypes object DavUtils { - @JvmStatic val allPropset: Array - get() = getAllPropSet().plus(OCShareTypes.NAME) + @JvmStatic val allPropSet: Array + get() = arrayOf( + DisplayName.NAME, + GetContentType.NAME, + ResourceType.NAME, + GetContentLength.NAME, + GetLastModified.NAME, + CreationDate.NAME, + GetETag.NAME, + OCPermissions.NAME, + OCId.NAME, + OCSize.NAME, + OCPrivatelink.NAME, + OCShareTypes.NAME, + ) val quotaPropSet: Array get() = getQuotaPropset() 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 index dd7d0a56..da9b685f 100644 --- 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 @@ -25,7 +25,7 @@ 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.allPropset +import com.owncloud.android.lib.common.http.methods.webdav.DavUtils.allPropSet 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 @@ -59,7 +59,7 @@ class CheckPathExistenceRemoteOperation( val stringUrl = baseStringUrl + WebdavUtils.encodePath(remotePath) return try { - val propFindMethod = PropfindMethod(URL(stringUrl), 0, allPropset).apply { + val propFindMethod = PropfindMethod(URL(stringUrl), 0, allPropSet).apply { setReadTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS) setConnectionTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS) } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/GetBaseUrlRemoteOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/GetBaseUrlRemoteOperation.kt index 904a9bea..65a8faf9 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/GetBaseUrlRemoteOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/GetBaseUrlRemoteOperation.kt @@ -44,7 +44,7 @@ class GetBaseUrlRemoteOperation : RemoteOperation() { return try { val stringUrl = client.baseFilesWebDavUri.toString() - val propFindMethod = PropfindMethod(URL(stringUrl), 0, DavUtils.allPropset).apply { + val propFindMethod = PropfindMethod(URL(stringUrl), 0, DavUtils.allPropSet).apply { setReadTimeout(TIMEOUT, TimeUnit.SECONDS) setConnectionTimeout(TIMEOUT, TimeUnit.SECONDS) } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.kt index cf29b60e..787fb751 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFileOperation.kt @@ -62,7 +62,7 @@ class ReadRemoteFileOperation( val propFind = PropfindMethod( url = getFinalWebDavUrl(), depth = DEPTH_0, - propertiesToRequest = DavUtils.allPropset + propertiesToRequest = DavUtils.allPropSet ).apply { setReadTimeout(SYNC_READ_TIMEOUT, TimeUnit.SECONDS) setConnectionTimeout(SYNC_CONNECTION_TIMEOUT, TimeUnit.SECONDS) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt index 16600fe1..da1dcac6 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/ReadRemoteFolderOperation.kt @@ -64,7 +64,7 @@ class ReadRemoteFolderOperation( val propfindMethod = PropfindMethod( getFinalWebDavUrl(), DavConstants.DEPTH_1, - DavUtils.allPropset + DavUtils.allPropSet ) val status = client.executeHttpMethod(propfindMethod) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.kt index 791a0765..16ec6748 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/RemoteFile.kt @@ -39,8 +39,6 @@ import at.bitfire.dav4jvm.property.OCId import at.bitfire.dav4jvm.property.OCPermissions import at.bitfire.dav4jvm.property.OCPrivatelink import at.bitfire.dav4jvm.property.OCSize -import at.bitfire.dav4jvm.property.QuotaAvailableBytes -import at.bitfire.dav4jvm.property.QuotaUsedBytes import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.http.HttpConstants import com.owncloud.android.lib.common.http.methods.webdav.properties.OCShareTypes @@ -51,7 +49,6 @@ import kotlinx.parcelize.Parcelize import okhttp3.HttpUrl import timber.log.Timber import java.io.File -import java.math.BigDecimal /** * Contains the data of a Remote File from a WebDavEntry @@ -73,8 +70,6 @@ data class RemoteFile( var permissions: String? = null, var remoteId: String? = null, var size: Long = 0, - var quotaUsedBytes: BigDecimal? = null, - var quotaAvailableBytes: BigDecimal? = null, var privateLink: String? = null, var owner: String, var sharedByLink: Boolean = false, @@ -137,12 +132,6 @@ data class RemoteFile( is OCSize -> { remoteFile.size = property.size } - is QuotaUsedBytes -> { - remoteFile.quotaUsedBytes = BigDecimal.valueOf(property.quotaUsedBytes) - } - is QuotaAvailableBytes -> { - remoteFile.quotaAvailableBytes = BigDecimal.valueOf(property.quotaAvailableBytes) - } is OCPrivatelink -> { remoteFile.privateLink = property.link } From 1f93cfaf527147570484e62be5ea4c56452174a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Thu, 16 Mar 2023 13:06:00 +0100 Subject: [PATCH 37/49] Bump target sdk to 33 --- owncloudComLibrary/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index 40bb8c6d..6aaacfd4 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -26,7 +26,7 @@ android { defaultConfig { minSdkVersion 21 - targetSdkVersion 31 + targetSdkVersion 33 } lint { From 3681f1001a0e55ec8c092fe2e99a0ac0767bbdb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Wed, 22 Mar 2023 15:23:57 +0100 Subject: [PATCH 38/49] Remove permission parsing from spaces. Will be done via WebDav permissions --- .../spaces/responses/SpacesResponse.kt | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt index 6ce50498..213e8871 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/spaces/responses/SpacesResponse.kt @@ -61,7 +61,6 @@ data class QuotaResponse( data class RootResponse( val eTag: String?, val id: String, - val permissions: List?, val webDavUrl: String, val deleted: DeleteResponse?, ) @@ -88,38 +87,11 @@ data class FileResponse( val mimeType: String ) -@JsonClass(generateAdapter = true) -data class IdentityPermissionResponse( - val id: String, - val displayName: String?, -) - -@JsonClass(generateAdapter = true) -data class GrantedToIdentitiesResponse( - val user: IdentityPermissionResponse?, - val group: IdentityPermissionResponse?, -) - @JsonClass(generateAdapter = true) data class DeleteResponse( val state: String, ) -@JsonClass(generateAdapter = true) -data class PermissionResponse( - val grantedTo: List?, - val grantedToIdentities: List?, - val roles: List, -) { - /** - * Supports api renaming from grantedTo to grantedToIdentities on v1.0.1 - * https://github.com/owncloud/libre-graph-api/releases/tag/v1.0.1 - */ - fun getGrantedToIdentitiesResponse(): List { - return grantedToIdentities ?: grantedTo ?: throw IllegalArgumentException("Permissions not granted to anyone") - } -} - @JsonClass(generateAdapter = true) data class SpecialFolderResponse( val name: String From c429b575a9e5e4c64b8015d9028d434f4179e773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Tue, 21 Mar 2023 18:26:20 +0100 Subject: [PATCH 39/49] Add accept language header to all requests --- .../java/com/owncloud/android/lib/common/OwnCloudClient.java | 2 ++ .../com/owncloud/android/lib/common/http/HttpConstants.java | 1 + 2 files changed, 3 insertions(+) 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 1281ec13..c8c3ca11 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 @@ -43,6 +43,7 @@ import timber.log.Timber; import java.io.IOException; import java.io.InputStream; import java.util.List; +import java.util.Locale; import static com.owncloud.android.lib.common.http.HttpConstants.AUTHORIZATION_HEADER; import static com.owncloud.android.lib.common.http.HttpConstants.HTTP_MOVED_PERMANENTLY; @@ -128,6 +129,7 @@ public class OwnCloudClient extends HttpClient { Timber.d("Executing in request with id %s", requestId); method.setRequestHeader(HttpConstants.OC_X_REQUEST_ID, requestId); method.setRequestHeader(HttpConstants.USER_AGENT_HEADER, SingleSessionManager.getUserAgent()); + method.setRequestHeader(HttpConstants.ACCEPT_LANGUAGE_HEADER, Locale.getDefault().getLanguage()); method.setRequestHeader(HttpConstants.ACCEPT_ENCODING_HEADER, HttpConstants.ACCEPT_ENCODING_IDENTITY); if (mCredentials.getHeaderAuth() != null && !mCredentials.getHeaderAuth().isEmpty()) { method.setRequestHeader(AUTHORIZATION_HEADER, mCredentials.getHeaderAuth()); 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 8978a556..475c6c3f 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 @@ -40,6 +40,7 @@ public class HttpConstants { public static final String IF_MATCH_HEADER = "If-Match"; public static final String IF_NONE_MATCH_HEADER = "If-None-Match"; public static final String CONTENT_TYPE_HEADER = "Content-Type"; + public static final String ACCEPT_LANGUAGE_HEADER = "Accept-Language"; public static final String CONTENT_LENGTH_HEADER = "Content-Length"; public static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length"; public static final String OC_X_OC_MTIME_HEADER = "X-OC-Mtime"; From 14baadd7ea7717cdaf2ecb904ec039e8d787db1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Fri, 31 Mar 2023 09:41:57 +0200 Subject: [PATCH 40/49] Webfinger calls won't follow redirections. Only working with 2XX --- .../webfinger/GetInstancesViaWebFingerOperation.kt | 6 +++++- .../lib/resources/webfinger/responses/WebFingerResponse.kt | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebFingerOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebFingerOperation.kt index 2517b14b..0a19b5e8 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebFingerOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/GetInstancesViaWebFingerOperation.kt @@ -75,13 +75,17 @@ class GetInstancesViaWebFingerOperation( val response = parseResponse(rawResponse) Timber.d("Successful WebFinger request: $response") val operationResult = RemoteOperationResult>(RemoteOperationResult.ResultCode.OK) - operationResult.data = response.links.map { it.href } + operationResult.data = response.links?.map { it.href } ?: listOf() return operationResult } override fun run(client: OwnCloudClient): RemoteOperationResult> { val requestUri = buildRequestUri() val getMethod = GetMethod(URL(requestUri.toString())) + + // First iteration won't follow redirections. + getMethod.followRedirects = false + return try { val status = client.executeHttpMethod(getMethod) val response = getMethod.getResponseBodyAsString()!! diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponse.kt index d7e5a6bb..aeb6af8f 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponse.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponse.kt @@ -29,7 +29,7 @@ import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) data class WebFingerResponse( val subject: String, - val links: List + val links: List? ) @JsonClass(generateAdapter = true) From 3a27baad3a0fbe4316bce0f924f8a04e9bb8ce63 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Tue, 4 Apr 2023 11:51:06 +0200 Subject: [PATCH 41/49] Fix WebfingerResponse tests --- .../webfinger/responses/WebFingerResponseTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponseTest.kt b/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponseTest.kt index bed95002..4b275cd7 100644 --- a/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponseTest.kt +++ b/owncloudComLibrary/src/test/java/com/owncloud/android/lib/resources/webfinger/responses/WebFingerResponseTest.kt @@ -22,20 +22,20 @@ class WebFingerResponseTest { @Test fun `check rel in too much information - ok`() { val response = loadResponses(TOO_MUCH_INFORMATION_JSON)!! - Assert.assertEquals("https://gast.somedomain.de", response.links[0].href) - Assert.assertEquals("http://webfinger.owncloud/rel/server-instance", response.links[0].rel) + Assert.assertEquals("https://gast.somedomain.de", response.links!![0].href) + Assert.assertEquals("http://webfinger.owncloud/rel/server-instance", response.links!![0].rel) } @Test(expected = JsonDataException::class) fun `check key value pairs - ko - no href key`() { val response = loadResponses(BROKEN_JSON)!! - Assert.assertEquals("https://gast.somedomain.de", response.links[0].href) + Assert.assertEquals("https://gast.somedomain.de", response.links!![0].href) } @Test(expected = JsonDataException::class) fun `check key value pairs - ko - no rel key`() { val response = loadResponses(BROKEN_JSON)!! - Assert.assertEquals("https://gast.somedomain.de", response.links[0].href) + Assert.assertEquals("https://gast.somedomain.de", response.links!![0].href) } companion object { From 173b12eeca2416dbdef5da239c012a84d1b85df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Fri, 24 Mar 2023 12:52:11 +0100 Subject: [PATCH 42/49] Retrieve the list of available apps to open in web --- .../GetRemoteAppRegistryOperation.kt | 82 +++++++++++++++++++ .../responses/AppRegistryResponse.kt | 56 +++++++++++++ .../services/AppRegistryService.kt | 31 +++++++ .../services/OCAppRegistryService.kt | 33 ++++++++ 4 files changed, 202 insertions(+) create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetRemoteAppRegistryOperation.kt create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/responses/AppRegistryResponse.kt create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetRemoteAppRegistryOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetRemoteAppRegistryOperation.kt new file mode 100644 index 00000000..60367ff0 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetRemoteAppRegistryOperation.kt @@ -0,0 +1,82 @@ +/* ownCloud Android Library is available under MIT license + * @author Abel García de Prada + * + * Copyright (C) 2023 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.appregistry + +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.OK +import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryResponse +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.Moshi +import timber.log.Timber +import java.net.URL + +class GetRemoteAppRegistryOperation : RemoteOperation() { + + override fun run(client: OwnCloudClient): RemoteOperationResult { + var result: RemoteOperationResult + + try { + val uriBuilder = client.baseUri.buildUpon().apply { + appendEncodedPath(APP_REGISTRY_ENDPOINT) + } + val getMethod = GetMethod(URL(uriBuilder.build().toString())) + val status = client.executeHttpMethod(getMethod) + + val response = getMethod.getResponseBodyAsString() + + if (status == HttpConstants.HTTP_OK) { + Timber.d("Successful response $response") + + // Parse the response + val moshi: Moshi = Moshi.Builder().build() + val adapter: JsonAdapter = moshi.adapter(AppRegistryResponse::class.java) + val appRegistryResponse: AppRegistryResponse = response?.let { adapter.fromJson(it) } ?: AppRegistryResponse(value = emptyList()) + + result = RemoteOperationResult(OK) + result.data = appRegistryResponse + + Timber.d("Get AppRegistry completed and parsed to ${result.data}") + } else { + result = RemoteOperationResult(getMethod) + Timber.e("Failed response while getting app registry from the server status code: $status; response message: $response") + } + + } catch (e: Exception) { + result = RemoteOperationResult(e) + Timber.e(e, "Exception while getting app registry") + } + + return result + } + + companion object { + private const val APP_REGISTRY_ENDPOINT = "app/list" + } +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/responses/AppRegistryResponse.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/responses/AppRegistryResponse.kt new file mode 100644 index 00000000..f3f247d9 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/responses/AppRegistryResponse.kt @@ -0,0 +1,56 @@ +/* ownCloud Android Library is available under MIT license + * @author Abel García de Prada + * + * Copyright (C) 2023 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.appregistry.responses + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class AppRegistryResponse( + @Json(name = "mime-types") + val value: List +) + +@JsonClass(generateAdapter = true) +data class AppRegistryMimeTypeResponse( + @Json(name = "mime_type") val mimeType: String, + val ext: String? = null, + @Json(name = "app_providers") + val appProviders: List, + val name: String? = null, + val icon: String? = null, + val description: String? = null, + @Json(name = "allow_creation") + val allowCreation: Boolean? = null, + @Json(name = "default_application") + val defaultApplication: String? = null +) + +@JsonClass(generateAdapter = true) +data class AppRegistryProviderResponse( + val name: String, + val icon: String, +) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt new file mode 100644 index 00000000..3950faab --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt @@ -0,0 +1,31 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2023 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.appregistry.services + +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.Service +import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryResponse + +interface AppRegistryService : Service { + fun getAppRegistry(): RemoteOperationResult +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt new file mode 100644 index 00000000..e0d93a33 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt @@ -0,0 +1,33 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2023 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.appregistry.services + +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryResponse +import com.owncloud.android.lib.resources.appregistry.GetRemoteAppRegistryOperation + +class OCAppRegistryService(override val client: OwnCloudClient) : AppRegistryService { + override fun getAppRegistry(): RemoteOperationResult = + GetRemoteAppRegistryOperation().execute(client) +} From 2ac5cf0657a833757e01c1049c8bee88ad6f4191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Fri, 24 Mar 2023 14:56:14 +0100 Subject: [PATCH 43/49] Move open in web operations to their proper location --- .../GetUrlToOpenInWebRemoteOperation.kt | 4 ++-- .../resources/appregistry/services/AppRegistryService.kt | 2 ++ .../resources/appregistry/services/OCAppRegistryService.kt | 6 +++++- .../android/lib/resources/files/services/FileService.kt | 2 -- .../files/services/implementation/OCFileService.kt | 5 ----- 5 files changed, 9 insertions(+), 10 deletions(-) rename owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/{files => appregistry}/GetUrlToOpenInWebRemoteOperation.kt (95%) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/GetUrlToOpenInWebRemoteOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetUrlToOpenInWebRemoteOperation.kt similarity index 95% rename from owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/GetUrlToOpenInWebRemoteOperation.kt rename to owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetUrlToOpenInWebRemoteOperation.kt index b36cb760..9a9c1c5c 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/GetUrlToOpenInWebRemoteOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetUrlToOpenInWebRemoteOperation.kt @@ -21,7 +21,7 @@ * THE SOFTWARE. * */ -package com.owncloud.android.lib.resources.files +package com.owncloud.android.lib.resources.appregistry import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.http.HttpConstants @@ -30,7 +30,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.files.GetUrlToOpenInWebRemoteOperation.OpenInWebParams.Companion.PARAM_FILE_ID +import com.owncloud.android.lib.resources.appregistry.GetUrlToOpenInWebRemoteOperation.OpenInWebParams.Companion.PARAM_FILE_ID import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonClass import com.squareup.moshi.Moshi diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt index 3950faab..23cd9e70 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt @@ -28,4 +28,6 @@ import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryRespo interface AppRegistryService : Service { fun getAppRegistry(): RemoteOperationResult + + fun getUrlToOpenInWeb(openWebEndpoint: String, fileId: String): RemoteOperationResult } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt index e0d93a33..22209219 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt @@ -24,10 +24,14 @@ package com.owncloud.android.lib.resources.appregistry.services import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.operations.RemoteOperationResult -import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryResponse import com.owncloud.android.lib.resources.appregistry.GetRemoteAppRegistryOperation +import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryResponse +import com.owncloud.android.lib.resources.appregistry.GetUrlToOpenInWebRemoteOperation class OCAppRegistryService(override val client: OwnCloudClient) : AppRegistryService { override fun getAppRegistry(): RemoteOperationResult = GetRemoteAppRegistryOperation().execute(client) + + override fun getUrlToOpenInWeb(openWebEndpoint: String, fileId: String): RemoteOperationResult = + GetUrlToOpenInWebRemoteOperation(openWithWebEndpoint = openWebEndpoint, fileId = fileId).execute(client) } 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 index 1421648b..b524dc3f 100644 --- 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 @@ -28,8 +28,6 @@ import com.owncloud.android.lib.resources.Service import com.owncloud.android.lib.resources.files.RemoteFile interface FileService : Service { - fun getUrlToOpenInWeb(openWebEndpoint: String, fileId: String): RemoteOperationResult - fun checkPathExistence( path: String, isUserLogged: Boolean, 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 index 8ec44d46..7b86a4fa 100644 --- 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 @@ -29,7 +29,6 @@ import com.owncloud.android.lib.resources.files.CheckPathExistenceRemoteOperatio import com.owncloud.android.lib.resources.files.CopyRemoteFileOperation import com.owncloud.android.lib.resources.files.CreateRemoteFolderOperation import com.owncloud.android.lib.resources.files.DownloadRemoteFileOperation -import com.owncloud.android.lib.resources.files.GetUrlToOpenInWebRemoteOperation import com.owncloud.android.lib.resources.files.MoveRemoteFileOperation import com.owncloud.android.lib.resources.files.ReadRemoteFileOperation import com.owncloud.android.lib.resources.files.ReadRemoteFolderOperation @@ -39,7 +38,6 @@ import com.owncloud.android.lib.resources.files.RenameRemoteFileOperation import com.owncloud.android.lib.resources.files.services.FileService class OCFileService(override val client: OwnCloudClient) : FileService { - override fun checkPathExistence( path: String, isUserLogged: Boolean, @@ -51,9 +49,6 @@ class OCFileService(override val client: OwnCloudClient) : FileService { spaceWebDavUrl = spaceWebDavUrl, ).execute(client) - override fun getUrlToOpenInWeb(openWebEndpoint: String, fileId: String): RemoteOperationResult = - GetUrlToOpenInWebRemoteOperation(openWithWebEndpoint = openWebEndpoint, fileId = fileId).execute(client) - override fun copyFile( sourceRemotePath: String, targetRemotePath: String, From f35daacdf18529a7ad62c42df11285bb68b1c043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Mon, 27 Mar 2023 08:39:29 +0200 Subject: [PATCH 44/49] Pleasure the lint --- .../lib/resources/appregistry/services/OCAppRegistryService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt index 22209219..595f7895 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt @@ -25,8 +25,8 @@ package com.owncloud.android.lib.resources.appregistry.services import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.resources.appregistry.GetRemoteAppRegistryOperation -import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryResponse import com.owncloud.android.lib.resources.appregistry.GetUrlToOpenInWebRemoteOperation +import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryResponse class OCAppRegistryService(override val client: OwnCloudClient) : AppRegistryService { override fun getAppRegistry(): RemoteOperationResult = From 393ec6e07e12783ee6f5f5f8b7d2d75b7a9ba0ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abel=20Garc=C3=ADa=20de=20Prada?= Date: Tue, 28 Mar 2023 10:32:24 +0200 Subject: [PATCH 45/49] Open file in web with a specific app --- .../GetUrlToOpenInWebRemoteOperation.kt | 18 +++++++++++++----- .../appregistry/services/AppRegistryService.kt | 6 +++++- .../services/OCAppRegistryService.kt | 8 ++++++-- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetUrlToOpenInWebRemoteOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetUrlToOpenInWebRemoteOperation.kt index 9a9c1c5c..422db268 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetUrlToOpenInWebRemoteOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetUrlToOpenInWebRemoteOperation.kt @@ -30,7 +30,6 @@ 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.appregistry.GetUrlToOpenInWebRemoteOperation.OpenInWebParams.Companion.PARAM_FILE_ID import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonClass import com.squareup.moshi.Moshi @@ -43,14 +42,16 @@ import java.util.concurrent.TimeUnit class GetUrlToOpenInWebRemoteOperation( val openWithWebEndpoint: String, val fileId: String, + val appName: String, ) : RemoteOperation() { override fun run(client: OwnCloudClient): RemoteOperationResult { return try { - val openInWebRequestBody = OpenInWebParams(fileId).toRequestBody() + val openInWebRequestBody = OpenInWebParams(fileId, appName).toRequestBody() - val stringUrl = client.baseUri.toString() + WebdavUtils.encodePath(openWithWebEndpoint) + "?$PARAM_FILE_ID=$fileId" + val stringUrl = + client.baseUri.toString() + WebdavUtils.encodePath(openWithWebEndpoint) val postMethod = PostMethod(URL(stringUrl), openInWebRequestBody).apply { setReadTimeout(TIMEOUT, TimeUnit.MILLISECONDS) @@ -77,12 +78,19 @@ class GetUrlToOpenInWebRemoteOperation( private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_MULTI_STATUS - data class OpenInWebParams(val fileId: String) { + data class OpenInWebParams( + val fileId: String, + val appName: String, + ) { fun toRequestBody(): RequestBody = - FormBody.Builder().build() + FormBody.Builder() + .add(PARAM_FILE_ID, fileId) + .add(PARAM_APP_NAME, appName) + .build() companion object { const val PARAM_FILE_ID = "file_id" + const val PARAM_APP_NAME = "app_name" } } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt index 23cd9e70..4b94f1f7 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt @@ -29,5 +29,9 @@ import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryRespo interface AppRegistryService : Service { fun getAppRegistry(): RemoteOperationResult - fun getUrlToOpenInWeb(openWebEndpoint: String, fileId: String): RemoteOperationResult + fun getUrlToOpenInWeb( + openWebEndpoint: String, + fileId: String, + appName: String, + ): RemoteOperationResult } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt index 595f7895..f80fe821 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt @@ -32,6 +32,10 @@ class OCAppRegistryService(override val client: OwnCloudClient) : AppRegistrySer override fun getAppRegistry(): RemoteOperationResult = GetRemoteAppRegistryOperation().execute(client) - override fun getUrlToOpenInWeb(openWebEndpoint: String, fileId: String): RemoteOperationResult = - GetUrlToOpenInWebRemoteOperation(openWithWebEndpoint = openWebEndpoint, fileId = fileId).execute(client) + override fun getUrlToOpenInWeb(openWebEndpoint: String, fileId: String, appName: String): RemoteOperationResult = + GetUrlToOpenInWebRemoteOperation( + openWithWebEndpoint = openWebEndpoint, + fileId = fileId, + appName = appName + ).execute(client) } From 15bccd3f80e9bcc2f2284df2226939740322a387 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Apr 2023 02:57:14 +0000 Subject: [PATCH 46/49] Bump org.robolectric:robolectric from 4.9.2 to 4.10 Bumps [org.robolectric:robolectric](https://github.com/robolectric/robolectric) from 4.9.2 to 4.10. - [Release notes](https://github.com/robolectric/robolectric/releases) - [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.9.2...robolectric-4.10) --- updated-dependencies: - dependency-name: org.robolectric:robolectric dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- owncloudComLibrary/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index 6aaacfd4..e626c033 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -17,7 +17,7 @@ dependencies { ksp "com.squareup.moshi:moshi-kotlin-codegen:$comSquareupMoshi" testImplementation 'junit:junit:4.13.2' - testImplementation 'org.robolectric:robolectric:4.9.2' + testImplementation 'org.robolectric:robolectric:4.10' debugImplementation 'com.facebook.stetho:stetho-okhttp3:1.6.0' } From 17aa1ea7bd5adbdac59b02f21a08d48f7f41f0e1 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Tue, 11 Apr 2023 08:57:21 +0200 Subject: [PATCH 47/49] Introduce new error message for ProtocolException --- .../lib/common/operations/RemoteOperationResult.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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 5d849b08..b56db410 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 @@ -46,6 +46,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.net.MalformedURLException; +import java.net.ProtocolException; import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; @@ -166,7 +167,10 @@ public class RemoteOperationResult } else if (e instanceof FileNotFoundException) { mCode = ResultCode.LOCAL_FILE_NOT_FOUND; - } else { + } else if (e instanceof ProtocolException) { + mCode = ResultCode.NETWORK_ERROR; + } + else { mCode = ResultCode.UNKNOWN_ERROR; } } @@ -589,5 +593,6 @@ public class RemoteOperationResult SPECIFIC_METHOD_NOT_ALLOWED, SPECIFIC_BAD_REQUEST, TOO_EARLY, + NETWORK_ERROR, } } From ab3a594e5c2ecd0d39781ebe0fae5cde2876bff3 Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Fri, 14 Apr 2023 11:02:21 +0200 Subject: [PATCH 48/49] Create network call to create file via app provider --- ...reateRemoteFileWithAppProviderOperation.kt | 108 ++++++++++++++++++ .../GetUrlToOpenInWebRemoteOperation.kt | 11 +- .../services/AppRegistryService.kt | 7 ++ .../services/OCAppRegistryService.kt | 13 +++ 4 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/CreateRemoteFileWithAppProviderOperation.kt diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/CreateRemoteFileWithAppProviderOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/CreateRemoteFileWithAppProviderOperation.kt new file mode 100644 index 00000000..e4f85a32 --- /dev/null +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/CreateRemoteFileWithAppProviderOperation.kt @@ -0,0 +1,108 @@ +/* ownCloud Android Library is available under MIT license + * Copyright (C) 2023 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.appregistry + +import com.owncloud.android.lib.common.OwnCloudClient +import com.owncloud.android.lib.common.http.HttpConstants +import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod +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.squareup.moshi.Json +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonClass +import com.squareup.moshi.Moshi +import okhttp3.FormBody +import okhttp3.RequestBody +import timber.log.Timber +import java.net.URL +import java.util.concurrent.TimeUnit + +class CreateRemoteFileWithAppProviderOperation( + private val createFileWithAppProviderEndpoint: String, + private val parentContainerId: String, + private val filename: String, +) : RemoteOperation() { + + override fun run(client: OwnCloudClient): RemoteOperationResult { + return try { + + val createFileWithAppProviderRequestBody = CreateFileWithAppProviderParams(parentContainerId, filename) + .toRequestBody() + + val stringUrl = client.baseUri.toString() + WebdavUtils.encodePath(createFileWithAppProviderEndpoint) + + val postMethod = PostMethod(URL(stringUrl), createFileWithAppProviderRequestBody).apply { + setReadTimeout(TIMEOUT, TimeUnit.MILLISECONDS) + setConnectionTimeout(TIMEOUT, TimeUnit.MILLISECONDS) + } + + val status = client.executeHttpMethod(postMethod) + Timber.d("Create file $filename with app provider in folder with ID $parentContainerId - $status${if (!isSuccess(status)) "(FAIL)" else ""}") + + if (isSuccess(status)) RemoteOperationResult(ResultCode.OK).apply { + val moshi = Moshi.Builder().build() + val adapter: JsonAdapter = moshi.adapter(CreateFileWithAppProviderResponse::class.java) + + data = postMethod.getResponseBodyAsString()?.let { adapter.fromJson(it)!!.fileId } + } + else RemoteOperationResult(postMethod).apply { data = "" } + + } catch (e: Exception) { + val result = RemoteOperationResult(e) + Timber.e(e, "Create file $filename with app provider in folder with ID $parentContainerId failed") + result + } + } + + private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK + + data class CreateFileWithAppProviderParams( + val parentContainerId: String, + val filename: String, + ) { + fun toRequestBody(): RequestBody = + FormBody.Builder() + .add(PARAM_PARENT_CONTAINER_ID, parentContainerId) + .add(PARAM_FILENAME, filename) + .build() + + companion object { + const val PARAM_PARENT_CONTAINER_ID = "parent_container_id" + const val PARAM_FILENAME = "filename" + } + } + + @JsonClass(generateAdapter = true) + data class CreateFileWithAppProviderResponse( + @Json(name = "file_id") + val fileId: String, + ) + + companion object { + private const val TIMEOUT: Long = 5_000 + } +} diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetUrlToOpenInWebRemoteOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetUrlToOpenInWebRemoteOperation.kt index 422db268..84b32514 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetUrlToOpenInWebRemoteOperation.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/GetUrlToOpenInWebRemoteOperation.kt @@ -1,5 +1,5 @@ /* ownCloud Android Library is available under MIT license -* Copyright (C) 2022 ownCloud GmbH. +* Copyright (C) 2023 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 @@ -21,6 +21,7 @@ * THE SOFTWARE. * */ + package com.owncloud.android.lib.resources.appregistry import com.owncloud.android.lib.common.OwnCloudClient @@ -40,9 +41,9 @@ import java.net.URL import java.util.concurrent.TimeUnit class GetUrlToOpenInWebRemoteOperation( - val openWithWebEndpoint: String, - val fileId: String, - val appName: String, + private val openWithWebEndpoint: String, + private val fileId: String, + private val appName: String, ) : RemoteOperation() { override fun run(client: OwnCloudClient): RemoteOperationResult { @@ -76,7 +77,7 @@ class GetUrlToOpenInWebRemoteOperation( } } - private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_MULTI_STATUS + private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK data class OpenInWebParams( val fileId: String, diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt index 4b94f1f7..50145892 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/AppRegistryService.kt @@ -20,6 +20,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package com.owncloud.android.lib.resources.appregistry.services import com.owncloud.android.lib.common.operations.RemoteOperationResult @@ -34,4 +35,10 @@ interface AppRegistryService : Service { fileId: String, appName: String, ): RemoteOperationResult + + fun createFileWithAppProvider( + createFileWithAppProviderEndpoint: String, + parentContainerId: String, + filename: String, + ): RemoteOperationResult } diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt index f80fe821..e07ac100 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/appregistry/services/OCAppRegistryService.kt @@ -20,10 +20,12 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + package com.owncloud.android.lib.resources.appregistry.services import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.appregistry.CreateRemoteFileWithAppProviderOperation import com.owncloud.android.lib.resources.appregistry.GetRemoteAppRegistryOperation import com.owncloud.android.lib.resources.appregistry.GetUrlToOpenInWebRemoteOperation import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryResponse @@ -38,4 +40,15 @@ class OCAppRegistryService(override val client: OwnCloudClient) : AppRegistrySer fileId = fileId, appName = appName ).execute(client) + + override fun createFileWithAppProvider( + createFileWithAppProviderEndpoint: String, + parentContainerId: String, + filename: String + ): RemoteOperationResult = + CreateRemoteFileWithAppProviderOperation( + createFileWithAppProviderEndpoint = createFileWithAppProviderEndpoint, + parentContainerId = parentContainerId, + filename = filename, + ).execute(client) } From e6937b4210513d74901f0cd4923bbf5d93b93e9b Mon Sep 17 00:00:00 2001 From: Juan Carlos Garrote Date: Mon, 15 May 2023 14:01:16 +0200 Subject: [PATCH 49/49] Removed publicUpload parameter from public shares creation and update requests --- .../resources/shares/CreateRemoteShareOperation.kt | 9 ++------- .../resources/shares/UpdateRemoteShareOperation.kt | 14 +------------- .../lib/resources/shares/services/ShareService.kt | 2 -- .../services/implementation/OCShareService.kt | 4 ---- 4 files changed, 3 insertions(+), 26 deletions(-) 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 ed2b7417..fed12f83 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 @@ -89,8 +89,6 @@ class CreateRemoteShareOperation( var expirationDateInMillis: Long = INIT_EXPIRATION_DATE_IN_MILLIS // Expiration date to set for the public link - var publicUpload: Boolean = false // Upload permissions for the public link (only folders) - var retrieveShareDetails = false // To retrieve more info about the just created share private fun buildRequestUri(baseUri: Uri) = @@ -99,7 +97,7 @@ class CreateRemoteShareOperation( .appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT) .build() - private fun parseResponse(response: String): ShareResponse? { + private fun parseResponse(response: String): ShareResponse { val moshi = Moshi.Builder().build() val commonOcsType: Type = Types.newParameterizedType(CommonOcsResponse::class.java, ShareItem::class.java) val adapter: JsonAdapter> = moshi.adapter(commonOcsType) @@ -155,12 +153,10 @@ class CreateRemoteShareOperation( formBodyBuilder.add(PARAM_EXPIRATION_DATE, formattedExpirationDate) } - if (publicUpload) { - formBodyBuilder.add(PARAM_PUBLIC_UPLOAD, publicUpload.toString()) - } if (password.isNotEmpty()) { formBodyBuilder.add(PARAM_PASSWORD, password) } + if (RemoteShare.DEFAULT_PERMISSION != permissions) { formBodyBuilder.add(PARAM_PERMISSIONS, permissions.toString()) } @@ -207,7 +203,6 @@ class CreateRemoteShareOperation( private const val PARAM_SHARE_TYPE = "shareType" private const val PARAM_SHARE_WITH = "shareWith" private const val PARAM_PASSWORD = "password" - private const val PARAM_PUBLIC_UPLOAD = "publicUpload" private const val PARAM_PERMISSIONS = "permissions" //Arguments - constant values 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 a6cc71e3..b9f814a2 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 @@ -103,13 +103,6 @@ class UpdateRemoteShareOperation */ var permissions: Int = DEFAULT_PERMISSION - /** - * Enable upload permissions to update in Share resource. - * - * Null results in no update applied to the upload permission. - */ - var publicUpload: Boolean? = null - var retrieveShareDetails = false // To retrieve more info about the just updated share private fun buildRequestUri(baseUri: Uri) = @@ -119,7 +112,7 @@ class UpdateRemoteShareOperation .appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT) .build() - private fun parseResponse(response: String): ShareResponse? { + private fun parseResponse(response: String): ShareResponse { val moshi = Moshi.Builder().build() val commonOcsType: Type = Types.newParameterizedType(CommonOcsResponse::class.java, ShareItem::class.java) val adapter: JsonAdapter> = moshi.adapter(commonOcsType) @@ -181,10 +174,6 @@ class UpdateRemoteShareOperation formBodyBuilder.add(PARAM_EXPIRATION_DATE, formattedExpirationDate) } // else, ignore - no update - if (publicUpload != null) { - formBodyBuilder.add(PARAM_PUBLIC_UPLOAD, publicUpload.toString()) - } - // IMPORTANT: permissions parameter needs to be updated after mPublicUpload parameter, // otherwise they would be set always as 1 (READ) in the server when mPublicUpload was updated if (permissions > DEFAULT_PERMISSION) { @@ -233,7 +222,6 @@ class UpdateRemoteShareOperation private const val PARAM_PASSWORD = "password" private const val PARAM_EXPIRATION_DATE = "expireDate" private const val PARAM_PERMISSIONS = "permissions" - private const val PARAM_PUBLIC_UPLOAD = "publicUpload" //Arguments - constant values private const val FORMAT_EXPIRATION_DATE = "yyyy-MM-dd" diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareService.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareService.kt index 7e77c62b..53458c59 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareService.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/shares/services/ShareService.kt @@ -46,7 +46,6 @@ interface ShareService : Service { name: String, password: String, expirationDate: Long, - publicUpload: Boolean ): RemoteOperationResult fun updateShare( @@ -55,7 +54,6 @@ interface ShareService : Service { password: String?, expirationDate: Long, permissions: Int, - publicUpload: Boolean ): RemoteOperationResult fun deleteShare(remoteId: String): RemoteOperationResult 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 index 68a22654..96381b6a 100644 --- 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 @@ -55,7 +55,6 @@ class OCShareService(override val client: OwnCloudClient) : ShareService { name: String, password: String, expirationDate: Long, - publicUpload: Boolean ): RemoteOperationResult = CreateRemoteShareOperation( remoteFilePath, @@ -66,7 +65,6 @@ class OCShareService(override val client: OwnCloudClient) : ShareService { this.name = name this.password = password this.expirationDateInMillis = expirationDate - this.publicUpload = publicUpload this.retrieveShareDetails = true }.execute(client) @@ -76,7 +74,6 @@ class OCShareService(override val client: OwnCloudClient) : ShareService { password: String?, expirationDate: Long, permissions: Int, - publicUpload: Boolean ): RemoteOperationResult = UpdateRemoteShareOperation( remoteId @@ -85,7 +82,6 @@ class OCShareService(override val client: OwnCloudClient) : ShareService { this.password = password this.expirationDateInMillis = expirationDate this.permissions = permissions - this.publicUpload = publicUpload this.retrieveShareDetails = true }.execute(client)