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

Simplify operation to refresh OAuth2 access token

This commit is contained in:
David A. Velasco 2017-07-25 19:04:52 +02:00
parent 95fdf75d38
commit ae8e3ca904
2 changed files with 53 additions and 97 deletions

View File

@ -48,9 +48,7 @@ public class OAuth2GetRefreshedAccessTokenOperation extends RemoteOperation {
private String mClientSecret; private String mClientSecret;
private String mGrantType; private String mGrantType;
private String mOAuth2RefreshAccessTokenQueryParams; private String mRefreshToken;
private Map<String, String> mOAuth2ParsedRefreshAccessTokenQueryParams;
private Map<String, String> mResultTokenMap; private Map<String, String> mResultTokenMap;
@ -58,14 +56,13 @@ public class OAuth2GetRefreshedAccessTokenOperation extends RemoteOperation {
String clientId, String clientId,
String secretId, String secretId,
String grantType, String grantType,
String oAuth2RefreshAccessTokenQueryParams String refreshToken
) { ) {
mClientId = clientId; mClientId = clientId;
mClientSecret = secretId; mClientSecret = secretId;
mGrantType = grantType; mGrantType = grantType;
mOAuth2RefreshAccessTokenQueryParams = oAuth2RefreshAccessTokenQueryParams; mRefreshToken = refreshToken;
mOAuth2ParsedRefreshAccessTokenQueryParams = new HashMap<>();
mResultTokenMap = null; mResultTokenMap = null;
} }
@ -76,60 +73,44 @@ public class OAuth2GetRefreshedAccessTokenOperation extends RemoteOperation {
PostMethod postMethod = null; PostMethod postMethod = null;
try { try {
parseAuthorizationResponse(); NameValuePair[] nameValuePairs = new NameValuePair[3];
nameValuePairs[0] = new NameValuePair(OAuth2Constants.KEY_GRANT_TYPE, mGrantType);
nameValuePairs[1] = new NameValuePair(OAuth2Constants.KEY_CLIENT_ID, mClientId);
nameValuePairs[2] = new NameValuePair(OAuth2Constants.KEY_REFRESH_TOKEN, mRefreshToken);
if (mOAuth2ParsedRefreshAccessTokenQueryParams.keySet().contains(OAuth2Constants. Uri.Builder uriBuilder = client.getBaseUri().buildUpon();
KEY_ERROR)) {
if (OAuth2Constants.VALUE_ERROR_ACCESS_DENIED.equals( postMethod = new PostMethod(uriBuilder.build().toString());
mOAuth2ParsedRefreshAccessTokenQueryParams.get(OAuth2Constants.KEY_ERROR))) { postMethod.setRequestBody(nameValuePairs);
result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR_ACCESS_DENIED);
} else { 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);
parseNewAccessTokenResult(tokenJson);
if (mResultTokenMap.get(OAuth2Constants.KEY_ERROR) != null ||
mResultTokenMap.get(OAuth2Constants.KEY_ACCESS_TOKEN) == null) {
result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR); result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR);
}
}
if (result == null) {
NameValuePair[] nameValuePairs = new NameValuePair[3];
nameValuePairs[0] = new NameValuePair(OAuth2Constants.KEY_GRANT_TYPE, mGrantType);
nameValuePairs[1] = new NameValuePair(OAuth2Constants.KEY_CLIENT_ID, mClientId);
nameValuePairs[2] = new NameValuePair(OAuth2Constants.KEY_REFRESH_TOKEN,
mOAuth2ParsedRefreshAccessTokenQueryParams.get(OAuth2Constants.KEY_REFRESH_TOKEN));
Uri.Builder uriBuilder = client.getBaseUri().buildUpon();
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);
parseNewAccessTokenResult(tokenJson);
if (mResultTokenMap.get(OAuth2Constants.KEY_ERROR) != null ||
mResultTokenMap.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(mResultTokenMap);
result.setData(data);
}
} else { } else {
result = new RemoteOperationResult(false, postMethod); result = new RemoteOperationResult(true, postMethod);
client.exhaustResponse(postMethod.getResponseBodyAsStream()); ArrayList<Object> data = new ArrayList<>();
data.add(mResultTokenMap);
result.setData(data);
} }
} else {
result = new RemoteOperationResult(false, postMethod);
client.exhaustResponse(postMethod.getResponseBodyAsStream());
} }
} catch (Exception e) { } catch (Exception e) {
@ -139,27 +120,29 @@ public class OAuth2GetRefreshedAccessTokenOperation extends RemoteOperation {
if (postMethod != null) if (postMethod != null)
postMethod.releaseConnection(); // let the connection available for other methods postMethod.releaseConnection(); // let the connection available for other methods
/*
if (result.isSuccess()) { if (result.isSuccess()) {
Log_OC.i(TAG, "OAuth2 TOKEN REQUEST with auth code " + Log_OC.i(TAG, "OAuth2 TOKEN REQUEST with refresh token " +
mOAuth2ParsedRefreshAccessTokenQueryParams.get("code") + " to " + mRefreshToken + " to " +
client.getWebdavUri() + ": " + result.getLogMessage()); client.getWebdavUri() + ": " + result.getLogMessage());
} else if (result.getException() != null) { } else if (result.getException() != null) {
Log_OC.e(TAG, "OAuth2 TOKEN REQUEST with auth code " + Log_OC.e(TAG, "OAuth2 TOKEN REQUEST with refresh token " +
mOAuth2ParsedRefreshAccessTokenQueryParams.get("code") + " to " + client. mRefreshToken + " to " + client.
getWebdavUri() + ": " + result.getLogMessage(), result.getException()); getWebdavUri() + ": " + result.getLogMessage(), result.getException());
} else if (result.getCode() == ResultCode.OAUTH2_ERROR) { } else if (result.getCode() == ResultCode.OAUTH2_ERROR) {
Log_OC.e(TAG, "OAuth2 TOKEN REQUEST with auth code " + Log_OC.e(TAG, "OAuth2 TOKEN REQUEST with refresh token " +
mOAuth2ParsedRefreshAccessTokenQueryParams.get("code") + " to " + client. mRefreshToken + " to " + client.
getWebdavUri() + ": " + ((mResultTokenMap != null) ? mResultTokenMap. getWebdavUri() + ": " + ((mResultTokenMap != null) ? mResultTokenMap.
get(OAuth2Constants.KEY_ERROR) : "NULL")); get(OAuth2Constants.KEY_ERROR) : "NULL"));
} else { } else {
Log_OC.e(TAG, "OAuth2 TOKEN REQUEST with auth code " + Log_OC.e(TAG, "OAuth2 TOKEN REQUEST with refresh token " +
mOAuth2ParsedRefreshAccessTokenQueryParams.get("code") + " to " + client. mRefreshToken + " to " + client.
getWebdavUri() + ": " + result.getLogMessage()); getWebdavUri() + ": " + result.getLogMessage());
} }
*/
} }
return result; return result;
@ -172,33 +155,6 @@ public class OAuth2GetRefreshedAccessTokenOperation extends RemoteOperation {
return previousCredentials; return previousCredentials;
} }
private void parseAuthorizationResponse() {
String[] pairs = mOAuth2RefreshAccessTokenQueryParams.split("&");
int i = 0;
String key = "";
String value = "";
StringBuilder sb = new StringBuilder();
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;
sb.append(key + " = ");
} else if (j == 1) {
value = p;
mOAuth2ParsedRefreshAccessTokenQueryParams.put(key, value);
sb.append(value + "\n");
}
Log_OC.v(TAG, "[" + i + "," + j + "] = " + p);
j++;
}
i++;
}
}
private void parseNewAccessTokenResult(JSONObject tokenJson) throws JSONException { private void parseNewAccessTokenResult(JSONObject tokenJson) throws JSONException {
mResultTokenMap = new HashMap<>(); mResultTokenMap = new HashMap<>();

View File

@ -29,15 +29,12 @@ import android.accounts.AccountManager;
import android.accounts.AccountsException; import android.accounts.AccountsException;
import android.accounts.AuthenticatorException; import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException; import android.accounts.OperationCanceledException;
import android.app.Activity;
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.OwnCloudCredentialsFactory; 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.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
@ -241,7 +238,7 @@ public abstract class RemoteOperation implements Runnable {
*/ */
@Override @Override
public final void run() { public final void run() {
RemoteOperationResult result = null; RemoteOperationResult result;
boolean repeat; boolean repeat;
int repeatCounter = 0; int repeatCounter = 0;
do { do {
@ -267,8 +264,10 @@ public abstract class RemoteOperation implements Runnable {
repeatCounter++; repeatCounter++;
// this will result in a new loop, and grantOwnCloudClient() will // this will result in a new loop, and grantOwnCloudClient() will
// create a new instance for mClient, refreshing the token via the account // create a new instance for mClient, getting a new fresh token in the
// manager // way, in the AccountAuthenticator * ;
// this, unfortunately, is a hidden runtime dependency back to the app;
// we should fix it ASAP
} }
// else: operation will finish with ResultCode.UNAUTHORIZED // else: operation will finish with ResultCode.UNAUTHORIZED
} }
@ -293,7 +292,8 @@ public abstract class RemoteOperation implements Runnable {
} }
} }
private void grantOwnCloudClient() throws AccountUtils.AccountNotFoundException, OperationCanceledException, AuthenticatorException, IOException { private void grantOwnCloudClient() throws
AccountUtils.AccountNotFoundException, OperationCanceledException, AuthenticatorException, IOException {
if (mClient == null) { if (mClient == null) {
if (mAccount != null && mContext != null) { if (mAccount != null && mContext != null) {
OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext); OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);