mirror of https://github.com/nextcloud/android
Fix GetServerInfo and GetStatus operations
Signed-off-by: ZetaTom <70907959+ZetaTom@users.noreply.github.com>
This commit is contained in:
parent
4c550c72c6
commit
ce101d2c9b
|
@ -898,7 +898,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
*
|
||||
* @param result Result of the check.
|
||||
*/
|
||||
private void onGetServerInfoFinish(RemoteOperationResult result) {
|
||||
private void onGetServerInfoFinish(RemoteOperationResult<GetServerInfoOperation.ServerInfo> result) {
|
||||
/// update activity state
|
||||
mWaitingForOpId = Long.MAX_VALUE;
|
||||
|
||||
|
@ -908,7 +908,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
// 2. server is installed
|
||||
// 3. we got the server version
|
||||
// 4. we got the authentication method required by the server
|
||||
mServerInfo = (GetServerInfoOperation.ServerInfo) (result.getData().get(0));
|
||||
mServerInfo = result.getResultData();
|
||||
|
||||
// show outdated warning
|
||||
if (CapabilityUtils.checkOutdatedWarning(getResources(),
|
||||
|
|
|
@ -20,11 +20,10 @@
|
|||
|
||||
package com.owncloud.android.operations;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.nextcloud.common.NextcloudClient;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
@ -38,68 +37,43 @@ import java.util.Locale;
|
|||
|
||||
/**
|
||||
* Operation to find out what authentication method requires the server to access files.
|
||||
*
|
||||
* <p>
|
||||
* Basically, tries to access to the root folder without authorization and analyzes the response.
|
||||
*
|
||||
* <p>
|
||||
* When successful, the instance of {@link RemoteOperationResult} passed through
|
||||
* {@link com.owncloud.android.lib.common.operations.OnRemoteOperationListener
|
||||
* #onRemoteOperationFinish(RemoteOperation, RemoteOperationResult)} returns in
|
||||
* {@link RemoteOperationResult#getData()} a value of {@link AuthenticationMethod}.
|
||||
* {@link com.owncloud.android.lib.common.operations.OnRemoteOperationListener #onRemoteOperationFinish(RemoteOperation,
|
||||
* RemoteOperationResult)} returns in {@link RemoteOperationResult#getData()} a value of {@link AuthenticationMethod}.
|
||||
*/
|
||||
public class DetectAuthenticationMethodOperation extends RemoteOperation {
|
||||
public class DetectAuthenticationMethodOperation extends RemoteOperation<DetectAuthenticationMethodOperation.AuthenticationMethod> {
|
||||
|
||||
private static final String TAG = DetectAuthenticationMethodOperation.class.getSimpleName();
|
||||
|
||||
public enum AuthenticationMethod {
|
||||
UNKNOWN,
|
||||
NONE,
|
||||
BASIC_HTTP_AUTH,
|
||||
SAML_WEB_SSO,
|
||||
BEARER_TOKEN
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param context Android context of the caller.
|
||||
*/
|
||||
public DetectAuthenticationMethodOperation(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs the operation.
|
||||
*
|
||||
* Triggers a check of existence on the root folder of the server, granting
|
||||
* that the request is not authenticated.
|
||||
*
|
||||
* Analyzes the result of check to find out what authentication method, if
|
||||
* any, is requested by the server.
|
||||
* Performs the operation.
|
||||
* <p>
|
||||
* Triggers a check of existence on the root folder of the server, granting that the request is not authenticated.
|
||||
* <p>
|
||||
* Analyzes the result of check to find out what authentication method, if any, is requested by the server.
|
||||
*/
|
||||
@Override
|
||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||
RemoteOperationResult result = null;
|
||||
AuthenticationMethod authMethod = AuthenticationMethod.UNKNOWN;
|
||||
|
||||
RemoteOperation operation = new ExistenceCheckRemoteOperation("", mContext, false);
|
||||
client.clearCredentials();
|
||||
public RemoteOperationResult<AuthenticationMethod> run(NextcloudClient client) {
|
||||
RemoteOperation<Void> operation = new ExistenceCheckRemoteOperation("", false);
|
||||
client.setCredentials("");
|
||||
client.setFollowRedirects(false);
|
||||
|
||||
// try to access the root folder, following redirections but not SAML SSO redirections
|
||||
result = operation.execute(client);
|
||||
String redirectedLocation = result.getRedirectedLocation();
|
||||
while (!TextUtils.isEmpty(redirectedLocation) && !result.isIdPRedirection()) {
|
||||
client.setBaseUri(Uri.parse(result.getRedirectedLocation()));
|
||||
result = operation.execute(client);
|
||||
redirectedLocation = result.getRedirectedLocation();
|
||||
RemoteOperationResult<Void> existanceCheckResult = operation.execute(client);
|
||||
String redirectedLocation = existanceCheckResult.getRedirectedLocation();
|
||||
while (!TextUtils.isEmpty(redirectedLocation) && !existanceCheckResult.isIdPRedirection()) {
|
||||
client.setBaseUri(Uri.parse(existanceCheckResult.getRedirectedLocation()));
|
||||
existanceCheckResult = operation.execute(client);
|
||||
redirectedLocation = existanceCheckResult.getRedirectedLocation();
|
||||
}
|
||||
|
||||
// analyze response
|
||||
if (result.getHttpCode() == HttpStatus.SC_UNAUTHORIZED || result.getHttpCode() == HttpStatus.SC_FORBIDDEN) {
|
||||
ArrayList<String> authHeaders = result.getAuthenticateHeaders();
|
||||
AuthenticationMethod authMethod = AuthenticationMethod.UNKNOWN;
|
||||
if (existanceCheckResult.getHttpCode() == HttpStatus.SC_UNAUTHORIZED || existanceCheckResult.getHttpCode() == HttpStatus.SC_FORBIDDEN) {
|
||||
ArrayList<String> authHeaders = existanceCheckResult.getAuthenticateHeaders();
|
||||
|
||||
for (String header : authHeaders) {
|
||||
// currently we only support basic auth
|
||||
|
@ -110,38 +84,35 @@ public class DetectAuthenticationMethodOperation extends RemoteOperation {
|
|||
}
|
||||
// else - fall back to UNKNOWN
|
||||
|
||||
} else if (result.isSuccess()) {
|
||||
} else if (existanceCheckResult.isSuccess()) {
|
||||
authMethod = AuthenticationMethod.NONE;
|
||||
|
||||
} else if (result.isIdPRedirection()) {
|
||||
} else if (existanceCheckResult.isIdPRedirection()) {
|
||||
authMethod = AuthenticationMethod.SAML_WEB_SSO;
|
||||
}
|
||||
// else - fall back to UNKNOWN
|
||||
Log_OC.d(TAG, "Authentication method found: " + authenticationMethodToString(authMethod));
|
||||
|
||||
if (authMethod != AuthenticationMethod.UNKNOWN) {
|
||||
result = new RemoteOperationResult(true, result.getHttpCode(), result.getHttpPhrase(), new Header[0]);
|
||||
}
|
||||
ArrayList<Object> data = new ArrayList<>();
|
||||
data.add(authMethod);
|
||||
result.setData(data);
|
||||
boolean isSuccess = authMethod != AuthenticationMethod.UNKNOWN || existanceCheckResult.isSuccess();
|
||||
RemoteOperationResult<AuthenticationMethod> result = new RemoteOperationResult<>(isSuccess,
|
||||
existanceCheckResult.getHttpCode(), existanceCheckResult.getHttpPhrase(), new Header[0]);
|
||||
result.setResultData(authMethod);
|
||||
return result; // same result instance, so that other errors
|
||||
// can be handled by the caller transparently
|
||||
}
|
||||
|
||||
private String authenticationMethodToString(AuthenticationMethod value) {
|
||||
switch (value) {
|
||||
case NONE:
|
||||
return "NONE";
|
||||
case BASIC_HTTP_AUTH:
|
||||
return "BASIC_HTTP_AUTH";
|
||||
case BEARER_TOKEN:
|
||||
return "BEARER_TOKEN";
|
||||
case SAML_WEB_SSO:
|
||||
return "SAML_WEB_SSO";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
return switch (value) {
|
||||
case NONE -> "NONE";
|
||||
case BASIC_HTTP_AUTH -> "BASIC_HTTP_AUTH";
|
||||
case BEARER_TOKEN -> "BEARER_TOKEN";
|
||||
case SAML_WEB_SSO -> "SAML_WEB_SSO";
|
||||
default -> "UNKNOWN";
|
||||
};
|
||||
}
|
||||
|
||||
public enum AuthenticationMethod {
|
||||
UNKNOWN, NONE, BASIC_HTTP_AUTH, SAML_WEB_SSO, BEARER_TOKEN
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ package com.owncloud.android.operations;
|
|||
|
||||
import android.content.Context;
|
||||
|
||||
import com.nextcloud.common.NextcloudClient;
|
||||
import com.owncloud.android.authentication.AuthenticatorUrlUtils;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||
|
@ -33,23 +33,26 @@ import com.owncloud.android.lib.resources.status.GetStatusRemoteOperation;
|
|||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
import com.owncloud.android.operations.DetectAuthenticationMethodOperation.AuthenticationMethod;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import org.apache.commons.httpclient.Header;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import kotlin.Pair;
|
||||
|
||||
/**
|
||||
* Get basic information from an ownCloud server given its URL.
|
||||
*
|
||||
* Checks the existence of a configured ownCloud server in the URL, gets its version
|
||||
* and finds out what authentication method is needed to access files in it.
|
||||
* <p>
|
||||
* Checks the existence of a configured ownCloud server in the URL, gets its version and finds out what authentication
|
||||
* method is needed to access files in it.
|
||||
*/
|
||||
|
||||
public class GetServerInfoOperation extends RemoteOperation {
|
||||
public class GetServerInfoOperation extends RemoteOperation<GetServerInfoOperation.ServerInfo> {
|
||||
|
||||
private static final String TAG = GetServerInfoOperation.class.getSimpleName();
|
||||
|
||||
private String mUrl;
|
||||
private Context mContext;
|
||||
private ServerInfo mResultData;
|
||||
private final String mUrl;
|
||||
private final Context mContext;
|
||||
private final ServerInfo mResultData;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -67,44 +70,42 @@ public class GetServerInfoOperation extends RemoteOperation {
|
|||
/**
|
||||
* Performs the operation
|
||||
*
|
||||
* @return Result of the operation. If successful, includes an instance of
|
||||
* {@link ServerInfo} with the information retrieved from the server.
|
||||
* Call {@link RemoteOperationResult#getData()}.get(0) to get it.
|
||||
* @return Result of the operation. If successful, includes an instance of {@link ServerInfo} with the information
|
||||
* retrieved from the server. Call {@link RemoteOperationResult#getResultData()} to get it.
|
||||
*/
|
||||
@Override
|
||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||
@Override
|
||||
public RemoteOperationResult<ServerInfo> run(NextcloudClient client) {
|
||||
|
||||
// first: check the status of the server (including its version)
|
||||
// first: check the status of the server (including its version)
|
||||
GetStatusRemoteOperation getStatus = new GetStatusRemoteOperation(mContext);
|
||||
|
||||
RemoteOperationResult result = getStatus.execute(client);
|
||||
RemoteOperationResult<Pair<OwnCloudVersion, Boolean>> getStatusResult = getStatus.execute(client);
|
||||
RemoteOperationResult<ServerInfo> result = new RemoteOperationResult<>(getStatusResult.isSuccess(),
|
||||
getStatusResult.getHttpCode(),
|
||||
getStatusResult.getHttpPhrase(),
|
||||
new Header[0]);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
if (getStatusResult.isSuccess()) {
|
||||
// second: get authentication method required by the server
|
||||
mResultData.mVersion = (OwnCloudVersion) result.getData().get(0);
|
||||
mResultData.hasExtendedSupport = (boolean) result.getData().get(1);
|
||||
mResultData.mIsSslConn = result.getCode() == ResultCode.OK_SSL;
|
||||
mResultData.mVersion = getStatusResult.getResultData().component1();
|
||||
mResultData.hasExtendedSupport = getStatusResult.getResultData().component2();
|
||||
mResultData.mIsSslConn = getStatusResult.getCode() == ResultCode.OK_SSL;
|
||||
mResultData.mBaseUrl = normalizeProtocolPrefix(mUrl, mResultData.mIsSslConn);
|
||||
RemoteOperationResult detectAuthResult = detectAuthorizationMethod(client);
|
||||
RemoteOperationResult<AuthenticationMethod> detectAuthResult = detectAuthorizationMethod(client);
|
||||
|
||||
// third: merge results
|
||||
if (detectAuthResult.isSuccess()) {
|
||||
mResultData.mAuthMethod = (AuthenticationMethod) detectAuthResult.getData().get(0);
|
||||
ArrayList<Object> data = new ArrayList<Object>();
|
||||
data.add(mResultData);
|
||||
result.setData(data);
|
||||
} else {
|
||||
result = detectAuthResult;
|
||||
}
|
||||
mResultData.mAuthMethod = detectAuthResult.getResultData();
|
||||
result.setResultData(mResultData);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private RemoteOperationResult detectAuthorizationMethod(OwnCloudClient client) {
|
||||
private RemoteOperationResult<AuthenticationMethod> detectAuthorizationMethod(NextcloudClient client) {
|
||||
Log_OC.d(TAG, "Trying empty authorization to detect authentication method");
|
||||
DetectAuthenticationMethodOperation operation =
|
||||
new DetectAuthenticationMethodOperation(mContext);
|
||||
new DetectAuthenticationMethodOperation();
|
||||
return operation.execute(client);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue