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

add OCAccount

add OCAccount
This commit is contained in:
DerSchabi 2018-05-18 12:21:47 +02:00 committed by davigonz
parent e354a716cb
commit 1249e205d6
10 changed files with 289 additions and 148 deletions

View File

@ -2,6 +2,7 @@ package com.owncloud.android.lib.refactor;
import android.net.Uri;
import com.owncloud.android.lib.refactor.account.OCAccount;
import com.owncloud.android.lib.refactor.authentication.OCCredentials;
@ -18,33 +19,13 @@ public class OCContext {
private static final boolean PARAM_SINGLE_COOKIE_HEADER_VALUE = true;
private static final String PARAM_PROTOCOL_VERSION = "http.protocol.version";
private OCCredentials mCredentials = null;
private Uri mBaseUri;
private OCAccount mOCAccount;
public class Builder {
OCContext ocContext = new OCContext();
public Builder setCredentials(OCCredentials credentials) {
ocContext.mCredentials = credentials;
return this;
}
public Builder setBaseUri(Uri baseUri) {
ocContext.mBaseUri = baseUri;
return this;
}
public OCContext build() {
return ocContext;
}
public OCContext(OCAccount account) {
mOCAccount = account;
}
public OCCredentials getCredentials() {
return mCredentials;
}
public Uri getBaseUri() {
return mBaseUri;
public OCAccount getOCAccount() {
return mOCAccount;
}
}

View File

@ -1,5 +1,7 @@
package com.owncloud.android.lib.refactor;
import android.net.Uri;
import java.util.Map;
import okhttp3.OkHttpClient;
@ -29,16 +31,26 @@ public abstract class RemoteOperation {
return httpClient;
}
public Uri.Builder getBaseUriBuilder() {
return mContext.getOCAccount().getBaseUri().buildUpon();
}
public Request.Builder getRequestBuilder() {
Request.Builder builder = new Request.Builder();
for(Map.Entry<String, String> header
: mContext.getCredentials().getCredentialHeaders().entrySet()) {
: mContext.getOCAccount()
.getCredentials()
.getCredentialHeaders()
.entrySet()) {
builder.addHeader(header.getKey(), header.getValue());
}
//TODO: Remove this part once SAML is obsolet
final String credentialCookie = mContext.getCredentials().getCredentialCookie();
final String credentialCookie = mContext
.getOCAccount()
.getCredentials()
.getCredentialCookie();
if(credentialCookie == null) {
builder.addHeader("Cookie", credentialCookie);
}

View File

@ -27,7 +27,7 @@ package com.owncloud.android.lib.refactor;
import android.accounts.Account;
import android.accounts.AccountsException;
import com.owncloud.android.lib.refactor.utils.AccountUtils;
import com.owncloud.android.lib.refactor.exceptions.AccountNotFoundException;
import com.owncloud.android.lib.refactor.exceptions.CertificateCombinedException;
import com.owncloud.android.lib.refactor.exceptions.OperationCancelledException;
import com.owncloud.android.lib.refactor.utils.ErrorMessageParser;
@ -71,7 +71,7 @@ public class RemoteOperationResult implements Serializable {
/**
* Generated - should be refreshed every time the class changes!!
*/
private static final long serialVersionUID = 4968939884332372230L;
private static final long serialVersionUID = 4968939884332652230L;
private static final String TAG = RemoteOperationResult.class.getSimpleName();
@ -184,7 +184,7 @@ public class RemoteOperationResult implements Serializable {
} else if (e instanceof UnknownHostException) {
mCode = ResultCode.HOST_NOT_AVAILABLE;
} else if (e instanceof AccountUtils.AccountNotFoundException) {
} else if (e instanceof AccountNotFoundException) {
mCode = ResultCode.ACCOUNT_NOT_FOUND;
} else if (e instanceof AccountsException) {
@ -444,9 +444,9 @@ public class RemoteOperationResult implements Serializable {
if(mException instanceof DavException) return "Unexpected WebDAV exception";
if(mException instanceof HttpException) return "HTTP violation";
if(mException instanceof IOException) return "Unrecovered transport exception";
if(mException instanceof AccountUtils.AccountNotFoundException) {
if(mException instanceof AccountNotFoundException) {
Account failedAccount =
((AccountUtils.AccountNotFoundException) mException).getFailedAccount();
((AccountNotFoundException) mException).getFailedAccount();
return mException.getMessage() + " (" +
(failedAccount != null ? failedAccount.name : "NULL") + ")";

View File

@ -22,7 +22,7 @@
*
*/
package com.owncloud.android.lib.refactor.utils;
package com.owncloud.android.lib.refactor.account;
/**
* @author masensio

View File

@ -23,7 +23,7 @@
*
*/
package com.owncloud.android.lib.refactor.utils;
package com.owncloud.android.lib.refactor.account;
import android.accounts.Account;
import android.accounts.AccountManager;
@ -33,16 +33,23 @@ import android.accounts.OperationCanceledException;
import android.content.Context;
import android.net.Uri;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.accounts.AccountTypeUtils;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.refactor.Log_OC;
import com.owncloud.android.lib.refactor.OCContext;
import com.owncloud.android.lib.refactor.authentication.OCCredentials;
import com.owncloud.android.lib.refactor.authentication.credentials.OCBasicCredentials;
import com.owncloud.android.lib.refactor.authentication.credentials.OCBearerCredentials;
import com.owncloud.android.lib.refactor.authentication.credentials.OCSamlSsoCredentials;
import com.owncloud.android.lib.refactor.exceptions.AccountNotFoundException;
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.auth.AuthenticationException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Cookie;
public class AccountUtils {
@ -59,7 +66,7 @@ public class AccountUtils {
public static String getWebDavUrlForAccount(Context context, Account account)
throws AccountNotFoundException {
return getBaseUrlForAccount(context, account) + OwnCloudClient.WEBDAV_PATH_4_0;
return getBaseUrlForAccount(context, account) + OCContext.WEBDAV_PATH_4_0;
}
@ -121,73 +128,65 @@ public class AccountUtils {
}
/**
* @return
* @return OCCredentials
* @throws IOException
* @throws AuthenticatorException
* @throws OperationCanceledException
*/
public static OwnCloudCredentials getCredentialsForAccount(Context context, Account account)
/**
*
* @param context an Android context
* @param account the coresponding Android account
* @return
* @throws OperationCanceledException
* @throws AuthenticatorException
* @throws IOException
*/
public static OCCredentials getCredentialsForAccount(Context context, Account account)
throws OperationCanceledException, AuthenticatorException, IOException {
OwnCloudCredentials credentials = null;
AccountManager am = AccountManager.get(context);
String supportsOAuth2 = am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_OAUTH2);
boolean isOauth2 = supportsOAuth2 != null && supportsOAuth2.equals("TRUE");
final AccountManager am = AccountManager.get(context);
final String supportsOAuth2 = am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_OAUTH2);
final boolean isOauth2 = supportsOAuth2 != null && supportsOAuth2.equals("TRUE");
String supportsSamlSSo = am.getUserData(account,
AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO);
boolean isSamlSso = supportsSamlSSo != null && supportsSamlSSo.equals("TRUE");
String username = AccountUtils.getUsernameForAccount(account);
OwnCloudVersion version = new OwnCloudVersion(am.getUserData(account, Constants.KEY_OC_VERSION));
final boolean isSamlSso = supportsSamlSSo != null && supportsSamlSSo.equals("TRUE");
final String username = AccountUtils.getUsernameForAccount(account);
if (isOauth2) {
String accessToken = am.blockingGetAuthToken(
final String accessToken = am.blockingGetAuthToken(
account,
AccountTypeUtils.getAuthTokenTypeAccessToken(account.type),
false);
credentials = OwnCloudCredentialsFactory.newBearerCredentials(username, accessToken);
return new OCBearerCredentials(username, accessToken);
} else if (isSamlSso) {
String accessToken = am.blockingGetAuthToken(
account,
AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type),
false);
credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken);
try {
final String accessToken = am.blockingGetAuthToken(
account,
AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type),
false);
return new OCSamlSsoCredentials(username, accessToken,
Uri.parse(getBaseUrlForAccount(context, account)));
} catch (AccountNotFoundException e) {
throw new AuthenticationException("Account not found", e);
}
} else {
String password = am.blockingGetAuthToken(
final String password = am.blockingGetAuthToken(
account,
AccountTypeUtils.getAuthTokenTypePass(account.type),
false);
credentials = OwnCloudCredentialsFactory.newBasicCredentials(
username,
password,
version.isPreemptiveAuthenticationPreferred()
);
return new OCBasicCredentials(username, password);
}
return credentials;
}
public static String buildAccountNameOld(Uri serverBaseUrl, String username) {
if (serverBaseUrl.getScheme() == null) {
serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString());
}
String accountName = username + "@" + serverBaseUrl.getHost();
if (serverBaseUrl.getPort() >= 0) {
accountName += ":" + serverBaseUrl.getPort();
}
return accountName;
}
public static String buildAccountName(Uri serverBaseUrl, String username) {
if (serverBaseUrl.getScheme() == null) {
serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString());
@ -203,80 +202,60 @@ public class AccountUtils {
return accountName;
}
public static void saveClient(OwnCloudClient client, Account savedAccount, Context context) {
public static void saveCookies(List<Cookie> cookies, Account savedAccount, Context context) {
// Account Manager
AccountManager ac = AccountManager.get(context.getApplicationContext());
if (client != null) {
String cookiesString = client.getCookiesString();
if (!"".equals(cookiesString)) {
ac.setUserData(savedAccount, Constants.KEY_COOKIES, cookiesString);
// Log_OC.d(TAG, "Saving Cookies: "+ cookiesString );
if (cookies != null && cookies.size() != 0) {
StringBuilder cookiesString = new StringBuilder();
for (Cookie cookie : cookies) {
cookiesString.append(cookiesString + cookie.toString() + ";");
}
ac.setUserData(savedAccount, Constants.KEY_COOKIES, cookiesString.toString());
}
}
/**
* Restore the client cookies persisted in an account stored in the system AccountManager.
* Restore the client cookies persisted in an account stored in the system AccountManager.
*
* @param account Stored account.
* @param client Client to restore cookies in.
* @param context Android context used to access the system AccountManager.
* @param account
* @param context
* @return
* @throws AccountsException
*/
public static void restoreCookies(Account account, OwnCloudClient client, Context context) {
public static List<Cookie> getCookiesFromAccount(Account account, Context context) throws AccountsException {
if (account == null) {
Log_OC.d(TAG, "Cannot restore cookie for null account");
return new ArrayList<>();
}
} else {
Log_OC.d(TAG, "Restoring cookies for " + account.name);
Log_OC.d(TAG, "Restoring cookies for " + account.name);
// Account Manager
AccountManager am = AccountManager.get(context.getApplicationContext());
final AccountManager am = AccountManager.get(context.getApplicationContext());
final Uri serverUri = Uri.parse(getBaseUrlForAccount(context, account));
final String cookiesString = am.getUserData(account, Constants.KEY_COOKIES);
final List<Cookie> cookies = new ArrayList<>();
Uri serverUri = (client.getBaseUri() != null) ? client.getBaseUri() : client.getWebdavUri();
if (cookiesString != null) {
String[] rawCookies = cookiesString.split(";");
for (String rawCookie : rawCookies) {
final int equalPos = rawCookie.indexOf('=');
String cookiesString = am.getUserData(account, Constants.KEY_COOKIES);
if (cookiesString != null) {
String[] cookies = cookiesString.split(";");
if (cookies.length > 0) {
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = new Cookie();
int equalPos = cookies[i].indexOf('=');
cookie.setName(cookies[i].substring(0, equalPos));
cookie.setValue(cookies[i].substring(equalPos + 1));
cookie.setDomain(serverUri.getHost()); // VERY IMPORTANT
cookie.setPath(serverUri.getPath()); // VERY IMPORTANT
client.getState().addCookie(cookie);
}
}
cookies.add(new Cookie.Builder()
.name(rawCookie.substring(0, equalPos))
.value(rawCookie.substring(equalPos + 1))
.domain(serverUri.getHost())
.path(serverUri.getPath())
.build());
}
}
return cookies;
}
public static class AccountNotFoundException extends AccountsException {
/**
* Generated - should be refreshed every time the class changes!!
*/
private static final long serialVersionUID = -1684392454798508693L;
private Account mFailedAccount;
public AccountNotFoundException(Account failedAccount, String message, Throwable cause) {
super(message, cause);
mFailedAccount = failedAccount;
}
public Account getFailedAccount() {
return mFailedAccount;
}
}
public static class Constants {
/**
* Version should be 3 numbers separated by dot so it can be parsed by

View File

@ -0,0 +1,155 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2016 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.refactor.account;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context;
import android.net.Uri;
import com.owncloud.android.lib.refactor.authentication.OCCredentials;
import com.owncloud.android.lib.refactor.authentication.credentials.OCAnonymousCredentials;
import com.owncloud.android.lib.refactor.exceptions.AccountNotFoundException;
import java.io.IOException;
/**
* OwnCloud Account
*
* @author David A. Velasco
*/
public class OCAccount {
private Uri mBaseUri;
private OCCredentials mCredentials;
private String mDisplayName;
private String mSavedAccountName;
private Account mSavedAccount;
/**
* Constructor for already saved OC accounts.
*
* Do not use for anonymous credentials.
*/
public OCAccount(Account savedAccount, Context context) throws AccountNotFoundException {
if (savedAccount == null) {
throw new IllegalArgumentException("Parameter 'savedAccount' cannot be null");
}
if (context == null) {
throw new IllegalArgumentException("Parameter 'context' cannot be null");
}
mSavedAccount = savedAccount;
mSavedAccountName = savedAccount.name;
mCredentials = null; // load of credentials is delayed
AccountManager ama = AccountManager.get(context.getApplicationContext());
String baseUrl = ama.getUserData(mSavedAccount, AccountUtils.Constants.KEY_OC_BASE_URL);
if (baseUrl == null ) {
throw new AccountNotFoundException(mSavedAccount, "Account not found", null);
}
mBaseUri = Uri.parse(AccountUtils.getBaseUrlForAccount(context, mSavedAccount));
mDisplayName = ama.getUserData(mSavedAccount, AccountUtils.Constants.KEY_DISPLAY_NAME);
}
/**
* Constructor for non yet saved OC accounts.
*
* @param baseUri URI to the OC server to get access to.
* @param credentials Credentials to authenticate in the server. NULL is valid for anonymous credentials.
*/
public OCAccount(Uri baseUri, OCCredentials credentials) {
if (baseUri == null) {
throw new IllegalArgumentException("Parameter 'baseUri' cannot be null");
}
mSavedAccount = null;
mSavedAccountName = null;
mBaseUri = baseUri;
mCredentials = credentials != null
? credentials
: new OCAnonymousCredentials();
String username = mCredentials.getUsername();
if (username != null) {
mSavedAccountName = AccountUtils.buildAccountName(mBaseUri, username);
}
}
/**
* Method for deferred load of account attributes from AccountManager
*
* @param context
* @throws AccountNotFoundException
* @throws AuthenticatorException
* @throws IOException
* @throws OperationCanceledException
*/
public void loadCredentials(Context context)
throws AccountNotFoundException, AuthenticatorException,
IOException, OperationCanceledException {
if (context == null) {
throw new IllegalArgumentException("Parameter 'context' cannot be null");
}
if (mSavedAccount != null) {
mCredentials = AccountUtils.getCredentialsForAccount(context, mSavedAccount);
}
}
public Uri getBaseUri() {
return mBaseUri;
}
public OCCredentials getCredentials() {
return mCredentials;
}
public String getName() {
return mSavedAccountName;
}
public Account getSavedAccount() {
return mSavedAccount;
}
public String getDisplayName() {
if (mDisplayName != null && mDisplayName.length() > 0) {
return mDisplayName;
} else if (mCredentials != null) {
return mCredentials.getUsername();
} else if (mSavedAccount != null) {
return AccountUtils.getUsernameForAccount(mSavedAccount);
} else {
return null;
}
}
}

View File

@ -84,13 +84,6 @@ public class OAuth2GetAccessTokenOperation extends RemoteOperation {
@Override
public RemoteOperationResult exec() {
try {
final Uri uri = getOCContext()
.getBaseUri()
.buildUpon()
.appendEncodedPath(mAccessTokenEndpointPath)
.build();
final RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(OAuth2Constants.KEY_GRANT_TYPE, mGrantType)
@ -100,7 +93,10 @@ public class OAuth2GetAccessTokenOperation extends RemoteOperation {
.build();
final Request request = getRequestBuilder()
.url(uri.toString())
.url(getBaseUriBuilder()
.appendEncodedPath(mAccessTokenEndpointPath)
.build()
.toString())
.method("POST", requestBody)
.build();
@ -109,6 +105,7 @@ public class OAuth2GetAccessTokenOperation extends RemoteOperation {
.execute();
final String responseData = response.body().string();
if (responseData != null && responseData.length() > 0) {
JSONObject tokenJson = new JSONObject(responseData);
Map<String, String> accessTokenResult =

View File

@ -79,8 +79,6 @@ public class OAuth2RefreshAccessTokenOperation extends RemoteOperation {
@Override
public RemoteOperationResult exec() {
try {
final RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(OAuth2Constants.KEY_GRANT_TYPE,
@ -90,20 +88,15 @@ public class OAuth2RefreshAccessTokenOperation extends RemoteOperation {
.build();
final Request request = getRequestBuilder()
.url(getOCContext().getBaseUri().buildUpon()
.url(getBaseUriBuilder()
.appendEncodedPath(mAccessTokenEndpointPath)
.build()
.toString())
.method("POST", requestBody)
.build();
OCCredentials oauthCredentials = new OCBasicCredentials(
mClientId,
mClientSecret
);
final Response response = getClient().newCall(request).execute();
final String responseData = response.body().string();
Log_OC.d(TAG, "OAUTH2: raw response from POST TOKEN: " + responseData);

View File

@ -0,0 +1,23 @@
package com.owncloud.android.lib.refactor.exceptions;
import android.accounts.Account;
import android.accounts.AccountsException;
public class AccountNotFoundException extends AccountsException {
/**
* Generated - should be refreshed every time the class changes!!
*/
private static final long serialVersionUID = -1684392454778508693L;
private Account mFailedAccount;
public AccountNotFoundException(Account failedAccount, String message, Throwable cause) {
super(message, cause);
mFailedAccount = failedAccount;
}
public Account getFailedAccount() {
return mFailedAccount;
}
}

View File

@ -13,6 +13,7 @@ public class PropfindOperation extends RemoteOperation {
@Override
public RemoteOperationResult exec() {
return null;
}
}