mirror of
				https://github.com/owncloud/android-library.git
				synced 2025-10-31 02:17:41 +00:00 
			
		
		
		
	
						commit
						5ecd3c9311
					
				| @ -1,6 +1,7 @@ | |||||||
| buildscript { | buildscript { | ||||||
|     ext { |     ext { | ||||||
|         kotlinVersion = '1.3.71' |         kotlinVersion = '1.3.71' | ||||||
|  |         moshiVersion = "1.9.2" | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     repositories { |     repositories { | ||||||
|  | |||||||
| @ -9,6 +9,12 @@ dependencies { | |||||||
|     api 'com.gitlab.ownclouders:dav4android:oc_support_1.0.1' |     api 'com.gitlab.ownclouders:dav4android:oc_support_1.0.1' | ||||||
|     api 'com.github.hannesa2:Logcat:1.6.0' |     api 'com.github.hannesa2:Logcat:1.6.0' | ||||||
|     api 'net.openid:appauth:0.7.1' |     api 'net.openid:appauth:0.7.1' | ||||||
|  | 
 | ||||||
|  |     // Moshi | ||||||
|  |     implementation ("com.squareup.moshi:moshi-kotlin:$moshiVersion") { | ||||||
|  |         exclude module: "kotlin-reflect" | ||||||
|  |     } | ||||||
|  |     kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshiVersion" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| allOpen { | allOpen { | ||||||
|  | |||||||
| @ -53,6 +53,7 @@ import static com.owncloud.android.lib.common.http.HttpConstants.OC_X_REQUEST_ID | |||||||
| public class OwnCloudClient extends HttpClient { | public class OwnCloudClient extends HttpClient { | ||||||
| 
 | 
 | ||||||
|     public static final String WEBDAV_FILES_PATH_4_0 = "/remote.php/dav/files/"; |     public static final String WEBDAV_FILES_PATH_4_0 = "/remote.php/dav/files/"; | ||||||
|  |     public static final String WEBDAV_PATH_4_0_AND_LATER = "/remote.php/dav"; | ||||||
|     private static final String WEBDAV_UPLOADS_PATH_4_0 = "/remote.php/dav/uploads/"; |     private static final String WEBDAV_UPLOADS_PATH_4_0 = "/remote.php/dav/uploads/"; | ||||||
|     public static final String STATUS_PATH = "/status.php"; |     public static final String STATUS_PATH = "/status.php"; | ||||||
| 
 | 
 | ||||||
| @ -230,7 +231,7 @@ public class OwnCloudClient extends HttpClient { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Uri getUserFilesWebDavUri() { |     public Uri getUserFilesWebDavUri() { | ||||||
|         return mCredentials instanceof OwnCloudAnonymousCredentials |         return (mCredentials instanceof OwnCloudAnonymousCredentials || mAccount == null) | ||||||
|                 ? Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0) |                 ? Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0) | ||||||
|                 : Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0 + AccountUtils.getUserId( |                 : Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0 + AccountUtils.getUserId( | ||||||
|                 mAccount.getSavedAccount(), getContext() |                 mAccount.getSavedAccount(), getContext() | ||||||
|  | |||||||
| @ -46,7 +46,6 @@ import java.util.ArrayList; | |||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| public class AccountUtils { | public class AccountUtils { | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Constructs full url to host and webdav resource basing on host version |      * Constructs full url to host and webdav resource basing on host version | ||||||
|      * |      * | ||||||
| @ -140,7 +139,7 @@ public class AccountUtils { | |||||||
|         AccountManager am = AccountManager.get(context); |         AccountManager am = AccountManager.get(context); | ||||||
| 
 | 
 | ||||||
|         String supportsOAuth2 = am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_OAUTH2); |         String supportsOAuth2 = am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_OAUTH2); | ||||||
|         boolean isOauth2 = supportsOAuth2 != null && supportsOAuth2.equals("TRUE"); |         boolean isOauth2 = supportsOAuth2 != null && supportsOAuth2.equals(Constants.OAUTH_SUPPORTED_TRUE); | ||||||
| 
 | 
 | ||||||
|         String username = AccountUtils.getUsernameForAccount(account); |         String username = AccountUtils.getUsernameForAccount(account); | ||||||
| 
 | 
 | ||||||
| @ -295,6 +294,8 @@ public class AccountUtils { | |||||||
|          */ |          */ | ||||||
|         public static final String KEY_SUPPORTS_OAUTH2 = "oc_supports_oauth2"; |         public static final String KEY_SUPPORTS_OAUTH2 = "oc_supports_oauth2"; | ||||||
| 
 | 
 | ||||||
|  |         public static final String OAUTH_SUPPORTED_TRUE = "TRUE"; | ||||||
|  | 
 | ||||||
|         /** |         /** | ||||||
|          * OC account cookies |          * OC account cookies | ||||||
|          */ |          */ | ||||||
| @ -329,5 +330,7 @@ public class AccountUtils { | |||||||
|          * OAuth2 scope |          * OAuth2 scope | ||||||
|          */ |          */ | ||||||
|         public static final String KEY_OAUTH2_SCOPE = "oc_oauth2_scope"; |         public static final String KEY_OAUTH2_SCOPE = "oc_oauth2_scope"; | ||||||
|  | 
 | ||||||
|  |         public static final int ACCOUNT_VERSION = 1; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -34,11 +34,12 @@ import java.text.SimpleDateFormat; | |||||||
| import java.util.Date; | import java.util.Date; | ||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
| 
 | 
 | ||||||
| public class WebdavUtils { | import static com.owncloud.android.lib.common.OwnCloudClient.WEBDAV_FILES_PATH_4_0; | ||||||
|     public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat( | import static com.owncloud.android.lib.common.OwnCloudClient.WEBDAV_PATH_4_0_AND_LATER; | ||||||
|             "dd.MM.yyyy hh:mm"); |  | ||||||
| 
 | 
 | ||||||
|     private static final SimpleDateFormat DATETIME_FORMATS[] = { | public class WebdavUtils { | ||||||
|  | 
 | ||||||
|  |     private static final SimpleDateFormat[] DATETIME_FORMATS = { | ||||||
|             new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US), |             new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US), | ||||||
|             new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US), |             new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US), | ||||||
|             new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US), |             new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US), | ||||||
| @ -50,11 +51,11 @@ public class WebdavUtils { | |||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     public static Date parseResponseDate(String date) { |     public static Date parseResponseDate(String date) { | ||||||
|         Date returnDate = null; |         Date returnDate; | ||||||
|         SimpleDateFormat format = null; |         SimpleDateFormat format; | ||||||
|         for (int i = 0; i < DATETIME_FORMATS.length; ++i) { |         for (SimpleDateFormat datetimeFormat : DATETIME_FORMATS) { | ||||||
|             try { |             try { | ||||||
|                 format = DATETIME_FORMATS[i]; |                 format = datetimeFormat; | ||||||
|                 synchronized (format) { |                 synchronized (format) { | ||||||
|                     returnDate = format.parse(date); |                     returnDate = format.parse(date); | ||||||
|                 } |                 } | ||||||
| @ -82,23 +83,6 @@ public class WebdavUtils { | |||||||
|         return encodedPath; |         return encodedPath; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * @param rawEtag |  | ||||||
|      * @return |  | ||||||
|      */ |  | ||||||
|     public static String parseEtag(String rawEtag) { |  | ||||||
|         if (rawEtag == null || rawEtag.length() == 0) { |  | ||||||
|             return ""; |  | ||||||
|         } |  | ||||||
|         if (rawEtag.endsWith("-gzip")) { |  | ||||||
|             rawEtag = rawEtag.substring(0, rawEtag.length() - 5); |  | ||||||
|         } |  | ||||||
|         if (rawEtag.length() >= 2 && rawEtag.startsWith("\"") && rawEtag.endsWith("\"")) { |  | ||||||
|             rawEtag = rawEtag.substring(1, rawEtag.length() - 1); |  | ||||||
|         } |  | ||||||
|         return rawEtag; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * @param httpBaseMethod from which to get the etag |      * @param httpBaseMethod from which to get the etag | ||||||
|      * @return etag from response |      * @return etag from response | ||||||
| @ -120,4 +104,17 @@ public class WebdavUtils { | |||||||
|         } |         } | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public static String normalizeProtocolPrefix(String url, boolean isSslConn) { | ||||||
|  |         if (!url.toLowerCase().startsWith("http://") && | ||||||
|  |                 !url.toLowerCase().startsWith("https://")) { | ||||||
|  |             if (isSslConn) { | ||||||
|  |                 return "https://" + url; | ||||||
|  |             } else { | ||||||
|  |                 return "http://" + url; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return url; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
| @ -66,7 +66,7 @@ public class RemoteOperationResult<T> | |||||||
|     private Exception mException = null; |     private Exception mException = null; | ||||||
|     private ResultCode mCode = ResultCode.UNKNOWN_ERROR; |     private ResultCode mCode = ResultCode.UNKNOWN_ERROR; | ||||||
|     private String mRedirectedLocation; |     private String mRedirectedLocation; | ||||||
|     private ArrayList<String> mAuthenticate = new ArrayList<>(); |     private String mAuthenticate; | ||||||
|     private String mLastPermanentLocation = null; |     private String mLastPermanentLocation = null; | ||||||
|     private T mData = null; |     private T mData = null; | ||||||
| 
 | 
 | ||||||
| @ -253,7 +253,7 @@ public class RemoteOperationResult<T> | |||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|                 if ("www-authenticate".equals(header.getKey().toLowerCase())) { |                 if ("www-authenticate".equals(header.getKey().toLowerCase())) { | ||||||
|                     mAuthenticate.add(header.getValue().get(0).toLowerCase()); |                     mAuthenticate = header.getValue().get(0).toLowerCase(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @ -494,7 +494,7 @@ public class RemoteOperationResult<T> | |||||||
|         return (mRedirectedLocation != null && !(mRedirectedLocation.toLowerCase().startsWith("https://"))); |         return (mRedirectedLocation != null && !(mRedirectedLocation.toLowerCase().startsWith("https://"))); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public ArrayList<String> getAuthenticateHeaders() { |     public String getAuthenticateHeaders() { | ||||||
|         return mAuthenticate; |         return mAuthenticate; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -0,0 +1,46 @@ | |||||||
|  | /* 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 | ||||||
|  | 
 | ||||||
|  | import com.squareup.moshi.JsonClass | ||||||
|  | 
 | ||||||
|  | // Response retrieved by OCS Rest API, used to obtain capabilities, shares and user info among others. | ||||||
|  | // More info: https://doc.owncloud.com/server/developer_manual/core/apis/ocs-capabilities.html | ||||||
|  | @JsonClass(generateAdapter = true) | ||||||
|  | data class CommonOcsResponse<T>( | ||||||
|  |     val ocs: OCSResponse<T> | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | @JsonClass(generateAdapter = true) | ||||||
|  | data class OCSResponse<T>( | ||||||
|  |     val meta: MetaData, | ||||||
|  |     val data: T | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | @JsonClass(generateAdapter = true) | ||||||
|  | data class MetaData( | ||||||
|  |     val status: String, | ||||||
|  |     val statuscode: Int, | ||||||
|  |     val message: String? | ||||||
|  | ) | ||||||
| @ -0,0 +1,115 @@ | |||||||
|  | /* ownCloud Android Library is available under MIT license | ||||||
|  | *   Copyright (C) 2020 ownCloud GmbH. | ||||||
|  | * | ||||||
|  | *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  | *   of this software and associated documentation files (the "Software"), to deal | ||||||
|  | *   in the Software without restriction, including without limitation the rights | ||||||
|  | *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  | *   copies of the Software, and to permit persons to whom the Software is | ||||||
|  | *   furnished to do so, subject to the following conditions: | ||||||
|  | * | ||||||
|  | *   The above copyright notice and this permission notice shall be included in | ||||||
|  | *   all copies or substantial portions of the Software. | ||||||
|  | * | ||||||
|  | *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  | *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  | *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  | *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  | *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  | *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  | *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  | *   THE SOFTWARE. | ||||||
|  | * | ||||||
|  | */ | ||||||
|  | package com.owncloud.android.lib.resources.files | ||||||
|  | 
 | ||||||
|  | import com.owncloud.android.lib.common.OwnCloudClient | ||||||
|  | import com.owncloud.android.lib.common.http.HttpConstants | ||||||
|  | import com.owncloud.android.lib.common.http.methods.webdav.DavUtils | ||||||
|  | import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod | ||||||
|  | import com.owncloud.android.lib.common.network.RedirectionPath | ||||||
|  | import com.owncloud.android.lib.common.network.WebdavUtils | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperation | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode | ||||||
|  | import timber.log.Timber | ||||||
|  | import java.net.URL | ||||||
|  | import java.util.concurrent.TimeUnit | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Operation to check the existence of a path in a remote server. | ||||||
|  |  * | ||||||
|  |  * @author David A. Velasco | ||||||
|  |  * @author David González Verdugo | ||||||
|  |  * @author Abel García de Prada | ||||||
|  |  * | ||||||
|  |  * @param remotePath      Path to append to the URL owned by the client instance. | ||||||
|  |  * @param isUserLogged    When `true`, the username won't be added at the end of the PROPFIND url since is not | ||||||
|  |  *                        needed to check user credentials | ||||||
|  |  */ | ||||||
|  | class CheckPathExistenceRemoteOperation( | ||||||
|  |     val remotePath: String? = "", | ||||||
|  |     val isUserLogged: Boolean | ||||||
|  | ) : RemoteOperation<Boolean>() { | ||||||
|  |     /** | ||||||
|  |      * Gets the sequence of redirections followed during the execution of the operation. | ||||||
|  |      * | ||||||
|  |      * @return Sequence of redirections followed, if any, or NULL if the operation was not executed. | ||||||
|  |      */ | ||||||
|  |     var redirectionPath: RedirectionPath? = null | ||||||
|  |         private set | ||||||
|  | 
 | ||||||
|  |     override fun run(client: OwnCloudClient): RemoteOperationResult<Boolean> { | ||||||
|  |         val previousFollowRedirects = client.followRedirects() | ||||||
|  |         return try { | ||||||
|  |             val stringUrl = | ||||||
|  |                 if (isUserLogged) client.baseFilesWebDavUri.toString() | ||||||
|  |                 else client.userFilesWebDavUri.toString() + WebdavUtils.encodePath(remotePath) | ||||||
|  | 
 | ||||||
|  |             val propFindMethod = PropfindMethod(URL(stringUrl), 0, DavUtils.getAllPropset()).apply { | ||||||
|  |                 setReadTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS) | ||||||
|  |                 setConnectionTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS) | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             client.setFollowRedirects(false) | ||||||
|  |             var status = client.executeHttpMethod(propFindMethod) | ||||||
|  |             if (previousFollowRedirects) { | ||||||
|  |                 redirectionPath = client.followRedirection(propFindMethod) | ||||||
|  |                 status = redirectionPath?.lastStatus!! | ||||||
|  |             } | ||||||
|  |             /* PROPFIND method | ||||||
|  |              * 404 NOT FOUND: path doesn't exist, | ||||||
|  |              * 207 MULTI_STATUS: path exists. | ||||||
|  |              */ | ||||||
|  |             Timber.d( | ||||||
|  |                 "Existence check for $stringUrl finished with HTTP status $status${if (!isSuccess(status)) "(FAIL)" else ""}" | ||||||
|  |             ) | ||||||
|  |             if (isSuccess(status)) RemoteOperationResult<Boolean>(ResultCode.OK).apply { data = true } | ||||||
|  |             else RemoteOperationResult<Boolean>(propFindMethod).apply { data = false } | ||||||
|  | 
 | ||||||
|  |         } catch (e: Exception) { | ||||||
|  |             val result = RemoteOperationResult<Boolean>(e) | ||||||
|  |             Timber.e( | ||||||
|  |                 e, | ||||||
|  |                 "Existence check for ${client.userFilesWebDavUri}${WebdavUtils.encodePath(remotePath)} : ${result.logMessage}" | ||||||
|  |             ) | ||||||
|  |             result | ||||||
|  |         } finally { | ||||||
|  |             client.setFollowRedirects(previousFollowRedirects) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * @return 'True' if the operation was executed and at least one redirection was followed. | ||||||
|  |      */ | ||||||
|  |     fun wasRedirected() = redirectionPath?.redirectionsCount ?: 0 > 0 | ||||||
|  | 
 | ||||||
|  |     private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_MULTI_STATUS | ||||||
|  | 
 | ||||||
|  |     companion object { | ||||||
|  |         /** | ||||||
|  |          * Maximum time to wait for a response from the server in milliseconds. | ||||||
|  |          */ | ||||||
|  |         private const val TIMEOUT = 10000 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,150 +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.files; |  | ||||||
| 
 |  | ||||||
| import com.owncloud.android.lib.common.OwnCloudClient; |  | ||||||
| import com.owncloud.android.lib.common.http.HttpConstants; |  | ||||||
| import com.owncloud.android.lib.common.http.methods.webdav.DavUtils; |  | ||||||
| import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod; |  | ||||||
| import com.owncloud.android.lib.common.network.RedirectionPath; |  | ||||||
| import com.owncloud.android.lib.common.network.WebdavUtils; |  | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; |  | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; |  | ||||||
| import timber.log.Timber; |  | ||||||
| 
 |  | ||||||
| import java.net.URL; |  | ||||||
| import java.util.concurrent.TimeUnit; |  | ||||||
| 
 |  | ||||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Operation to check the existence or absence of a path in a remote server. |  | ||||||
|  * |  | ||||||
|  * @author David A. Velasco |  | ||||||
|  * @author David González Verdugo |  | ||||||
|  */ |  | ||||||
| public class ExistenceCheckRemoteOperation extends RemoteOperation { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Maximum time to wait for a response from the server in MILLISECONDs. |  | ||||||
|      */ |  | ||||||
|     public static final int TIMEOUT = 10000; |  | ||||||
| 
 |  | ||||||
|     private String mPath; |  | ||||||
|     private boolean mSuccessIfAbsent; |  | ||||||
|     private boolean mIsLogin; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Sequence of redirections followed. Available only after executing the operation |  | ||||||
|      */ |  | ||||||
|     private RedirectionPath mRedirectionPath = null; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Full constructor. Success of the operation will depend upon the value of successIfAbsent. |  | ||||||
|      * |  | ||||||
|      * @param remotePath      Path to append to the URL owned by the client instance. |  | ||||||
|      * @param successIfAbsent When 'true', the operation finishes in success if the path does |  | ||||||
|      *                        NOT exist in the remote server (HTTP 404). |  | ||||||
|      * @param isLogin         When `true`, the username won't be added at the end of the PROPFIND url since is not |  | ||||||
|      *                        needed to check user credentials |  | ||||||
|      */ |  | ||||||
|     public ExistenceCheckRemoteOperation(String remotePath, boolean successIfAbsent, boolean isLogin) { |  | ||||||
|         mPath = (remotePath != null) ? remotePath : ""; |  | ||||||
|         mSuccessIfAbsent = successIfAbsent; |  | ||||||
|         mIsLogin = isLogin; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     protected RemoteOperationResult run(OwnCloudClient client) { |  | ||||||
| 
 |  | ||||||
|         boolean previousFollowRedirects = client.followRedirects(); |  | ||||||
| 
 |  | ||||||
|         try { |  | ||||||
|             String stringUrl = mIsLogin ? |  | ||||||
|                     client.getBaseFilesWebDavUri().toString() : |  | ||||||
|                     client.getUserFilesWebDavUri() + WebdavUtils.encodePath(mPath); |  | ||||||
|             PropfindMethod propfindMethod = new PropfindMethod( |  | ||||||
|                     new URL(stringUrl), |  | ||||||
|                     0, |  | ||||||
|                     DavUtils.getAllPropset() |  | ||||||
|             ); |  | ||||||
|             propfindMethod.setReadTimeout(TIMEOUT, TimeUnit.SECONDS); |  | ||||||
|             propfindMethod.setConnectionTimeout(TIMEOUT, TimeUnit.SECONDS); |  | ||||||
| 
 |  | ||||||
|             client.setFollowRedirects(false); |  | ||||||
|             int status = client.executeHttpMethod(propfindMethod); |  | ||||||
| 
 |  | ||||||
|             if (previousFollowRedirects) { |  | ||||||
|                 mRedirectionPath = client.followRedirection(propfindMethod); |  | ||||||
|                 status = mRedirectionPath.getLastStatus(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             /* |  | ||||||
|              *  PROPFIND method |  | ||||||
|              *  404 NOT FOUND: path doesn't exist, |  | ||||||
|              *  207 MULTI_STATUS: path exists. |  | ||||||
|              */ |  | ||||||
| 
 |  | ||||||
|             Timber.d("Existence check for " + stringUrl + WebdavUtils.encodePath(mPath) + |  | ||||||
|                     " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + |  | ||||||
|                     "finished with HTTP status " + status + (!isSuccess(status) ? "(FAIL)" : "")); |  | ||||||
| 
 |  | ||||||
|             return isSuccess(status) |  | ||||||
|                     ? new RemoteOperationResult<>(OK) |  | ||||||
|                     : new RemoteOperationResult<>(propfindMethod); |  | ||||||
| 
 |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             final RemoteOperationResult result = new RemoteOperationResult<>(e); |  | ||||||
|             Timber.e(result.getException(), |  | ||||||
|                     "Existence check for " + client.getUserFilesWebDavUri() + WebdavUtils.encodePath(mPath) + " " + |  | ||||||
|                             "targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + ": " + result.getLogMessage()); |  | ||||||
|             return result; |  | ||||||
|         } finally { |  | ||||||
|             client.setFollowRedirects(previousFollowRedirects); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Gets the sequence of redirections followed during the execution of the operation. |  | ||||||
|      * |  | ||||||
|      * @return Sequence of redirections followed, if any, or NULL if the operation was not executed. |  | ||||||
|      */ |  | ||||||
|     public RedirectionPath getRedirectionPath() { |  | ||||||
|         return mRedirectionPath; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @return 'True' if the operation was executed and at least one redirection was followed. |  | ||||||
|      */ |  | ||||||
|     public boolean wasRedirected() { |  | ||||||
|         return (mRedirectionPath != null && mRedirectionPath.getRedirectionsCount() > 0); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private boolean isSuccess(int status) { |  | ||||||
|         return ((status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_MULTI_STATUS) && !mSuccessIfAbsent) |  | ||||||
|                 || (status == HttpConstants.HTTP_MULTI_STATUS && !mSuccessIfAbsent) |  | ||||||
|                 || (status == HttpConstants.HTTP_NOT_FOUND && mSuccessIfAbsent); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -123,9 +123,9 @@ public class RenameRemoteFileOperation extends RemoteOperation { | |||||||
|      * @return 'True' if the target path is already used by an existing file. |      * @return 'True' if the target path is already used by an existing file. | ||||||
|      */ |      */ | ||||||
|     private boolean targetPathIsUsed(OwnCloudClient client) { |     private boolean targetPathIsUsed(OwnCloudClient client) { | ||||||
|         ExistenceCheckRemoteOperation existenceCheckRemoteOperation = |         CheckPathExistenceRemoteOperation checkPathExistenceRemoteOperation = | ||||||
|                 new ExistenceCheckRemoteOperation(mNewRemotePath, false, false); |                 new CheckPathExistenceRemoteOperation(mNewRemotePath, false); | ||||||
|         RemoteOperationResult exists = existenceCheckRemoteOperation.run(client); |         RemoteOperationResult exists = checkPathExistenceRemoteOperation.execute(client); | ||||||
|         return exists.isSuccess(); |         return exists.isSuccess(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -0,0 +1,31 @@ | |||||||
|  | /* ownCloud Android Library is available under MIT license | ||||||
|  |  *   Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  *   of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  *   in the Software without restriction, including without limitation the rights | ||||||
|  |  *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  *   copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  *   furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  *   The above copyright notice and this permission notice shall be included in | ||||||
|  |  *   all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  |  *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  |  *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  |  *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |  *   THE SOFTWARE. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | package com.owncloud.android.lib.resources.files.services | ||||||
|  | 
 | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.resources.Service | ||||||
|  | 
 | ||||||
|  | interface FileService: Service { | ||||||
|  |     fun checkPathExistence(path: String, isUserLogged: Boolean): RemoteOperationResult<Boolean> | ||||||
|  | } | ||||||
| @ -0,0 +1,34 @@ | |||||||
|  | /** | ||||||
|  |  * ownCloud Android client application | ||||||
|  |  * | ||||||
|  |  * @author Abel García de Prada | ||||||
|  |  * Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License version 2, | ||||||
|  |  * as published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package com.owncloud.android.lib.resources.files.services.implementation | ||||||
|  | 
 | ||||||
|  | import com.owncloud.android.lib.common.OwnCloudClient | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.resources.files.CheckPathExistenceRemoteOperation | ||||||
|  | import com.owncloud.android.lib.resources.files.services.FileService | ||||||
|  | 
 | ||||||
|  | class OCFileService(override val client: OwnCloudClient) : | ||||||
|  |     FileService { | ||||||
|  |     override fun checkPathExistence(path: String, isUserLogged: Boolean): RemoteOperationResult<Boolean> = | ||||||
|  |         CheckPathExistenceRemoteOperation( | ||||||
|  |             remotePath = path, | ||||||
|  |             isUserLogged = isUserLogged | ||||||
|  |         ).execute(client) | ||||||
|  | } | ||||||
| @ -18,10 +18,12 @@ | |||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| package com.owncloud.android.lib.resources.shares | package com.owncloud.android.lib.resources.shares.services | ||||||
| 
 | 
 | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult | import com.owncloud.android.lib.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.ShareType | ||||||
| 
 | 
 | ||||||
| interface ShareService : Service { | interface ShareService : Service { | ||||||
|     fun getShares( |     fun getShares( | ||||||
| @ -18,7 +18,7 @@ | |||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| package com.owncloud.android.lib.resources.shares | package com.owncloud.android.lib.resources.shares.services | ||||||
| 
 | 
 | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
| import com.owncloud.android.lib.resources.Service | import com.owncloud.android.lib.resources.Service | ||||||
| @ -0,0 +1,91 @@ | |||||||
|  | /** | ||||||
|  |  * ownCloud Android client application | ||||||
|  |  * | ||||||
|  |  * @author David González Verdugo | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License version 2, | ||||||
|  |  * as published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * <p> | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package com.owncloud.android.lib.resources.shares.services.implementation | ||||||
|  | 
 | ||||||
|  | import com.owncloud.android.lib.common.OwnCloudClient | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.resources.shares.CreateRemoteShareOperation | ||||||
|  | import com.owncloud.android.lib.resources.shares.GetRemoteSharesForFileOperation | ||||||
|  | import com.owncloud.android.lib.resources.shares.RemoveRemoteShareOperation | ||||||
|  | import com.owncloud.android.lib.resources.shares.ShareParserResult | ||||||
|  | import com.owncloud.android.lib.resources.shares.ShareType | ||||||
|  | import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation | ||||||
|  | import com.owncloud.android.lib.resources.shares.services.ShareService | ||||||
|  | 
 | ||||||
|  | class OCShareService(override val client: OwnCloudClient) : | ||||||
|  |     ShareService { | ||||||
|  |     override fun getShares( | ||||||
|  |         remoteFilePath: String, | ||||||
|  |         reshares: Boolean, | ||||||
|  |         subfiles: Boolean | ||||||
|  |     ): RemoteOperationResult<ShareParserResult> = GetRemoteSharesForFileOperation( | ||||||
|  |         remoteFilePath, | ||||||
|  |         reshares, | ||||||
|  |         subfiles | ||||||
|  |     ).execute(client) | ||||||
|  | 
 | ||||||
|  |     override fun insertShare( | ||||||
|  |         remoteFilePath: String, | ||||||
|  |         shareType: ShareType, | ||||||
|  |         shareWith: String, | ||||||
|  |         permissions: Int, | ||||||
|  |         name: String, | ||||||
|  |         password: String, | ||||||
|  |         expirationDate: Long, | ||||||
|  |         publicUpload: Boolean | ||||||
|  |     ): RemoteOperationResult<ShareParserResult> = | ||||||
|  |         CreateRemoteShareOperation( | ||||||
|  |             remoteFilePath, | ||||||
|  |             shareType, | ||||||
|  |             shareWith, | ||||||
|  |             permissions | ||||||
|  |         ).apply { | ||||||
|  |             this.name = name | ||||||
|  |             this.password = password | ||||||
|  |             this.expirationDateInMillis = expirationDate | ||||||
|  |             this.publicUpload = publicUpload | ||||||
|  |             this.retrieveShareDetails = true | ||||||
|  |         }.execute(client) | ||||||
|  | 
 | ||||||
|  |     override fun updateShare( | ||||||
|  |         remoteId: Long, | ||||||
|  |         name: String, | ||||||
|  |         password: String?, | ||||||
|  |         expirationDate: Long, | ||||||
|  |         permissions: Int, | ||||||
|  |         publicUpload: Boolean | ||||||
|  |     ): RemoteOperationResult<ShareParserResult> = | ||||||
|  |         UpdateRemoteShareOperation( | ||||||
|  |             remoteId | ||||||
|  |         ).apply { | ||||||
|  |             this.name = name | ||||||
|  |             this.password = password | ||||||
|  |             this.expirationDateInMillis = expirationDate | ||||||
|  |             this.permissions = permissions | ||||||
|  |             this.publicUpload = publicUpload | ||||||
|  |             this.retrieveShareDetails = true | ||||||
|  |         }.execute(client) | ||||||
|  | 
 | ||||||
|  |     override fun deleteShare(remoteId: Long): RemoteOperationResult<ShareParserResult> = | ||||||
|  |         RemoveRemoteShareOperation( | ||||||
|  |             remoteId | ||||||
|  |         ).execute(client) | ||||||
|  | } | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | /** | ||||||
|  |  * ownCloud Android client application | ||||||
|  |  * | ||||||
|  |  * @author David González Verdugo | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License version 2, | ||||||
|  |  * as published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * <p> | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package com.owncloud.android.lib.resources.shares.services.implementation | ||||||
|  | 
 | ||||||
|  | import com.owncloud.android.lib.common.OwnCloudClient | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.resources.shares.GetRemoteShareesOperation | ||||||
|  | import com.owncloud.android.lib.resources.shares.services.ShareeService | ||||||
|  | import org.json.JSONObject | ||||||
|  | import java.util.ArrayList | ||||||
|  | 
 | ||||||
|  | class OCShareeService(override val client: OwnCloudClient) : | ||||||
|  |     ShareeService { | ||||||
|  |     override fun getSharees( | ||||||
|  |         searchString: String, | ||||||
|  |         page: Int, | ||||||
|  |         perPage: Int | ||||||
|  |     ): RemoteOperationResult<ArrayList<JSONObject>> = | ||||||
|  |         GetRemoteShareesOperation( | ||||||
|  |             searchString, | ||||||
|  |             page, | ||||||
|  |             perPage | ||||||
|  |         ).execute(client) | ||||||
|  | } | ||||||
| @ -1,196 +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.status; |  | ||||||
| 
 |  | ||||||
| import android.content.Context; |  | ||||||
| import android.net.ConnectivityManager; |  | ||||||
| import android.net.Uri; |  | ||||||
| 
 |  | ||||||
| import com.owncloud.android.lib.common.OwnCloudClient; |  | ||||||
| import com.owncloud.android.lib.common.http.HttpConstants; |  | ||||||
| import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; |  | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; |  | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; |  | ||||||
| import org.json.JSONException; |  | ||||||
| import org.json.JSONObject; |  | ||||||
| import timber.log.Timber; |  | ||||||
| 
 |  | ||||||
| import javax.net.ssl.SSLException; |  | ||||||
| import java.net.URL; |  | ||||||
| import java.util.concurrent.TimeUnit; |  | ||||||
| 
 |  | ||||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Checks if the server is valid and if the server supports the Share API |  | ||||||
|  * |  | ||||||
|  * @author David A. Velasco |  | ||||||
|  * @author masensio |  | ||||||
|  * @author David González Verdugo |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| public class GetRemoteStatusOperation extends RemoteOperation<OwnCloudVersion> { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Maximum time to wait for a response from the server when the connection is being tested, |  | ||||||
|      * in MILLISECONDs. |  | ||||||
|      */ |  | ||||||
|     public static final long TRY_CONNECTION_TIMEOUT = 5000; |  | ||||||
| 
 |  | ||||||
|     private static final String NODE_INSTALLED = "installed"; |  | ||||||
|     private static final String NODE_VERSION = "version"; |  | ||||||
|     private static final String HTTPS_PREFIX = "https://"; |  | ||||||
|     private static final String HTTP_PREFIX = "http://"; |  | ||||||
| 
 |  | ||||||
|     private RemoteOperationResult<OwnCloudVersion> mLatestResult; |  | ||||||
|     private Context mContext; |  | ||||||
| 
 |  | ||||||
|     public GetRemoteStatusOperation(Context context) { |  | ||||||
|         mContext = context; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private boolean tryConnection(OwnCloudClient client) { |  | ||||||
|         boolean retval = false; |  | ||||||
|         String baseUrlSt = client.getBaseUri().toString(); |  | ||||||
|         try { |  | ||||||
|             GetMethod getMethod = new GetMethod(new URL(baseUrlSt + OwnCloudClient.STATUS_PATH)); |  | ||||||
| 
 |  | ||||||
|             getMethod.setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS); |  | ||||||
|             getMethod.setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS); |  | ||||||
| 
 |  | ||||||
|             client.setFollowRedirects(false); |  | ||||||
|             boolean isRedirectToNonSecureConnection = false; |  | ||||||
|             int status; |  | ||||||
|             try { |  | ||||||
|                 status = client.executeHttpMethod(getMethod); |  | ||||||
|                 mLatestResult = isSuccess(status) |  | ||||||
|                         ? new RemoteOperationResult<>(OK) |  | ||||||
|                         : new RemoteOperationResult<>(getMethod); |  | ||||||
|             } catch (SSLException sslE) { |  | ||||||
|                 mLatestResult = new RemoteOperationResult(sslE); |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             String redirectedLocation = mLatestResult.getRedirectedLocation(); |  | ||||||
|             while (redirectedLocation != null && redirectedLocation.length() > 0 |  | ||||||
|                     && !mLatestResult.isSuccess()) { |  | ||||||
| 
 |  | ||||||
|                 isRedirectToNonSecureConnection |= ( |  | ||||||
|                         baseUrlSt.startsWith(HTTPS_PREFIX) && |  | ||||||
|                                 redirectedLocation.startsWith(HTTP_PREFIX) |  | ||||||
|                 ); |  | ||||||
| 
 |  | ||||||
|                 getMethod = new GetMethod(new URL(redirectedLocation)); |  | ||||||
|                 getMethod.setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS); |  | ||||||
|                 getMethod.setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS); |  | ||||||
| 
 |  | ||||||
|                 status = client.executeHttpMethod(getMethod); |  | ||||||
|                 mLatestResult = new RemoteOperationResult<>(getMethod); |  | ||||||
|                 redirectedLocation = mLatestResult.getRedirectedLocation(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (isSuccess(status)) { |  | ||||||
| 
 |  | ||||||
|                 JSONObject respJSON = new JSONObject(getMethod.getResponseBodyAsString()); |  | ||||||
|                 if (!respJSON.getBoolean(NODE_INSTALLED)) { |  | ||||||
|                     mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED); |  | ||||||
|                 } else { |  | ||||||
|                     String version = respJSON.getString(NODE_VERSION); |  | ||||||
|                     OwnCloudVersion ocVersion = new OwnCloudVersion(version); |  | ||||||
|                     /// the version object will be returned even if the version is invalid, no error code; |  | ||||||
|                     /// every app will decide how to act if (ocVersion.isVersionValid() == false) |  | ||||||
| 
 |  | ||||||
|                     if (isRedirectToNonSecureConnection) { |  | ||||||
|                         mLatestResult = new RemoteOperationResult<>( |  | ||||||
|                                 RemoteOperationResult.ResultCode. |  | ||||||
|                                         OK_REDIRECT_TO_NON_SECURE_CONNECTION); |  | ||||||
|                     } else { |  | ||||||
|                         mLatestResult = new RemoteOperationResult<>( |  | ||||||
|                                 baseUrlSt.startsWith(HTTPS_PREFIX) ? |  | ||||||
|                                         RemoteOperationResult.ResultCode.OK_SSL : |  | ||||||
|                                         RemoteOperationResult.ResultCode.OK_NO_SSL); |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     mLatestResult.setData(ocVersion); |  | ||||||
|                     retval = true; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|             } else { |  | ||||||
|                 mLatestResult = new RemoteOperationResult<>(getMethod); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|         } catch (JSONException e) { |  | ||||||
|             mLatestResult = new RemoteOperationResult<>( |  | ||||||
|                     RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED); |  | ||||||
| 
 |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             mLatestResult = new RemoteOperationResult<>(e); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (mLatestResult.isSuccess()) { |  | ||||||
|             Timber.i("Connection check at " + baseUrlSt + ": " + mLatestResult.getLogMessage()); |  | ||||||
| 
 |  | ||||||
|         } else if (mLatestResult.getException() != null) { |  | ||||||
|             Timber.e(mLatestResult.getException(), "Connection check at " + baseUrlSt + ": " + mLatestResult.getLogMessage()); |  | ||||||
| 
 |  | ||||||
|         } else { |  | ||||||
|             Timber.e("Connection check at " + baseUrlSt + ": " + mLatestResult.getLogMessage()); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return retval; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private boolean isOnline() { |  | ||||||
|         ConnectivityManager cm = (ConnectivityManager) mContext |  | ||||||
|                 .getSystemService(Context.CONNECTIVITY_SERVICE); |  | ||||||
|         return cm != null && cm.getActiveNetworkInfo() != null |  | ||||||
|                 && cm.getActiveNetworkInfo().isConnectedOrConnecting(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     protected RemoteOperationResult<OwnCloudVersion> run(OwnCloudClient client) { |  | ||||||
|         if (!isOnline()) { |  | ||||||
|             return new RemoteOperationResult<>(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION); |  | ||||||
|         } |  | ||||||
|         String baseUriStr = client.getBaseUri().toString(); |  | ||||||
|         if (baseUriStr.startsWith(HTTP_PREFIX) || baseUriStr.startsWith(HTTPS_PREFIX)) { |  | ||||||
|             tryConnection(client); |  | ||||||
| 
 |  | ||||||
|         } else { |  | ||||||
|             client.setBaseUri(Uri.parse(HTTPS_PREFIX + baseUriStr)); |  | ||||||
|             boolean httpsSuccess = tryConnection(client); |  | ||||||
|             if (!httpsSuccess && !mLatestResult.isSslRecoverableException()) { |  | ||||||
|                 Timber.d("Establishing secure connection failed, trying non secure connection"); |  | ||||||
|                 client.setBaseUri(Uri.parse(HTTP_PREFIX + baseUriStr)); |  | ||||||
|                 tryConnection(client); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return mLatestResult; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private boolean isSuccess(int status) { |  | ||||||
|         return (status == HttpConstants.HTTP_OK); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -0,0 +1,160 @@ | |||||||
|  | /* ownCloud Android Library is available under MIT license | ||||||
|  | *   Copyright (C) 2020 ownCloud GmbH. | ||||||
|  | * | ||||||
|  | *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  | *   of this software and associated documentation files (the "Software"), to deal | ||||||
|  | *   in the Software without restriction, including without limitation the rights | ||||||
|  | *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  | *   copies of the Software, and to permit persons to whom the Software is | ||||||
|  | *   furnished to do so, subject to the following conditions: | ||||||
|  | * | ||||||
|  | *   The above copyright notice and this permission notice shall be included in | ||||||
|  | *   all copies or substantial portions of the Software. | ||||||
|  | * | ||||||
|  | *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  | *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  | *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  | *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  | *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  | *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  | *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  | *   THE SOFTWARE. | ||||||
|  | * | ||||||
|  | */ | ||||||
|  | package com.owncloud.android.lib.resources.status | ||||||
|  | 
 | ||||||
|  | import android.net.Uri | ||||||
|  | import com.owncloud.android.lib.common.OwnCloudClient | ||||||
|  | import com.owncloud.android.lib.common.http.HttpConstants | ||||||
|  | import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperation | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode | ||||||
|  | import org.json.JSONException | ||||||
|  | import org.json.JSONObject | ||||||
|  | import timber.log.Timber | ||||||
|  | import java.net.URL | ||||||
|  | import java.util.concurrent.TimeUnit | ||||||
|  | import javax.net.ssl.SSLException | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Checks if the server is valid | ||||||
|  |  * | ||||||
|  |  * @author David A. Velasco | ||||||
|  |  * @author masensio | ||||||
|  |  * @author David González Verdugo | ||||||
|  |  * @author Abel García de Prada | ||||||
|  |  */ | ||||||
|  | class GetRemoteStatusOperation : RemoteOperation<OwnCloudVersion>() { | ||||||
|  |     private lateinit var latestResult: RemoteOperationResult<OwnCloudVersion> | ||||||
|  | 
 | ||||||
|  |     override fun run(client: OwnCloudClient): RemoteOperationResult<OwnCloudVersion> { | ||||||
|  | 
 | ||||||
|  |         val baseUriStr = client.baseUri.toString() | ||||||
|  |         if (baseUriStr.startsWith(HTTP_PREFIX) || baseUriStr.startsWith( | ||||||
|  |                 HTTPS_PREFIX | ||||||
|  |             )) { | ||||||
|  |             tryConnection(client) | ||||||
|  |         } else { | ||||||
|  |             client.baseUri = Uri.parse(HTTPS_PREFIX + baseUriStr) | ||||||
|  |             val httpsSuccess = tryConnection(client) | ||||||
|  |             if (!httpsSuccess && !latestResult.isSslRecoverableException) { | ||||||
|  |                 Timber.d("Establishing secure connection failed, trying non secure connection") | ||||||
|  |                 client.baseUri = Uri.parse(HTTP_PREFIX + baseUriStr) | ||||||
|  |                 tryConnection(client) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return latestResult | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun tryConnection(client: OwnCloudClient): Boolean { | ||||||
|  |         var successfulConnection = false | ||||||
|  |         val baseUrlSt = client.baseUri.toString() | ||||||
|  |         try { | ||||||
|  |             var getMethod = GetMethod(URL(baseUrlSt + OwnCloudClient.STATUS_PATH)).apply { | ||||||
|  |                 setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS) | ||||||
|  |                 setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS) | ||||||
|  |             } | ||||||
|  |             client.setFollowRedirects(false) | ||||||
|  |             var isRedirectToNonSecureConnection = false | ||||||
|  |             var status: Int | ||||||
|  |             try { | ||||||
|  |                 status = client.executeHttpMethod(getMethod) | ||||||
|  |                 latestResult = | ||||||
|  |                     if (isSuccess(status)) RemoteOperationResult(ResultCode.OK) | ||||||
|  |                     else RemoteOperationResult(getMethod) | ||||||
|  | 
 | ||||||
|  |             } catch (sslE: SSLException) { | ||||||
|  |                 latestResult = RemoteOperationResult(sslE) | ||||||
|  |                 return successfulConnection | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var redirectedLocation = latestResult.redirectedLocation | ||||||
|  |             while (!redirectedLocation.isNullOrEmpty() && !latestResult.isSuccess) { | ||||||
|  |                 isRedirectToNonSecureConnection = | ||||||
|  |                     isRedirectToNonSecureConnection || | ||||||
|  |                             (baseUrlSt.startsWith(HTTPS_PREFIX) && redirectedLocation.startsWith( | ||||||
|  |                                 HTTP_PREFIX | ||||||
|  |                             )) | ||||||
|  | 
 | ||||||
|  |                 getMethod = GetMethod(URL(redirectedLocation)).apply { | ||||||
|  |                     setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS) | ||||||
|  |                     setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS) | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 status = client.executeHttpMethod(getMethod) | ||||||
|  |                 latestResult = RemoteOperationResult(getMethod) | ||||||
|  |                 redirectedLocation = latestResult.redirectedLocation | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (isSuccess(status)) { | ||||||
|  |                 val respJSON = JSONObject(getMethod.responseBodyAsString) | ||||||
|  |                 if (!respJSON.getBoolean(NODE_INSTALLED)) { | ||||||
|  |                     latestResult = RemoteOperationResult(ResultCode.INSTANCE_NOT_CONFIGURED) | ||||||
|  |                 } else { | ||||||
|  |                     val version = respJSON.getString(NODE_VERSION) | ||||||
|  |                     val ocVersion = OwnCloudVersion(version) | ||||||
|  |                     // the version object will be returned even if the version is invalid, no error code; | ||||||
|  |                     // every app will decide how to act if (ocVersion.isVersionValid() == false) | ||||||
|  |                     latestResult = if (isRedirectToNonSecureConnection) { | ||||||
|  |                         RemoteOperationResult(ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION) | ||||||
|  |                     } else { | ||||||
|  |                         if (baseUrlSt.startsWith(HTTPS_PREFIX)) RemoteOperationResult(ResultCode.OK_SSL) | ||||||
|  |                         else RemoteOperationResult(ResultCode.OK_NO_SSL) | ||||||
|  |                     } | ||||||
|  |                     latestResult.data = ocVersion | ||||||
|  |                     successfulConnection = true | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 latestResult = RemoteOperationResult(getMethod) | ||||||
|  |             } | ||||||
|  |         } catch (e: JSONException) { | ||||||
|  |             latestResult = RemoteOperationResult(ResultCode.INSTANCE_NOT_CONFIGURED) | ||||||
|  |         } catch (e: Exception) { | ||||||
|  |             latestResult = RemoteOperationResult(e) | ||||||
|  |         } | ||||||
|  |         when { | ||||||
|  |             latestResult.isSuccess -> Timber.i("Connection check at $baseUrlSt successful: ${latestResult.logMessage}") | ||||||
|  | 
 | ||||||
|  |             latestResult.isException -> | ||||||
|  |                 Timber.e(latestResult.exception, "Connection check at $baseUrlSt: ${latestResult.logMessage}") | ||||||
|  | 
 | ||||||
|  |             else -> Timber.e("Connection check at $baseUrlSt failed: ${latestResult.logMessage}") | ||||||
|  |         } | ||||||
|  |         return successfulConnection | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK | ||||||
|  | 
 | ||||||
|  |     companion object { | ||||||
|  |         /** | ||||||
|  |          * Maximum time to wait for a response from the server when the connection is being tested, | ||||||
|  |          * in MILLISECONDs. | ||||||
|  |          */ | ||||||
|  |         private const val TRY_CONNECTION_TIMEOUT: Long = 5000 | ||||||
|  |         private const val NODE_INSTALLED = "installed" | ||||||
|  |         private const val NODE_VERSION = "version" | ||||||
|  |         private const val HTTPS_PREFIX = "https://" | ||||||
|  |         private const val HTTP_PREFIX = "http://" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -18,10 +18,11 @@ | |||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| package com.owncloud.android.lib.resources.status | package com.owncloud.android.lib.resources.status.services | ||||||
| 
 | 
 | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
| import com.owncloud.android.lib.resources.Service | import com.owncloud.android.lib.resources.Service | ||||||
|  | import com.owncloud.android.lib.resources.status.RemoteCapability | ||||||
| 
 | 
 | ||||||
| interface CapabilityService: Service { | interface CapabilityService: Service { | ||||||
|     fun getCapabilities() : RemoteOperationResult<RemoteCapability> |     fun getCapabilities() : RemoteOperationResult<RemoteCapability> | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | /* ownCloud Android Library is available under MIT license | ||||||
|  |  *   Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  *   of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  *   in the Software without restriction, including without limitation the rights | ||||||
|  |  *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  *   copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  *   furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  *   The above copyright notice and this permission notice shall be included in | ||||||
|  |  *   all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  |  *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  |  *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  |  *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |  *   THE SOFTWARE. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | package com.owncloud.android.lib.resources.status.services | ||||||
|  | 
 | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.resources.status.OwnCloudVersion | ||||||
|  | 
 | ||||||
|  | interface ServerInfoService { | ||||||
|  |     fun checkPathExistence(path: String, isUserLogged: Boolean): RemoteOperationResult<Boolean> | ||||||
|  | 
 | ||||||
|  |     fun getRemoteStatus(path: String): RemoteOperationResult<OwnCloudVersion> | ||||||
|  | } | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | /** | ||||||
|  |  * ownCloud Android client application | ||||||
|  |  * | ||||||
|  |  * @author David González Verdugo | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License version 2, | ||||||
|  |  * as published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package com.owncloud.android.lib.resources.status.services.implementation | ||||||
|  | 
 | ||||||
|  | import com.owncloud.android.lib.common.OwnCloudClient | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.resources.status.services.CapabilityService | ||||||
|  | import com.owncloud.android.lib.resources.status.GetRemoteCapabilitiesOperation | ||||||
|  | import com.owncloud.android.lib.resources.status.RemoteCapability | ||||||
|  | 
 | ||||||
|  | class OCCapabilityService(override val client: OwnCloudClient) : | ||||||
|  |     CapabilityService { | ||||||
|  |     override fun getCapabilities(): RemoteOperationResult<RemoteCapability> = | ||||||
|  |         GetRemoteCapabilitiesOperation().execute(client) | ||||||
|  | } | ||||||
| @ -0,0 +1,43 @@ | |||||||
|  | /** | ||||||
|  |  * ownCloud Android client application | ||||||
|  |  * | ||||||
|  |  * @author Abel García de Prada | ||||||
|  |  * Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License version 2, | ||||||
|  |  * as published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package com.owncloud.android.lib.resources.status.services.implementation | ||||||
|  | 
 | ||||||
|  | import android.net.Uri | ||||||
|  | import com.owncloud.android.lib.common.OwnCloudClient | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.resources.status.services.ServerInfoService | ||||||
|  | import com.owncloud.android.lib.resources.files.CheckPathExistenceRemoteOperation | ||||||
|  | import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation | ||||||
|  | import com.owncloud.android.lib.resources.status.OwnCloudVersion | ||||||
|  | 
 | ||||||
|  | class OCServerInfoService : ServerInfoService { | ||||||
|  |     override fun checkPathExistence(path: String, isUserLogged: Boolean): RemoteOperationResult<Boolean> = | ||||||
|  |         CheckPathExistenceRemoteOperation( | ||||||
|  |             remotePath = path, | ||||||
|  |             isUserLogged = true | ||||||
|  |         ).execute(createClientFromPath(path)) | ||||||
|  | 
 | ||||||
|  |     override fun getRemoteStatus(path: String): RemoteOperationResult<OwnCloudVersion> = | ||||||
|  |         GetRemoteStatusOperation().execute(createClientFromPath(path)) | ||||||
|  | 
 | ||||||
|  |     private fun createClientFromPath(path: String): OwnCloudClient { | ||||||
|  |         return OwnCloudClient(Uri.parse(path)) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,111 +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.users; |  | ||||||
| 
 |  | ||||||
| import com.owncloud.android.lib.common.OwnCloudClient; |  | ||||||
| import com.owncloud.android.lib.common.http.HttpConstants; |  | ||||||
| import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; |  | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperation; |  | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult; |  | ||||||
| import org.json.JSONObject; |  | ||||||
| import timber.log.Timber; |  | ||||||
| 
 |  | ||||||
| import java.net.URL; |  | ||||||
| 
 |  | ||||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Gets information (id, display name, and e-mail address) about the user logged in. |  | ||||||
|  * |  | ||||||
|  * @author masensio |  | ||||||
|  * @author David A. Velasco |  | ||||||
|  * @author David González Verdugo |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| public class GetRemoteUserInfoOperation extends RemoteOperation<GetRemoteUserInfoOperation.UserInfo> { |  | ||||||
| 
 |  | ||||||
|     // OCS Route |  | ||||||
|     private static final String OCS_ROUTE = "/ocs/v2.php/cloud/user?format=json"; |  | ||||||
| 
 |  | ||||||
|     // JSON Node names |  | ||||||
|     private static final String NODE_OCS = "ocs"; |  | ||||||
|     private static final String NODE_DATA = "data"; |  | ||||||
|     private static final String NODE_ID = "id"; |  | ||||||
|     private static final String NODE_DISPLAY_NAME = "display-name"; |  | ||||||
|     private static final String NODE_EMAIL = "email"; |  | ||||||
| 
 |  | ||||||
|     public GetRemoteUserInfoOperation() { |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     protected RemoteOperationResult<UserInfo> run(OwnCloudClient client) { |  | ||||||
|         RemoteOperationResult<UserInfo> result; |  | ||||||
| 
 |  | ||||||
|         //Get the user |  | ||||||
|         try { |  | ||||||
|             GetMethod getMethod = new GetMethod(new URL(client.getBaseUri() + OCS_ROUTE)); |  | ||||||
| 
 |  | ||||||
|             int status = client.executeHttpMethod(getMethod); |  | ||||||
| 
 |  | ||||||
|             if (isSuccess(status)) { |  | ||||||
|                 Timber.d("Successful response"); |  | ||||||
| 
 |  | ||||||
|                 JSONObject respJSON = new JSONObject(getMethod.getResponseBodyAsString()); |  | ||||||
|                 JSONObject respOCS = respJSON.getJSONObject(NODE_OCS); |  | ||||||
|                 JSONObject respData = respOCS.getJSONObject(NODE_DATA); |  | ||||||
| 
 |  | ||||||
|                 UserInfo userInfo = new UserInfo(); |  | ||||||
|                 userInfo.mId = respData.getString(NODE_ID); |  | ||||||
|                 userInfo.mDisplayName = respData.getString(NODE_DISPLAY_NAME); |  | ||||||
|                 userInfo.mEmail = respData.getString(NODE_EMAIL); |  | ||||||
| 
 |  | ||||||
|                 result = new RemoteOperationResult<>(OK); |  | ||||||
| 
 |  | ||||||
|                 result.setData(userInfo); |  | ||||||
| 
 |  | ||||||
|             } else { |  | ||||||
|                 result = new RemoteOperationResult<>(getMethod); |  | ||||||
|                 String response = getMethod.getResponseBodyAsString(); |  | ||||||
|                 Timber.e("Failed response while getting user information "); |  | ||||||
|                 Timber.e("*** status code: " + status + " ; response message: " + response); |  | ||||||
|             } |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             result = new RemoteOperationResult<>(e); |  | ||||||
|             Timber.e(e, "Exception while getting OC user information"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return result; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private boolean isSuccess(int status) { |  | ||||||
|         return (status == HttpConstants.HTTP_OK); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static class UserInfo { |  | ||||||
|         public String mId = ""; |  | ||||||
|         public String mDisplayName = ""; |  | ||||||
|         public String mEmail = ""; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -0,0 +1,81 @@ | |||||||
|  | /*   ownCloud Android Library is available under MIT license | ||||||
|  |  *   Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  *   of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  *   in the Software without restriction, including without limitation the rights | ||||||
|  |  *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  *   copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  *   furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  *   The above copyright notice and this permission notice shall be included in | ||||||
|  |  *   all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  |  *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  |  *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  |  *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |  *   THE SOFTWARE. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | package com.owncloud.android.lib.resources.users | ||||||
|  | 
 | ||||||
|  | import com.owncloud.android.lib.common.OwnCloudClient | ||||||
|  | import com.owncloud.android.lib.common.http.HttpConstants | ||||||
|  | import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperation | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode | ||||||
|  | import com.owncloud.android.lib.resources.CommonOcsResponse | ||||||
|  | import com.squareup.moshi.JsonAdapter | ||||||
|  | import com.squareup.moshi.Moshi | ||||||
|  | import com.squareup.moshi.Types | ||||||
|  | import timber.log.Timber | ||||||
|  | import java.lang.reflect.Type | ||||||
|  | import java.net.URL | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Gets information (id, display name, and e-mail address) about the user logged in. | ||||||
|  |  * | ||||||
|  |  * @author masensio | ||||||
|  |  * @author David A. Velasco | ||||||
|  |  * @author David González Verdugo | ||||||
|  |  * @author Abel García de Prada | ||||||
|  |  */ | ||||||
|  | class GetRemoteUserInfoOperation : RemoteOperation<RemoteUserInfo>() { | ||||||
|  |     override fun run(client: OwnCloudClient): RemoteOperationResult<RemoteUserInfo> { | ||||||
|  |         var result: RemoteOperationResult<RemoteUserInfo> | ||||||
|  |         //Get the user | ||||||
|  |         try { | ||||||
|  |             val getMethod = GetMethod(URL(client.baseUri.toString() + OCS_ROUTE)) | ||||||
|  |             val status = client.executeHttpMethod(getMethod) | ||||||
|  |             val response = getMethod.responseBodyAsString | ||||||
|  |             if (status == HttpConstants.HTTP_OK) { | ||||||
|  |                 Timber.d("Successful response $response") | ||||||
|  | 
 | ||||||
|  |                 val moshi: Moshi = Moshi.Builder().build() | ||||||
|  |                 val type: Type = Types.newParameterizedType(CommonOcsResponse::class.java, UserInfoResponse::class.java) | ||||||
|  |                 val adapter: JsonAdapter<CommonOcsResponse<UserInfoResponse>> = moshi.adapter(type) | ||||||
|  |                 val commonResponse: CommonOcsResponse<UserInfoResponse>? = adapter.fromJson(response) | ||||||
|  | 
 | ||||||
|  |                 result = RemoteOperationResult(ResultCode.OK) | ||||||
|  |                 result.data = commonResponse?.ocs?.data?.toRemoteUserInfo() | ||||||
|  |             } else { | ||||||
|  |                 result = RemoteOperationResult(getMethod) | ||||||
|  |                 Timber.e("Failed response while getting user information status code: $status, response: $response") | ||||||
|  |             } | ||||||
|  |         } catch (e: Exception) { | ||||||
|  |             result = RemoteOperationResult(e) | ||||||
|  |             Timber.e(e, "Exception while getting OC user information") | ||||||
|  |         } | ||||||
|  |         return result | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     companion object { | ||||||
|  |         // OCS Route | ||||||
|  |         private const val OCS_ROUTE = "/ocs/v2.php/cloud/user?format=json" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,30 @@ | |||||||
|  | /* ownCloud Android Library is available under MIT license | ||||||
|  |  * | ||||||
|  |  *   Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  *   of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  *   in the Software without restriction, including without limitation the rights | ||||||
|  |  *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  *   copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  *   furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  *   The above copyright notice and this permission notice shall be included in | ||||||
|  |  *   all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  |  *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  |  *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  |  *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |  *   THE SOFTWARE. | ||||||
|  |  */ | ||||||
|  | package com.owncloud.android.lib.resources.users | ||||||
|  | 
 | ||||||
|  | data class RemoteUserInfo( | ||||||
|  |     val id: String, | ||||||
|  |     val displayName: String, | ||||||
|  |     val email: String? | ||||||
|  | ) | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | /* ownCloud Android Library is available under MIT license | ||||||
|  |  * | ||||||
|  |  *   Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  *   of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  *   in the Software without restriction, including without limitation the rights | ||||||
|  |  *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  *   copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  *   furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  *   The above copyright notice and this permission notice shall be included in | ||||||
|  |  *   all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  |  *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  |  *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  |  *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |  *   THE SOFTWARE. | ||||||
|  |  */ | ||||||
|  | package com.owncloud.android.lib.resources.users | ||||||
|  | 
 | ||||||
|  | import com.squareup.moshi.Json | ||||||
|  | import com.squareup.moshi.JsonClass | ||||||
|  | 
 | ||||||
|  | @JsonClass(generateAdapter = true) | ||||||
|  | data class UserInfoResponse( | ||||||
|  |     val id: String, | ||||||
|  |     @Json(name = "display-name") | ||||||
|  |     val displayName: String, | ||||||
|  |     val email: String? | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | fun UserInfoResponse.toRemoteUserInfo() = | ||||||
|  |     RemoteUserInfo( | ||||||
|  |         id = id, | ||||||
|  |         displayName = displayName, | ||||||
|  |         email = email | ||||||
|  |     ) | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | /* ownCloud Android Library is available under MIT license | ||||||
|  |  *   Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  *   of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  *   in the Software without restriction, including without limitation the rights | ||||||
|  |  *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  *   copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  *   furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  *   The above copyright notice and this permission notice shall be included in | ||||||
|  |  *   all copies or substantial portions of the Software. | ||||||
|  |  * | ||||||
|  |  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  |  *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  |  *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  |  *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |  *   THE SOFTWARE. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package com.owncloud.android.lib.resources.users.services | ||||||
|  | 
 | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.resources.Service | ||||||
|  | import com.owncloud.android.lib.resources.users.RemoteUserInfo | ||||||
|  | 
 | ||||||
|  | interface UserService: Service { | ||||||
|  |     fun getUserInfo() : RemoteOperationResult<RemoteUserInfo> | ||||||
|  | } | ||||||
| @ -0,0 +1,32 @@ | |||||||
|  | /** | ||||||
|  |  * ownCloud Android client application | ||||||
|  |  * | ||||||
|  |  * @author Abel García de Prada | ||||||
|  |  * Copyright (C) 2020 ownCloud GmbH. | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License version 2, | ||||||
|  |  * as published by the Free Software Foundation. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * <p> | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package com.owncloud.android.lib.resources.users.services.implementation | ||||||
|  | 
 | ||||||
|  | import com.owncloud.android.lib.common.OwnCloudClient | ||||||
|  | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
|  | import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation | ||||||
|  | import com.owncloud.android.lib.resources.users.RemoteUserInfo | ||||||
|  | import com.owncloud.android.lib.resources.users.services.UserService | ||||||
|  | 
 | ||||||
|  | class OCUserService(override val client: OwnCloudClient) : | ||||||
|  |     UserService { | ||||||
|  |     override fun getUserInfo(): RemoteOperationResult<RemoteUserInfo> = | ||||||
|  |         GetRemoteUserInfoOperation().execute(client) | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user