diff --git a/build.gradle b/build.gradle index 33a0fd753..71bce4b26 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,8 @@ repositories { dependencies { compile 'org.apache.jackrabbit:jackrabbit-webdav:2.12.4' + compile 'org.parceler:parceler-api:1.1.6' + annotationProcessor 'org.parceler:parceler:1.1.6' } android { diff --git a/src/com/owncloud/android/lib/common/Quota.java b/src/com/owncloud/android/lib/common/Quota.java new file mode 100644 index 000000000..6703033be --- /dev/null +++ b/src/com/owncloud/android/lib/common/Quota.java @@ -0,0 +1,87 @@ +/** + * Nextcloud Android client application + * + * @author Mario Danic + * Copyright (C) 2017 Nextcloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.owncloud.android.lib.common; + +import org.parceler.Parcel; + +/** + * Quota data model + */ + +@Parcel +public class Quota { + public long free; + public long used; + public long total; + public long quota; + public double relative; + + public Quota() { + } + + public Quota(long free, long used, long total, double relative, long quota) { + + this.free = free; + this.used = used; + this.total = total; + this.quota = quota; + this.relative = relative; + } + + public long getFree() { + return free; + } + + public void setFree(long free) { + this.free = free; + } + + public long getUsed() { + return used; + } + + public void setUsed(long used) { + this.used = used; + } + + public long getTotal() { + return total; + } + + public void setTotal(long total) { + this.total = total; + } + + public long getQuota() { + return quota; + } + + public void setQuota(long quota) { + this.quota = quota; + } + + public double getRelative() { + return relative; + } + + public void setRelative(double relative) { + this.relative = relative; + } +} diff --git a/src/com/owncloud/android/lib/common/UserInfo.java b/src/com/owncloud/android/lib/common/UserInfo.java new file mode 100644 index 000000000..e77399314 --- /dev/null +++ b/src/com/owncloud/android/lib/common/UserInfo.java @@ -0,0 +1,127 @@ +/** + * Nextcloud Android client application + * + * @author Mario Danic + * Copyright (C) 2017 Nextcloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.owncloud.android.lib.common; + +import org.parceler.Parcel; + +/** + * User information data model + */ + +@Parcel +public class UserInfo { + public String id; + public Boolean enabled; + public String displayName; + public String email; + public String phone; + public String address; + public String webpage; + public String twitter; + public Quota quota; + + public UserInfo() { + } + + public UserInfo(String id, Boolean enabled, String displayName, String email, String phone, String address, + String webpage, String twitter, Quota quota) { + this.id = id; + this.enabled = enabled; + this.displayName = displayName; + this.email = email; + this.phone = phone; + this.address = address; + this.webpage = webpage; + this.twitter = twitter; + this.quota = quota; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getWebpage() { + return webpage; + } + + public void setWebpage(String webpage) { + this.webpage = webpage; + } + + public String getTwitter() { + return twitter; + } + + public void setTwitter(String twitter) { + this.twitter = twitter; + } + + public Quota getQuota() { + return quota; + } + + public void setQuota(Quota quota) { + this.quota = quota; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } +} diff --git a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java index 1b9f85461..bd69ca7ca 100644 --- a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java +++ b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java @@ -50,6 +50,8 @@ public class OwnCloudVersion implements Comparable { public static final int VERSION_8 = 0x08000000; // 8.0 public static final int MINIMUM_VERSION_CAPABILITIES_API = 0x08010000; // 8.1 + + public static final int MINIMUM_SELF_API = 0x11000200; private static final int MAX_DOTS = 3; @@ -156,4 +158,9 @@ public boolean isSearchUsersSupported() { public boolean isVersionWithCapabilitiesAPI(){ return (mVersion>= MINIMUM_VERSION_CAPABILITIES_API); } + + public boolean isSelfSupported() { + return (mVersion >= MINIMUM_SELF_API); + } + } diff --git a/src/com/owncloud/android/lib/resources/users/GetRemoteUserInfoOperation.java b/src/com/owncloud/android/lib/resources/users/GetRemoteUserInfoOperation.java index bce20ba56..dd586ce94 100644 --- a/src/com/owncloud/android/lib/resources/users/GetRemoteUserInfoOperation.java +++ b/src/com/owncloud/android/lib/resources/users/GetRemoteUserInfoOperation.java @@ -1,6 +1,7 @@ /* ownCloud Android Library is available under MIT license * Copyright (C) 2015 ownCloud Inc. - * + * Copyright (C) 2017 Nextcloud 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 @@ -24,36 +25,79 @@ package com.owncloud.android.lib.resources.users; +import android.text.TextUtils; + +import com.owncloud.android.lib.common.OwnCloudBasicCredentials; import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.Quota; +import com.owncloud.android.lib.common.UserInfo; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.GetMethod; +import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; /** - * Gets information (id, display name, and e-mail address) about the user logged in. + * Gets information (id, display name, and e-mail address and many other things) about the user logged in. * * @author masensio * @author David A. Velasco + * @author Mario Danic */ public class GetRemoteUserInfoOperation extends RemoteOperation { private static final String TAG = GetRemoteUserInfoOperation.class.getSimpleName(); // OCS Route - private static final String OCS_ROUTE = "/ocs/v1.php/cloud/user?format=json"; + private static final String OCS_ROUTE_SELF = "/ocs/v1.php/cloud/user"; + private static final String OCS_ROUTE_SEARCH = "/ocs/v1.php/cloud/users/"; // 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_DISPLAY_NAME_ALT = "displayname"; private static final String NODE_EMAIL = "email"; + private static final String NODE_ENABLED = "enabled"; + private static final String NODE_PHONE = "phone"; + private static final String NODE_ADDRESS = "address"; + private static final String NODE_WEBPAGE = "webpage"; + private static final String NODE_TWITTER = "twitter"; + + private static final String NODE_QUOTA = "quota"; + private static final String NODE_QUOTA_FREE = "free"; + private static final String NODE_QUOTA_USED = "used"; + private static final String NODE_QUOTA_TOTAL = "total"; + private static final String NODE_QUOTA_RELATIVE = "relative"; + + /** + * Quota return value for a not computed space value. + */ + public static final long SPACE_NOT_COMPUTED = -1; + + /** + * Quota return value for unknown space value. + */ + public static final long SPACE_UNKNOWN = -2; + + /** + * Quota return value for unlimited space. + */ + public static final long SPACE_UNLIMITED = -3; + + /** + * Quota return value for quota information not available. + */ + public static final long QUOTA_LIMIT_INFO_NOT_AVAILABLE = Long.MIN_VALUE; + public GetRemoteUserInfoOperation() { } @@ -63,12 +107,26 @@ protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; int status = -1; GetMethod get = null; + String url; + + OwnCloudBasicCredentials credentials = (OwnCloudBasicCredentials) client.getCredentials(); + + OwnCloudVersion version = client.getOwnCloudVersion(); + boolean versionWithSelfAPI = version != null && version.isSelfSupported(); //Get the user try { - get = new GetMethod(client.getBaseUri() + OCS_ROUTE); + if (!versionWithSelfAPI) { + url = client.getBaseUri() + OCS_ROUTE_SEARCH + credentials.getUsername(); + } else { + url = client.getBaseUri() + OCS_ROUTE_SELF; + } + + get = new GetMethod(url); get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); + get.setQueryString(new NameValuePair[]{new NameValuePair("format", "json")}); status = client.executeMethod(get); + if (isSuccess(status)) { String response = get.getResponseBodyAsString(); Log_OC.d(TAG, "Successful response: " + response); @@ -79,9 +137,67 @@ protected RemoteOperationResult run(OwnCloudClient client) { 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); + + // we don't really always have the ID + if (respData.has(NODE_ID)) { + userInfo.setId(respData.getString(NODE_ID)); + } else { + userInfo.setId(credentials.getUsername()); + } + + // Two endpoints, two different responses + if (respData.has(NODE_DISPLAY_NAME)) { + userInfo.setDisplayName(respData.getString(NODE_DISPLAY_NAME)); + } else { + userInfo.setDisplayName(respData.getString(NODE_DISPLAY_NAME_ALT)); + } + + if (respData.has(NODE_EMAIL) && !respData.isNull(NODE_EMAIL) && + !TextUtils.isEmpty(respData.getString(NODE_EMAIL))) { + userInfo.setEmail(respData.getString(NODE_EMAIL)); + } + + JSONObject quota = respData.getJSONObject(NODE_QUOTA); + final Long quotaFree = quota.getLong(NODE_QUOTA_FREE); + final Long quotaUsed = quota.getLong(NODE_QUOTA_USED); + final Long quotaTotal = quota.getLong(NODE_QUOTA_TOTAL); + final Double quotaRelative = quota.getDouble(NODE_QUOTA_RELATIVE); + + Long quotaValue; + try { + quotaValue = quota.getLong(NODE_QUOTA); + } catch (JSONException e) { + Log_OC.i(TAG, "Legacy server in use < Nextcloud 9.0.54"); + quotaValue = QUOTA_LIMIT_INFO_NOT_AVAILABLE; + } + + userInfo.setQuota(new Quota(quotaFree, quotaUsed, quotaTotal, quotaRelative, quotaValue)); + + if (versionWithSelfAPI) { + if (respData.has(NODE_PHONE) && !respData.isNull(NODE_PHONE) && + !TextUtils.isEmpty(respData.getString(NODE_PHONE))) { + userInfo.setPhone(respData.getString(NODE_PHONE)); + } + + if (respData.has(NODE_ADDRESS) && !respData.isNull(NODE_ADDRESS) && + !TextUtils.isEmpty(respData.getString(NODE_ADDRESS))) { + userInfo.setAddress(respData.getString(NODE_ADDRESS)); + } + + if (respData.has(NODE_WEBPAGE) && !respData.isNull(NODE_WEBPAGE) && + !TextUtils.isEmpty(respData.getString(NODE_WEBPAGE))) { + userInfo.setWebpage(respData.getString(NODE_WEBPAGE)); + } + + if (respData.has(NODE_TWITTER) && !respData.isNull(NODE_TWITTER) && + !TextUtils.isEmpty(respData.getString(NODE_TWITTER))) { + userInfo.setTwitter(respData.getString(NODE_TWITTER)); + } + } + + if (respData.has(NODE_ENABLED)) { + userInfo.setEnabled(respData.getBoolean(NODE_ENABLED)); + } // Result result = new RemoteOperationResult(true, status, get.getResponseHeaders()); @@ -113,10 +229,4 @@ protected RemoteOperationResult run(OwnCloudClient client) { private boolean isSuccess(int status) { return (status == HttpStatus.SC_OK); } - - public static class UserInfo { - public String mId = ""; - public String mDisplayName = ""; - public String mEmail = ""; - } } diff --git a/src/com/owncloud/android/lib/resources/users/RemoteGetUserQuotaOperation.java b/src/com/owncloud/android/lib/resources/users/RemoteGetUserQuotaOperation.java deleted file mode 100644 index 9f6d69e02..000000000 --- a/src/com/owncloud/android/lib/resources/users/RemoteGetUserQuotaOperation.java +++ /dev/null @@ -1,187 +0,0 @@ -/* Nextcloud Android Library is available under MIT license - * - * Copyright (C) 2016 Nextcloud - * Copyright (C) 2016 Andy Scherzinger - * Copyright (C) 2015 ownCloud Inc. - * Copyright (C) 2015 Bartosz Przybylski - * Copyright (C) 2014 Marcello Steiner - * - * 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.OwnCloudBasicCredentials; -import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.operations.RemoteOperation; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; - -import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.NameValuePair; -import org.apache.commons.httpclient.methods.GetMethod; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; - -/** - * Gets a logged in user's quota information (free, used, total and quota). - * - * @author marcello - * @author Andy Scherzinger - */ -public class RemoteGetUserQuotaOperation extends RemoteOperation { - - static public class Quota { - private long mFree, mUsed, mTotal, mQuota; - private double mRelative; - - public Quota(long free, long used, long total, double relative, long quota) { - mFree = free; - mUsed = used; - mTotal = total; - mRelative = relative; - mQuota = quota; - } - - public long getFree() { - return mFree; - } - - public long getUsed() { - return mUsed; - } - - public long getTotal() { - return mTotal; - } - - public long getQuota() { - return mQuota; - } - - public double getRelative() { - return mRelative; - } - } - - private static final String TAG = RemoteGetUserQuotaOperation.class.getSimpleName(); - - private static final String NODE_OCS = "ocs"; - private static final String NODE_DATA = "data"; - private static final String NODE_QUOTA = "quota"; - private static final String NODE_QUOTA_FREE = "free"; - private static final String NODE_QUOTA_USED = "used"; - private static final String NODE_QUOTA_TOTAL = "total"; - private static final String NODE_QUOTA_RELATIVE = "relative"; - - /** - * Quota return value for a not computed space value. - */ - public static final long SPACE_NOT_COMPUTED = -1; - - /** - * Quota return value for unknown space value. - */ - public static final long SPACE_UNKNOWN = -2; - - /** - * Quota return value for unlimited space. - */ - public static final long SPACE_UNLIMITED = -3; - - /** - * Quota return value for quota information not available. - */ - public static final long QUOTA_LIMIT_INFO_NOT_AVAILABLE = Long.MIN_VALUE; - - // OCS Route - private static final String OCS_ROUTE = "/ocs/v1.php/cloud/users/"; - - @Override - protected RemoteOperationResult run(OwnCloudClient client) { - RemoteOperationResult result = null; - int status; - GetMethod get = null; - - //Get the user - try { - OwnCloudBasicCredentials credentials = (OwnCloudBasicCredentials) client.getCredentials(); - String url = client.getBaseUri() + OCS_ROUTE + credentials.getUsername(); - - get = new GetMethod(url); - get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE); - get.setQueryString(new NameValuePair[]{new NameValuePair("format", "json")}); - status = client.executeMethod(get); - - if (isSuccess(status)) { - String response = get.getResponseBodyAsString(); - - // Parse the response - JSONObject respJSON = new JSONObject(response); - JSONObject respOCS = respJSON.getJSONObject(NODE_OCS); - JSONObject respData = respOCS.getJSONObject(NODE_DATA); - JSONObject quota = respData.getJSONObject(NODE_QUOTA); - final Long quotaFree = quota.getLong(NODE_QUOTA_FREE); - final Long quotaUsed = quota.getLong(NODE_QUOTA_USED); - final Long quotaTotal = quota.getLong(NODE_QUOTA_TOTAL); - final Double quotaRelative = quota.getDouble(NODE_QUOTA_RELATIVE); - Long quotaValue; - try { - quotaValue = quota.getLong(NODE_QUOTA); - } catch (JSONException e) { - Log_OC.i(TAG, "Legacy server in use < Nextcloud 9.0.54"); - quotaValue = QUOTA_LIMIT_INFO_NOT_AVAILABLE; - } - - // Result - result = new RemoteOperationResult(true, status, get.getResponseHeaders()); - - // Quota data in data collection - ArrayList data = new ArrayList<>(); - data.add(new Quota(quotaFree, quotaUsed, quotaTotal, quotaRelative, quotaValue)); - result.setData(data); - } else { - result = new RemoteOperationResult(false, status, get.getResponseHeaders()); - String response = get.getResponseBodyAsString(); - Log_OC.e(TAG, "Failed response while getting user quota information "); - if (response != null) { - Log_OC.e(TAG, "*** status code: " + status + " ; response message: " + response); - } else { - Log_OC.e(TAG, "*** status code: " + status); - } - } - } catch (Exception e) { - result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Exception while getting OC user information", e); - } finally { - if (get != null) { - get.releaseConnection(); - } - } - return result; - } - - private boolean isSuccess(int status) { - return (status == HttpStatus.SC_OK); - } -} diff --git a/test_client/src/com/owncloud/android/lib/test_project/TestActivity.java b/test_client/src/com/owncloud/android/lib/test_project/TestActivity.java index 8eec85a26..a8626fd49 100644 --- a/test_client/src/com/owncloud/android/lib/test_project/TestActivity.java +++ b/test_client/src/com/owncloud/android/lib/test_project/TestActivity.java @@ -35,7 +35,6 @@ import com.owncloud.android.lib.common.OwnCloudClientFactory; import com.owncloud.android.lib.common.OwnCloudCredentialsFactory; import com.owncloud.android.lib.common.network.NetworkUtils; -import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.resources.files.ChunkedUploadRemoteFileOperation; import com.owncloud.android.lib.resources.files.CreateRemoteFolderOperation; @@ -49,7 +48,6 @@ import com.owncloud.android.lib.resources.shares.GetRemoteSharesOperation; import com.owncloud.android.lib.resources.shares.RemoveRemoteShareOperation; import com.owncloud.android.lib.resources.shares.ShareType; -import com.owncloud.android.lib.resources.users.RemoteGetUserQuotaOperation; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; @@ -338,11 +336,6 @@ public RemoteOperationResult removeShare(int idShare) { } - public RemoteOperationResult getQuota() { - RemoteGetUserQuotaOperation getUserQuotaOperation = new RemoteGetUserQuotaOperation(); - return getUserQuotaOperation.execute(mClient); - } - /** * Extracts file from AssetManager to cache folder. diff --git a/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetUserQuotaTest.java b/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetUserQuotaTest.java index 897af33bb..daa2a3cff 100644 --- a/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetUserQuotaTest.java +++ b/test_client/tests/src/com/owncloud/android/lib/test_project/test/GetUserQuotaTest.java @@ -32,7 +32,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; -import com.owncloud.android.lib.resources.users.RemoteGetUserQuotaOperation.Quota; import com.owncloud.android.lib.test_project.TestActivity; import com.owncloud.android.lib.resources.files.*;