mirror of
https://github.com/owncloud/android-library.git
synced 2025-06-07 16:06:08 +00:00
Merge pull request #430 from owncloud/feature/parse_shares
[FEATURE REQUEST] Use Moshi to parse shares
This commit is contained in:
commit
1baeebe5ee
@ -66,6 +66,18 @@ public class HttpConstants {
|
|||||||
public static final String CONTENT_TYPE_JSON = "application/json";
|
public static final String CONTENT_TYPE_JSON = "application/json";
|
||||||
public static final String CONTENT_TYPE_WWW_FORM = "application/x-www-form-urlencoded";
|
public static final String CONTENT_TYPE_WWW_FORM = "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
|
/***********************************************************************************************************
|
||||||
|
************************************************ ARGUMENTS NAMES ********************************************
|
||||||
|
***********************************************************************************************************/
|
||||||
|
|
||||||
|
public static final String PARAM_FORMAT = "format";
|
||||||
|
|
||||||
|
/***********************************************************************************************************
|
||||||
|
************************************************ ARGUMENTS VALUES ********************************************
|
||||||
|
***********************************************************************************************************/
|
||||||
|
|
||||||
|
public static final String VALUE_FORMAT = "json";
|
||||||
|
|
||||||
/***********************************************************************************************************
|
/***********************************************************************************************************
|
||||||
************************************************ STATUS CODES *********************************************
|
************************************************ STATUS CODES *********************************************
|
||||||
***********************************************************************************************************/
|
***********************************************************************************************************/
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
* @author masensio
|
* @author masensio
|
||||||
* @author David A. Velasco
|
* @author David A. Velasco
|
||||||
* @author David González Verdugo
|
* @author David González Verdugo
|
||||||
* Copyright (C) 2020 ownCloud GmbH
|
* @author Fernando Sanz Velasco
|
||||||
|
* Copyright (C) 2021 ownCloud GmbH
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -27,14 +28,23 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares
|
package com.owncloud.android.lib.resources.shares
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient
|
import com.owncloud.android.lib.common.OwnCloudClient
|
||||||
import com.owncloud.android.lib.common.http.HttpConstants
|
import com.owncloud.android.lib.common.http.HttpConstants
|
||||||
|
import com.owncloud.android.lib.common.http.HttpConstants.PARAM_FORMAT
|
||||||
|
import com.owncloud.android.lib.common.http.HttpConstants.VALUE_FORMAT
|
||||||
import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod
|
import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation
|
import com.owncloud.android.lib.common.operations.RemoteOperation
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
||||||
|
import com.owncloud.android.lib.resources.CommonOcsResponse
|
||||||
import com.owncloud.android.lib.resources.shares.RemoteShare.Companion.INIT_EXPIRATION_DATE_IN_MILLIS
|
import com.owncloud.android.lib.resources.shares.RemoteShare.Companion.INIT_EXPIRATION_DATE_IN_MILLIS
|
||||||
|
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 okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import java.lang.reflect.Type
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
@ -46,6 +56,7 @@ import java.util.Locale
|
|||||||
* @author masensio
|
* @author masensio
|
||||||
* @author David A. Velasco
|
* @author David A. Velasco
|
||||||
* @author David González Verdugo
|
* @author David González Verdugo
|
||||||
|
* @author Fernando Sanz Velasco
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,7 +81,8 @@ class CreateRemoteShareOperation(
|
|||||||
private val shareType: ShareType,
|
private val shareType: ShareType,
|
||||||
private val shareWith: String,
|
private val shareWith: String,
|
||||||
private val permissions: Int
|
private val permissions: Int
|
||||||
) : RemoteOperation<ShareParserResult>() {
|
) : RemoteOperation<ShareResponse>() {
|
||||||
|
|
||||||
var name = "" // Name to set for the public link
|
var name = "" // Name to set for the public link
|
||||||
|
|
||||||
var password: String = "" // Password to set for the public link
|
var password: String = "" // Password to set for the public link
|
||||||
@ -81,90 +93,125 @@ class CreateRemoteShareOperation(
|
|||||||
|
|
||||||
var retrieveShareDetails = false // To retrieve more info about the just created share
|
var retrieveShareDetails = false // To retrieve more info about the just created share
|
||||||
|
|
||||||
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareParserResult> {
|
private fun buildRequestUri(baseUri: Uri) =
|
||||||
var result: RemoteOperationResult<ShareParserResult>
|
baseUri.buildUpon()
|
||||||
|
.appendEncodedPath(OCS_ROUTE)
|
||||||
|
.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT)
|
||||||
|
.build()
|
||||||
|
|
||||||
try {
|
private fun parseResponse(response: String): ShareResponse? {
|
||||||
val formBodyBuilder = FormBody.Builder()
|
val moshi = Moshi.Builder().build()
|
||||||
.add(PARAM_PATH, remoteFilePath)
|
val commonOcsType: Type = Types.newParameterizedType(CommonOcsResponse::class.java, ShareItem::class.java)
|
||||||
.add(PARAM_SHARE_TYPE, shareType.value.toString())
|
val adapter: JsonAdapter<CommonOcsResponse<ShareItem>> = moshi.adapter(commonOcsType)
|
||||||
.add(PARAM_SHARE_WITH, shareWith)
|
val remoteShare = adapter.fromJson(response)?.ocs?.data?.toRemoteShare()
|
||||||
|
return ShareResponse(remoteShare?.let { listOf(it) } ?: listOf())
|
||||||
|
}
|
||||||
|
|
||||||
if (name.isNotEmpty()) {
|
private fun onResultUnsuccessful(
|
||||||
formBodyBuilder.add(PARAM_NAME, name)
|
method: PostMethod,
|
||||||
}
|
response: String?,
|
||||||
|
status: Int
|
||||||
|
): RemoteOperationResult<ShareResponse> {
|
||||||
|
Timber.e("Failed response while while creating new remote share operation ")
|
||||||
|
if (response != null) {
|
||||||
|
Timber.e("*** status code: $status; response message: $response")
|
||||||
|
} else {
|
||||||
|
Timber.e("*** status code: $status")
|
||||||
|
}
|
||||||
|
return RemoteOperationResult(method)
|
||||||
|
}
|
||||||
|
|
||||||
if (expirationDateInMillis > INIT_EXPIRATION_DATE_IN_MILLIS) {
|
private fun onRequestSuccessful(response: String?): RemoteOperationResult<ShareResponse> {
|
||||||
val dateFormat = SimpleDateFormat(FORMAT_EXPIRATION_DATE, Locale.getDefault())
|
val result = RemoteOperationResult<ShareResponse>(RemoteOperationResult.ResultCode.OK)
|
||||||
val expirationDate = Calendar.getInstance()
|
Timber.d("Successful response: $response")
|
||||||
expirationDate.timeInMillis = expirationDateInMillis
|
result.data = parseResponse(response!!)
|
||||||
val formattedExpirationDate = dateFormat.format(expirationDate.time)
|
Timber.d("*** Creating new remote share operation completed ")
|
||||||
formBodyBuilder.add(PARAM_EXPIRATION_DATE, formattedExpirationDate)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (publicUpload) {
|
val emptyShare = result.data.shares.first()
|
||||||
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())
|
|
||||||
}
|
|
||||||
|
|
||||||
val requestUri = client.baseUri
|
return if (retrieveShareDetails) {
|
||||||
val uriBuilder = requestUri.buildUpon()
|
// retrieve more info - PUT only returns the index of the new share
|
||||||
uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH)
|
GetRemoteShareOperation(emptyShare.id).execute(client)
|
||||||
|
} else {
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val postMethod = PostMethod(URL(uriBuilder.build().toString()), formBodyBuilder.build())
|
private fun createFormBody(): FormBody {
|
||||||
|
|
||||||
postMethod.setRequestHeader(HttpConstants.CONTENT_TYPE_HEADER, HttpConstants.CONTENT_TYPE_URLENCODED_UTF8)
|
val formBodyBuilder = FormBody.Builder()
|
||||||
postMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE)
|
.add(PARAM_PATH, remoteFilePath)
|
||||||
|
.add(PARAM_SHARE_TYPE, shareType.value.toString())
|
||||||
|
.add(PARAM_SHARE_WITH, shareWith)
|
||||||
|
|
||||||
|
if (name.isNotEmpty()) {
|
||||||
|
formBodyBuilder.add(PARAM_NAME, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expirationDateInMillis > INIT_EXPIRATION_DATE_IN_MILLIS) {
|
||||||
|
val dateFormat = SimpleDateFormat(FORMAT_EXPIRATION_DATE, Locale.getDefault())
|
||||||
|
val expirationDate = Calendar.getInstance()
|
||||||
|
expirationDate.timeInMillis = expirationDateInMillis
|
||||||
|
val formattedExpirationDate = dateFormat.format(expirationDate.time)
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
|
||||||
|
return formBodyBuilder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareResponse> {
|
||||||
|
val requestUri = buildRequestUri(client.baseUri)
|
||||||
|
|
||||||
|
val postMethod = PostMethod(URL(requestUri.toString()), createFormBody()).apply {
|
||||||
|
setRequestHeader(HttpConstants.CONTENT_TYPE_HEADER, HttpConstants.CONTENT_TYPE_URLENCODED_UTF8)
|
||||||
|
addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE)
|
||||||
|
}
|
||||||
|
|
||||||
|
return try {
|
||||||
val status = client.executeHttpMethod(postMethod)
|
val status = client.executeHttpMethod(postMethod)
|
||||||
|
val response = postMethod.getResponseBodyAsString()
|
||||||
val parser = ShareToRemoteOperationResultParser(
|
|
||||||
ShareXMLParser()
|
|
||||||
)
|
|
||||||
|
|
||||||
if (isSuccess(status)) {
|
if (isSuccess(status)) {
|
||||||
parser.oneOrMoreSharesRequired = true
|
onRequestSuccessful(response)
|
||||||
parser.ownCloudVersion = client.ownCloudVersion
|
|
||||||
parser.serverBaseUri = client.baseUri
|
|
||||||
result = parser.parse(postMethod.getResponseBodyAsString())
|
|
||||||
|
|
||||||
if (result.isSuccess && retrieveShareDetails) {
|
|
||||||
// retrieve more info - POST only returns the index of the new share
|
|
||||||
val emptyShare = result.data.shares[0]
|
|
||||||
val getInfo = GetRemoteShareOperation(
|
|
||||||
emptyShare.id
|
|
||||||
)
|
|
||||||
result = getInfo.execute(client)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
result = parser.parse(postMethod.getResponseBodyAsString())
|
onResultUnsuccessful(postMethod, response, status)
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
result = RemoteOperationResult(e)
|
Timber.e(e, "Exception while creating new remote share operation ")
|
||||||
Timber.e(e, "Exception while Creating New Share")
|
RemoteOperationResult(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
|
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
//OCS Route
|
||||||
|
private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/shares"
|
||||||
|
|
||||||
|
//Arguments - names
|
||||||
|
|
||||||
private const val PARAM_NAME = "name"
|
private const val PARAM_NAME = "name"
|
||||||
private const val PARAM_PASSWORD = "password"
|
|
||||||
private const val PARAM_EXPIRATION_DATE = "expireDate"
|
private const val PARAM_EXPIRATION_DATE = "expireDate"
|
||||||
private const val PARAM_PUBLIC_UPLOAD = "publicUpload"
|
|
||||||
private const val PARAM_PATH = "path"
|
private const val PARAM_PATH = "path"
|
||||||
private const val PARAM_SHARE_TYPE = "shareType"
|
private const val PARAM_SHARE_TYPE = "shareType"
|
||||||
private const val PARAM_SHARE_WITH = "shareWith"
|
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"
|
private const val PARAM_PERMISSIONS = "permissions"
|
||||||
|
|
||||||
|
//Arguments - constant values
|
||||||
private const val FORMAT_EXPIRATION_DATE = "yyyy-MM-dd"
|
private const val FORMAT_EXPIRATION_DATE = "yyyy-MM-dd"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,94 +0,0 @@
|
|||||||
/* ownCloud Android Library is available under MIT license
|
|
||||||
* @author David A. Velasco
|
|
||||||
* @author David González Verdugo
|
|
||||||
* Copyright (C) 2020 ownCloud GmbH.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares;
|
|
||||||
|
|
||||||
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 timber.log.Timber;
|
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the data about a Share resource, known its remote ID.
|
|
||||||
*
|
|
||||||
* @author David A. Velasco
|
|
||||||
* @author David González Verdugo
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class GetRemoteShareOperation extends RemoteOperation<ShareParserResult> {
|
|
||||||
|
|
||||||
private String mRemoteId;
|
|
||||||
|
|
||||||
public GetRemoteShareOperation(String remoteId) {
|
|
||||||
mRemoteId = remoteId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
|
||||||
RemoteOperationResult<ShareParserResult> result;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Uri requestUri = client.getBaseUri();
|
|
||||||
Uri.Builder uriBuilder = requestUri.buildUpon();
|
|
||||||
uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH);
|
|
||||||
uriBuilder.appendEncodedPath(mRemoteId);
|
|
||||||
|
|
||||||
GetMethod getMethod = new GetMethod(new URL(uriBuilder.build().toString()));
|
|
||||||
getMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
|
||||||
|
|
||||||
int status = client.executeHttpMethod(getMethod);
|
|
||||||
|
|
||||||
if (isSuccess(status)) {
|
|
||||||
// Parse xml response and obtain the list of shares
|
|
||||||
ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
|
|
||||||
new ShareXMLParser()
|
|
||||||
);
|
|
||||||
parser.setOneOrMoreSharesRequired(true);
|
|
||||||
parser.setOwnCloudVersion(client.getOwnCloudVersion());
|
|
||||||
parser.setServerBaseUri(client.getBaseUri());
|
|
||||||
result = parser.parse(getMethod.getResponseBodyAsString());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
result = new RemoteOperationResult<>(getMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
result = new RemoteOperationResult<>(e);
|
|
||||||
Timber.e(e, "Exception while getting remote shares");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isSuccess(int status) {
|
|
||||||
return (status == HttpConstants.HTTP_OK);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,116 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
* @author Fernando Sanz Velasco
|
||||||
|
* Copyright (C) 2021 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.shares
|
||||||
|
|
||||||
|
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.HttpConstants.PARAM_FORMAT
|
||||||
|
import com.owncloud.android.lib.common.http.HttpConstants.VALUE_FORMAT
|
||||||
|
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.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
|
||||||
|
|
||||||
|
class GetRemoteShareOperation(private val remoteId: String) : RemoteOperation<ShareResponse>() {
|
||||||
|
|
||||||
|
private fun buildRequestUri(baseUri: Uri) =
|
||||||
|
baseUri.buildUpon()
|
||||||
|
.appendEncodedPath(OCS_ROUTE)
|
||||||
|
.appendEncodedPath(remoteId)
|
||||||
|
.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<CommonOcsResponse<List<ShareItem>>> = moshi.adapter(commonOcsType)
|
||||||
|
return adapter.fromJson(response)?.ocs?.data?.let { listOfShareItems ->
|
||||||
|
ShareResponse(listOfShareItems.map { shareItem ->
|
||||||
|
shareItem.toRemoteShare()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onResultUnsuccessful(
|
||||||
|
method: GetMethod,
|
||||||
|
response: String?,
|
||||||
|
status: Int
|
||||||
|
): RemoteOperationResult<ShareResponse> {
|
||||||
|
Timber.e("Failed response while while getting remote shares ")
|
||||||
|
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<ShareResponse> {
|
||||||
|
val result = RemoteOperationResult<ShareResponse>(RemoteOperationResult.ResultCode.OK)
|
||||||
|
Timber.d("Successful response: $response")
|
||||||
|
result.data = parseResponse(response!!)
|
||||||
|
Timber.d("*** Get Users or groups completed ")
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareResponse> {
|
||||||
|
val requestUri = buildRequestUri(client.baseUri)
|
||||||
|
|
||||||
|
val getMethod = GetMethod(URL(requestUri.toString())).apply {
|
||||||
|
addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE)
|
||||||
|
}
|
||||||
|
|
||||||
|
return try {
|
||||||
|
val status = client.executeHttpMethod(getMethod)
|
||||||
|
val response = getMethod.getResponseBodyAsString()
|
||||||
|
|
||||||
|
if (!isSuccess(status)) {
|
||||||
|
onResultUnsuccessful(getMethod, response, status)
|
||||||
|
} else {
|
||||||
|
onRequestSuccessful(response)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e, "Exception while getting remote shares")
|
||||||
|
RemoteOperationResult(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
//OCS Route
|
||||||
|
private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/shares"
|
||||||
|
}
|
||||||
|
}
|
@ -32,6 +32,8 @@ package com.owncloud.android.lib.resources.shares
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient
|
import com.owncloud.android.lib.common.OwnCloudClient
|
||||||
import com.owncloud.android.lib.common.http.HttpConstants
|
import com.owncloud.android.lib.common.http.HttpConstants
|
||||||
|
import com.owncloud.android.lib.common.http.HttpConstants.PARAM_FORMAT
|
||||||
|
import com.owncloud.android.lib.common.http.HttpConstants.VALUE_FORMAT
|
||||||
import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod
|
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.RemoteOperation
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
||||||
@ -136,10 +138,10 @@ class GetRemoteShareesOperation
|
|||||||
val status = client.executeHttpMethod(getMethod)
|
val status = client.executeHttpMethod(getMethod)
|
||||||
val response = getMethod.getResponseBodyAsString()
|
val response = getMethod.getResponseBodyAsString()
|
||||||
|
|
||||||
if (!isSuccess(status)) {
|
if (isSuccess(status)) {
|
||||||
onResultUnsuccessful(getMethod, response, status)
|
|
||||||
} else {
|
|
||||||
onRequestSuccessful(response)
|
onRequestSuccessful(response)
|
||||||
|
} else {
|
||||||
|
onResultUnsuccessful(getMethod, response, status)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e(e, "Exception while getting users/groups")
|
Timber.e(e, "Exception while getting users/groups")
|
||||||
@ -155,14 +157,12 @@ class GetRemoteShareesOperation
|
|||||||
private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/sharees" // from OC 8.2
|
private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/sharees" // from OC 8.2
|
||||||
|
|
||||||
// Arguments - names
|
// Arguments - names
|
||||||
private const val PARAM_FORMAT = "format"
|
|
||||||
private const val PARAM_ITEM_TYPE = "itemType"
|
private const val PARAM_ITEM_TYPE = "itemType"
|
||||||
private const val PARAM_SEARCH = "search"
|
private const val PARAM_SEARCH = "search"
|
||||||
private const val PARAM_PAGE = "page" // default = 1
|
private const val PARAM_PAGE = "page" // default = 1
|
||||||
private const val PARAM_PER_PAGE = "perPage" // default = 200
|
private const val PARAM_PER_PAGE = "perPage" // default = 200
|
||||||
|
|
||||||
// Arguments - constant values
|
// Arguments - constant values
|
||||||
private const val VALUE_FORMAT = "json"
|
|
||||||
private const val VALUE_ITEM_TYPE = "file" // to get the server search for users / groups
|
private const val VALUE_ITEM_TYPE = "file" // to get the server search for users / groups
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
* @author masensio
|
* @author masensio
|
||||||
* @author David A. Velasco
|
* @author David A. Velasco
|
||||||
* @author David González Verdugo
|
* @author David González Verdugo
|
||||||
* Copyright (C) 2020 ownCloud GmbH.
|
* @author Fernando Sanz Velasco
|
||||||
|
* Copyright (C) 2021 ownCloud GmbH
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -27,12 +28,21 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares
|
package com.owncloud.android.lib.resources.shares
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient
|
import com.owncloud.android.lib.common.OwnCloudClient
|
||||||
import com.owncloud.android.lib.common.http.HttpConstants
|
import com.owncloud.android.lib.common.http.HttpConstants
|
||||||
|
import com.owncloud.android.lib.common.http.HttpConstants.PARAM_FORMAT
|
||||||
|
import com.owncloud.android.lib.common.http.HttpConstants.VALUE_FORMAT
|
||||||
import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod
|
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.RemoteOperation
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
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 timber.log.Timber
|
||||||
|
import java.lang.reflect.Type
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,6 +53,7 @@ import java.net.URL
|
|||||||
* @author masensio
|
* @author masensio
|
||||||
* @author David A. Velasco
|
* @author David A. Velasco
|
||||||
* @author David González Verdugo
|
* @author David González Verdugo
|
||||||
|
* @author Fernando Sanz Velasco
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,52 +70,82 @@ class GetRemoteSharesForFileOperation(
|
|||||||
private val remoteFilePath: String,
|
private val remoteFilePath: String,
|
||||||
private val reshares: Boolean,
|
private val reshares: Boolean,
|
||||||
private val subfiles: Boolean
|
private val subfiles: Boolean
|
||||||
) : RemoteOperation<ShareParserResult>() {
|
) : RemoteOperation<ShareResponse>() {
|
||||||
|
|
||||||
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareParserResult> {
|
private fun buildRequestUri(baseUri: Uri) =
|
||||||
var result: RemoteOperationResult<ShareParserResult>
|
baseUri.buildUpon()
|
||||||
|
.appendEncodedPath(OCS_ROUTE)
|
||||||
|
.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT)
|
||||||
|
.appendQueryParameter(PARAM_PATH, remoteFilePath)
|
||||||
|
.appendQueryParameter(PARAM_RESHARES, reshares.toString())
|
||||||
|
.appendQueryParameter(PARAM_SUBFILES, subfiles.toString())
|
||||||
|
.build()
|
||||||
|
|
||||||
try {
|
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<CommonOcsResponse<List<ShareItem>>> = moshi.adapter(commonOcsType)
|
||||||
|
return adapter.fromJson(response)?.ocs?.data?.let { listOfShareItems ->
|
||||||
|
ShareResponse(listOfShareItems.map { shareItem ->
|
||||||
|
shareItem.toRemoteShare()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val requestUri = client.baseUri
|
private fun onResultUnsuccessful(
|
||||||
val uriBuilder = requestUri.buildUpon()
|
method: GetMethod,
|
||||||
uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH)
|
response: String?,
|
||||||
uriBuilder.appendQueryParameter(PARAM_PATH, remoteFilePath)
|
status: Int
|
||||||
uriBuilder.appendQueryParameter(PARAM_RESHARES, reshares.toString())
|
): RemoteOperationResult<ShareResponse> {
|
||||||
uriBuilder.appendQueryParameter(PARAM_SUBFILES, subfiles.toString())
|
Timber.e("Failed response while while getting remote shares for file operation ")
|
||||||
|
if (response != null) {
|
||||||
|
Timber.e("*** status code: $status; response message: $response")
|
||||||
|
} else {
|
||||||
|
Timber.e("*** status code: $status")
|
||||||
|
}
|
||||||
|
return RemoteOperationResult(method)
|
||||||
|
}
|
||||||
|
|
||||||
val getMethod = GetMethod(URL(uriBuilder.build().toString()))
|
private fun onRequestSuccessful(response: String?): RemoteOperationResult<ShareResponse> {
|
||||||
|
val result = RemoteOperationResult<ShareResponse>(RemoteOperationResult.ResultCode.OK)
|
||||||
|
Timber.d("Successful response: $response")
|
||||||
|
result.data = parseResponse(response!!)
|
||||||
|
Timber.d("*** Getting remote shares for file completed ")
|
||||||
|
Timber.d("Got ${result.data.shares.size} shares")
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
getMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE)
|
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareResponse> {
|
||||||
|
val requestUri = buildRequestUri(client.baseUri)
|
||||||
|
|
||||||
val status = client.executeHttpMethod(getMethod)
|
val getMethod = GetMethod(URL(requestUri.toString())).apply {
|
||||||
|
addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE)
|
||||||
if (isSuccess(status)) {
|
|
||||||
// Parse xml response and obtain the list of shares
|
|
||||||
val parser = ShareToRemoteOperationResultParser(
|
|
||||||
ShareXMLParser()
|
|
||||||
)
|
|
||||||
parser.ownCloudVersion = client.ownCloudVersion
|
|
||||||
parser.serverBaseUri = client.baseUri
|
|
||||||
result = parser.parse(getMethod.getResponseBodyAsString())
|
|
||||||
|
|
||||||
if (result.isSuccess) {
|
|
||||||
Timber.d("Got ${result.data.shares.size} shares")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = RemoteOperationResult(getMethod)
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
result = RemoteOperationResult(e)
|
|
||||||
Timber.e(e, "Exception while getting shares")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
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 for file operation")
|
||||||
|
RemoteOperationResult(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
|
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
//OCS Route
|
||||||
|
private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/shares"
|
||||||
|
|
||||||
|
//Arguments - names
|
||||||
private const val PARAM_PATH = "path"
|
private const val PARAM_PATH = "path"
|
||||||
private const val PARAM_RESHARES = "reshares"
|
private const val PARAM_RESHARES = "reshares"
|
||||||
private const val PARAM_SUBFILES = "subfiles"
|
private const val PARAM_SUBFILES = "subfiles"
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares
|
package com.owncloud.android.lib.resources.shares
|
||||||
|
|
||||||
import java.io.File
|
import com.owncloud.android.lib.resources.shares.responses.ItemType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains the data of a Share from the Share API
|
* Contains the data of a Share from the Share API
|
||||||
@ -38,6 +38,7 @@ data class RemoteShare(
|
|||||||
var shareWith: String = "",
|
var shareWith: String = "",
|
||||||
var path: String = "",
|
var path: String = "",
|
||||||
var token: String = "",
|
var token: String = "",
|
||||||
|
var itemType: String = "",
|
||||||
var sharedWithDisplayName: String = "",
|
var sharedWithDisplayName: String = "",
|
||||||
var sharedWithAdditionalInfo: String = "",
|
var sharedWithAdditionalInfo: String = "",
|
||||||
var name: String = "",
|
var name: String = "",
|
||||||
@ -46,7 +47,7 @@ data class RemoteShare(
|
|||||||
var permissions: Int = DEFAULT_PERMISSION,
|
var permissions: Int = DEFAULT_PERMISSION,
|
||||||
var sharedDate: Long = INIT_SHARED_DATE,
|
var sharedDate: Long = INIT_SHARED_DATE,
|
||||||
var expirationDate: Long = INIT_EXPIRATION_DATE_IN_MILLIS,
|
var expirationDate: Long = INIT_EXPIRATION_DATE_IN_MILLIS,
|
||||||
var isFolder: Boolean = path.endsWith(File.separator)
|
var isFolder: Boolean = (itemType == ItemType.FOLDER.fileValue)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
* @author masensio
|
* @author masensio
|
||||||
* @author David A. Velasco
|
* @author David A. Velasco
|
||||||
* @author David González Verdugo
|
* @author David González Verdugo
|
||||||
* Copyright (C) 2020 ownCloud GmbH.
|
* @author Fernando Sanz Velasco
|
||||||
|
* Copyright (C) 2021 ownCloud GmbH
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -27,12 +28,21 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares
|
package com.owncloud.android.lib.resources.shares
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient
|
import com.owncloud.android.lib.common.OwnCloudClient
|
||||||
import com.owncloud.android.lib.common.http.HttpConstants
|
import com.owncloud.android.lib.common.http.HttpConstants
|
||||||
|
import com.owncloud.android.lib.common.http.HttpConstants.PARAM_FORMAT
|
||||||
|
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.http.methods.nonwebdav.DeleteMethod
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation
|
import com.owncloud.android.lib.common.operations.RemoteOperation
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
||||||
|
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 timber.log.Timber
|
||||||
|
import java.lang.reflect.Type
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,6 +51,7 @@ import java.net.URL
|
|||||||
* @author masensio
|
* @author masensio
|
||||||
* @author David A. Velasco
|
* @author David A. Velasco
|
||||||
* @author David González Verdugo
|
* @author David González Verdugo
|
||||||
|
* @author Fernando Sanz Velasco
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,46 +59,76 @@ import java.net.URL
|
|||||||
*
|
*
|
||||||
* @param remoteShareId Share ID
|
* @param remoteShareId Share ID
|
||||||
*/
|
*/
|
||||||
class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOperation<ShareParserResult>() {
|
class RemoveRemoteShareOperation(private val remoteShareId: String) : RemoteOperation<ShareResponse>() {
|
||||||
|
|
||||||
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareParserResult> {
|
private fun buildRequestUri(baseUri: Uri) =
|
||||||
var result: RemoteOperationResult<ShareParserResult>
|
baseUri.buildUpon()
|
||||||
|
.appendEncodedPath(OCS_ROUTE)
|
||||||
|
.appendEncodedPath(remoteShareId)
|
||||||
|
.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT)
|
||||||
|
.build()
|
||||||
|
|
||||||
try {
|
private fun parseResponse(response: String): ShareResponse? {
|
||||||
val requestUri = client.baseUri
|
val moshi = Moshi.Builder().build()
|
||||||
val uriBuilder = requestUri.buildUpon()
|
val listOfShareItemType: Type = Types.newParameterizedType(List::class.java, ShareItem::class.java)
|
||||||
uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH)
|
val commonOcsType: Type = Types.newParameterizedType(CommonOcsResponse::class.java, listOfShareItemType)
|
||||||
uriBuilder.appendEncodedPath(remoteShareId)
|
val adapter: JsonAdapter<CommonOcsResponse<List<ShareItem>>> = moshi.adapter(commonOcsType)
|
||||||
|
return adapter.fromJson(response)?.ocs?.data?.let { listOfShareItems ->
|
||||||
val deleteMethod = DeleteMethod(
|
ShareResponse(listOfShareItems.map { shareItem ->
|
||||||
URL(uriBuilder.build().toString())
|
shareItem.toRemoteShare()
|
||||||
)
|
})
|
||||||
|
|
||||||
deleteMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE)
|
|
||||||
|
|
||||||
val status = client.executeHttpMethod(deleteMethod)
|
|
||||||
|
|
||||||
if (isSuccess(status)) {
|
|
||||||
|
|
||||||
// Parse xml response and obtain the list of shares
|
|
||||||
val parser = ShareToRemoteOperationResultParser(
|
|
||||||
ShareXMLParser()
|
|
||||||
)
|
|
||||||
result = parser.parse(deleteMethod.getResponseBodyAsString())
|
|
||||||
|
|
||||||
Timber.d("Unshare $remoteShareId: ${result.logMessage}")
|
|
||||||
|
|
||||||
} else {
|
|
||||||
result = RemoteOperationResult(deleteMethod)
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (e: Exception) {
|
|
||||||
result = RemoteOperationResult(e)
|
|
||||||
Timber.e(e, "Unshare Link Exception ${result.logMessage}")
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onResultUnsuccessful(
|
||||||
|
method: DeleteMethod,
|
||||||
|
response: String?,
|
||||||
|
status: Int
|
||||||
|
): RemoteOperationResult<ShareResponse> {
|
||||||
|
Timber.e("Failed response while unshare link ")
|
||||||
|
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<ShareResponse> {
|
||||||
|
val result = RemoteOperationResult<ShareResponse>(RemoteOperationResult.ResultCode.OK)
|
||||||
|
Timber.d("Successful response: $response")
|
||||||
|
result.data = parseResponse(response!!)
|
||||||
|
Timber.d("*** Unshare link completed ")
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareResponse> {
|
||||||
|
|
||||||
|
val requestUri = buildRequestUri(client.baseUri)
|
||||||
|
|
||||||
|
val deleteMethod = DeleteMethod(URL(requestUri.toString())).apply {
|
||||||
|
addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE)
|
||||||
|
}
|
||||||
|
|
||||||
|
return try {
|
||||||
|
val status = client.executeHttpMethod(deleteMethod)
|
||||||
|
val response = deleteMethod.getResponseBodyAsString()
|
||||||
|
|
||||||
|
if (isSuccess(status)) {
|
||||||
|
onRequestSuccessful(response)
|
||||||
|
} else {
|
||||||
|
onResultUnsuccessful(deleteMethod, response, status)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e, "Exception while unshare link")
|
||||||
|
RemoteOperationResult(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
|
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
//OCS Route
|
||||||
|
private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/shares"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,4 +25,4 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares
|
package com.owncloud.android.lib.resources.shares
|
||||||
|
|
||||||
class ShareParserResult(val shares: List<RemoteShare>)
|
data class ShareResponse(val shares: List<RemoteShare>)
|
@ -1,120 +0,0 @@
|
|||||||
/* ownCloud Android Library is available under MIT license
|
|
||||||
* @author David A. Velasco
|
|
||||||
* @author David González Verdugo
|
|
||||||
* @author Christian Schabesberger
|
|
||||||
* Copyright (C) 2020 ownCloud GmbH.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares
|
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
|
||||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion
|
|
||||||
import org.xmlpull.v1.XmlPullParserException
|
|
||||||
import timber.log.Timber
|
|
||||||
import java.io.ByteArrayInputStream
|
|
||||||
import java.io.IOException
|
|
||||||
import java.util.ArrayList
|
|
||||||
|
|
||||||
class ShareToRemoteOperationResultParser(private var shareXmlParser: ShareXMLParser?) {
|
|
||||||
var oneOrMoreSharesRequired = false
|
|
||||||
var ownCloudVersion: OwnCloudVersion? = null
|
|
||||||
var serverBaseUri: Uri? = null
|
|
||||||
|
|
||||||
fun parse(serverResponse: String?): RemoteOperationResult<ShareParserResult> {
|
|
||||||
if (serverResponse.isNullOrEmpty()) {
|
|
||||||
return RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE)
|
|
||||||
}
|
|
||||||
|
|
||||||
var result: RemoteOperationResult<ShareParserResult>
|
|
||||||
val resultData: List<RemoteShare>?
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Parse xml response and obtain the list of shares
|
|
||||||
val byteArrayServerResponse = ByteArrayInputStream(serverResponse.toByteArray())
|
|
||||||
if (shareXmlParser == null) {
|
|
||||||
Timber.w("No ShareXmlParser provided, creating new instance")
|
|
||||||
shareXmlParser = ShareXMLParser()
|
|
||||||
}
|
|
||||||
val shares = shareXmlParser?.parseXMLResponse(byteArrayServerResponse)
|
|
||||||
|
|
||||||
when {
|
|
||||||
shareXmlParser?.isSuccess!! -> {
|
|
||||||
if (!shares.isNullOrEmpty() || !oneOrMoreSharesRequired) {
|
|
||||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.OK)
|
|
||||||
|
|
||||||
resultData = shares?.map { share ->
|
|
||||||
if (share.shareType != ShareType.PUBLIC_LINK ||
|
|
||||||
share.shareLink.isNotEmpty() ||
|
|
||||||
share.token.isEmpty()
|
|
||||||
) {
|
|
||||||
return@map share
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serverBaseUri != null) {
|
|
||||||
val sharingLinkPath = ShareUtils.SHARING_LINK_PATH
|
|
||||||
share.shareLink = serverBaseUri.toString() + sharingLinkPath + share.token
|
|
||||||
} else {
|
|
||||||
Timber.e("Couldn't build link for public share :(")
|
|
||||||
}
|
|
||||||
|
|
||||||
share
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resultData != null) {
|
|
||||||
result.setData(ShareParserResult(ArrayList(resultData.toMutableList())))
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE)
|
|
||||||
Timber.e("Successful status with no share in the response")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shareXmlParser?.isWrongParameter!! -> {
|
|
||||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER)
|
|
||||||
result.httpPhrase = shareXmlParser?.message
|
|
||||||
}
|
|
||||||
shareXmlParser?.isNotFound!! -> {
|
|
||||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_NOT_FOUND)
|
|
||||||
result.httpPhrase = shareXmlParser?.message
|
|
||||||
}
|
|
||||||
shareXmlParser?.isForbidden!! -> {
|
|
||||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_FORBIDDEN)
|
|
||||||
result.httpPhrase = shareXmlParser?.message
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: XmlPullParserException) {
|
|
||||||
Timber.e(e, "Error parsing response from server")
|
|
||||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE)
|
|
||||||
|
|
||||||
} catch (e: IOException) {
|
|
||||||
Timber.e(e, "Error reading response from server")
|
|
||||||
result = RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
/* ownCloud Android Library is available under MIT license
|
|
||||||
* Copyright (C) 2020 ownCloud GmbH.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contains Constants for Share Operation
|
|
||||||
*
|
|
||||||
* @author masensio
|
|
||||||
* @author David González Verdugo
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class ShareUtils {
|
|
||||||
|
|
||||||
// OCS Route
|
|
||||||
public static final String SHARING_API_PATH = "ocs/v2.php/apps/files_sharing/api/v1/shares";
|
|
||||||
|
|
||||||
// String to build the link with the token of a share:
|
|
||||||
public static final String SHARING_LINK_PATH = "/index.php/s/";
|
|
||||||
}
|
|
@ -1,420 +0,0 @@
|
|||||||
/* ownCloud Android Library is available under MIT license
|
|
||||||
* Copyright (C) 2020 ownCloud GmbH.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
||||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares
|
|
||||||
|
|
||||||
import android.util.Xml
|
|
||||||
import com.owncloud.android.lib.common.network.WebdavUtils
|
|
||||||
import org.xmlpull.v1.XmlPullParser
|
|
||||||
import org.xmlpull.v1.XmlPullParserException
|
|
||||||
import org.xmlpull.v1.XmlPullParserFactory
|
|
||||||
import java.io.File
|
|
||||||
import java.io.IOException
|
|
||||||
import java.io.InputStream
|
|
||||||
import java.util.ArrayList
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parser for Share API Response
|
|
||||||
*
|
|
||||||
* @author masensio
|
|
||||||
* @author David González Verdugo
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ShareXMLParser {
|
|
||||||
// Getters and Setters
|
|
||||||
var status: String? = null
|
|
||||||
var statusCode: Int = 0
|
|
||||||
var message: String? = null
|
|
||||||
|
|
||||||
val isSuccess: Boolean
|
|
||||||
get() = statusCode == SUCCESS
|
|
||||||
|
|
||||||
val isForbidden: Boolean
|
|
||||||
get() = statusCode == ERROR_FORBIDDEN
|
|
||||||
|
|
||||||
val isNotFound: Boolean
|
|
||||||
get() = statusCode == ERROR_NOT_FOUND
|
|
||||||
|
|
||||||
val isWrongParameter: Boolean
|
|
||||||
get() = statusCode == ERROR_WRONG_PARAMETER
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
init {
|
|
||||||
statusCode = INIT
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse is as response of Share API
|
|
||||||
* @param inputStream
|
|
||||||
* @return List of ShareRemoteFiles
|
|
||||||
* @throws XmlPullParserException
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
@Throws(XmlPullParserException::class, IOException::class)
|
|
||||||
fun parseXMLResponse(inputStream: InputStream): ArrayList<RemoteShare> {
|
|
||||||
|
|
||||||
try {
|
|
||||||
// XMLPullParser
|
|
||||||
val factory = XmlPullParserFactory.newInstance()
|
|
||||||
factory.isNamespaceAware = true
|
|
||||||
|
|
||||||
val parser = Xml.newPullParser()
|
|
||||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
|
|
||||||
parser.setInput(inputStream, null)
|
|
||||||
parser.nextTag()
|
|
||||||
return readOCS(parser)
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
inputStream.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse OCS node
|
|
||||||
* @param parser
|
|
||||||
* @return List of ShareRemoteFiles
|
|
||||||
* @throws XmlPullParserException
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
@Throws(XmlPullParserException::class, IOException::class)
|
|
||||||
private fun readOCS(parser: XmlPullParser): ArrayList<RemoteShare> {
|
|
||||||
var shares = ArrayList<RemoteShare>()
|
|
||||||
parser.require(XmlPullParser.START_TAG, ns, NODE_OCS)
|
|
||||||
while (parser.next() != XmlPullParser.END_TAG) {
|
|
||||||
if (parser.eventType != XmlPullParser.START_TAG) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
val name = parser.name
|
|
||||||
// read NODE_META and NODE_DATA
|
|
||||||
when {
|
|
||||||
name.equals(NODE_META, ignoreCase = true) -> {
|
|
||||||
readMeta(parser)
|
|
||||||
}
|
|
||||||
name.equals(NODE_DATA, ignoreCase = true) -> {
|
|
||||||
shares = readData(parser)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
skip(parser)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return shares
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse Meta node
|
|
||||||
* @param parser
|
|
||||||
* @throws XmlPullParserException
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
@Throws(XmlPullParserException::class, IOException::class)
|
|
||||||
private fun readMeta(parser: XmlPullParser) {
|
|
||||||
parser.require(XmlPullParser.START_TAG, ns, NODE_META)
|
|
||||||
while (parser.next() != XmlPullParser.END_TAG) {
|
|
||||||
if (parser.eventType != XmlPullParser.START_TAG) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
val name = parser.name
|
|
||||||
|
|
||||||
when {
|
|
||||||
name.equals(NODE_STATUS, ignoreCase = true) -> {
|
|
||||||
status = readNode(parser, NODE_STATUS)
|
|
||||||
}
|
|
||||||
name.equals(NODE_STATUS_CODE, ignoreCase = true) -> {
|
|
||||||
statusCode = Integer.parseInt(readNode(parser, NODE_STATUS_CODE))
|
|
||||||
}
|
|
||||||
name.equals(NODE_MESSAGE, ignoreCase = true) -> {
|
|
||||||
message = readNode(parser, NODE_MESSAGE)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
skip(parser)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse Data node
|
|
||||||
* @param parser
|
|
||||||
* @return
|
|
||||||
* @throws XmlPullParserException
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
@Throws(XmlPullParserException::class, IOException::class)
|
|
||||||
private fun readData(parser: XmlPullParser): ArrayList<RemoteShare> {
|
|
||||||
val shares = ArrayList<RemoteShare>()
|
|
||||||
var share: RemoteShare? = null
|
|
||||||
|
|
||||||
parser.require(XmlPullParser.START_TAG, ns, NODE_DATA)
|
|
||||||
while (parser.next() != XmlPullParser.END_TAG) {
|
|
||||||
if (parser.eventType != XmlPullParser.START_TAG) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
val name = parser.name
|
|
||||||
when {
|
|
||||||
name.equals(NODE_ELEMENT, ignoreCase = true) -> {
|
|
||||||
readElement(parser, shares)
|
|
||||||
}
|
|
||||||
name.equals(NODE_ID, ignoreCase = true) -> { // Parse Create XML Response
|
|
||||||
share = RemoteShare()
|
|
||||||
val value = readNode(parser, NODE_ID)
|
|
||||||
share.id = value
|
|
||||||
}
|
|
||||||
name.equals(NODE_URL, ignoreCase = true) -> {
|
|
||||||
// NOTE: this field is received in all the public shares from OC 9.0.0
|
|
||||||
// in previous versions, it's received in the result of POST requests, but not
|
|
||||||
// in GET requests
|
|
||||||
share!!.shareType = ShareType.PUBLIC_LINK
|
|
||||||
val value = readNode(parser, NODE_URL)
|
|
||||||
share.shareLink = value
|
|
||||||
}
|
|
||||||
name.equals(NODE_TOKEN, ignoreCase = true) -> {
|
|
||||||
share!!.token = readNode(parser, NODE_TOKEN)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
skip(parser)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (share != null) {
|
|
||||||
// this is the response of a request for creation; don't pass to isValidShare()
|
|
||||||
shares.add(share)
|
|
||||||
}
|
|
||||||
|
|
||||||
return shares
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse Element node
|
|
||||||
* @param parser
|
|
||||||
* @return
|
|
||||||
* @throws XmlPullParserException
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
@Throws(XmlPullParserException::class, IOException::class)
|
|
||||||
private fun readElement(parser: XmlPullParser, shares: ArrayList<RemoteShare>) {
|
|
||||||
parser.require(XmlPullParser.START_TAG, ns, NODE_ELEMENT)
|
|
||||||
|
|
||||||
val remoteShare = RemoteShare()
|
|
||||||
|
|
||||||
while (parser.next() != XmlPullParser.END_TAG) {
|
|
||||||
if (parser.eventType != XmlPullParser.START_TAG) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
val name = parser.name
|
|
||||||
|
|
||||||
when {
|
|
||||||
name.equals(NODE_ELEMENT, ignoreCase = true) -> {
|
|
||||||
// patch to work around servers responding with extra <element> surrounding all
|
|
||||||
// the shares on the same file before
|
|
||||||
// https://github.com/owncloud/core/issues/6992 was fixed
|
|
||||||
readElement(parser, shares)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_ID, ignoreCase = true) -> {
|
|
||||||
remoteShare.id = readNode(parser, NODE_ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_ITEM_TYPE, ignoreCase = true) -> {
|
|
||||||
remoteShare.isFolder = readNode(parser, NODE_ITEM_TYPE).equals(TYPE_FOLDER, ignoreCase = true)
|
|
||||||
fixPathForFolder(remoteShare)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_PARENT, ignoreCase = true) -> {
|
|
||||||
readNode(parser, NODE_PARENT)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_SHARE_TYPE, ignoreCase = true) -> {
|
|
||||||
val value = Integer.parseInt(readNode(parser, NODE_SHARE_TYPE))
|
|
||||||
remoteShare.shareType = ShareType.fromValue(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_SHARE_WITH, ignoreCase = true) -> {
|
|
||||||
remoteShare.shareWith = readNode(parser, NODE_SHARE_WITH)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_PATH, ignoreCase = true) -> {
|
|
||||||
remoteShare.path = readNode(parser, NODE_PATH)
|
|
||||||
fixPathForFolder(remoteShare)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_PERMISSIONS, ignoreCase = true) -> {
|
|
||||||
remoteShare.permissions = Integer.parseInt(readNode(parser, NODE_PERMISSIONS))
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_STIME, ignoreCase = true) -> {
|
|
||||||
remoteShare.sharedDate = java.lang.Long.parseLong(readNode(parser, NODE_STIME))
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_EXPIRATION, ignoreCase = true) -> {
|
|
||||||
val value = readNode(parser, NODE_EXPIRATION)
|
|
||||||
if (value.isNotEmpty()) {
|
|
||||||
remoteShare.expirationDate = WebdavUtils.parseResponseDate(value)!!.time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_TOKEN, ignoreCase = true) -> {
|
|
||||||
remoteShare.token = readNode(parser, NODE_TOKEN)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_STORAGE, ignoreCase = true) -> {
|
|
||||||
readNode(parser, NODE_STORAGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_MAIL_SEND, ignoreCase = true) -> {
|
|
||||||
readNode(parser, NODE_MAIL_SEND)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_SHARE_WITH_DISPLAY_NAME, ignoreCase = true) -> {
|
|
||||||
remoteShare.sharedWithDisplayName = readNode(parser, NODE_SHARE_WITH_DISPLAY_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_SHARE_WITH_ADDITIONAL_INFO, ignoreCase = true) -> {
|
|
||||||
remoteShare.sharedWithAdditionalInfo = readNode(parser, NODE_SHARE_WITH_ADDITIONAL_INFO)
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_URL, ignoreCase = true) -> {
|
|
||||||
val value = readNode(parser, NODE_URL)
|
|
||||||
remoteShare.shareLink = value
|
|
||||||
}
|
|
||||||
|
|
||||||
name.equals(NODE_NAME, ignoreCase = true) -> {
|
|
||||||
remoteShare.name = readNode(parser, NODE_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
skip(parser)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shares.add(remoteShare)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun fixPathForFolder(share: RemoteShare) {
|
|
||||||
if (share.isFolder && share.path.isNotEmpty() &&
|
|
||||||
!share.path.endsWith(File.separator)
|
|
||||||
) {
|
|
||||||
share.path = share.path + File.separator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a node, to obtain its text. Needs readText method
|
|
||||||
* @param parser
|
|
||||||
* @param node
|
|
||||||
* @return Text of the node
|
|
||||||
* @throws XmlPullParserException
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
@Throws(XmlPullParserException::class, IOException::class)
|
|
||||||
private fun readNode(parser: XmlPullParser, node: String): String {
|
|
||||||
parser.require(XmlPullParser.START_TAG, ns, node)
|
|
||||||
val value = readText(parser)
|
|
||||||
parser.require(XmlPullParser.END_TAG, ns, node)
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the text from a node
|
|
||||||
* @param parser
|
|
||||||
* @return Text of the node
|
|
||||||
* @throws IOException
|
|
||||||
* @throws XmlPullParserException
|
|
||||||
*/
|
|
||||||
@Throws(IOException::class, XmlPullParserException::class)
|
|
||||||
private fun readText(parser: XmlPullParser): String {
|
|
||||||
var result = ""
|
|
||||||
if (parser.next() == XmlPullParser.TEXT) {
|
|
||||||
result = parser.text
|
|
||||||
parser.nextTag()
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Skip tags in parser procedure
|
|
||||||
* @param parser
|
|
||||||
* @throws XmlPullParserException
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
@Throws(XmlPullParserException::class, IOException::class)
|
|
||||||
private fun skip(parser: XmlPullParser) {
|
|
||||||
if (parser.eventType != XmlPullParser.START_TAG) {
|
|
||||||
throw IllegalStateException()
|
|
||||||
}
|
|
||||||
var depth = 1
|
|
||||||
while (depth != 0) {
|
|
||||||
when (parser.next()) {
|
|
||||||
XmlPullParser.END_TAG -> depth--
|
|
||||||
XmlPullParser.START_TAG -> depth++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
// No namespaces
|
|
||||||
private val ns: String? = null
|
|
||||||
|
|
||||||
// NODES for XML Parser
|
|
||||||
private const val NODE_OCS = "ocs"
|
|
||||||
|
|
||||||
private const val NODE_META = "meta"
|
|
||||||
private const val NODE_STATUS = "status"
|
|
||||||
private const val NODE_STATUS_CODE = "statuscode"
|
|
||||||
private const val NODE_MESSAGE = "message"
|
|
||||||
|
|
||||||
private const val NODE_DATA = "data"
|
|
||||||
private const val NODE_ELEMENT = "element"
|
|
||||||
private const val NODE_ID = "id"
|
|
||||||
private const val NODE_ITEM_TYPE = "item_type"
|
|
||||||
private const val NODE_PARENT = "parent"
|
|
||||||
private const val NODE_SHARE_TYPE = "share_type"
|
|
||||||
private const val NODE_SHARE_WITH = "share_with"
|
|
||||||
private const val NODE_PATH = "path"
|
|
||||||
private const val NODE_PERMISSIONS = "permissions"
|
|
||||||
private const val NODE_STIME = "stime"
|
|
||||||
private const val NODE_EXPIRATION = "expiration"
|
|
||||||
private const val NODE_TOKEN = "token"
|
|
||||||
private const val NODE_STORAGE = "storage"
|
|
||||||
private const val NODE_MAIL_SEND = "mail_send"
|
|
||||||
private const val NODE_SHARE_WITH_DISPLAY_NAME = "share_with_displayname"
|
|
||||||
private const val NODE_SHARE_WITH_ADDITIONAL_INFO = "share_with_additional_info"
|
|
||||||
private const val NODE_NAME = "name"
|
|
||||||
|
|
||||||
private const val NODE_URL = "url"
|
|
||||||
|
|
||||||
private const val TYPE_FOLDER = "folder"
|
|
||||||
|
|
||||||
private const val SUCCESS = 200
|
|
||||||
private const val ERROR_WRONG_PARAMETER = 400
|
|
||||||
private const val ERROR_FORBIDDEN = 403
|
|
||||||
private const val ERROR_NOT_FOUND = 404
|
|
||||||
private const val INIT = -1
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,9 @@
|
|||||||
/* ownCloud Android Library is available under MIT license
|
/* ownCloud Android Library is available under MIT license
|
||||||
*
|
* @author masensio
|
||||||
* Copyright (C) 2020 ownCloud GmbH.
|
* @author David A. Velasco
|
||||||
|
* @author David González Verdugo
|
||||||
|
* @author Fernando Sanz Velasco
|
||||||
|
* Copyright (C) 2021 ownCloud GmbH
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -25,14 +28,23 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.shares
|
package com.owncloud.android.lib.resources.shares
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient
|
import com.owncloud.android.lib.common.OwnCloudClient
|
||||||
import com.owncloud.android.lib.common.http.HttpConstants
|
import com.owncloud.android.lib.common.http.HttpConstants
|
||||||
|
import com.owncloud.android.lib.common.http.HttpConstants.PARAM_FORMAT
|
||||||
|
import com.owncloud.android.lib.common.http.HttpConstants.VALUE_FORMAT
|
||||||
import com.owncloud.android.lib.common.http.methods.nonwebdav.PutMethod
|
import com.owncloud.android.lib.common.http.methods.nonwebdav.PutMethod
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation
|
import com.owncloud.android.lib.common.operations.RemoteOperation
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
||||||
|
import com.owncloud.android.lib.resources.CommonOcsResponse
|
||||||
import com.owncloud.android.lib.resources.shares.RemoteShare.Companion.DEFAULT_PERMISSION
|
import com.owncloud.android.lib.resources.shares.RemoteShare.Companion.DEFAULT_PERMISSION
|
||||||
|
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 okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import java.lang.reflect.Type
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
@ -46,6 +58,7 @@ import java.util.Locale
|
|||||||
*
|
*
|
||||||
* @author David A. Velasco
|
* @author David A. Velasco
|
||||||
* @author David González Verdugo
|
* @author David González Verdugo
|
||||||
|
* @author Fernando Sanz Velasco
|
||||||
*/
|
*/
|
||||||
class UpdateRemoteShareOperation
|
class UpdateRemoteShareOperation
|
||||||
/**
|
/**
|
||||||
@ -57,7 +70,7 @@ class UpdateRemoteShareOperation
|
|||||||
*/
|
*/
|
||||||
private val remoteId: String
|
private val remoteId: String
|
||||||
|
|
||||||
) : RemoteOperation<ShareParserResult>() {
|
) : RemoteOperation<ShareResponse>() {
|
||||||
/**
|
/**
|
||||||
* Name to update in Share resource. Ignored by servers previous to version 10.0.0
|
* Name to update in Share resource. Ignored by servers previous to version 10.0.0
|
||||||
*
|
*
|
||||||
@ -99,100 +112,131 @@ class UpdateRemoteShareOperation
|
|||||||
|
|
||||||
var retrieveShareDetails = false // To retrieve more info about the just updated share
|
var retrieveShareDetails = false // To retrieve more info about the just updated share
|
||||||
|
|
||||||
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareParserResult> {
|
private fun buildRequestUri(baseUri: Uri) =
|
||||||
var result: RemoteOperationResult<ShareParserResult>
|
baseUri.buildUpon()
|
||||||
|
.appendEncodedPath(OCS_ROUTE)
|
||||||
|
.appendEncodedPath(remoteId)
|
||||||
|
.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT)
|
||||||
|
.build()
|
||||||
|
|
||||||
try {
|
private fun parseResponse(response: String): ShareResponse? {
|
||||||
val formBodyBuilder = FormBody.Builder()
|
val moshi = Moshi.Builder().build()
|
||||||
|
val commonOcsType: Type = Types.newParameterizedType(CommonOcsResponse::class.java, ShareItem::class.java)
|
||||||
|
val adapter: JsonAdapter<CommonOcsResponse<ShareItem>> = moshi.adapter(commonOcsType)
|
||||||
|
val remoteShare = adapter.fromJson(response)?.ocs?.data?.toRemoteShare()
|
||||||
|
return ShareResponse(remoteShare?.let { listOf(it) } ?: listOf())
|
||||||
|
}
|
||||||
|
|
||||||
// Parameters to update
|
private fun onResultUnsuccessful(
|
||||||
if (name != null) {
|
method: PutMethod,
|
||||||
formBodyBuilder.add(PARAM_NAME, name!!)
|
response: String?,
|
||||||
}
|
status: Int
|
||||||
|
): RemoteOperationResult<ShareResponse> {
|
||||||
|
Timber.e("Failed response while while updating remote shares ")
|
||||||
|
if (response != null) {
|
||||||
|
Timber.e("*** status code: $status; response message: $response")
|
||||||
|
} else {
|
||||||
|
Timber.e("*** status code: $status")
|
||||||
|
}
|
||||||
|
return RemoteOperationResult(method)
|
||||||
|
}
|
||||||
|
|
||||||
if (password != null) {
|
private fun onRequestSuccessful(response: String?): RemoteOperationResult<ShareResponse> {
|
||||||
formBodyBuilder.add(PARAM_PASSWORD, password!!)
|
val result = RemoteOperationResult<ShareResponse>(RemoteOperationResult.ResultCode.OK)
|
||||||
}
|
Timber.d("Successful response: $response")
|
||||||
|
result.data = parseResponse(response!!)
|
||||||
|
Timber.d("*** Retrieve the index of the new share completed ")
|
||||||
|
val emptyShare = result.data.shares.first()
|
||||||
|
|
||||||
if (expirationDateInMillis < INITIAL_EXPIRATION_DATE_IN_MILLIS) {
|
return if (retrieveShareDetails) {
|
||||||
// clear expiration date
|
// retrieve more info - PUT only returns the index of the new share
|
||||||
formBodyBuilder.add(PARAM_EXPIRATION_DATE, "")
|
GetRemoteShareOperation(emptyShare.id).execute(client)
|
||||||
|
} else {
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (expirationDateInMillis > INITIAL_EXPIRATION_DATE_IN_MILLIS) {
|
private fun createFormBodyBuilder(): FormBody.Builder {
|
||||||
// set expiration date
|
val formBodyBuilder = FormBody.Builder()
|
||||||
val dateFormat = SimpleDateFormat(FORMAT_EXPIRATION_DATE, Locale.getDefault())
|
|
||||||
val expirationDate = Calendar.getInstance()
|
|
||||||
expirationDate.timeInMillis = expirationDateInMillis
|
|
||||||
val formattedExpirationDate = dateFormat.format(expirationDate.time)
|
|
||||||
formBodyBuilder.add(PARAM_EXPIRATION_DATE, formattedExpirationDate)
|
|
||||||
} // else, ignore - no update
|
|
||||||
|
|
||||||
if (publicUpload != null) {
|
// Parameters to update
|
||||||
formBodyBuilder.add(PARAM_PUBLIC_UPLOAD, publicUpload.toString())
|
if (name != null) {
|
||||||
}
|
formBodyBuilder.add(PARAM_NAME, name.orEmpty())
|
||||||
|
|
||||||
// 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) {
|
|
||||||
// set permissions
|
|
||||||
formBodyBuilder.add(PARAM_PERMISSIONS, permissions.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
val requestUri = client.baseUri
|
|
||||||
val uriBuilder = requestUri.buildUpon()
|
|
||||||
uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH)
|
|
||||||
uriBuilder.appendEncodedPath(remoteId.toString())
|
|
||||||
|
|
||||||
val putMethod = PutMethod(URL(uriBuilder.build().toString()), formBodyBuilder.build())
|
|
||||||
|
|
||||||
putMethod.setRequestHeader(HttpConstants.CONTENT_TYPE_HEADER, HttpConstants.CONTENT_TYPE_URLENCODED_UTF8)
|
|
||||||
putMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE)
|
|
||||||
|
|
||||||
val status = client.executeHttpMethod(putMethod)
|
|
||||||
|
|
||||||
// Parse xml response
|
|
||||||
val parser = ShareToRemoteOperationResultParser(
|
|
||||||
ShareXMLParser()
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!isSuccess(status)) {
|
|
||||||
return parser.parse(putMethod.getResponseBodyAsString())
|
|
||||||
}
|
|
||||||
|
|
||||||
parser.ownCloudVersion = client.ownCloudVersion
|
|
||||||
parser.serverBaseUri = client.baseUri
|
|
||||||
result = parser.parse(putMethod.getResponseBodyAsString())
|
|
||||||
|
|
||||||
if (result.isSuccess && retrieveShareDetails) {
|
|
||||||
// retrieve more info - PUT only returns the index of the new share
|
|
||||||
val emptyShare = result.data.shares.first()
|
|
||||||
val getInfo = GetRemoteShareOperation(
|
|
||||||
emptyShare.id
|
|
||||||
)
|
|
||||||
result = getInfo.execute(client)
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (e: Exception) {
|
|
||||||
result = RemoteOperationResult(e)
|
|
||||||
Timber.e(e, "Exception while Creating New Share")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
if (password != null) {
|
||||||
|
formBodyBuilder.add(PARAM_PASSWORD, password.orEmpty())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expirationDateInMillis < INITIAL_EXPIRATION_DATE_IN_MILLIS) {
|
||||||
|
// clear expiration date
|
||||||
|
formBodyBuilder.add(PARAM_EXPIRATION_DATE, "")
|
||||||
|
|
||||||
|
} else if (expirationDateInMillis > INITIAL_EXPIRATION_DATE_IN_MILLIS) {
|
||||||
|
// set expiration date
|
||||||
|
val dateFormat = SimpleDateFormat(FORMAT_EXPIRATION_DATE, Locale.getDefault())
|
||||||
|
val expirationDate = Calendar.getInstance()
|
||||||
|
expirationDate.timeInMillis = expirationDateInMillis
|
||||||
|
val formattedExpirationDate = dateFormat.format(expirationDate.time)
|
||||||
|
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) {
|
||||||
|
// set permissions
|
||||||
|
formBodyBuilder.add(PARAM_PERMISSIONS, permissions.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
return formBodyBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun run(client: OwnCloudClient): RemoteOperationResult<ShareResponse> {
|
||||||
|
val requestUri = buildRequestUri(client.baseUri)
|
||||||
|
|
||||||
|
val formBodyBuilder = createFormBodyBuilder()
|
||||||
|
|
||||||
|
val putMethod = PutMethod(URL(requestUri.toString()), formBodyBuilder.build()).apply {
|
||||||
|
setRequestHeader(HttpConstants.CONTENT_TYPE_HEADER, HttpConstants.CONTENT_TYPE_URLENCODED_UTF8)
|
||||||
|
addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return try {
|
||||||
|
val status = client.executeHttpMethod(putMethod)
|
||||||
|
val response = putMethod.getResponseBodyAsString()
|
||||||
|
|
||||||
|
if (isSuccess(status)) {
|
||||||
|
onRequestSuccessful(response)
|
||||||
|
} else {
|
||||||
|
onResultUnsuccessful(putMethod, response, status)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e, "Exception while updating remote share")
|
||||||
|
RemoteOperationResult(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
|
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
//OCS Route
|
||||||
|
private const val OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/shares"
|
||||||
|
|
||||||
|
//Arguments - names
|
||||||
private const val PARAM_NAME = "name"
|
private const val PARAM_NAME = "name"
|
||||||
private const val PARAM_PASSWORD = "password"
|
private const val PARAM_PASSWORD = "password"
|
||||||
private const val PARAM_EXPIRATION_DATE = "expireDate"
|
private const val PARAM_EXPIRATION_DATE = "expireDate"
|
||||||
private const val PARAM_PERMISSIONS = "permissions"
|
private const val PARAM_PERMISSIONS = "permissions"
|
||||||
private const val PARAM_PUBLIC_UPLOAD = "publicUpload"
|
private const val PARAM_PUBLIC_UPLOAD = "publicUpload"
|
||||||
private const val FORMAT_EXPIRATION_DATE = "yyyy-MM-dd"
|
|
||||||
private const val ENTITY_CONTENT_TYPE = "application/x-www-form-urlencoded"
|
|
||||||
private const val ENTITY_CHARSET = "UTF-8"
|
|
||||||
|
|
||||||
|
//Arguments - constant values
|
||||||
|
private const val FORMAT_EXPIRATION_DATE = "yyyy-MM-dd"
|
||||||
private const val INITIAL_EXPIRATION_DATE_IN_MILLIS: Long = 0
|
private const val INITIAL_EXPIRATION_DATE_IN_MILLIS: Long = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
* @author Fernando Sanz Velasco
|
||||||
|
* Copyright (C) 2021 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.shares.responses
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.network.WebdavUtils
|
||||||
|
import com.owncloud.android.lib.resources.shares.RemoteShare
|
||||||
|
import com.owncloud.android.lib.resources.shares.RemoteShare.Companion.DEFAULT_PERMISSION
|
||||||
|
import com.owncloud.android.lib.resources.shares.RemoteShare.Companion.INIT_EXPIRATION_DATE_IN_MILLIS
|
||||||
|
import com.owncloud.android.lib.resources.shares.RemoteShare.Companion.INIT_SHARED_DATE
|
||||||
|
import com.owncloud.android.lib.resources.shares.ShareType
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class ShareItem(
|
||||||
|
val id: String? = null,
|
||||||
|
|
||||||
|
@Json(name = "share_with")
|
||||||
|
val shareWith: String? = null,
|
||||||
|
|
||||||
|
val path: String? = null,
|
||||||
|
val token: String? = null,
|
||||||
|
|
||||||
|
@Json(name = "item_type")
|
||||||
|
val itemType: String? = null,
|
||||||
|
|
||||||
|
@Json(name = "share_with_displayname")
|
||||||
|
val sharedWithDisplayName: String? = null,
|
||||||
|
|
||||||
|
@Json(name = "share_with_additional_info")
|
||||||
|
val sharedWithAdditionalInfo: String? = null,
|
||||||
|
|
||||||
|
val name: String? = null,
|
||||||
|
|
||||||
|
@Json(name = "url")
|
||||||
|
val shareLink: String? = null,
|
||||||
|
|
||||||
|
@Json(name = "share_type")
|
||||||
|
val shareType: Int? = null,
|
||||||
|
|
||||||
|
val permissions: Int? = null,
|
||||||
|
|
||||||
|
@Json(name = "stime")
|
||||||
|
val sharedDate: Long? = null,
|
||||||
|
|
||||||
|
@Json(name = "expiration")
|
||||||
|
val expirationDate: String? = null,
|
||||||
|
) {
|
||||||
|
fun toRemoteShare() = RemoteShare(
|
||||||
|
id = id ?: "0",
|
||||||
|
shareWith = shareWith.orEmpty(),
|
||||||
|
path = if (itemType == ItemType.FOLDER.fileValue) path.plus(File.separator) else path.orEmpty(),
|
||||||
|
token = token.orEmpty(),
|
||||||
|
itemType = itemType.orEmpty(),
|
||||||
|
sharedWithDisplayName = sharedWithDisplayName.orEmpty(),
|
||||||
|
sharedWithAdditionalInfo = sharedWithAdditionalInfo.orEmpty(),
|
||||||
|
name = name.orEmpty(),
|
||||||
|
shareLink = shareLink.orEmpty(),
|
||||||
|
shareType = ShareType.values().firstOrNull { it.value == shareType } ?: ShareType.UNKNOWN,
|
||||||
|
permissions = permissions ?: DEFAULT_PERMISSION,
|
||||||
|
sharedDate = sharedDate ?: INIT_SHARED_DATE,
|
||||||
|
expirationDate = expirationDate?.let {
|
||||||
|
WebdavUtils.parseResponseDate(it)?.time
|
||||||
|
} ?: INIT_EXPIRATION_DATE_IN_MILLIS,
|
||||||
|
isFolder = itemType?.equals(ItemType.FOLDER.fileValue) ?: false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class ItemType(val fileValue: String) { FILE("file"), FOLDER("folder") }
|
@ -22,7 +22,7 @@ package com.owncloud.android.lib.resources.shares.services
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
||||||
import com.owncloud.android.lib.resources.Service
|
import com.owncloud.android.lib.resources.Service
|
||||||
import com.owncloud.android.lib.resources.shares.ShareParserResult
|
import com.owncloud.android.lib.resources.shares.ShareResponse
|
||||||
import com.owncloud.android.lib.resources.shares.ShareType
|
import com.owncloud.android.lib.resources.shares.ShareType
|
||||||
|
|
||||||
interface ShareService : Service {
|
interface ShareService : Service {
|
||||||
@ -30,7 +30,7 @@ interface ShareService : Service {
|
|||||||
remoteFilePath: String,
|
remoteFilePath: String,
|
||||||
reshares: Boolean,
|
reshares: Boolean,
|
||||||
subfiles: Boolean
|
subfiles: Boolean
|
||||||
): RemoteOperationResult<ShareParserResult>
|
): RemoteOperationResult<ShareResponse>
|
||||||
|
|
||||||
fun insertShare(
|
fun insertShare(
|
||||||
remoteFilePath: String,
|
remoteFilePath: String,
|
||||||
@ -41,7 +41,7 @@ interface ShareService : Service {
|
|||||||
password: String,
|
password: String,
|
||||||
expirationDate: Long,
|
expirationDate: Long,
|
||||||
publicUpload: Boolean
|
publicUpload: Boolean
|
||||||
): RemoteOperationResult<ShareParserResult>
|
): RemoteOperationResult<ShareResponse>
|
||||||
|
|
||||||
fun updateShare(
|
fun updateShare(
|
||||||
remoteId: String,
|
remoteId: String,
|
||||||
@ -50,7 +50,7 @@ interface ShareService : Service {
|
|||||||
expirationDate: Long,
|
expirationDate: Long,
|
||||||
permissions: Int,
|
permissions: Int,
|
||||||
publicUpload: Boolean
|
publicUpload: Boolean
|
||||||
): RemoteOperationResult<ShareParserResult>
|
): RemoteOperationResult<ShareResponse>
|
||||||
|
|
||||||
fun deleteShare(remoteId: String): RemoteOperationResult<ShareParserResult>
|
fun deleteShare(remoteId: String): RemoteOperationResult<ShareResponse>
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
|||||||
import com.owncloud.android.lib.resources.shares.CreateRemoteShareOperation
|
import com.owncloud.android.lib.resources.shares.CreateRemoteShareOperation
|
||||||
import com.owncloud.android.lib.resources.shares.GetRemoteSharesForFileOperation
|
import com.owncloud.android.lib.resources.shares.GetRemoteSharesForFileOperation
|
||||||
import com.owncloud.android.lib.resources.shares.RemoveRemoteShareOperation
|
import com.owncloud.android.lib.resources.shares.RemoveRemoteShareOperation
|
||||||
import com.owncloud.android.lib.resources.shares.ShareParserResult
|
import com.owncloud.android.lib.resources.shares.ShareResponse
|
||||||
import com.owncloud.android.lib.resources.shares.ShareType
|
import com.owncloud.android.lib.resources.shares.ShareType
|
||||||
import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation
|
import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation
|
||||||
import com.owncloud.android.lib.resources.shares.services.ShareService
|
import com.owncloud.android.lib.resources.shares.services.ShareService
|
||||||
@ -36,7 +36,7 @@ class OCShareService(override val client: OwnCloudClient) :
|
|||||||
remoteFilePath: String,
|
remoteFilePath: String,
|
||||||
reshares: Boolean,
|
reshares: Boolean,
|
||||||
subfiles: Boolean
|
subfiles: Boolean
|
||||||
): RemoteOperationResult<ShareParserResult> = GetRemoteSharesForFileOperation(
|
): RemoteOperationResult<ShareResponse> = GetRemoteSharesForFileOperation(
|
||||||
remoteFilePath,
|
remoteFilePath,
|
||||||
reshares,
|
reshares,
|
||||||
subfiles
|
subfiles
|
||||||
@ -51,7 +51,7 @@ class OCShareService(override val client: OwnCloudClient) :
|
|||||||
password: String,
|
password: String,
|
||||||
expirationDate: Long,
|
expirationDate: Long,
|
||||||
publicUpload: Boolean
|
publicUpload: Boolean
|
||||||
): RemoteOperationResult<ShareParserResult> =
|
): RemoteOperationResult<ShareResponse> =
|
||||||
CreateRemoteShareOperation(
|
CreateRemoteShareOperation(
|
||||||
remoteFilePath,
|
remoteFilePath,
|
||||||
shareType,
|
shareType,
|
||||||
@ -72,7 +72,7 @@ class OCShareService(override val client: OwnCloudClient) :
|
|||||||
expirationDate: Long,
|
expirationDate: Long,
|
||||||
permissions: Int,
|
permissions: Int,
|
||||||
publicUpload: Boolean
|
publicUpload: Boolean
|
||||||
): RemoteOperationResult<ShareParserResult> =
|
): RemoteOperationResult<ShareResponse> =
|
||||||
UpdateRemoteShareOperation(
|
UpdateRemoteShareOperation(
|
||||||
remoteId
|
remoteId
|
||||||
).apply {
|
).apply {
|
||||||
@ -84,7 +84,7 @@ class OCShareService(override val client: OwnCloudClient) :
|
|||||||
this.retrieveShareDetails = true
|
this.retrieveShareDetails = true
|
||||||
}.execute(client)
|
}.execute(client)
|
||||||
|
|
||||||
override fun deleteShare(remoteId: String): RemoteOperationResult<ShareParserResult> =
|
override fun deleteShare(remoteId: String): RemoteOperationResult<ShareResponse> =
|
||||||
RemoveRemoteShareOperation(
|
RemoveRemoteShareOperation(
|
||||||
remoteId
|
remoteId
|
||||||
).execute(client)
|
).execute(client)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user