Merge pull request #4644 from nextcloud/detectAuth

Allow broader check on CheckAuth
This commit is contained in:
Tobias Kaminsky 2019-10-09 21:06:00 +02:00 committed by GitHub
commit 07d0abe87e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,5 +1,5 @@
/** /**
* ownCloud Android client application * ownCloud Android client application
* *
* @author David A. Velasco * @author David A. Velasco
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2015 ownCloud Inc.
@ -46,78 +46,78 @@ import java.util.Locale;
* {@link RemoteOperationResult#getData()} a value of {@link AuthenticationMethod}. * {@link RemoteOperationResult#getData()} a value of {@link AuthenticationMethod}.
*/ */
public class DetectAuthenticationMethodOperation extends RemoteOperation { public class DetectAuthenticationMethodOperation extends RemoteOperation {
private static final String TAG = DetectAuthenticationMethodOperation.class.getSimpleName(); private static final String TAG = DetectAuthenticationMethodOperation.class.getSimpleName();
public enum AuthenticationMethod { public enum AuthenticationMethod {
UNKNOWN, UNKNOWN,
NONE, NONE,
BASIC_HTTP_AUTH, BASIC_HTTP_AUTH,
SAML_WEB_SSO, SAML_WEB_SSO,
BEARER_TOKEN BEARER_TOKEN
} }
private Context mContext; private Context mContext;
/** /**
* Constructor * Constructor
* *
* @param context Android context of the caller. * @param context Android context of the caller.
*/ */
public DetectAuthenticationMethodOperation(Context context) { public DetectAuthenticationMethodOperation(Context context) {
mContext = context; mContext = context;
} }
/** /**
* Performs the operation. * Performs the operation.
* *
* Triggers a check of existence on the root folder of the server, granting * Triggers a check of existence on the root folder of the server, granting
* that the request is not authenticated. * that the request is not authenticated.
* *
* Analyzes the result of check to find out what authentication method, if * Analyzes the result of check to find out what authentication method, if
* any, is requested by the server. * any, is requested by the server.
*/ */
@Override @Override
protected RemoteOperationResult run(OwnCloudClient client) { protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null; RemoteOperationResult result = null;
AuthenticationMethod authMethod = AuthenticationMethod.UNKNOWN; AuthenticationMethod authMethod = AuthenticationMethod.UNKNOWN;
RemoteOperation operation = new ExistenceCheckRemoteOperation("", mContext, false); RemoteOperation operation = new ExistenceCheckRemoteOperation("", mContext, false);
client.clearCredentials(); client.clearCredentials();
client.setFollowRedirects(false); client.setFollowRedirects(false);
// try to access the root folder, following redirections but not SAML SSO redirections // try to access the root folder, following redirections but not SAML SSO redirections
result = operation.execute(client); result = operation.execute(client);
String redirectedLocation = result.getRedirectedLocation(); String redirectedLocation = result.getRedirectedLocation();
while (!TextUtils.isEmpty(redirectedLocation) && !result.isIdPRedirection()) { while (!TextUtils.isEmpty(redirectedLocation) && !result.isIdPRedirection()) {
client.setBaseUri(Uri.parse(result.getRedirectedLocation())); client.setBaseUri(Uri.parse(result.getRedirectedLocation()));
result = operation.execute(client); result = operation.execute(client);
redirectedLocation = result.getRedirectedLocation(); redirectedLocation = result.getRedirectedLocation();
} }
// analyze response // analyze response
if (result.getHttpCode() == HttpStatus.SC_UNAUTHORIZED) { if (result.getHttpCode() == HttpStatus.SC_UNAUTHORIZED || result.getHttpCode() == HttpStatus.SC_FORBIDDEN) {
ArrayList<String> authHeaders = result.getAuthenticateHeaders(); ArrayList<String> authHeaders = result.getAuthenticateHeaders();
for (String header : authHeaders) { for (String header : authHeaders) {
// currently we only support basic auth // currently we only support basic auth
if (header.toLowerCase(Locale.ROOT).startsWith("basic")) { if (header.toLowerCase(Locale.ROOT).contains("basic")) {
authMethod = AuthenticationMethod.BASIC_HTTP_AUTH; authMethod = AuthenticationMethod.BASIC_HTTP_AUTH;
break; break;
} }
} }
// else - fall back to UNKNOWN // else - fall back to UNKNOWN
} else if (result.isSuccess()) { } else if (result.isSuccess()) {
authMethod = AuthenticationMethod.NONE; authMethod = AuthenticationMethod.NONE;
} else if (result.isIdPRedirection()) { } else if (result.isIdPRedirection()) {
authMethod = AuthenticationMethod.SAML_WEB_SSO; authMethod = AuthenticationMethod.SAML_WEB_SSO;
} }
// else - fall back to UNKNOWN // else - fall back to UNKNOWN
Log_OC.d(TAG, "Authentication method found: " + authenticationMethodToString(authMethod)); Log_OC.d(TAG, "Authentication method found: " + authenticationMethodToString(authMethod));
if (authMethod != AuthenticationMethod.UNKNOWN) { if (authMethod != AuthenticationMethod.UNKNOWN) {
result = new RemoteOperationResult(true, result.getHttpCode(), result.getHttpPhrase(), null); result = new RemoteOperationResult(true, result.getHttpCode(), result.getHttpPhrase(), null);
} }
@ -125,22 +125,22 @@ public class DetectAuthenticationMethodOperation extends RemoteOperation {
data.add(authMethod); data.add(authMethod);
result.setData(data); result.setData(data);
return result; // same result instance, so that other errors return result; // same result instance, so that other errors
// can be handled by the caller transparently // can be handled by the caller transparently
} }
private String authenticationMethodToString(AuthenticationMethod value) { private String authenticationMethodToString(AuthenticationMethod value) {
switch (value){ switch (value) {
case NONE: case NONE:
return "NONE"; return "NONE";
case BASIC_HTTP_AUTH: case BASIC_HTTP_AUTH:
return "BASIC_HTTP_AUTH"; return "BASIC_HTTP_AUTH";
case BEARER_TOKEN: case BEARER_TOKEN:
return "BEARER_TOKEN"; return "BEARER_TOKEN";
case SAML_WEB_SSO: case SAML_WEB_SSO:
return "SAML_WEB_SSO"; return "SAML_WEB_SSO";
default: default:
return "UNKNOWN"; return "UNKNOWN";
} }
} }
} }