mirror of
https://github.com/owncloud/android-library.git
synced 2025-06-07 16:06:08 +00:00
commit
2289358775
@ -35,7 +35,7 @@ import java.util.List;
|
|||||||
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
|
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
|
import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
|
||||||
import com.owncloud.android.lib.resources.files.RemoteFile;
|
import com.owncloud.android.lib.resources.files.RemoteFile;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||||
|
@ -29,6 +29,8 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
||||||
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
@ -122,10 +124,10 @@ public class OwnCloudAccount {
|
|||||||
throw new IllegalArgumentException("Parameter 'context' cannot be null");
|
throw new IllegalArgumentException("Parameter 'context' cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSavedAccount != null) {
|
if (mSavedAccount != null) {
|
||||||
mCredentials = AccountUtils.getCredentialsForAccount(context, mSavedAccount);
|
mCredentials = AccountUtils.getCredentialsForAccount(context, mSavedAccount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri getBaseUri() {
|
public Uri getBaseUri() {
|
||||||
return mBaseUri;
|
return mBaseUri;
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
/* 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.common;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.commons.httpclient.auth.AuthPolicy;
|
|
||||||
import org.apache.commons.httpclient.auth.AuthScope;
|
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.network.BearerAuthScheme;
|
|
||||||
import com.owncloud.android.lib.common.network.BearerCredentials;
|
|
||||||
|
|
||||||
public class OwnCloudBearerCredentials implements OwnCloudCredentials {
|
|
||||||
|
|
||||||
private String mAccessToken;
|
|
||||||
|
|
||||||
public OwnCloudBearerCredentials(String accessToken) {
|
|
||||||
mAccessToken = accessToken != null ? accessToken : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applyTo(OwnCloudClient client) {
|
|
||||||
AuthPolicy.registerAuthScheme(BearerAuthScheme.AUTH_POLICY, BearerAuthScheme.class);
|
|
||||||
|
|
||||||
List<String> authPrefs = new ArrayList<String>(1);
|
|
||||||
authPrefs.add(BearerAuthScheme.AUTH_POLICY);
|
|
||||||
client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
|
|
||||||
|
|
||||||
client.getParams().setAuthenticationPreemptive(true);
|
|
||||||
client.getParams().setCredentialCharset(OwnCloudCredentialsFactory.CREDENTIAL_CHARSET);
|
|
||||||
client.getState().setCredentials(
|
|
||||||
AuthScope.ANY,
|
|
||||||
new BearerCredentials(mAccessToken)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsername() {
|
|
||||||
// its unknown
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAuthToken() {
|
|
||||||
return mAccessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean authTokenExpires() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
/* ownCloud Android Library is available under MIT license
|
/* ownCloud Android Library is available under MIT license
|
||||||
* Copyright (C) 2016 ownCloud GmbH.
|
* Copyright (C) 2017 ownCloud GmbH.
|
||||||
* Copyright (C) 2012 Bartek Przybylski
|
* Copyright (C) 2012 Bartek Przybylski
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -33,7 +33,6 @@ import org.apache.commons.httpclient.Header;
|
|||||||
import org.apache.commons.httpclient.HostConfiguration;
|
import org.apache.commons.httpclient.HostConfiguration;
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
import org.apache.commons.httpclient.HttpClient;
|
||||||
import org.apache.commons.httpclient.HttpConnectionManager;
|
import org.apache.commons.httpclient.HttpConnectionManager;
|
||||||
import org.apache.commons.httpclient.HttpException;
|
|
||||||
import org.apache.commons.httpclient.HttpMethod;
|
import org.apache.commons.httpclient.HttpMethod;
|
||||||
import org.apache.commons.httpclient.HttpMethodBase;
|
import org.apache.commons.httpclient.HttpMethodBase;
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
@ -41,23 +40,27 @@ import org.apache.commons.httpclient.HttpVersion;
|
|||||||
import org.apache.commons.httpclient.URI;
|
import org.apache.commons.httpclient.URI;
|
||||||
import org.apache.commons.httpclient.URIException;
|
import org.apache.commons.httpclient.URIException;
|
||||||
import org.apache.commons.httpclient.cookie.CookiePolicy;
|
import org.apache.commons.httpclient.cookie.CookiePolicy;
|
||||||
import org.apache.commons.httpclient.methods.HeadMethod;
|
|
||||||
import org.apache.commons.httpclient.params.HttpMethodParams;
|
import org.apache.commons.httpclient.params.HttpMethodParams;
|
||||||
import org.apache.commons.httpclient.params.HttpParams;
|
import org.apache.commons.httpclient.params.HttpParams;
|
||||||
|
|
||||||
|
import android.accounts.AccountManager;
|
||||||
|
import android.accounts.AccountsException;
|
||||||
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials;
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials;
|
||||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
||||||
import com.owncloud.android.lib.common.network.RedirectionPath;
|
import com.owncloud.android.lib.common.network.RedirectionPath;
|
||||||
import com.owncloud.android.lib.common.network.WebdavUtils;
|
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
|
|
||||||
public class OwnCloudClient extends HttpClient {
|
public class OwnCloudClient extends HttpClient {
|
||||||
|
|
||||||
private static final String TAG = OwnCloudClient.class.getSimpleName();
|
private static final String TAG = OwnCloudClient.class.getSimpleName();
|
||||||
public static final int MAX_REDIRECTIONS_COUNT = 3;
|
private static final int MAX_REDIRECTIONS_COUNT = 3;
|
||||||
|
private static final int MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS = 1;
|
||||||
private static final String PARAM_SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header";
|
private static final String PARAM_SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header";
|
||||||
private static final boolean PARAM_SINGLE_COOKIE_HEADER_VALUE = true;
|
private static final boolean PARAM_SINGLE_COOKIE_HEADER_VALUE = true;
|
||||||
private static final String PARAM_PROTOCOL_VERSION = "http.protocol.version";
|
private static final String PARAM_PROTOCOL_VERSION = "http.protocol.version";
|
||||||
@ -73,6 +76,25 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
|
|
||||||
private OwnCloudVersion mVersion = null;
|
private OwnCloudVersion mVersion = null;
|
||||||
|
|
||||||
|
/// next too attributes are a very ugly dependency, added to grant silent retry of OAuth token when needed ;
|
||||||
|
/// see #shouldInvalidateCredentials and #invalidateCredentials for more details
|
||||||
|
private Context mContext;
|
||||||
|
private OwnCloudAccount mAccount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link @OwnCloudClientManager} holding a reference to this object and delivering it to callers; might be
|
||||||
|
* NULL
|
||||||
|
*/
|
||||||
|
private OwnCloudClientManager mOwnCloudClientManager = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When 'true', the method {@link #executeMethod(HttpMethod)} tries to silently refresh credentials
|
||||||
|
* if fails due to lack of authorization, if credentials support authorization refresh.
|
||||||
|
*/
|
||||||
|
private boolean mSilentRefreshOfAccountCredentials = true;
|
||||||
|
|
||||||
|
private String mRedirectedLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
@ -142,28 +164,6 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
mCredentials.applyTo(this);
|
mCredentials.applyTo(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a file exists in the OC server
|
|
||||||
*
|
|
||||||
* @return 'true' if the file exists; 'false' it doesn't exist
|
|
||||||
* @throws Exception When the existence could not be determined
|
|
||||||
* @deprecated Use ExistenceCheckOperation instead
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public boolean existsFile(String path) throws IOException, HttpException {
|
|
||||||
HeadMethod head = new HeadMethod(getWebdavUri() + WebdavUtils.encodePath(path));
|
|
||||||
try {
|
|
||||||
int status = executeMethod(head);
|
|
||||||
Log_OC.d(TAG, "HEAD to " + path + " finished with HTTP status " + status +
|
|
||||||
((status != HttpStatus.SC_OK) ? "(FAIL)" : ""));
|
|
||||||
exhaustResponse(head.getResponseBodyAsStream());
|
|
||||||
return (status == HttpStatus.SC_OK);
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
head.releaseConnection(); // let the connection available for other methods
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests the received method with the received timeout (milliseconds).
|
* Requests the received method with the received timeout (milliseconds).
|
||||||
*
|
*
|
||||||
@ -207,25 +207,40 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int executeMethod(HttpMethod method) throws IOException {
|
public int executeMethod(HttpMethod method) throws IOException {
|
||||||
// Update User Agent
|
|
||||||
HttpParams params = method.getParams();
|
|
||||||
String userAgent = OwnCloudClientManagerFactory.getUserAgent();
|
|
||||||
params.setParameter(HttpMethodParams.USER_AGENT, userAgent);
|
|
||||||
|
|
||||||
preventCrashDueToInvalidPort(method);
|
boolean repeatWithFreshCredentials;
|
||||||
|
int repeatCounter = 0;
|
||||||
|
int status;
|
||||||
|
|
||||||
Log_OC.d(TAG + " #" + mInstanceNumber, "REQUEST " +
|
do {
|
||||||
|
// Update User Agent
|
||||||
|
HttpParams params = method.getParams();
|
||||||
|
String userAgent = OwnCloudClientManagerFactory.getUserAgent();
|
||||||
|
params.setParameter(HttpMethodParams.USER_AGENT, userAgent);
|
||||||
|
|
||||||
|
preventCrashDueToInvalidPort(method);
|
||||||
|
|
||||||
|
Log_OC.d(TAG + " #" + mInstanceNumber, "REQUEST " +
|
||||||
method.getName() + " " + method.getPath());
|
method.getName() + " " + method.getPath());
|
||||||
|
|
||||||
//logCookiesAtRequest(method.getRequestHeaders(), "before");
|
//logCookiesAtRequest(method.getRequestHeaders(), "before");
|
||||||
//logCookiesAtState("before");
|
//logCookiesAtState("before");
|
||||||
method.setFollowRedirects(false);
|
method.setFollowRedirects(false);
|
||||||
|
|
||||||
int status = super.executeMethod(method);
|
status = super.executeMethod(method);
|
||||||
|
|
||||||
if (mFollowRedirects) {
|
checkFirstRedirection(method);
|
||||||
status = followRedirection(method).getLastStatus();
|
|
||||||
}
|
if (mFollowRedirects) {
|
||||||
|
status = followRedirection(method).getLastStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
repeatWithFreshCredentials = checkUnauthorizedAccess(status, repeatCounter);
|
||||||
|
if (repeatWithFreshCredentials) {
|
||||||
|
repeatCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (repeatWithFreshCredentials);
|
||||||
|
|
||||||
//logCookiesAtRequest(method.getRequestHeaders(), "after");
|
//logCookiesAtRequest(method.getRequestHeaders(), "after");
|
||||||
//logCookiesAtState("after");
|
//logCookiesAtState("after");
|
||||||
@ -234,6 +249,17 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkFirstRedirection(HttpMethod method) {
|
||||||
|
Header[] httpHeaders = method.getResponseHeaders();
|
||||||
|
|
||||||
|
for (Header httpHeader : httpHeaders) {
|
||||||
|
|
||||||
|
if ("location".equals(httpHeader.getName().toLowerCase())) {
|
||||||
|
mRedirectedLocation = httpHeader.getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fix for https://github.com/owncloud/android/issues/1847#issuecomment-267558274
|
* Fix for https://github.com/owncloud/android/issues/1847#issuecomment-267558274
|
||||||
@ -266,6 +292,7 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
int redirectionsCount = 0;
|
int redirectionsCount = 0;
|
||||||
int status = method.getStatusCode();
|
int status = method.getStatusCode();
|
||||||
RedirectionPath result = new RedirectionPath(status, MAX_REDIRECTIONS_COUNT);
|
RedirectionPath result = new RedirectionPath(status, MAX_REDIRECTIONS_COUNT);
|
||||||
|
|
||||||
while (redirectionsCount < MAX_REDIRECTIONS_COUNT &&
|
while (redirectionsCount < MAX_REDIRECTIONS_COUNT &&
|
||||||
(status == HttpStatus.SC_MOVED_PERMANENTLY ||
|
(status == HttpStatus.SC_MOVED_PERMANENTLY ||
|
||||||
status == HttpStatus.SC_MOVED_TEMPORARILY ||
|
status == HttpStatus.SC_MOVED_TEMPORARILY ||
|
||||||
@ -277,10 +304,11 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
location = method.getResponseHeader("location");
|
location = method.getResponseHeader("location");
|
||||||
}
|
}
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
Log_OC.d(TAG + " #" + mInstanceNumber,
|
|
||||||
"Location to redirect: " + location.getValue());
|
|
||||||
|
|
||||||
String locationStr = location.getValue();
|
String locationStr = location.getValue();
|
||||||
|
|
||||||
|
Log_OC.d(TAG + " #" + mInstanceNumber,
|
||||||
|
"Location to redirect: " + locationStr);
|
||||||
|
|
||||||
result.addLocation(locationStr);
|
result.addLocation(locationStr);
|
||||||
|
|
||||||
// Release the connection to avoid reach the max number of connections per host
|
// Release the connection to avoid reach the max number of connections per host
|
||||||
@ -468,4 +496,138 @@ public class OwnCloudClient extends HttpClient {
|
|||||||
public OwnCloudVersion getOwnCloudVersion() {
|
public OwnCloudVersion getOwnCloudVersion() {
|
||||||
return mVersion;
|
return mVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setContext(Context context) {
|
||||||
|
this.mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context getContext() {
|
||||||
|
return mContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccount(OwnCloudAccount account) {
|
||||||
|
this.mAccount = account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OwnCloudAccount getAccount() {
|
||||||
|
return mAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or disables silent refresh of credentials, if supported by credentials themselves.
|
||||||
|
*/
|
||||||
|
public void setSilentRefreshOfAccountCredentials(boolean silentRefreshOfAccountCredentials) {
|
||||||
|
mSilentRefreshOfAccountCredentials = silentRefreshOfAccountCredentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getSilentRefreshOfAccountCredentials() {
|
||||||
|
return mSilentRefreshOfAccountCredentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the status code of an execution and decides if should be repeated with fresh credentials.
|
||||||
|
*
|
||||||
|
* Invalidates current credentials if the request failed as anauthorized.
|
||||||
|
*
|
||||||
|
* Refresh current credentials if possible, and marks a retry.
|
||||||
|
*
|
||||||
|
* @param status
|
||||||
|
* @param repeatCounter
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean checkUnauthorizedAccess(int status, int repeatCounter) {
|
||||||
|
boolean credentialsWereRefreshed = false;
|
||||||
|
|
||||||
|
if (shouldInvalidateAccountCredentials(status)) {
|
||||||
|
boolean invalidated = invalidateAccountCredentials();
|
||||||
|
|
||||||
|
if (invalidated) {
|
||||||
|
if (getCredentials().authTokenCanBeRefreshed() &&
|
||||||
|
repeatCounter < MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
mAccount.loadCredentials(mContext);
|
||||||
|
// if mAccount.getCredentials().length() == 0 --> refresh failed
|
||||||
|
setCredentials(mAccount.getCredentials());
|
||||||
|
credentialsWereRefreshed = true;
|
||||||
|
|
||||||
|
} catch (AccountsException | IOException e) {
|
||||||
|
Log_OC.e(
|
||||||
|
TAG,
|
||||||
|
"Error while trying to refresh auth token for " + mAccount.getSavedAccount().name,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!credentialsWereRefreshed && mOwnCloudClientManager != null) {
|
||||||
|
// if credentials are not refreshed, client must be removed
|
||||||
|
// from the OwnCloudClientManager to prevent it is reused once and again
|
||||||
|
mOwnCloudClientManager.removeClientFor(mAccount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else: execute will finish with status 401
|
||||||
|
}
|
||||||
|
|
||||||
|
return credentialsWereRefreshed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if credentials should be invalidated according the to the HTTPS status
|
||||||
|
* of a network request just performed.
|
||||||
|
*
|
||||||
|
* @param httpStatusCode Result of the last request ran with the 'credentials' belows.
|
||||||
|
|
||||||
|
* @return 'True' if credentials should and might be invalidated, 'false' if shouldn't or
|
||||||
|
* cannot be invalidated with the given arguments.
|
||||||
|
*/
|
||||||
|
private boolean shouldInvalidateAccountCredentials(int httpStatusCode) {
|
||||||
|
|
||||||
|
boolean should = (httpStatusCode == HttpStatus.SC_UNAUTHORIZED || isIdPRedirection()); // invalid credentials
|
||||||
|
|
||||||
|
should &= (mCredentials != null && // real credentials
|
||||||
|
!(mCredentials instanceof OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials));
|
||||||
|
|
||||||
|
// test if have all the needed to effectively invalidate ...
|
||||||
|
should &= (mAccount != null && mAccount.getSavedAccount() != null && mContext != null);
|
||||||
|
|
||||||
|
return should;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates credentials stored for the given account in the system {@link AccountManager} and in
|
||||||
|
* current {@link OwnCloudClientManagerFactory#getDefaultSingleton()} instance.
|
||||||
|
*
|
||||||
|
* {@link #shouldInvalidateAccountCredentials(int)} should be called first.
|
||||||
|
*
|
||||||
|
* @return 'True' if invalidation was successful, 'false' otherwise.
|
||||||
|
*/
|
||||||
|
private boolean invalidateAccountCredentials() {
|
||||||
|
AccountManager am = AccountManager.get(mContext);
|
||||||
|
am.invalidateAuthToken(
|
||||||
|
mAccount.getSavedAccount().type,
|
||||||
|
mCredentials.getAuthToken()
|
||||||
|
);
|
||||||
|
am.clearPassword(mAccount.getSavedAccount()); // being strict, only needed for Basic Auth credentials
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OwnCloudClientManager getOwnCloudClientManager() {
|
||||||
|
return mOwnCloudClientManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOwnCloudClientManager(OwnCloudClientManager clientManager) {
|
||||||
|
mOwnCloudClientManager = clientManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the redirection is to an identity provider such as SAML or wayf
|
||||||
|
* @return true if the redirection location includes SAML or wayf, false otherwise
|
||||||
|
*/
|
||||||
|
private boolean isIdPRedirection() {
|
||||||
|
return (mRedirectedLocation != null &&
|
||||||
|
(mRedirectedLocation.toUpperCase().contains("SAML") ||
|
||||||
|
mRedirectedLocation.toLowerCase().contains("wayf")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ import com.owncloud.android.lib.common.accounts.AccountTypeUtils;
|
|||||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
||||||
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
||||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
|
|
||||||
@ -57,11 +58,12 @@ public class OwnCloudClientFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a OwnCloudClient setup for an ownCloud account
|
* Creates a OwnCloudClient setup for an ownCloud account
|
||||||
*
|
*
|
||||||
* Do not call this method from the main thread.
|
* Do not call this method from the main thread.
|
||||||
*
|
*
|
||||||
* @param account The ownCloud account
|
* @param account The ownCloud account
|
||||||
* @param appContext Android application context
|
* @param appContext Android application context
|
||||||
|
* @param currentActivity Caller {@link Activity}
|
||||||
* @return A OwnCloudClient object ready to be used
|
* @return A OwnCloudClient object ready to be used
|
||||||
* @throws AuthenticatorException If the authenticator failed to get the authorization
|
* @throws AuthenticatorException If the authenticator failed to get the authorization
|
||||||
* token for the account.
|
* token for the account.
|
||||||
@ -71,69 +73,7 @@ public class OwnCloudClientFactory {
|
|||||||
* authorization token for the account.
|
* authorization token for the account.
|
||||||
* @throws AccountNotFoundException If 'account' is unknown for the AccountManager
|
* @throws AccountNotFoundException If 'account' is unknown for the AccountManager
|
||||||
*
|
*
|
||||||
* @deprecated : Will be deleted in version 1.0.
|
|
||||||
* Use {@link #createOwnCloudClient(Account, Context, Activity)} instead.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public static OwnCloudClient createOwnCloudClient (Account account, Context appContext)
|
|
||||||
throws OperationCanceledException, AuthenticatorException, IOException,
|
|
||||||
AccountNotFoundException {
|
|
||||||
//Log_OC.d(TAG, "Creating OwnCloudClient associated to " + account.name);
|
|
||||||
Uri baseUri = Uri.parse(AccountUtils.getBaseUrlForAccount(appContext, account));
|
|
||||||
AccountManager am = AccountManager.get(appContext);
|
|
||||||
// TODO avoid calling to getUserData here
|
|
||||||
boolean isOauth2 =
|
|
||||||
am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_OAUTH2) != null;
|
|
||||||
boolean isSamlSso =
|
|
||||||
am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
|
|
||||||
OwnCloudClient client = createOwnCloudClient(baseUri, appContext, !isSamlSso);
|
|
||||||
|
|
||||||
String username = AccountUtils.getUsernameForAccount(account);
|
|
||||||
if (isOauth2) {
|
|
||||||
String accessToken = am.blockingGetAuthToken(
|
|
||||||
account,
|
|
||||||
AccountTypeUtils.getAuthTokenTypeAccessToken(account.type),
|
|
||||||
false);
|
|
||||||
|
|
||||||
client.setCredentials(
|
|
||||||
OwnCloudCredentialsFactory.newBearerCredentials(accessToken)
|
|
||||||
);
|
|
||||||
|
|
||||||
} else if (isSamlSso) { // TODO avoid a call to getUserData here
|
|
||||||
String accessToken = am.blockingGetAuthToken(
|
|
||||||
account,
|
|
||||||
AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type),
|
|
||||||
false);
|
|
||||||
|
|
||||||
client.setCredentials(
|
|
||||||
OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken)
|
|
||||||
);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//String password = am.getPassword(account);
|
|
||||||
String password = am.blockingGetAuthToken(
|
|
||||||
account,
|
|
||||||
AccountTypeUtils.getAuthTokenTypePass(account.type),
|
|
||||||
false);
|
|
||||||
|
|
||||||
OwnCloudVersion version = AccountUtils.getServerVersionForAccount(account, appContext);
|
|
||||||
client.setCredentials(
|
|
||||||
OwnCloudCredentialsFactory.newBasicCredentials(
|
|
||||||
username,
|
|
||||||
password,
|
|
||||||
(version != null && version.isPreemptiveAuthenticationPreferred())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore cookies
|
|
||||||
AccountUtils.restoreCookies(account, client, appContext);
|
|
||||||
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static OwnCloudClient createOwnCloudClient (Account account, Context appContext,
|
public static OwnCloudClient createOwnCloudClient (Account account, Context appContext,
|
||||||
Activity currentActivity)
|
Activity currentActivity)
|
||||||
throws OperationCanceledException, AuthenticatorException, IOException,
|
throws OperationCanceledException, AuthenticatorException, IOException,
|
||||||
@ -156,12 +96,12 @@ public class OwnCloudClientFactory {
|
|||||||
currentActivity,
|
currentActivity,
|
||||||
null,
|
null,
|
||||||
null);
|
null);
|
||||||
|
|
||||||
Bundle result = future.getResult();
|
Bundle result = future.getResult();
|
||||||
String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN);
|
String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN);
|
||||||
if (accessToken == null) throw new AuthenticatorException("WTF!");
|
if (accessToken == null) throw new AuthenticatorException("WTF!");
|
||||||
client.setCredentials(
|
client.setCredentials(
|
||||||
OwnCloudCredentialsFactory.newBearerCredentials(accessToken)
|
OwnCloudCredentialsFactory.newBearerCredentials(username, accessToken)
|
||||||
);
|
);
|
||||||
|
|
||||||
} else if (isSamlSso) { // TODO avoid a call to getUserData here
|
} else if (isSamlSso) { // TODO avoid a call to getUserData here
|
||||||
@ -172,7 +112,7 @@ public class OwnCloudClientFactory {
|
|||||||
currentActivity,
|
currentActivity,
|
||||||
null,
|
null,
|
||||||
null);
|
null);
|
||||||
|
|
||||||
Bundle result = future.getResult();
|
Bundle result = future.getResult();
|
||||||
String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN);
|
String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN);
|
||||||
if (accessToken == null) throw new AuthenticatorException("WTF!");
|
if (accessToken == null) throw new AuthenticatorException("WTF!");
|
||||||
@ -193,7 +133,7 @@ public class OwnCloudClientFactory {
|
|||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
Bundle result = future.getResult();
|
Bundle result = future.getResult();
|
||||||
String password = result.getString(AccountManager.KEY_AUTHTOKEN);
|
String password = result.getString(AccountManager.KEY_AUTHTOKEN);
|
||||||
OwnCloudVersion version = AccountUtils.getServerVersionForAccount(account, appContext);
|
OwnCloudVersion version = AccountUtils.getServerVersionForAccount(account, appContext);
|
||||||
@ -205,13 +145,13 @@ public class OwnCloudClientFactory {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore cookies
|
// Restore cookies
|
||||||
AccountUtils.restoreCookies(account, client, appContext);
|
AccountUtils.restoreCookies(account, client, appContext);
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a OwnCloudClient to access a URL and sets the desired parameters for ownCloud
|
* Creates a OwnCloudClient to access a URL and sets the desired parameters for ownCloud
|
||||||
* client connections.
|
* client connections.
|
||||||
@ -236,6 +176,7 @@ public class OwnCloudClientFactory {
|
|||||||
OwnCloudClient client = new OwnCloudClient(uri, NetworkUtils.getMultiThreadedConnManager());
|
OwnCloudClient client = new OwnCloudClient(uri, NetworkUtils.getMultiThreadedConnManager());
|
||||||
client.setDefaultTimeouts(DEFAULT_DATA_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT);
|
client.setDefaultTimeouts(DEFAULT_DATA_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT);
|
||||||
client.setFollowRedirects(followRedirects);
|
client.setFollowRedirects(followRedirects);
|
||||||
|
client.setContext(context);
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
@ -36,44 +36,47 @@ import com.owncloud.android.lib.common.utils.Log_OC;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class SimpleFactoryManager implements OwnCloudClientManager {
|
public class SimpleFactoryManager implements OwnCloudClientManager {
|
||||||
|
|
||||||
private static final String TAG = SimpleFactoryManager.class.getSimpleName();
|
|
||||||
|
|
||||||
@Override
|
private static final String TAG = SimpleFactoryManager.class.getSimpleName();
|
||||||
public OwnCloudClient getClientFor(OwnCloudAccount account, Context context)
|
|
||||||
throws AccountNotFoundException, OperationCanceledException, AuthenticatorException,
|
|
||||||
IOException {
|
|
||||||
|
|
||||||
Log_OC.d(TAG, "getClientFor(OwnCloudAccount ... : ");
|
@Override
|
||||||
|
public OwnCloudClient getClientFor(OwnCloudAccount account, Context context)
|
||||||
|
throws AccountNotFoundException, OperationCanceledException, AuthenticatorException,
|
||||||
|
IOException {
|
||||||
|
|
||||||
OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(
|
Log_OC.d(TAG, "getClientFor(OwnCloudAccount ... : ");
|
||||||
account.getBaseUri(),
|
|
||||||
context.getApplicationContext(),
|
|
||||||
true);
|
|
||||||
|
|
||||||
Log_OC.v(TAG, " new client {" +
|
OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(
|
||||||
(account.getName() != null ?
|
account.getBaseUri(),
|
||||||
account.getName() :
|
context.getApplicationContext(),
|
||||||
AccountUtils.buildAccountName(account.getBaseUri(), "")
|
true);
|
||||||
|
|
||||||
) + ", " + client.hashCode() + "}");
|
Log_OC.v(TAG, " new client {" +
|
||||||
|
(account.getName() != null ?
|
||||||
|
account.getName() :
|
||||||
|
AccountUtils.buildAccountName(account.getBaseUri(), "")
|
||||||
|
|
||||||
|
) + ", " + client.hashCode() + "}");
|
||||||
|
|
||||||
if (account.getCredentials() == null) {
|
if (account.getCredentials() == null) {
|
||||||
account.loadCredentials(context);
|
account.loadCredentials(context);
|
||||||
}
|
}
|
||||||
client.setCredentials(account.getCredentials());
|
client.setCredentials(account.getCredentials());
|
||||||
return client;
|
client.setAccount(account);
|
||||||
}
|
client.setContext(context);
|
||||||
|
client.setOwnCloudClientManager(this);
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OwnCloudClient removeClientFor(OwnCloudAccount account) {
|
public OwnCloudClient removeClientFor(OwnCloudAccount account) {
|
||||||
// nothing to do - not taking care of tracking instances!
|
// nothing to do - not taking care of tracking instances!
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveAllClients(Context context, String accountType) {
|
public void saveAllClients(Context context, String accountType) {
|
||||||
// nothing to do - not taking care of tracking instances!
|
// nothing to do - not taking care of tracking instances!
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
||||||
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,8 +116,11 @@ public class SingleSessionManager implements OwnCloudClientManager {
|
|||||||
context.getApplicationContext(),
|
context.getApplicationContext(),
|
||||||
true); // TODO remove dependency on OwnCloudClientFactory
|
true); // TODO remove dependency on OwnCloudClientFactory
|
||||||
client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
|
client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
|
||||||
// enable cookie tracking
|
client.setAccount(account);
|
||||||
|
client.setContext(context);
|
||||||
|
client.setOwnCloudClientManager(this);
|
||||||
|
|
||||||
|
// enable cookie tracking
|
||||||
AccountUtils.restoreCookies(account.getSavedAccount(), client, context);
|
AccountUtils.restoreCookies(account.getSavedAccount(), client, context);
|
||||||
|
|
||||||
account.loadCredentials(context);
|
account.loadCredentials(context);
|
||||||
|
@ -28,6 +28,7 @@ package com.owncloud.android.lib.common.accounts;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.commons.httpclient.Cookie;
|
import org.apache.commons.httpclient.Cookie;
|
||||||
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
@ -37,9 +38,12 @@ import android.accounts.OperationCanceledException;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentials;
|
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||||
|
|
||||||
@ -53,45 +57,25 @@ public class AccountUtils {
|
|||||||
/**
|
/**
|
||||||
* Constructs full url to host and webdav resource basing on host version
|
* Constructs full url to host and webdav resource basing on host version
|
||||||
*
|
*
|
||||||
* @param context
|
* @param context Valid Android {@link Context}, needed to access the {@link AccountManager}
|
||||||
* @param account
|
* @param account A stored ownCloud {@link Account}
|
||||||
* @return url or null on failure
|
* @return Full URL to WebDAV endpoint in the server corresponding to 'account'.
|
||||||
* @throws AccountNotFoundException When 'account' is unknown for the AccountManager
|
* @throws AccountNotFoundException When 'account' is unknown for the AccountManager
|
||||||
* @deprecated To be removed in release 1.0.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
public static String getWebDavUrlForAccount(Context context, Account account)
|
||||||
public static String constructFullURLForAccount(Context context, Account account) throws AccountNotFoundException {
|
|
||||||
AccountManager ama = AccountManager.get(context);
|
|
||||||
String baseurl = ama.getUserData(account, Constants.KEY_OC_BASE_URL);
|
|
||||||
if (baseurl == null) {
|
|
||||||
throw new AccountNotFoundException(account, "Account not found", null);
|
|
||||||
}
|
|
||||||
return baseurl + WEBDAV_PATH_4_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts url server from the account
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param account
|
|
||||||
* @return url server or null on failure
|
|
||||||
* @throws AccountNotFoundException When 'account' is unknown for the AccountManager
|
|
||||||
* @deprecated This method will be removed in version 1.0.
|
|
||||||
* Use {@link #getBaseUrlForAccount(Context, Account)}
|
|
||||||
* instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public static String constructBasicURLForAccount(Context context, Account account)
|
|
||||||
throws AccountNotFoundException {
|
throws AccountNotFoundException {
|
||||||
return getBaseUrlForAccount(context, account);
|
|
||||||
|
return getBaseUrlForAccount(context, account) + WEBDAV_PATH_4_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts url server from the account
|
* Extracts url server from the account
|
||||||
*
|
*
|
||||||
* @param context
|
* @param context Valid Android {@link Context}, needed to access the {@link AccountManager}
|
||||||
* @param account
|
* @param account A stored ownCloud {@link Account}
|
||||||
* @return url server or null on failure
|
* @return Full URL to the server corresponding to 'account', ending in the base path
|
||||||
|
* common to all API endpoints.
|
||||||
* @throws AccountNotFoundException When 'account' is unknown for the AccountManager
|
* @throws AccountNotFoundException When 'account' is unknown for the AccountManager
|
||||||
*/
|
*/
|
||||||
public static String getBaseUrlForAccount(Context context, Account account)
|
public static String getBaseUrlForAccount(Context context, Account account)
|
||||||
@ -171,7 +155,7 @@ public class AccountUtils {
|
|||||||
AccountTypeUtils.getAuthTokenTypeAccessToken(account.type),
|
AccountTypeUtils.getAuthTokenTypeAccessToken(account.type),
|
||||||
false);
|
false);
|
||||||
|
|
||||||
credentials = OwnCloudCredentialsFactory.newBearerCredentials(accessToken);
|
credentials = OwnCloudCredentialsFactory.newBearerCredentials(username, accessToken);
|
||||||
|
|
||||||
} else if (isSamlSso) {
|
} else if (isSamlSso) {
|
||||||
String accessToken = am.blockingGetAuthToken(
|
String accessToken = am.blockingGetAuthToken(
|
||||||
@ -300,15 +284,6 @@ public class AccountUtils {
|
|||||||
|
|
||||||
|
|
||||||
public static class Constants {
|
public static class Constants {
|
||||||
/**
|
|
||||||
* Value under this key should handle path to webdav php script. Will be
|
|
||||||
* removed and usage should be replaced by combining
|
|
||||||
* {@link #KEY_OC_BASE_URL } and
|
|
||||||
* {@link com.owncloud.android.lib.resources.status.OwnCloudVersion}
|
|
||||||
*
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
public static final String KEY_OC_URL = "oc_url";
|
|
||||||
/**
|
/**
|
||||||
* Version should be 3 numbers separated by dot so it can be parsed by
|
* Version should be 3 numbers separated by dot so it can be parsed by
|
||||||
* {@link com.owncloud.android.lib.resources.status.OwnCloudVersion}
|
* {@link com.owncloud.android.lib.resources.status.OwnCloudVersion}
|
||||||
@ -327,12 +302,6 @@ public class AccountUtils {
|
|||||||
* Flag signaling if the ownCloud server can be accessed with session cookies from SAML-based web single-sign-on.
|
* Flag signaling if the ownCloud server can be accessed with session cookies from SAML-based web single-sign-on.
|
||||||
*/
|
*/
|
||||||
public static final String KEY_SUPPORTS_SAML_WEB_SSO = "oc_supports_saml_web_sso";
|
public static final String KEY_SUPPORTS_SAML_WEB_SSO = "oc_supports_saml_web_sso";
|
||||||
/**
|
|
||||||
* Flag signaling if the ownCloud server supports Share API"
|
|
||||||
*
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
public static final String KEY_SUPPORTS_SHARE_API = "oc_supports_share_api";
|
|
||||||
/**
|
/**
|
||||||
* OC account cookies
|
* OC account cookies
|
||||||
*/
|
*/
|
||||||
@ -348,6 +317,11 @@ public class AccountUtils {
|
|||||||
*/
|
*/
|
||||||
public static final String KEY_DISPLAY_NAME = "oc_display_name";
|
public static final String KEY_DISPLAY_NAME = "oc_display_name";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuth2 refresh token
|
||||||
|
**/
|
||||||
|
public static final String KEY_OAUTH2_REFRESH_TOKEN = "oc_oauth2_refresh_token";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,9 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package com.owncloud.android.lib.common;
|
package com.owncloud.android.lib.common.authentication;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -29,6 +31,8 @@ import java.util.List;
|
|||||||
import org.apache.commons.httpclient.UsernamePasswordCredentials;
|
import org.apache.commons.httpclient.UsernamePasswordCredentials;
|
||||||
import org.apache.commons.httpclient.auth.AuthPolicy;
|
import org.apache.commons.httpclient.auth.AuthPolicy;
|
||||||
import org.apache.commons.httpclient.auth.AuthScope;
|
import org.apache.commons.httpclient.auth.AuthScope;
|
||||||
|
import org.apache.commons.httpclient.auth.AuthState;
|
||||||
|
import org.apache.commons.httpclient.auth.BasicScheme;
|
||||||
|
|
||||||
public class OwnCloudBasicCredentials implements OwnCloudCredentials {
|
public class OwnCloudBasicCredentials implements OwnCloudCredentials {
|
||||||
|
|
||||||
@ -50,6 +54,8 @@ public class OwnCloudBasicCredentials implements OwnCloudCredentials {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyTo(OwnCloudClient client) {
|
public void applyTo(OwnCloudClient client) {
|
||||||
|
AuthPolicy.registerAuthScheme(AuthState.PREEMPTIVE_AUTH_SCHEME, BasicScheme.class);
|
||||||
|
|
||||||
List<String> authPrefs = new ArrayList<String>(1);
|
List<String> authPrefs = new ArrayList<String>(1);
|
||||||
authPrefs.add(AuthPolicy.BASIC);
|
authPrefs.add(AuthPolicy.BASIC);
|
||||||
client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
|
client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
|
||||||
@ -77,4 +83,9 @@ public class OwnCloudBasicCredentials implements OwnCloudCredentials {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean authTokenCanBeRefreshed() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
/* 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.common.authentication;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.httpclient.auth.AuthPolicy;
|
||||||
|
import org.apache.commons.httpclient.auth.AuthScope;
|
||||||
|
import org.apache.commons.httpclient.auth.AuthState;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
|
import com.owncloud.android.lib.common.authentication.oauth.BearerAuthScheme;
|
||||||
|
import com.owncloud.android.lib.common.authentication.oauth.BearerCredentials;
|
||||||
|
|
||||||
|
public class OwnCloudBearerCredentials implements OwnCloudCredentials {
|
||||||
|
|
||||||
|
private String mUsername;
|
||||||
|
private String mAccessToken;
|
||||||
|
|
||||||
|
public OwnCloudBearerCredentials(String username, String accessToken) {
|
||||||
|
mUsername = username != null ? username : "";
|
||||||
|
mAccessToken = accessToken != null ? accessToken : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyTo(OwnCloudClient client) {
|
||||||
|
AuthPolicy.registerAuthScheme(BearerAuthScheme.AUTH_POLICY, BearerAuthScheme.class);
|
||||||
|
AuthPolicy.registerAuthScheme(AuthState.PREEMPTIVE_AUTH_SCHEME, BearerAuthScheme.class);
|
||||||
|
|
||||||
|
List<String> authPrefs = new ArrayList<>(1);
|
||||||
|
authPrefs.add(BearerAuthScheme.AUTH_POLICY);
|
||||||
|
client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
|
||||||
|
|
||||||
|
client.getParams().setAuthenticationPreemptive(true); // true enforces BASIC AUTH ; library is stupid
|
||||||
|
client.getParams().setCredentialCharset(OwnCloudCredentialsFactory.CREDENTIAL_CHARSET);
|
||||||
|
client.getState().setCredentials(
|
||||||
|
AuthScope.ANY,
|
||||||
|
new BearerCredentials(mAccessToken)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
// not relevant for authentication, but relevant for informational purposes
|
||||||
|
return mUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAuthToken() {
|
||||||
|
return mAccessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean authTokenExpires() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean authTokenCanBeRefreshed() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -22,16 +22,19 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.owncloud.android.lib.common;
|
package com.owncloud.android.lib.common.authentication;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
|
|
||||||
public interface OwnCloudCredentials {
|
public interface OwnCloudCredentials {
|
||||||
|
|
||||||
public void applyTo(OwnCloudClient ownCloudClient);
|
void applyTo(OwnCloudClient ownCloudClient);
|
||||||
|
|
||||||
public String getUsername();
|
String getUsername();
|
||||||
|
|
||||||
public String getAuthToken();
|
String getAuthToken();
|
||||||
|
|
||||||
public boolean authTokenExpires();
|
boolean authTokenExpires();
|
||||||
|
|
||||||
|
boolean authTokenCanBeRefreshed();
|
||||||
}
|
}
|
@ -22,7 +22,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.owncloud.android.lib.common;
|
package com.owncloud.android.lib.common.authentication;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
|
|
||||||
public class OwnCloudCredentialsFactory {
|
public class OwnCloudCredentialsFactory {
|
||||||
|
|
||||||
@ -40,8 +42,8 @@ public class OwnCloudCredentialsFactory {
|
|||||||
return new OwnCloudBasicCredentials(username, password, preemptiveMode);
|
return new OwnCloudBasicCredentials(username, password, preemptiveMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OwnCloudCredentials newBearerCredentials(String authToken) {
|
public static OwnCloudCredentials newBearerCredentials(String username, String authToken) {
|
||||||
return new OwnCloudBearerCredentials(authToken);
|
return new OwnCloudBearerCredentials(username, authToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OwnCloudCredentials newSamlSsoCredentials(String username, String sessionCookie) {
|
public static OwnCloudCredentials newSamlSsoCredentials(String username, String sessionCookie) {
|
||||||
@ -76,6 +78,11 @@ public class OwnCloudCredentialsFactory {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean authTokenCanBeRefreshed() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
// no user name
|
// no user name
|
@ -21,63 +21,70 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package com.owncloud.android.lib.common;
|
package com.owncloud.android.lib.common.authentication;
|
||||||
|
|
||||||
import org.apache.commons.httpclient.Cookie;
|
import org.apache.commons.httpclient.Cookie;
|
||||||
import org.apache.commons.httpclient.cookie.CookiePolicy;
|
import org.apache.commons.httpclient.cookie.CookiePolicy;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
|
|
||||||
public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials {
|
public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials {
|
||||||
|
|
||||||
private String mUsername;
|
private String mUsername;
|
||||||
private String mSessionCookie;
|
private String mSessionCookie;
|
||||||
|
|
||||||
public OwnCloudSamlSsoCredentials(String username, String sessionCookie) {
|
public OwnCloudSamlSsoCredentials(String username, String sessionCookie) {
|
||||||
mUsername = username != null ? username : "";
|
mUsername = username != null ? username : "";
|
||||||
mSessionCookie = sessionCookie != null ? sessionCookie : "";
|
mSessionCookie = sessionCookie != null ? sessionCookie : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyTo(OwnCloudClient client) {
|
public void applyTo(OwnCloudClient client) {
|
||||||
client.getParams().setAuthenticationPreemptive(false);
|
client.getParams().setAuthenticationPreemptive(false);
|
||||||
client.getParams().setCredentialCharset(OwnCloudCredentialsFactory.CREDENTIAL_CHARSET);
|
client.getParams().setCredentialCharset(OwnCloudCredentialsFactory.CREDENTIAL_CHARSET);
|
||||||
client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
|
client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
|
||||||
client.setFollowRedirects(false);
|
client.setFollowRedirects(false);
|
||||||
|
|
||||||
Uri serverUri = client.getBaseUri();
|
Uri serverUri = client.getBaseUri();
|
||||||
|
|
||||||
String[] cookies = mSessionCookie.split(";");
|
String[] cookies = mSessionCookie.split(";");
|
||||||
if (cookies.length > 0) {
|
if (cookies.length > 0) {
|
||||||
Cookie cookie = null;
|
Cookie cookie = null;
|
||||||
for (int i=0; i<cookies.length; i++) {
|
for (int i = 0; i < cookies.length; i++) {
|
||||||
int equalPos = cookies[i].indexOf('=');
|
int equalPos = cookies[i].indexOf('=');
|
||||||
if (equalPos >= 0) {
|
if (equalPos >= 0) {
|
||||||
cookie = new Cookie();
|
cookie = new Cookie();
|
||||||
cookie.setName(cookies[i].substring(0, equalPos));
|
cookie.setName(cookies[i].substring(0, equalPos));
|
||||||
cookie.setValue(cookies[i].substring(equalPos + 1));
|
cookie.setValue(cookies[i].substring(equalPos + 1));
|
||||||
cookie.setDomain(serverUri.getHost()); // VERY IMPORTANT
|
cookie.setDomain(serverUri.getHost()); // VERY IMPORTANT
|
||||||
cookie.setPath(serverUri.getPath()); // VERY IMPORTANT
|
cookie.setPath(serverUri.getPath()); // VERY IMPORTANT
|
||||||
client.getState().addCookie(cookie);
|
client.getState().addCookie(cookie);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
// not relevant for authentication, but relevant for informational purposes
|
// not relevant for authentication, but relevant for informational purposes
|
||||||
return mUsername;
|
return mUsername;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAuthToken() {
|
|
||||||
return mSessionCookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean authTokenExpires() {
|
public String getAuthToken() {
|
||||||
return true;
|
return mSessionCookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean authTokenExpires() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean authTokenCanBeRefreshed() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.owncloud.android.lib.common.network;
|
package com.owncloud.android.lib.common.authentication.oauth;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -34,8 +34,6 @@ import org.apache.commons.httpclient.auth.AuthenticationException;
|
|||||||
import org.apache.commons.httpclient.auth.InvalidCredentialsException;
|
import org.apache.commons.httpclient.auth.InvalidCredentialsException;
|
||||||
import org.apache.commons.httpclient.auth.MalformedChallengeException;
|
import org.apache.commons.httpclient.auth.MalformedChallengeException;
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,8 +69,6 @@ public class BearerAuthScheme implements AuthScheme /*extends RFC2617Scheme*/ {
|
|||||||
* @param challenge Authentication challenge
|
* @param challenge Authentication challenge
|
||||||
*
|
*
|
||||||
* @throws MalformedChallengeException Thrown if the authentication challenge is malformed
|
* @throws MalformedChallengeException Thrown if the authentication challenge is malformed
|
||||||
*
|
|
||||||
* @deprecated Use parameterless constructor and {@link AuthScheme#processChallenge(String)} method
|
|
||||||
*/
|
*/
|
||||||
public BearerAuthScheme(final String challenge) throws MalformedChallengeException {
|
public BearerAuthScheme(final String challenge) throws MalformedChallengeException {
|
||||||
processChallenge(challenge);
|
processChallenge(challenge);
|
||||||
@ -125,13 +121,9 @@ public class BearerAuthScheme implements AuthScheme /*extends RFC2617Scheme*/ {
|
|||||||
* for this authentication scheme
|
* for this authentication scheme
|
||||||
* @throws AuthenticationException If authorization string cannot be generated due to an authentication failure
|
* @throws AuthenticationException If authorization string cannot be generated due to an authentication failure
|
||||||
* @return A bearer authorization string
|
* @return A bearer authorization string
|
||||||
*
|
|
||||||
* @deprecated Use {@link #authenticate(Credentials, HttpMethod)}
|
|
||||||
*/
|
*/
|
||||||
public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException {
|
public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException {
|
||||||
Log_OC.d(TAG, "enter BearerScheme.authenticate(Credentials, String, String)");
|
BearerCredentials bearer;
|
||||||
|
|
||||||
BearerCredentials bearer = null;
|
|
||||||
try {
|
try {
|
||||||
bearer = (BearerCredentials) credentials;
|
bearer = (BearerCredentials) credentials;
|
||||||
} catch (ClassCastException e) {
|
} catch (ClassCastException e) {
|
||||||
@ -164,8 +156,6 @@ public class BearerAuthScheme implements AuthScheme /*extends RFC2617Scheme*/ {
|
|||||||
* @return a basic authorization string
|
* @return a basic authorization string
|
||||||
*/
|
*/
|
||||||
public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
|
public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
|
||||||
Log_OC.d(TAG, "enter BearerScheme.authenticate(Credentials, HttpMethod)");
|
|
||||||
|
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new IllegalArgumentException("Method may not be null");
|
throw new IllegalArgumentException("Method may not be null");
|
||||||
}
|
}
|
||||||
@ -183,9 +173,7 @@ public class BearerAuthScheme implements AuthScheme /*extends RFC2617Scheme*/ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #authenticate(BearerCredentials, String)}
|
* Returns a bearer Authorization header value for the given
|
||||||
*
|
|
||||||
* Returns a bearer Authorization header value for the given
|
|
||||||
* {@link BearerCredentials}.
|
* {@link BearerCredentials}.
|
||||||
*
|
*
|
||||||
* @param credentials The credentials to encode.
|
* @param credentials The credentials to encode.
|
||||||
@ -208,7 +196,6 @@ public class BearerAuthScheme implements AuthScheme /*extends RFC2617Scheme*/ {
|
|||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public static String authenticate(BearerCredentials credentials, String charset) {
|
public static String authenticate(BearerCredentials credentials, String charset) {
|
||||||
Log_OC.d(TAG, "enter BearerAuthScheme.authenticate(BearerCredentials, String)");
|
|
||||||
|
|
||||||
if (credentials == null) {
|
if (credentials == null) {
|
||||||
throw new IllegalArgumentException("Credentials may not be null");
|
throw new IllegalArgumentException("Credentials may not be null");
|
||||||
@ -218,8 +205,7 @@ public class BearerAuthScheme implements AuthScheme /*extends RFC2617Scheme*/ {
|
|||||||
}
|
}
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
buffer.append(credentials.getAccessToken());
|
buffer.append(credentials.getAccessToken());
|
||||||
|
|
||||||
//return "Bearer " + EncodingUtil.getAsciiString(EncodingUtil.getBytes(buffer.toString(), charset));
|
|
||||||
return "Bearer " + buffer.toString();
|
return "Bearer " + buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,8 +225,6 @@ public class BearerAuthScheme implements AuthScheme /*extends RFC2617Scheme*/ {
|
|||||||
* This method simply returns the realm for the challenge.
|
* This method simply returns the realm for the challenge.
|
||||||
*
|
*
|
||||||
* @return String a String identifying the authentication challenge.
|
* @return String a String identifying the authentication challenge.
|
||||||
*
|
|
||||||
* @deprecated no longer used
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getID() {
|
public String getID() {
|
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.owncloud.android.lib.common.network;
|
package com.owncloud.android.lib.common.authentication.oauth;
|
||||||
|
|
||||||
import org.apache.commons.httpclient.Credentials;
|
import org.apache.commons.httpclient.Credentials;
|
||||||
import org.apache.commons.httpclient.util.LangUtils;
|
import org.apache.commons.httpclient.util.LangUtils;
|
@ -0,0 +1,66 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
public class OAuth2ClientConfiguration {
|
||||||
|
|
||||||
|
private String mClientId;
|
||||||
|
|
||||||
|
private String mClientSecret;
|
||||||
|
|
||||||
|
private String mRedirectUri;
|
||||||
|
|
||||||
|
public OAuth2ClientConfiguration(String clientId, String clientSecret, String redirectUri) {
|
||||||
|
mClientId = (clientId == null) ? "" : clientId;
|
||||||
|
mClientSecret = (clientSecret == null) ? "" : clientSecret;
|
||||||
|
mRedirectUri = (redirectUri == null) ? "" : redirectUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientId() {
|
||||||
|
return mClientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientId(String clientId) {
|
||||||
|
mClientId = (clientId == null) ? "" : clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientSecret() {
|
||||||
|
return mClientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientSecret(String clientSecret) {
|
||||||
|
mClientSecret = (clientSecret == null) ? "" : clientSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRedirectUri() {
|
||||||
|
return mRedirectUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRedirectUri(String redirectUri) {
|
||||||
|
this.mRedirectUri = (redirectUri == null) ? "" : redirectUri;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant values for OAuth 2 protocol.
|
||||||
|
*
|
||||||
|
* Includes required and optional parameter NAMES used in the 'authorization code' grant type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class OAuth2Constants {
|
||||||
|
|
||||||
|
/// Parameters to send to the Authorization Endpoint
|
||||||
|
public static final String KEY_RESPONSE_TYPE = "response_type";
|
||||||
|
public static final String KEY_REDIRECT_URI = "redirect_uri";
|
||||||
|
public static final String KEY_CLIENT_ID = "client_id";
|
||||||
|
public static final String KEY_SCOPE = "scope";
|
||||||
|
public static final String KEY_STATE = "state";
|
||||||
|
|
||||||
|
/// Additional parameters to send to the Token Endpoint
|
||||||
|
public static final String KEY_GRANT_TYPE = "grant_type";
|
||||||
|
public static final String KEY_CODE = "code";
|
||||||
|
|
||||||
|
// Used to get the Access Token using Refresh Token
|
||||||
|
public static final String OAUTH2_REFRESH_TOKEN_GRANT_TYPE = "refresh_token";
|
||||||
|
|
||||||
|
/// Parameters received in an OK response from the Token Endpoint
|
||||||
|
public static final String KEY_ACCESS_TOKEN = "access_token";
|
||||||
|
public static final String KEY_TOKEN_TYPE = "token_type";
|
||||||
|
public static final String KEY_EXPIRES_IN = "expires_in";
|
||||||
|
public static final String KEY_REFRESH_TOKEN = "refresh_token";
|
||||||
|
|
||||||
|
/// Parameters in an ERROR response
|
||||||
|
public static final String KEY_ERROR = "error";
|
||||||
|
public static final String KEY_ERROR_DESCRIPTION = "error_description";
|
||||||
|
public static final String KEY_ERROR_URI = "error_uri";
|
||||||
|
public static final String VALUE_ERROR_ACCESS_DENIED = "access_denied";
|
||||||
|
|
||||||
|
/// Extra not standard
|
||||||
|
public static final String KEY_USER_ID = "user_id";
|
||||||
|
|
||||||
|
/// Depends on oauth2 grant type
|
||||||
|
public static final String OAUTH2_RESPONSE_TYPE_CODE = "code";
|
||||||
|
}
|
@ -0,0 +1,148 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials;
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
|
||||||
|
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.apache.commons.httpclient.NameValuePair;
|
||||||
|
import org.apache.commons.httpclient.methods.PostMethod;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
public class OAuth2GetAccessTokenOperation extends RemoteOperation {
|
||||||
|
|
||||||
|
private String mGrantType;
|
||||||
|
private String mCode;
|
||||||
|
private String mClientId;
|
||||||
|
private String mClientSecret;
|
||||||
|
private String mRedirectUri;
|
||||||
|
private final String mAccessTokenEndpointPath;
|
||||||
|
|
||||||
|
private final OAuth2ResponseParser mResponseParser;
|
||||||
|
|
||||||
|
|
||||||
|
public OAuth2GetAccessTokenOperation(
|
||||||
|
String grantType,
|
||||||
|
String code,
|
||||||
|
String clientId,
|
||||||
|
String secretId,
|
||||||
|
String redirectUri,
|
||||||
|
String accessTokenEndpointPath
|
||||||
|
) {
|
||||||
|
mClientId = clientId;
|
||||||
|
mClientSecret = secretId;
|
||||||
|
mRedirectUri = redirectUri;
|
||||||
|
mGrantType = grantType;
|
||||||
|
mCode = code;
|
||||||
|
|
||||||
|
mAccessTokenEndpointPath =
|
||||||
|
accessTokenEndpointPath != null ?
|
||||||
|
accessTokenEndpointPath :
|
||||||
|
OwnCloudOAuth2Provider.ACCESS_TOKEN_ENDPOINT_PATH
|
||||||
|
;
|
||||||
|
|
||||||
|
mResponseParser = new OAuth2ResponseParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||||
|
RemoteOperationResult result = null;
|
||||||
|
PostMethod postMethod = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
NameValuePair[] nameValuePairs = new NameValuePair[4];
|
||||||
|
nameValuePairs[0] = new NameValuePair(OAuth2Constants.KEY_GRANT_TYPE, mGrantType);
|
||||||
|
nameValuePairs[1] = new NameValuePair(OAuth2Constants.KEY_CODE, mCode);
|
||||||
|
nameValuePairs[2] = new NameValuePair(OAuth2Constants.KEY_REDIRECT_URI, mRedirectUri);
|
||||||
|
nameValuePairs[3] = new NameValuePair(OAuth2Constants.KEY_CLIENT_ID, mClientId);
|
||||||
|
|
||||||
|
Uri.Builder uriBuilder = client.getBaseUri().buildUpon();
|
||||||
|
uriBuilder.appendEncodedPath(mAccessTokenEndpointPath);
|
||||||
|
|
||||||
|
postMethod = new PostMethod(uriBuilder.build().toString());
|
||||||
|
postMethod.setRequestBody(nameValuePairs);
|
||||||
|
|
||||||
|
OwnCloudCredentials oauthCredentials = new OwnCloudBasicCredentials(
|
||||||
|
mClientId,
|
||||||
|
mClientSecret
|
||||||
|
);
|
||||||
|
OwnCloudCredentials oldCredentials = switchClientCredentials(oauthCredentials);
|
||||||
|
|
||||||
|
client.executeMethod(postMethod);
|
||||||
|
switchClientCredentials(oldCredentials);
|
||||||
|
|
||||||
|
String response = postMethod.getResponseBodyAsString();
|
||||||
|
if (response != null && response.length() > 0) {
|
||||||
|
JSONObject tokenJson = new JSONObject(response);
|
||||||
|
Map<String, String> accessTokenResult =
|
||||||
|
mResponseParser.parseAccessTokenResult(tokenJson);
|
||||||
|
if (accessTokenResult.get(OAuth2Constants.KEY_ERROR) != null ||
|
||||||
|
accessTokenResult.get(OAuth2Constants.KEY_ACCESS_TOKEN) == null) {
|
||||||
|
result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
result = new RemoteOperationResult(true, postMethod);
|
||||||
|
ArrayList<Object> data = new ArrayList<>();
|
||||||
|
data.add(accessTokenResult);
|
||||||
|
result.setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
result = new RemoteOperationResult(false, postMethod);
|
||||||
|
client.exhaustResponse(postMethod.getResponseBodyAsStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
result = new RemoteOperationResult(e);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (postMethod != null)
|
||||||
|
postMethod.releaseConnection(); // let the connection available for other methods
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OwnCloudCredentials switchClientCredentials(OwnCloudCredentials newCredentials) {
|
||||||
|
OwnCloudCredentials previousCredentials = getClient().getCredentials();
|
||||||
|
getClient().setCredentials(newCredentials);
|
||||||
|
return previousCredentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
public enum OAuth2GrantType {
|
||||||
|
AUTHORIZATION_CODE("authorization_code"),
|
||||||
|
IMPLICIT("implicit"),
|
||||||
|
PASSWORD("password"),
|
||||||
|
CLIENT_CREDENTIAL("client_credentials"),
|
||||||
|
REFRESH_TOKEN("refresh_token") // not a grant type conceptually, but used as such to refresh access tokens
|
||||||
|
;
|
||||||
|
|
||||||
|
private String mValue;
|
||||||
|
|
||||||
|
OAuth2GrantType(String value) {
|
||||||
|
mValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return mValue;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
public interface OAuth2Provider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link OAuth2RequestBuilder} implementation for this provider.
|
||||||
|
*
|
||||||
|
* @return {@link OAuth2RequestBuilder} implementation.
|
||||||
|
*/
|
||||||
|
OAuth2RequestBuilder getOperationBuilder();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set configuration of the client that will use this {@link OAuth2Provider}
|
||||||
|
* @param oAuth2ClientConfiguration Configuration of the client that will use this {@link OAuth2Provider}
|
||||||
|
*/
|
||||||
|
void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration of the client that is using this {@link OAuth2Provider}
|
||||||
|
* return Configuration of the client that is usinng this {@link OAuth2Provider}
|
||||||
|
*/
|
||||||
|
OAuth2ClientConfiguration getClientConfiguration();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set base URI to authorization server.
|
||||||
|
*
|
||||||
|
* @param authorizationServerUri Set base URL to authorization server.
|
||||||
|
*/
|
||||||
|
void setAuthorizationServerUri(String authorizationServerUri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base URI to authorization server.
|
||||||
|
*
|
||||||
|
* @return Base URL to authorization server.
|
||||||
|
*/
|
||||||
|
String getAuthorizationServerUri();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class OAuth2ProvidersRegistry {
|
||||||
|
|
||||||
|
private Map<String, OAuth2Provider> mProviders = new HashMap<>();
|
||||||
|
|
||||||
|
private OAuth2Provider mDefaultProvider = null;
|
||||||
|
|
||||||
|
private OAuth2ProvidersRegistry () {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom
|
||||||
|
*/
|
||||||
|
private static class LazyHolder {
|
||||||
|
private static final OAuth2ProvidersRegistry INSTANCE = new OAuth2ProvidersRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton accesor.
|
||||||
|
*
|
||||||
|
* @return Singleton isntance of {@link OAuth2ProvidersRegistry}
|
||||||
|
*/
|
||||||
|
public static OAuth2ProvidersRegistry getInstance() {
|
||||||
|
return LazyHolder.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an {@link OAuth2Provider} with the name passed as parameter.
|
||||||
|
*
|
||||||
|
* @param name Name to bind 'oAuthProvider' in the registry.
|
||||||
|
* @param oAuth2Provider An {@link OAuth2Provider} instance to keep in the registry.
|
||||||
|
* @throws IllegalArgumentException if 'name' or 'oAuthProvider' are null.
|
||||||
|
*/
|
||||||
|
public void registerProvider(String name, OAuth2Provider oAuth2Provider) {
|
||||||
|
if (name == null) {
|
||||||
|
throw new IllegalArgumentException("Name must not be NULL");
|
||||||
|
}
|
||||||
|
if (oAuth2Provider == null) {
|
||||||
|
throw new IllegalArgumentException("oAuth2Provider must not be NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
mProviders.put(name, oAuth2Provider);
|
||||||
|
if (mProviders.size() == 1) {
|
||||||
|
mDefaultProvider = oAuth2Provider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public OAuth2Provider unregisterProvider(String name) {
|
||||||
|
OAuth2Provider unregisteredProvider = mProviders.remove(name);
|
||||||
|
if (mProviders.size() == 0) {
|
||||||
|
mDefaultProvider = null;
|
||||||
|
} else if (unregisteredProvider != null && unregisteredProvider == mDefaultProvider) {
|
||||||
|
mDefaultProvider = mProviders.values().iterator().next();
|
||||||
|
}
|
||||||
|
return unregisteredProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get default {@link OAuth2Provider}.
|
||||||
|
*
|
||||||
|
* @return Default provider, or NULL if there is no provider.
|
||||||
|
*/
|
||||||
|
public OAuth2Provider getProvider() {
|
||||||
|
return mDefaultProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get {@link OAuth2Provider} registered with the name passed as parameter.
|
||||||
|
*
|
||||||
|
* @param name Name used to register the desired {@link OAuth2Provider}
|
||||||
|
* @return {@link OAuth2Provider} registered with the name 'name'
|
||||||
|
*/
|
||||||
|
public OAuth2Provider getProvider(String name) {
|
||||||
|
return mProviders.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link OAuth2Provider} registered with the name passed as parameter as the default provider
|
||||||
|
*
|
||||||
|
* @param name Name used to register the {@link OAuth2Provider} to set as default.
|
||||||
|
* @return {@link OAuth2Provider} set as default, or NULL if no provider was registered with 'name'.
|
||||||
|
*/
|
||||||
|
public OAuth2Provider setDefaultProvider(String name) {
|
||||||
|
OAuth2Provider toDefault = mProviders.get(name);
|
||||||
|
if (toDefault != null) {
|
||||||
|
mDefaultProvider = toDefault;
|
||||||
|
}
|
||||||
|
return toDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
public class OAuth2QueryParser {
|
||||||
|
|
||||||
|
private static final String TAG = OAuth2QueryParser.class.getName();
|
||||||
|
|
||||||
|
private Map<String, String> mOAuth2ParsedAuthorizationResponse;
|
||||||
|
|
||||||
|
public OAuth2QueryParser() {
|
||||||
|
mOAuth2ParsedAuthorizationResponse = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> parse(String query) {
|
||||||
|
mOAuth2ParsedAuthorizationResponse.clear();
|
||||||
|
|
||||||
|
String[] pairs = query.split("&");
|
||||||
|
int i = 0;
|
||||||
|
String key = "";
|
||||||
|
String value;
|
||||||
|
while (pairs.length > i) {
|
||||||
|
int j = 0;
|
||||||
|
String[] part = pairs[i].split("=");
|
||||||
|
while (part.length > j) {
|
||||||
|
String p = part[j];
|
||||||
|
if (j == 0) {
|
||||||
|
key = p;
|
||||||
|
} else if (j == 1) {
|
||||||
|
value = p;
|
||||||
|
mOAuth2ParsedAuthorizationResponse.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log_OC.v(TAG, "[" + i + "," + j + "] = " + p);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mOAuth2ParsedAuthorizationResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,146 @@
|
|||||||
|
/**
|
||||||
|
* ownCloud Android client application
|
||||||
|
*
|
||||||
|
* @author David González Verdugo
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials;
|
||||||
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
|
||||||
|
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.common.utils.Log_OC;
|
||||||
|
|
||||||
|
import org.apache.commons.httpclient.NameValuePair;
|
||||||
|
import org.apache.commons.httpclient.methods.PostMethod;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class OAuth2RefreshAccessTokenOperation extends RemoteOperation {
|
||||||
|
|
||||||
|
private static final String TAG = OAuth2RefreshAccessTokenOperation.class.getSimpleName();
|
||||||
|
|
||||||
|
private String mClientId;
|
||||||
|
private String mClientSecret;
|
||||||
|
private String mRefreshToken;
|
||||||
|
|
||||||
|
private final String mAccessTokenEndpointPath;
|
||||||
|
|
||||||
|
private final OAuth2ResponseParser mResponseParser;
|
||||||
|
|
||||||
|
public OAuth2RefreshAccessTokenOperation(
|
||||||
|
String clientId,
|
||||||
|
String secretId,
|
||||||
|
String refreshToken,
|
||||||
|
String accessTokenEndpointPath
|
||||||
|
) {
|
||||||
|
|
||||||
|
mClientId = clientId;
|
||||||
|
mClientSecret = secretId;
|
||||||
|
mRefreshToken = refreshToken;
|
||||||
|
|
||||||
|
mAccessTokenEndpointPath =
|
||||||
|
accessTokenEndpointPath != null ?
|
||||||
|
accessTokenEndpointPath :
|
||||||
|
OwnCloudOAuth2Provider.ACCESS_TOKEN_ENDPOINT_PATH
|
||||||
|
;
|
||||||
|
|
||||||
|
mResponseParser = new OAuth2ResponseParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||||
|
|
||||||
|
RemoteOperationResult result = null;
|
||||||
|
PostMethod postMethod = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
NameValuePair[] nameValuePairs = new NameValuePair[3];
|
||||||
|
nameValuePairs[0] = new NameValuePair(
|
||||||
|
OAuth2Constants.KEY_GRANT_TYPE,
|
||||||
|
OAuth2GrantType.REFRESH_TOKEN.getValue() // always for this operation
|
||||||
|
);
|
||||||
|
nameValuePairs[1] = new NameValuePair(OAuth2Constants.KEY_CLIENT_ID, mClientId);
|
||||||
|
nameValuePairs[2] = new NameValuePair(OAuth2Constants.KEY_REFRESH_TOKEN, mRefreshToken);
|
||||||
|
|
||||||
|
Uri.Builder uriBuilder = client.getBaseUri().buildUpon();
|
||||||
|
uriBuilder.appendEncodedPath(mAccessTokenEndpointPath);
|
||||||
|
|
||||||
|
postMethod = new PostMethod(uriBuilder.build().toString());
|
||||||
|
postMethod.setRequestBody(nameValuePairs);
|
||||||
|
|
||||||
|
OwnCloudCredentials oauthCredentials = new OwnCloudBasicCredentials(
|
||||||
|
mClientId,
|
||||||
|
mClientSecret
|
||||||
|
);
|
||||||
|
|
||||||
|
OwnCloudCredentials oldCredentials = switchClientCredentials(oauthCredentials);
|
||||||
|
|
||||||
|
client.executeMethod(postMethod);
|
||||||
|
|
||||||
|
switchClientCredentials(oldCredentials);
|
||||||
|
|
||||||
|
String response = postMethod.getResponseBodyAsString();
|
||||||
|
Log_OC.d(TAG, "OAUTH2: raw response from POST TOKEN: " + response);
|
||||||
|
|
||||||
|
if (response != null && response.length() > 0) {
|
||||||
|
JSONObject tokenJson = new JSONObject(response);
|
||||||
|
Map<String, String> accessTokenResult =
|
||||||
|
mResponseParser.parseAccessTokenResult(tokenJson);
|
||||||
|
if (accessTokenResult.get(OAuth2Constants.KEY_ERROR) != null ||
|
||||||
|
accessTokenResult.get(OAuth2Constants.KEY_ACCESS_TOKEN) == null) {
|
||||||
|
result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
result = new RemoteOperationResult(true, postMethod);
|
||||||
|
ArrayList<Object> data = new ArrayList<>();
|
||||||
|
data.add(accessTokenResult);
|
||||||
|
result.setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
result = new RemoteOperationResult(false, postMethod);
|
||||||
|
client.exhaustResponse(postMethod.getResponseBodyAsStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
result = new RemoteOperationResult(e);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (postMethod != null) {
|
||||||
|
postMethod.releaseConnection(); // let the connection available for other methods
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OwnCloudCredentials switchClientCredentials(OwnCloudCredentials newCredentials) {
|
||||||
|
OwnCloudCredentials previousCredentials = getClient().getCredentials();
|
||||||
|
getClient().setCredentials(newCredentials);
|
||||||
|
return previousCredentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||||
|
|
||||||
|
public interface OAuth2RequestBuilder {
|
||||||
|
|
||||||
|
enum OAuthRequest {
|
||||||
|
GET_AUTHORIZATION_CODE, CREATE_ACCESS_TOKEN, REFRESH_ACCESS_TOKEN
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRequest(OAuthRequest operation);
|
||||||
|
|
||||||
|
void setGrantType(OAuth2GrantType grantType);
|
||||||
|
|
||||||
|
void setAuthorizationCode(String code);
|
||||||
|
|
||||||
|
void setRefreshToken(String refreshToken);
|
||||||
|
|
||||||
|
RemoteOperation buildOperation();
|
||||||
|
|
||||||
|
String buildUri();
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* ownCloud Android client application
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
class OAuth2ResponseParser {
|
||||||
|
|
||||||
|
Map<String, String> parseAccessTokenResult(JSONObject tokenJson) throws JSONException {
|
||||||
|
Map<String, String> resultTokenMap = new HashMap<>();
|
||||||
|
|
||||||
|
if (tokenJson.has(OAuth2Constants.KEY_ACCESS_TOKEN)) {
|
||||||
|
resultTokenMap.put(OAuth2Constants.KEY_ACCESS_TOKEN, tokenJson.
|
||||||
|
getString(OAuth2Constants.KEY_ACCESS_TOKEN));
|
||||||
|
}
|
||||||
|
if (tokenJson.has(OAuth2Constants.KEY_TOKEN_TYPE)) {
|
||||||
|
resultTokenMap.put(OAuth2Constants.KEY_TOKEN_TYPE, tokenJson.
|
||||||
|
getString(OAuth2Constants.KEY_TOKEN_TYPE));
|
||||||
|
}
|
||||||
|
if (tokenJson.has(OAuth2Constants.KEY_EXPIRES_IN)) {
|
||||||
|
resultTokenMap.put(OAuth2Constants.KEY_EXPIRES_IN, tokenJson.
|
||||||
|
getString(OAuth2Constants.KEY_EXPIRES_IN));
|
||||||
|
}
|
||||||
|
if (tokenJson.has(OAuth2Constants.KEY_REFRESH_TOKEN)) {
|
||||||
|
resultTokenMap.put(OAuth2Constants.KEY_REFRESH_TOKEN, tokenJson.
|
||||||
|
getString(OAuth2Constants.KEY_REFRESH_TOKEN));
|
||||||
|
}
|
||||||
|
if (tokenJson.has(OAuth2Constants.KEY_SCOPE)) {
|
||||||
|
resultTokenMap.put(OAuth2Constants.KEY_SCOPE, tokenJson.
|
||||||
|
getString(OAuth2Constants.KEY_SCOPE));
|
||||||
|
}
|
||||||
|
if (tokenJson.has(OAuth2Constants.KEY_ERROR)) {
|
||||||
|
resultTokenMap.put(OAuth2Constants.KEY_ERROR, tokenJson.
|
||||||
|
getString(OAuth2Constants.KEY_ERROR));
|
||||||
|
}
|
||||||
|
if (tokenJson.has(OAuth2Constants.KEY_ERROR_DESCRIPTION)) {
|
||||||
|
resultTokenMap.put(OAuth2Constants.KEY_ERROR_DESCRIPTION, tokenJson.
|
||||||
|
getString(OAuth2Constants.KEY_ERROR_DESCRIPTION));
|
||||||
|
}
|
||||||
|
if (tokenJson.has(OAuth2Constants.KEY_ERROR_URI)) {
|
||||||
|
resultTokenMap.put(OAuth2Constants.KEY_ERROR_URI, tokenJson.
|
||||||
|
getString(OAuth2Constants.KEY_ERROR_URI));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenJson.has(OAuth2Constants.KEY_USER_ID)) { // not standard
|
||||||
|
resultTokenMap.put(OAuth2Constants.KEY_USER_ID, tokenJson.
|
||||||
|
getString(OAuth2Constants.KEY_USER_ID));
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultTokenMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
|
|
||||||
|
public class OwnCloudOAuth2Provider implements OAuth2Provider {
|
||||||
|
|
||||||
|
public static final String NAME = OAuth2Provider.class.getName();
|
||||||
|
|
||||||
|
public static final String ACCESS_TOKEN_ENDPOINT_PATH = "index.php/apps/oauth2/api/v1/token";
|
||||||
|
private static final String AUTHORIZATION_CODE_ENDPOINT_PATH = "index.php/apps/oauth2/authorize";
|
||||||
|
|
||||||
|
private String mAuthorizationServerUrl = "";
|
||||||
|
private String mAccessTokenEndpointPath = ACCESS_TOKEN_ENDPOINT_PATH;
|
||||||
|
private String mAuthorizationCodeEndpointPath = AUTHORIZATION_CODE_ENDPOINT_PATH;
|
||||||
|
|
||||||
|
private OAuth2ClientConfiguration mClientConfiguration;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OAuth2RequestBuilder getOperationBuilder() {
|
||||||
|
return new OwnCloudOAuth2RequestBuilder(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration) {
|
||||||
|
mClientConfiguration = oAuth2ClientConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OAuth2ClientConfiguration getClientConfiguration() {
|
||||||
|
return mClientConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAuthorizationServerUri(String authorizationServerUri) {
|
||||||
|
mAuthorizationServerUrl = authorizationServerUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAuthorizationServerUri() {
|
||||||
|
return mAuthorizationServerUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccessTokenEndpointPath() {
|
||||||
|
return mAccessTokenEndpointPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessTokenEndpointPath(String accessTokenEndpointPath) {
|
||||||
|
if (accessTokenEndpointPath == null || accessTokenEndpointPath.length() <= 0) {
|
||||||
|
Log_OC.w(NAME, "Setting invalid access token endpoint path, going on with default");
|
||||||
|
mAccessTokenEndpointPath = ACCESS_TOKEN_ENDPOINT_PATH;
|
||||||
|
} else {
|
||||||
|
mAccessTokenEndpointPath = accessTokenEndpointPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthorizationCodeEndpointPath() {
|
||||||
|
return mAuthorizationCodeEndpointPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthorizationCodeEndpointPath(String authorizationCodeEndpointPath) {
|
||||||
|
if (authorizationCodeEndpointPath == null || authorizationCodeEndpointPath.length() <= 0) {
|
||||||
|
Log_OC.w(NAME, "Setting invalid authorization code endpoint path, going on with default");
|
||||||
|
mAuthorizationCodeEndpointPath = AUTHORIZATION_CODE_ENDPOINT_PATH;
|
||||||
|
} else {
|
||||||
|
mAuthorizationCodeEndpointPath = authorizationCodeEndpointPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,156 @@
|
|||||||
|
/* ownCloud Android Library is available under MIT license
|
||||||
|
*
|
||||||
|
* @author David A. Velasco
|
||||||
|
* Copyright (C) 2017 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.common.authentication.oauth;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||||
|
|
||||||
|
public class OwnCloudOAuth2RequestBuilder implements OAuth2RequestBuilder {
|
||||||
|
|
||||||
|
private OwnCloudOAuth2Provider mOAuth2Provider;
|
||||||
|
|
||||||
|
private OAuthRequest mRequest;
|
||||||
|
private OAuth2GrantType mGrantType = OAuth2GrantType.AUTHORIZATION_CODE;
|
||||||
|
private String mCode;
|
||||||
|
private String mRefreshToken;
|
||||||
|
|
||||||
|
public OwnCloudOAuth2RequestBuilder(OwnCloudOAuth2Provider ownCloudOAuth2Provider) {
|
||||||
|
mOAuth2Provider = ownCloudOAuth2Provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRequest(OAuthRequest request) {
|
||||||
|
mRequest = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setGrantType(OAuth2GrantType grantType) {
|
||||||
|
mGrantType = grantType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAuthorizationCode(String code) {
|
||||||
|
mCode = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRefreshToken(String refreshToken) {
|
||||||
|
mRefreshToken = refreshToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteOperation buildOperation() {
|
||||||
|
if (mGrantType != OAuth2GrantType.AUTHORIZATION_CODE &&
|
||||||
|
mGrantType != OAuth2GrantType.REFRESH_TOKEN) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"Unsupported grant type. Only " +
|
||||||
|
OAuth2GrantType.AUTHORIZATION_CODE.getValue() + " and " +
|
||||||
|
OAuth2GrantType.REFRESH_TOKEN + " are supported"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
OAuth2ClientConfiguration clientConfiguration = mOAuth2Provider.getClientConfiguration();
|
||||||
|
|
||||||
|
switch(mRequest) {
|
||||||
|
case CREATE_ACCESS_TOKEN:
|
||||||
|
return new OAuth2GetAccessTokenOperation(
|
||||||
|
mGrantType.getValue(),
|
||||||
|
mCode,
|
||||||
|
clientConfiguration.getClientId(),
|
||||||
|
clientConfiguration.getClientSecret(),
|
||||||
|
clientConfiguration.getRedirectUri(),
|
||||||
|
mOAuth2Provider.getAccessTokenEndpointPath()
|
||||||
|
);
|
||||||
|
|
||||||
|
case REFRESH_ACCESS_TOKEN:
|
||||||
|
return new OAuth2RefreshAccessTokenOperation(
|
||||||
|
clientConfiguration.getClientId(),
|
||||||
|
clientConfiguration.getClientSecret(),
|
||||||
|
mRefreshToken,
|
||||||
|
mOAuth2Provider.getAccessTokenEndpointPath()
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"Unsupported request"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildUri() {
|
||||||
|
if (OAuth2GrantType.AUTHORIZATION_CODE != mGrantType) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"Unsupported grant type. Only " +
|
||||||
|
OAuth2GrantType.AUTHORIZATION_CODE.getValue() + " is supported by this provider"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
OAuth2ClientConfiguration clientConfiguration = mOAuth2Provider.getClientConfiguration();
|
||||||
|
Uri uri;
|
||||||
|
Uri.Builder uriBuilder;
|
||||||
|
switch(mRequest) {
|
||||||
|
case GET_AUTHORIZATION_CODE:
|
||||||
|
uri = Uri.parse(mOAuth2Provider.getAuthorizationServerUri());
|
||||||
|
uriBuilder = uri.buildUpon();
|
||||||
|
uriBuilder.appendEncodedPath(mOAuth2Provider.getAuthorizationCodeEndpointPath());
|
||||||
|
uriBuilder.appendQueryParameter(
|
||||||
|
OAuth2Constants.KEY_RESPONSE_TYPE, OAuth2Constants.OAUTH2_RESPONSE_TYPE_CODE
|
||||||
|
);
|
||||||
|
uriBuilder.appendQueryParameter(
|
||||||
|
OAuth2Constants.KEY_REDIRECT_URI, clientConfiguration.getRedirectUri()
|
||||||
|
);
|
||||||
|
uriBuilder.appendQueryParameter(
|
||||||
|
OAuth2Constants.KEY_CLIENT_ID, clientConfiguration.getClientId()
|
||||||
|
);
|
||||||
|
|
||||||
|
uri = uriBuilder.build();
|
||||||
|
return uri.toString();
|
||||||
|
|
||||||
|
case CREATE_ACCESS_TOKEN:
|
||||||
|
uri = Uri.parse(mOAuth2Provider.getAuthorizationServerUri());
|
||||||
|
uriBuilder = uri.buildUpon();
|
||||||
|
uriBuilder.appendEncodedPath(mOAuth2Provider.getAccessTokenEndpointPath());
|
||||||
|
uriBuilder.appendQueryParameter(
|
||||||
|
OAuth2Constants.KEY_RESPONSE_TYPE, OAuth2Constants.OAUTH2_RESPONSE_TYPE_CODE
|
||||||
|
);
|
||||||
|
uriBuilder.appendQueryParameter(
|
||||||
|
OAuth2Constants.KEY_REDIRECT_URI, clientConfiguration.getRedirectUri()
|
||||||
|
);
|
||||||
|
uriBuilder.appendQueryParameter(
|
||||||
|
OAuth2Constants.KEY_CLIENT_ID, clientConfiguration.getClientId()
|
||||||
|
);
|
||||||
|
|
||||||
|
uri = uriBuilder.build();
|
||||||
|
return uri.toString();
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"Unsupported request"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/* ownCloud Android Library is available under MIT license
|
/* ownCloud Android Library is available under MIT license
|
||||||
* Copyright (C) 2016 ownCloud GmbH.
|
* Copyright (C) 2017 ownCloud GmbH.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -25,19 +25,16 @@
|
|||||||
package com.owncloud.android.lib.common.operations;
|
package com.owncloud.android.lib.common.operations;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
|
||||||
import android.accounts.AccountsException;
|
import android.accounts.AccountsException;
|
||||||
import android.app.Activity;
|
import android.accounts.AuthenticatorException;
|
||||||
|
import android.accounts.OperationCanceledException;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentials;
|
|
||||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -45,58 +42,69 @@ import java.io.IOException;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Operation which execution involves one or several interactions with an ownCloud server.
|
* Operation which execution involves one or several interactions with an ownCloud server.
|
||||||
*
|
*
|
||||||
* Provides methods to execute the operation both synchronously or asynchronously.
|
* Provides methods to execute the operation both synchronously or asynchronously.
|
||||||
*
|
*
|
||||||
* @author David A. Velasco
|
* @author David A. Velasco
|
||||||
|
* @author David González Verdugo
|
||||||
*/
|
*/
|
||||||
public abstract class RemoteOperation implements Runnable {
|
public abstract class RemoteOperation implements Runnable {
|
||||||
|
|
||||||
private static final String TAG = RemoteOperation.class.getSimpleName();
|
private static final String TAG = RemoteOperation.class.getSimpleName();
|
||||||
|
|
||||||
/** OCS API header name */
|
/**
|
||||||
|
* OCS API header name
|
||||||
|
*/
|
||||||
public static final String OCS_API_HEADER = "OCS-APIREQUEST";
|
public static final String OCS_API_HEADER = "OCS-APIREQUEST";
|
||||||
|
|
||||||
/** OCS API header value */
|
/**
|
||||||
|
* OCS API header value
|
||||||
|
*/
|
||||||
public static final String OCS_API_HEADER_VALUE = "true";
|
public static final String OCS_API_HEADER_VALUE = "true";
|
||||||
|
|
||||||
/** ownCloud account in the remote ownCloud server to operate */
|
/**
|
||||||
|
* ownCloud account in the remote ownCloud server to operate
|
||||||
|
*/
|
||||||
private Account mAccount = null;
|
private Account mAccount = null;
|
||||||
|
|
||||||
/** Android Application context */
|
/**
|
||||||
|
* Android Application context
|
||||||
|
*/
|
||||||
private Context mContext = null;
|
private Context mContext = null;
|
||||||
|
|
||||||
/** Object to interact with the remote server */
|
|
||||||
private OwnCloudClient mClient = null;
|
|
||||||
|
|
||||||
/** Callback object to notify about the execution of the remote operation */
|
|
||||||
private OnRemoteOperationListener mListener = null;
|
|
||||||
|
|
||||||
/** Handler to the thread where mListener methods will be called */
|
|
||||||
private Handler mListenerHandler = null;
|
|
||||||
|
|
||||||
/** Activity */
|
/**
|
||||||
private Activity mCallerActivity;
|
* Object to interact with the remote server
|
||||||
|
*/
|
||||||
|
private OwnCloudClient mClient = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback object to notify about the execution of the remote operation
|
||||||
|
*/
|
||||||
|
private OnRemoteOperationListener mListener = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to the thread where mListener methods will be called
|
||||||
|
*/
|
||||||
|
private Handler mListenerHandler = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract method to implement the operation in derived classes.
|
||||||
|
*/
|
||||||
|
protected abstract RemoteOperationResult run(OwnCloudClient client);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract method to implement the operation in derived classes.
|
|
||||||
*/
|
|
||||||
protected abstract RemoteOperationResult run(OwnCloudClient client);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronously executes the remote operation on the received ownCloud account.
|
* Synchronously executes the remote operation on the received ownCloud account.
|
||||||
*
|
*
|
||||||
* Do not call this method from the main thread.
|
* Do not call this method from the main thread.
|
||||||
*
|
*
|
||||||
* This method should be used whenever an ownCloud account is available, instead of
|
* This method should be used whenever an ownCloud account is available, instead of
|
||||||
* {@link #execute(OwnCloudClient)}.
|
* {@link #execute(OwnCloudClient)}.
|
||||||
*
|
*
|
||||||
* @param account ownCloud account in remote ownCloud server to reach during the
|
* @param account ownCloud account in remote ownCloud server to reach during the
|
||||||
* execution of the operation.
|
* execution of the operation.
|
||||||
* @param context Android context for the component calling the method.
|
* @param context Android context for the component calling the method.
|
||||||
* @return Result of the operation.
|
* @return Result of the operation.
|
||||||
*/
|
*/
|
||||||
public RemoteOperationResult execute(Account account, Context context) {
|
public RemoteOperationResult execute(Account account, Context context) {
|
||||||
if (account == null)
|
if (account == null)
|
||||||
@ -107,258 +115,187 @@ public abstract class RemoteOperation implements Runnable {
|
|||||||
"Context");
|
"Context");
|
||||||
mAccount = account;
|
mAccount = account;
|
||||||
mContext = context.getApplicationContext();
|
mContext = context.getApplicationContext();
|
||||||
try {
|
|
||||||
OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);
|
return runOperation();
|
||||||
mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
|
||||||
getClientFor(ocAccount, mContext);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, e);
|
|
||||||
return new RemoteOperationResult(e);
|
|
||||||
}
|
|
||||||
return run(mClient);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronously executes the remote operation
|
* Synchronously executes the remote operation
|
||||||
*
|
*
|
||||||
* Do not call this method from the main thread.
|
* Do not call this method from the main thread.
|
||||||
*
|
*
|
||||||
* @param client Client object to reach an ownCloud server during the execution of
|
* @param client Client object to reach an ownCloud server during the execution of
|
||||||
* the operation.
|
* the operation.
|
||||||
* @return Result of the operation.
|
* @return Result of the operation.
|
||||||
*/
|
|
||||||
public RemoteOperationResult execute(OwnCloudClient client) {
|
|
||||||
if (client == null)
|
|
||||||
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " +
|
|
||||||
"OwnCloudClient");
|
|
||||||
mClient = client;
|
|
||||||
return run(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asynchronously executes the remote operation
|
|
||||||
*
|
|
||||||
* This method should be used whenever an ownCloud account is available, instead of
|
|
||||||
* {@link #execute(OwnCloudClient)}.
|
|
||||||
*
|
|
||||||
* @deprecated This method will be removed in version 1.0.
|
|
||||||
* Use {@link #execute(Account, Context, OnRemoteOperationListener,
|
|
||||||
* Handler)} instead.
|
|
||||||
*
|
|
||||||
* @param account ownCloud account in remote ownCloud server to reach during
|
|
||||||
* the execution of the operation.
|
|
||||||
* @param context Android context for the component calling the method.
|
|
||||||
* @param listener Listener to be notified about the execution of the operation.
|
|
||||||
* @param listenerHandler Handler associated to the thread where the methods of the listener
|
|
||||||
* objects must be called.
|
|
||||||
* @return Thread were the remote operation is executed.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
public RemoteOperationResult execute(OwnCloudClient client) {
|
||||||
public Thread execute(Account account, Context context, OnRemoteOperationListener listener,
|
if (client == null)
|
||||||
Handler listenerHandler, Activity callerActivity) {
|
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " +
|
||||||
if (account == null)
|
"OwnCloudClient");
|
||||||
throw new IllegalArgumentException
|
mClient = client;
|
||||||
("Trying to execute a remote operation with a NULL Account");
|
if (client.getAccount() != null) {
|
||||||
if (context == null)
|
mAccount = client.getAccount().getSavedAccount();
|
||||||
throw new IllegalArgumentException
|
}
|
||||||
("Trying to execute a remote operation with a NULL Context");
|
mContext = client.getContext();
|
||||||
mAccount = account;
|
|
||||||
mContext = context.getApplicationContext();
|
return runOperation();
|
||||||
mCallerActivity = callerActivity;
|
|
||||||
mClient = null; // the client instance will be created from mAccount
|
|
||||||
// and mContext in the runnerThread to create below
|
|
||||||
mListener = listener;
|
|
||||||
|
|
||||||
mListenerHandler = listenerHandler;
|
|
||||||
|
|
||||||
Thread runnerThread = new Thread(this);
|
|
||||||
runnerThread.start();
|
|
||||||
return runnerThread;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously executes the remote operation
|
* Asynchronously executes the remote operation
|
||||||
*
|
*
|
||||||
* This method should be used whenever an ownCloud account is available,
|
* This method should be used whenever an ownCloud account is available,
|
||||||
* instead of {@link #execute(OwnCloudClient, OnRemoteOperationListener, Handler))}.
|
* instead of {@link #execute(OwnCloudClient, OnRemoteOperationListener, Handler))}.
|
||||||
*
|
*
|
||||||
* @param account ownCloud account in remote ownCloud server to reach during the
|
* @param account ownCloud account in remote ownCloud server to reach during the
|
||||||
* execution of the operation.
|
* execution of the operation.
|
||||||
* @param context Android context for the component calling the method.
|
* @param context Android context for the component calling the method.
|
||||||
* @param listener Listener to be notified about the execution of the operation.
|
* @param listener Listener to be notified about the execution of the operation.
|
||||||
* @param listenerHandler Handler associated to the thread where the methods of the listener
|
* @param listenerHandler Handler associated to the thread where the methods of the listener
|
||||||
* objects must be called.
|
* objects must be called.
|
||||||
* @return Thread were the remote operation is executed.
|
* @return Thread were the remote operation is executed.
|
||||||
*/
|
*/
|
||||||
public Thread execute(Account account, Context context,
|
public Thread execute(Account account, Context context,
|
||||||
OnRemoteOperationListener listener, Handler listenerHandler) {
|
OnRemoteOperationListener listener, Handler listenerHandler) {
|
||||||
|
|
||||||
if (account == null)
|
if (account == null)
|
||||||
throw new IllegalArgumentException
|
throw new IllegalArgumentException
|
||||||
("Trying to execute a remote operation with a NULL Account");
|
("Trying to execute a remote operation with a NULL Account");
|
||||||
if (context == null)
|
if (context == null)
|
||||||
throw new IllegalArgumentException
|
throw new IllegalArgumentException
|
||||||
("Trying to execute a remote operation with a NULL Context");
|
("Trying to execute a remote operation with a NULL Context");
|
||||||
|
// mAccount and mContext in the runnerThread to create below
|
||||||
mAccount = account;
|
mAccount = account;
|
||||||
mContext = context.getApplicationContext();
|
mContext = context.getApplicationContext();
|
||||||
mCallerActivity = null;
|
|
||||||
mClient = null; // the client instance will be created from
|
mClient = null; // the client instance will be created from
|
||||||
// mAccount and mContext in the runnerThread to create below
|
|
||||||
|
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
|
|
||||||
mListenerHandler = listenerHandler;
|
mListenerHandler = listenerHandler;
|
||||||
|
|
||||||
Thread runnerThread = new Thread(this);
|
Thread runnerThread = new Thread(this);
|
||||||
runnerThread.start();
|
runnerThread.start();
|
||||||
return runnerThread;
|
return runnerThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously executes the remote operation
|
* Asynchronously executes the remote operation
|
||||||
*
|
*
|
||||||
* @param client Client object to reach an ownCloud server
|
* @param client Client object to reach an ownCloud server
|
||||||
* during the execution of the operation.
|
* during the execution of the operation.
|
||||||
* @param listener Listener to be notified about the execution of the operation.
|
* @param listener Listener to be notified about the execution of the operation.
|
||||||
* @param listenerHandler Handler, if passed in, associated to the thread where the methods of
|
* @param listenerHandler Handler, if passed in, associated to the thread where the methods of
|
||||||
* the listener objects must be called.
|
* the listener objects must be called.
|
||||||
* @return Thread were the remote operation is executed.
|
* @return Thread were the remote operation is executed.
|
||||||
*/
|
*/
|
||||||
public Thread execute(OwnCloudClient client,
|
public Thread execute(OwnCloudClient client,
|
||||||
OnRemoteOperationListener listener, Handler listenerHandler) {
|
OnRemoteOperationListener listener, Handler listenerHandler) {
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
throw new IllegalArgumentException
|
throw new IllegalArgumentException
|
||||||
("Trying to execute a remote operation with a NULL OwnCloudClient");
|
("Trying to execute a remote operation with a NULL OwnCloudClient");
|
||||||
}
|
}
|
||||||
mClient = client;
|
mClient = client;
|
||||||
|
if (client.getAccount() != null) {
|
||||||
if (listener == null) {
|
mAccount = client.getAccount().getSavedAccount();
|
||||||
throw new IllegalArgumentException
|
}
|
||||||
|
mContext = client.getContext();
|
||||||
|
|
||||||
|
if (listener == null) {
|
||||||
|
throw new IllegalArgumentException
|
||||||
("Trying to execute a remote operation asynchronously " +
|
("Trying to execute a remote operation asynchronously " +
|
||||||
"without a listener to notiy the result");
|
"without a listener to notiy the result");
|
||||||
}
|
}
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
|
|
||||||
if (listenerHandler != null) {
|
if (listenerHandler != null) {
|
||||||
mListenerHandler = listenerHandler;
|
mListenerHandler = listenerHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Thread runnerThread = new Thread(this);
|
||||||
Thread runnerThread = new Thread(this);
|
runnerThread.start();
|
||||||
runnerThread.start();
|
return runnerThread;
|
||||||
return runnerThread;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronous execution of the operation
|
* Asynchronous execution of the operation
|
||||||
* started by {@link RemoteOperation#execute(OwnCloudClient,
|
* started by {@link RemoteOperation#execute(OwnCloudClient,
|
||||||
* OnRemoteOperationListener, Handler)},
|
* OnRemoteOperationListener, Handler)},
|
||||||
* and result posting.
|
* and result posting.
|
||||||
*
|
*/
|
||||||
* TODO refactor && clean the code; now it's a mess
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public final void run() {
|
public final void run() {
|
||||||
RemoteOperationResult result = null;
|
|
||||||
boolean repeat = false;
|
final RemoteOperationResult resultToSend = runOperation();
|
||||||
do {
|
|
||||||
try{
|
|
||||||
if (mClient == null) {
|
|
||||||
if (mAccount != null && mContext != null) {
|
|
||||||
/** DEPRECATED BLOCK - will be removed at version 1.0 */
|
|
||||||
if (mCallerActivity != null) {
|
|
||||||
mClient = OwnCloudClientFactory.createOwnCloudClient(
|
|
||||||
mAccount, mContext, mCallerActivity);
|
|
||||||
} else {
|
|
||||||
/** EOF DEPRECATED */
|
|
||||||
OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);
|
|
||||||
mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
|
||||||
getClientFor(ocAccount, mContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException("Trying to run a remote operation " +
|
|
||||||
"asynchronously with no client instance or account");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log_OC.e(TAG, "Error while trying to access to " + mAccount.name,
|
|
||||||
new AccountsException("I/O exception while trying to authorize the account",
|
|
||||||
e));
|
|
||||||
result = new RemoteOperationResult(e);
|
|
||||||
|
|
||||||
} catch (AccountsException e) {
|
|
||||||
Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, e);
|
|
||||||
result = new RemoteOperationResult(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == null)
|
|
||||||
result = run(mClient);
|
|
||||||
|
|
||||||
repeat = false;
|
|
||||||
/** DEPRECATED BLOCK - will be removed at version 1.0 ; don't trust in this code
|
|
||||||
* to trigger authentication update */
|
|
||||||
if (mCallerActivity != null && mAccount != null && mContext != null &&
|
|
||||||
!result.isSuccess() &&
|
|
||||||
ResultCode.UNAUTHORIZED.equals(result.getCode())
|
|
||||||
) {
|
|
||||||
/// possible fail due to lack of authorization
|
|
||||||
// in an operation performed in foreground
|
|
||||||
OwnCloudCredentials cred = mClient.getCredentials();
|
|
||||||
if (cred != null) {
|
|
||||||
/// confirmed : unauthorized operation
|
|
||||||
AccountManager am = AccountManager.get(mContext);
|
|
||||||
if (cred.authTokenExpires()) {
|
|
||||||
am.invalidateAuthToken(
|
|
||||||
mAccount.type,
|
|
||||||
cred.getAuthToken()
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
am.clearPassword(mAccount);
|
|
||||||
}
|
|
||||||
mClient = null;
|
|
||||||
// when repeated, the creation of a new OwnCloudClient after erasing the saved
|
|
||||||
// credentials will trigger the login activity
|
|
||||||
repeat = true;
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** EOF DEPRECATED BLOCK **/
|
|
||||||
} while (repeat);
|
|
||||||
|
|
||||||
if (mAccount != null && mContext != null) {
|
if (mAccount != null && mContext != null) {
|
||||||
// Save Client Cookies
|
// Save Client Cookies
|
||||||
AccountUtils.saveClient(mClient, mAccount, mContext);
|
AccountUtils.saveClient(mClient, mAccount, mContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
final RemoteOperationResult resultToSend = result;
|
|
||||||
if (mListenerHandler != null && mListener != null) {
|
if (mListenerHandler != null && mListener != null) {
|
||||||
mListenerHandler.post(new Runnable() {
|
mListenerHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mListener.onRemoteOperationFinish(RemoteOperation.this, resultToSend);
|
mListener.onRemoteOperationFinish(RemoteOperation.this, resultToSend);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} else if (mListener != null) {
|
||||||
else if(mListener != null) {
|
|
||||||
mListener.onRemoteOperationFinish(RemoteOperation.this, resultToSend);
|
mListener.onRemoteOperationFinish(RemoteOperation.this, resultToSend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run operation for asynchronous or synchronous 'execute' method.
|
||||||
|
*
|
||||||
|
* Considers and performs silent refresh of account credentials if possible, and if
|
||||||
|
* {@link RemoteOperation#setSilentRefreshOfAccountCredentials(boolean)} was called with
|
||||||
|
* parameter 'true' before the execution.
|
||||||
|
*
|
||||||
|
* @return Remote operation result
|
||||||
|
*/
|
||||||
|
private RemoteOperationResult runOperation() {
|
||||||
|
|
||||||
|
RemoteOperationResult result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
grantOwnCloudClient();
|
||||||
|
result = run(mClient);
|
||||||
|
|
||||||
|
} catch (AccountsException | IOException e) {
|
||||||
|
Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, e);
|
||||||
|
result = new RemoteOperationResult(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void grantOwnCloudClient() throws
|
||||||
|
AccountUtils.AccountNotFoundException, OperationCanceledException, AuthenticatorException, IOException {
|
||||||
|
if (mClient == null) {
|
||||||
|
if (mAccount != null && mContext != null) {
|
||||||
|
OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);
|
||||||
|
mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
||||||
|
getClientFor(ocAccount, mContext);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Trying to run a remote operation " +
|
||||||
|
"asynchronously with no client and no chance to create one (no account)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current client instance to access the remote server.
|
* Returns the current client instance to access the remote server.
|
||||||
*
|
*
|
||||||
* @return Current client instance to access the remote server.
|
* @return Current client instance to access the remote server.
|
||||||
*/
|
*/
|
||||||
public final OwnCloudClient getClient() {
|
public final OwnCloudClient getClient() {
|
||||||
return mClient;
|
return mClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -129,7 +129,7 @@ public class RemoteOperationResult implements Serializable {
|
|||||||
private Exception mException = null;
|
private Exception mException = null;
|
||||||
private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
|
private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
|
||||||
private String mRedirectedLocation;
|
private String mRedirectedLocation;
|
||||||
private String mAuthenticate;
|
private ArrayList<String> mAuthenticate = new ArrayList<>();
|
||||||
private String mLastPermanentLocation = null;
|
private String mLastPermanentLocation = null;
|
||||||
|
|
||||||
private ArrayList<Object> mData;
|
private ArrayList<Object> mData;
|
||||||
@ -313,16 +313,13 @@ public class RemoteOperationResult implements Serializable {
|
|||||||
public RemoteOperationResult(boolean success, int httpCode, String httpPhrase, Header[] httpHeaders) {
|
public RemoteOperationResult(boolean success, int httpCode, String httpPhrase, Header[] httpHeaders) {
|
||||||
this(success, httpCode, httpPhrase);
|
this(success, httpCode, httpPhrase);
|
||||||
if (httpHeaders != null) {
|
if (httpHeaders != null) {
|
||||||
Header current;
|
|
||||||
for (Header httpHeader : httpHeaders) {
|
for (Header httpHeader : httpHeaders) {
|
||||||
current = httpHeader;
|
if ("location".equals(httpHeader.getName().toLowerCase())) {
|
||||||
if ("location".equals(current.getName().toLowerCase())) {
|
mRedirectedLocation = httpHeader.getValue();
|
||||||
mRedirectedLocation = current.getValue();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ("www-authenticate".equals(current.getName().toLowerCase())) {
|
if ("www-authenticate".equals(httpHeader.getName().toLowerCase())) {
|
||||||
mAuthenticate = current.getValue();
|
mAuthenticate.add(httpHeader.getValue().toLowerCase());
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -562,7 +559,7 @@ public class RemoteOperationResult implements Serializable {
|
|||||||
return (mRedirectedLocation != null && !(mRedirectedLocation.toLowerCase().startsWith("https://")));
|
return (mRedirectedLocation != null && !(mRedirectedLocation.toLowerCase().startsWith("https://")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAuthenticateHeader() {
|
public ArrayList<String> getAuthenticateHeaders() {
|
||||||
return mAuthenticate;
|
return mAuthenticate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,19 +71,6 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
|
|||||||
mSuccessIfAbsent = successIfAbsent;
|
mSuccessIfAbsent = successIfAbsent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 context Android application context.
|
|
||||||
* @param successIfAbsent When 'true', the operation finishes in success if the path does
|
|
||||||
* NOT exist in the remote server (HTTP 404).
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
public ExistenceCheckRemoteOperation(String remotePath, Context context, boolean successIfAbsent) {
|
|
||||||
this(remotePath, successIfAbsent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||||
RemoteOperationResult result = null;
|
RemoteOperationResult result = null;
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
package com.owncloud.android.lib.resources.files;
|
package com.owncloud.android.lib.resources.files;
|
||||||
|
|
||||||
|
import android.os.RemoteException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
|
import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
|
||||||
@ -101,8 +103,7 @@ public class RenameRemoteFileOperation extends RemoteOperation {
|
|||||||
return new RemoteOperationResult(ResultCode.OK);
|
return new RemoteOperationResult(ResultCode.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if a file with the new name already exists
|
if (targetPathIsUsed(client)) {
|
||||||
if (client.existsFile(mNewRemotePath)) {
|
|
||||||
return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
|
return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +135,18 @@ public class RenameRemoteFileOperation extends RemoteOperation {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a file with the new name already exists.
|
||||||
|
*
|
||||||
|
* @return 'True' if the target path is already used by an existing file.
|
||||||
|
*/
|
||||||
|
private boolean targetPathIsUsed(OwnCloudClient client) {
|
||||||
|
ExistenceCheckRemoteOperation existenceCheckRemoteOperation =
|
||||||
|
new ExistenceCheckRemoteOperation(mNewRemotePath, false);
|
||||||
|
RemoteOperationResult exists = existenceCheckRemoteOperation.run(client);
|
||||||
|
return exists.isSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move operation
|
* Move operation
|
||||||
*/
|
*/
|
||||||
|
@ -63,14 +63,6 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
|
|||||||
private int mVersion;
|
private int mVersion;
|
||||||
private boolean mIsValid;
|
private boolean mIsValid;
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Will be removed in version 1.0 of the library.
|
|
||||||
*/
|
|
||||||
private OwnCloudVersion(int version) {
|
|
||||||
mVersion = version;
|
|
||||||
mIsValid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OwnCloudVersion(String version) {
|
public OwnCloudVersion(String version) {
|
||||||
mVersion = 0;
|
mVersion = 0;
|
||||||
mIsValid = false;
|
mIsValid = false;
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
package com.owncloud.android.lib.resources.users;
|
package com.owncloud.android.lib.resources.users;
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentials;
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
<string name="build_number"></string>
|
<string name="build_number"></string>
|
||||||
<string name="server_base_url"></string>
|
<string name="server_base_url">https://qa.oc.solidgear.es</string>
|
||||||
<string name="server_base_url_2"></string>
|
<string name="server_base_url_2">https://qa2.oc.solidgear.es</string>
|
||||||
<string name="username"></string>
|
<string name="username">android-library-test</string>
|
||||||
<string name="password"></string>
|
<string name="password">letitgo,letitgo,thatperfectappisgone</string>
|
||||||
<string name ="user_agent">Mozilla/5.0 (Android) ownCloud test project</string>
|
<string name ="user_agent">Mozilla/5.0 (Android) ownCloud test project</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -42,7 +42,7 @@ import android.view.Menu;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
|
@ -31,7 +31,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||||
|
@ -38,7 +38,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.lib.resources.status.GetRemoteCapabilitiesOperation;
|
import com.owncloud.android.lib.resources.status.GetRemoteCapabilitiesOperation;
|
||||||
|
@ -37,7 +37,7 @@ import org.json.JSONObject;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.lib.resources.shares.GetRemoteShareesOperation;
|
import com.owncloud.android.lib.resources.shares.GetRemoteShareesOperation;
|
||||||
|
@ -35,7 +35,7 @@ import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||||
|
@ -43,9 +43,9 @@ import android.test.AndroidTestCase;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentials;
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
|
||||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||||
import com.owncloud.android.lib.test_project.R;
|
import com.owncloud.android.lib.test_project.R;
|
||||||
import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory;
|
import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory;
|
||||||
@ -130,7 +130,7 @@ public class OwnCloudClientTest extends AndroidTestCase {
|
|||||||
client.setCredentials(credentials);
|
client.setCredentials(credentials);
|
||||||
assertEquals("Basic credentials not set", credentials, client.getCredentials());
|
assertEquals("Basic credentials not set", credentials, client.getCredentials());
|
||||||
|
|
||||||
credentials = OwnCloudCredentialsFactory.newBearerCredentials("bearerToken");
|
credentials = OwnCloudCredentialsFactory.newBearerCredentials("user", "bearerToken");
|
||||||
client.setCredentials(credentials);
|
client.setCredentials(credentials);
|
||||||
assertEquals("Bearer credentials not set", credentials, client.getCredentials());
|
assertEquals("Bearer credentials not set", credentials, client.getCredentials());
|
||||||
|
|
||||||
@ -294,7 +294,7 @@ public class OwnCloudClientTest extends AndroidTestCase {
|
|||||||
public void testGetWebdavUri() {
|
public void testGetWebdavUri() {
|
||||||
OwnCloudClient client =
|
OwnCloudClient client =
|
||||||
new OwnCloudClient(mServerUri, NetworkUtils.getMultiThreadedConnManager());
|
new OwnCloudClient(mServerUri, NetworkUtils.getMultiThreadedConnManager());
|
||||||
client.setCredentials(OwnCloudCredentialsFactory.newBearerCredentials("fakeToken"));
|
client.setCredentials(OwnCloudCredentialsFactory.newBearerCredentials("user", "fakeToken"));
|
||||||
Uri webdavUri = client.getWebdavUri();
|
Uri webdavUri = client.getWebdavUri();
|
||||||
assertTrue("WebDAV URI does not point to the right entry point",
|
assertTrue("WebDAV URI does not point to the right entry point",
|
||||||
webdavUri.getPath().endsWith(AccountUtils.WEBDAV_PATH_4_0));
|
webdavUri.getPath().endsWith(AccountUtils.WEBDAV_PATH_4_0));
|
||||||
|
@ -33,8 +33,8 @@ import android.test.AndroidTestCase;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
|
||||||
import com.owncloud.android.lib.common.SimpleFactoryManager;
|
import com.owncloud.android.lib.common.SimpleFactoryManager;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.test_project.R;
|
import com.owncloud.android.lib.test_project.R;
|
||||||
import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory;
|
import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory;
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ import android.test.AndroidTestCase;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
|
||||||
import com.owncloud.android.lib.common.SingleSessionManager;
|
import com.owncloud.android.lib.common.SingleSessionManager;
|
||||||
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.test_project.R;
|
import com.owncloud.android.lib.test_project.R;
|
||||||
import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory;
|
import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||||
|
@ -41,7 +41,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
||||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
|
||||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user