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

Merge pull request #307 from owncloud/new_arch/login

[New arch] Login
This commit is contained in:
David González Verdugo 2020-04-17 15:41:01 +02:00 committed by GitHub
commit 5ecd3c9311
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 894 additions and 494 deletions

View File

@ -1,6 +1,7 @@
buildscript {
ext {
kotlinVersion = '1.3.71'
moshiVersion = "1.9.2"
}
repositories {

View File

@ -9,6 +9,12 @@ dependencies {
api 'com.gitlab.ownclouders:dav4android:oc_support_1.0.1'
api 'com.github.hannesa2:Logcat:1.6.0'
api 'net.openid:appauth:0.7.1'
// Moshi
implementation ("com.squareup.moshi:moshi-kotlin:$moshiVersion") {
exclude module: "kotlin-reflect"
}
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshiVersion"
}
allOpen {

View File

@ -53,6 +53,7 @@ import static com.owncloud.android.lib.common.http.HttpConstants.OC_X_REQUEST_ID
public class OwnCloudClient extends HttpClient {
public static final String WEBDAV_FILES_PATH_4_0 = "/remote.php/dav/files/";
public static final String WEBDAV_PATH_4_0_AND_LATER = "/remote.php/dav";
private static final String WEBDAV_UPLOADS_PATH_4_0 = "/remote.php/dav/uploads/";
public static final String STATUS_PATH = "/status.php";
@ -230,7 +231,7 @@ public class OwnCloudClient extends HttpClient {
}
public Uri getUserFilesWebDavUri() {
return mCredentials instanceof OwnCloudAnonymousCredentials
return (mCredentials instanceof OwnCloudAnonymousCredentials || mAccount == null)
? Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0)
: Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0 + AccountUtils.getUserId(
mAccount.getSavedAccount(), getContext()

View File

@ -46,7 +46,6 @@ import java.util.ArrayList;
import java.util.List;
public class AccountUtils {
/**
* Constructs full url to host and webdav resource basing on host version
*
@ -140,7 +139,7 @@ public class AccountUtils {
AccountManager am = AccountManager.get(context);
String supportsOAuth2 = am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_OAUTH2);
boolean isOauth2 = supportsOAuth2 != null && supportsOAuth2.equals("TRUE");
boolean isOauth2 = supportsOAuth2 != null && supportsOAuth2.equals(Constants.OAUTH_SUPPORTED_TRUE);
String username = AccountUtils.getUsernameForAccount(account);
@ -295,6 +294,8 @@ public class AccountUtils {
*/
public static final String KEY_SUPPORTS_OAUTH2 = "oc_supports_oauth2";
public static final String OAUTH_SUPPORTED_TRUE = "TRUE";
/**
* OC account cookies
*/
@ -329,5 +330,7 @@ public class AccountUtils {
* OAuth2 scope
*/
public static final String KEY_OAUTH2_SCOPE = "oc_oauth2_scope";
public static final int ACCOUNT_VERSION = 1;
}
}

View File

@ -34,11 +34,12 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class WebdavUtils {
public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat(
"dd.MM.yyyy hh:mm");
import static com.owncloud.android.lib.common.OwnCloudClient.WEBDAV_FILES_PATH_4_0;
import static com.owncloud.android.lib.common.OwnCloudClient.WEBDAV_PATH_4_0_AND_LATER;
private static final SimpleDateFormat DATETIME_FORMATS[] = {
public class WebdavUtils {
private static final SimpleDateFormat[] DATETIME_FORMATS = {
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US),
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US),
@ -50,11 +51,11 @@ public class WebdavUtils {
};
public static Date parseResponseDate(String date) {
Date returnDate = null;
SimpleDateFormat format = null;
for (int i = 0; i < DATETIME_FORMATS.length; ++i) {
Date returnDate;
SimpleDateFormat format;
for (SimpleDateFormat datetimeFormat : DATETIME_FORMATS) {
try {
format = DATETIME_FORMATS[i];
format = datetimeFormat;
synchronized (format) {
returnDate = format.parse(date);
}
@ -82,23 +83,6 @@ public class WebdavUtils {
return encodedPath;
}
/**
* @param rawEtag
* @return
*/
public static String parseEtag(String rawEtag) {
if (rawEtag == null || rawEtag.length() == 0) {
return "";
}
if (rawEtag.endsWith("-gzip")) {
rawEtag = rawEtag.substring(0, rawEtag.length() - 5);
}
if (rawEtag.length() >= 2 && rawEtag.startsWith("\"") && rawEtag.endsWith("\"")) {
rawEtag = rawEtag.substring(1, rawEtag.length() - 1);
}
return rawEtag;
}
/**
* @param httpBaseMethod from which to get the etag
* @return etag from response
@ -120,4 +104,17 @@ public class WebdavUtils {
}
return result;
}
public static String normalizeProtocolPrefix(String url, boolean isSslConn) {
if (!url.toLowerCase().startsWith("http://") &&
!url.toLowerCase().startsWith("https://")) {
if (isSslConn) {
return "https://" + url;
} else {
return "http://" + url;
}
}
return url;
}
}

View File

@ -66,7 +66,7 @@ public class RemoteOperationResult<T>
private Exception mException = null;
private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
private String mRedirectedLocation;
private ArrayList<String> mAuthenticate = new ArrayList<>();
private String mAuthenticate;
private String mLastPermanentLocation = null;
private T mData = null;
@ -253,7 +253,7 @@ public class RemoteOperationResult<T>
continue;
}
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://")));
}
public ArrayList<String> getAuthenticateHeaders() {
public String getAuthenticateHeaders() {
return mAuthenticate;
}

View File

@ -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?
)

View File

@ -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
}
}

View File

@ -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);
}
}

View File

@ -123,9 +123,9 @@ public class RenameRemoteFileOperation extends RemoteOperation {
* @return 'True' if the target path is already used by an existing file.
*/
private boolean targetPathIsUsed(OwnCloudClient client) {
ExistenceCheckRemoteOperation existenceCheckRemoteOperation =
new ExistenceCheckRemoteOperation(mNewRemotePath, false, false);
RemoteOperationResult exists = existenceCheckRemoteOperation.run(client);
CheckPathExistenceRemoteOperation checkPathExistenceRemoteOperation =
new CheckPathExistenceRemoteOperation(mNewRemotePath, false);
RemoteOperationResult exists = checkPathExistenceRemoteOperation.execute(client);
return exists.isSuccess();
}
}

View File

@ -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>
}

View File

@ -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)
}

View File

@ -18,10 +18,12 @@
* 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.resources.Service
import com.owncloud.android.lib.resources.shares.ShareParserResult
import com.owncloud.android.lib.resources.shares.ShareType
interface ShareService : Service {
fun getShares(

View File

@ -18,7 +18,7 @@
* 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.resources.Service

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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);
}
}

View File

@ -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://"
}
}

View File

@ -18,10 +18,11 @@
* 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.resources.Service
import com.owncloud.android.lib.resources.status.RemoteCapability
interface CapabilityService: Service {
fun getCapabilities() : RemoteOperationResult<RemoteCapability>

View File

@ -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>
}

View File

@ -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)
}

View File

@ -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))
}
}

View File

@ -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 = "";
}
}

View File

@ -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"
}
}

View File

@ -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?
)

View File

@ -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
)

View File

@ -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>
}

View File

@ -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)
}