1
0
mirror of https://github.com/owncloud/android-library.git synced 2025-07-08 07:06:19 +00:00

Compare commits

..

9 Commits

Author SHA1 Message Date
Jesús Recio
ebe1967055
Merge pull request #506 from owncloud/master
1.0.16 to Stable
2022-09-07 12:05:32 +02:00
Abel García de Prada
0ea053d612
Merge pull request #503 from owncloud/feature/open_in_web
[Feature] Open in web
2022-09-01 10:54:05 +02:00
Abel García de Prada
0be462c9aa Set private link capability to unknown type when it is not retrieved
The CapabilityBooleanType.fromBooleanValue set it to FALSE when the capability is not retrieved. We don't want this for this case. Probably neither for the rest, but changing that now would need deeper testing
2022-08-31 17:21:55 +02:00
Abel García de Prada
32ef5d2125 Add a new capability to allow/disallow private links 2022-08-31 17:21:55 +02:00
Abel García de Prada
6282fbd419 Add the open in web to the service facade 2022-08-31 17:21:55 +02:00
Abel García de Prada
6d235fe74a Add a new remote operation to retrieve the url to open a file with ocis provider 2022-08-31 17:21:55 +02:00
Abel García de Prada
9ab7c139e1 Retrieve the app providers from the capabilities 2022-08-31 17:21:55 +02:00
Abel García de Prada
24b850d20c
Merge pull request #496 from owncloud/propfind_with_shares
Retrieve share type directly within the propfind
2022-07-07 14:59:20 +02:00
Abel García de Prada
5be4eca0f7 Added a new property, so that, we can retrieve the shares within the propfind 2022-07-07 08:18:54 +02:00
10 changed files with 276 additions and 4 deletions

View File

@ -26,10 +26,11 @@ 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 com.owncloud.android.lib.common.http.methods.webdav.properties.OCShareTypes
object DavUtils {
@JvmStatic val allPropset: Array<Property.Name>
get() = getAllPropSet()
get() = getAllPropSet().plus(OCShareTypes.NAME)
val quotaPropSet: Array<Property.Name>
get() = getQuotaPropset()

View File

@ -0,0 +1,44 @@
/* 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.common.http.methods.webdav.properties
import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.XmlUtils
import org.xmlpull.v1.XmlPullParser
class OCShareTypes : ShareTypeListProperty() {
class Factory : ShareTypeListProperty.Factory() {
override fun create(parser: XmlPullParser) =
create(parser, OCShareTypes())
override fun getName(): Property.Name = NAME
}
companion object {
@JvmField
val NAME = Property.Name(XmlUtils.NS_OWNCLOUD, "share-types")
}
}

View File

@ -0,0 +1,46 @@
/* 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.common.http.methods.webdav.properties
import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils
import org.xmlpull.v1.XmlPullParser
import java.util.LinkedList
abstract class ShareTypeListProperty : Property {
val shareTypes = LinkedList<String>()
override fun toString() = "share types =[" + shareTypes.joinToString(", ") + "]"
abstract class Factory : PropertyFactory {
fun create(parser: XmlPullParser, list: ShareTypeListProperty): ShareTypeListProperty {
XmlUtils.readTextPropertyList(parser, Property.Name(XmlUtils.NS_OWNCLOUD, "share-type"), list.shareTypes)
return list
}
}
}

View File

@ -0,0 +1,98 @@
/* 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.files
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.owncloud.android.lib.resources.files.GetUrlToOpenInWebRemoteOperation.OpenInWebParams.Companion.PARAM_FILE_ID
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 GetUrlToOpenInWebRemoteOperation(
val openWithWebEndpoint: String,
val fileId: String,
) : RemoteOperation<String>() {
override fun run(client: OwnCloudClient): RemoteOperationResult<String> {
return try {
val openInWebRequestBody = OpenInWebParams(fileId).toRequestBody()
val stringUrl = client.baseUri.toString() + WebdavUtils.encodePath(openWithWebEndpoint) + "?$PARAM_FILE_ID=$fileId"
val postMethod = PostMethod(URL(stringUrl), openInWebRequestBody).apply {
setReadTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
setConnectionTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
}
val status = client.executeHttpMethod(postMethod)
Timber.d("Open in web for file: $fileId - $status${if (!isSuccess(status)) "(FAIL)" else ""}")
if (isSuccess(status)) RemoteOperationResult<String>(ResultCode.OK).apply {
val moshi = Moshi.Builder().build()
val adapter: JsonAdapter<OpenInWebResponse> = moshi.adapter(OpenInWebResponse::class.java)
data = postMethod.getResponseBodyAsString()?.let { adapter.fromJson(it)!!.uri }
}
else RemoteOperationResult<String>(postMethod).apply { data = "" }
} catch (e: Exception) {
val result = RemoteOperationResult<String>(e)
Timber.e(e, "Open in web for file: $fileId failed")
result
}
}
private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_MULTI_STATUS
data class OpenInWebParams(val fileId: String) {
fun toRequestBody(): RequestBody =
FormBody.Builder().build()
companion object {
const val PARAM_FILE_ID = "file_id"
}
}
@JsonClass(generateAdapter = true)
data class OpenInWebResponse(val uri: String)
companion object {
/**
* Maximum time to wait for a response from the server in milliseconds.
*/
private const val TIMEOUT = 5_000L
}
}

View File

@ -24,6 +24,7 @@
package com.owncloud.android.lib.resources.files;
import at.bitfire.dav4jvm.PropertyRegistry;
import at.bitfire.dav4jvm.Response;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.accounts.AccountUtils;
@ -31,6 +32,7 @@ import com.owncloud.android.lib.common.http.HttpConstants;
import com.owncloud.android.lib.common.http.methods.webdav.DavConstants;
import com.owncloud.android.lib.common.http.methods.webdav.DavUtils;
import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod;
import com.owncloud.android.lib.common.http.methods.webdav.properties.OCShareTypes;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@ -72,6 +74,7 @@ public class ReadRemoteFolderOperation extends RemoteOperation<ArrayList<RemoteF
RemoteOperationResult<ArrayList<RemoteFile>> result = null;
try {
PropertyRegistry.INSTANCE.register(OCShareTypes.Factory.class.newInstance());
PropfindMethod propfindMethod = new PropfindMethod(
new URL(client.getUserFilesWebDavUri() + WebdavUtils.encodePath(mRemotePath)),
DavConstants.DEPTH_1,

View File

@ -40,10 +40,14 @@ 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.http.methods.webdav.properties.OCShareTypes;
import com.owncloud.android.lib.resources.shares.ShareType;
import timber.log.Timber;
import java.io.File;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;
/**
@ -85,6 +89,8 @@ public class RemoteFile implements Parcelable, Serializable {
private BigDecimal mQuotaUsedBytes;
private BigDecimal mQuotaAvailableBytes;
private String mPrivateLink;
private boolean mSharedByLink;
private boolean mSharedWithSharee;
public RemoteFile() {
resetData();
@ -153,6 +159,23 @@ public class RemoteFile implements Parcelable, Serializable {
if (property instanceof OCPrivatelink) {
this.setPrivateLink(((OCPrivatelink) property).getLink());
}
if (property instanceof OCShareTypes) {
LinkedList<String> list = ((OCShareTypes) property).getShareTypes();
for (int i = 0; i < list.size(); i++) {
ShareType shareType = ShareType.Companion.fromValue(Integer.parseInt(list.get(i)));
if (shareType == null) {
Timber.d("Illegal share type value: " + list.get(i));
continue;
}
if (shareType.equals(ShareType.PUBLIC_LINK)) {
this.setSharedViaLink(true);
} else if (shareType.equals(ShareType.USER) ||
shareType.equals(ShareType.FEDERATED) ||
shareType.equals(ShareType.GROUP)) {
this.setSharedWithSharee(true);
}
}
}
}
}
@ -266,6 +289,22 @@ public class RemoteFile implements Parcelable, Serializable {
mPrivateLink = privateLink;
}
public void setSharedWithSharee(boolean shareWithSharee) {
mSharedWithSharee = shareWithSharee;
}
public boolean isSharedWithSharee() {
return mSharedWithSharee;
}
public void setSharedViaLink(boolean sharedViaLink) {
mSharedByLink = sharedViaLink;
}
public boolean isSharedByLink() {
return mSharedByLink;
}
/**
* Used internally. Reset all file properties
*/
@ -282,6 +321,8 @@ public class RemoteFile implements Parcelable, Serializable {
mQuotaUsedBytes = null;
mQuotaAvailableBytes = null;
mPrivateLink = null;
mSharedWithSharee = false;
mSharedByLink = false;
}
public void readFromParcel(Parcel source) {

View File

@ -28,4 +28,5 @@ import com.owncloud.android.lib.resources.Service
interface FileService : Service {
fun checkPathExistence(path: String, isUserLogged: Boolean): RemoteOperationResult<Boolean>
fun getUrlToOpenInWeb(openWebEndpoint: String, fileId: String): RemoteOperationResult<String>
}

View File

@ -26,6 +26,7 @@ package com.owncloud.android.lib.resources.files.services.implementation
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.resources.files.CheckPathExistenceRemoteOperation
import com.owncloud.android.lib.resources.files.GetUrlToOpenInWebRemoteOperation
import com.owncloud.android.lib.resources.files.services.FileService
class OCFileService(override val client: OwnCloudClient) :
@ -35,4 +36,8 @@ class OCFileService(override val client: OwnCloudClient) :
remotePath = path,
isUserLoggedIn = isUserLogged
).execute(client)
override fun getUrlToOpenInWeb(openWebEndpoint: String, fileId: String): RemoteOperationResult<String> =
GetUrlToOpenInWebRemoteOperation(openWithWebEndpoint = openWebEndpoint, fileId = fileId).execute(client)
}

View File

@ -66,7 +66,9 @@ data class RemoteCapability(
// Files
var filesBigFileChunking: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN,
var filesUndelete: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN,
var filesVersioning: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN
var filesVersioning: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN,
val filesPrivateLinks: CapabilityBooleanType = CapabilityBooleanType.UNKNOWN,
val filesAppProviders: List<RemoteOCISProvider>?,
) {
/**
* Enum for Boolean Type in capabilities, with values:
@ -98,4 +100,13 @@ data class RemoteCapability(
}
}
}
data class RemoteOCISProvider(
val enabled: Boolean,
val version: String,
val appsUrl: String?,
val openUrl: String?,
val openWebUrl: String?,
val newUrl: String?,
)
}

View File

@ -26,6 +26,7 @@ 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.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@ -68,6 +69,8 @@ data class CapabilityResponse(
filesBigFileChunking = CapabilityBooleanType.fromBooleanValue(capabilities?.fileCapabilities?.bigfilechunking),
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() },
filesSharingFederationIncoming = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingFederation?.incoming),
filesSharingFederationOutgoing = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingFederation?.outgoing),
filesSharingUserProfilePicture = CapabilityBooleanType.fromBooleanValue(capabilities?.fileSharingCapabilities?.fileSharingUser?.profilePicture),
@ -160,9 +163,28 @@ data class FileSharingUser(
data class FileCapabilities(
val bigfilechunking: Boolean?,
val undelete: Boolean?,
val versioning: Boolean?
val versioning: Boolean?,
val privateLinks: Boolean?,
@Json(name = "app_providers")
val appProviders: List<AppProvider>?
)
@JsonClass(generateAdapter = true)
data class AppProvider(
val enabled: Boolean,
val version: String,
@Json(name = "apps_url")
val appsUrl: String?,
@Json(name = "open_url")
val openUrl: String?,
@Json(name = "open_web_url")
val openWebUrl: String?,
@Json(name = "new_url")
val newUrl: String?,
) {
fun toOCISProvider() = RemoteOCISProvider(enabled, version, appsUrl, openUrl, openWebUrl, newUrl)
}
@JsonClass(generateAdapter = true)
data class DavCapabilities(
val chunking: String?