X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/bef5d5c5f8ed2851116b83f58bb7373ad8264d05..0f0e210d6979f45a1f9609371bb39cbb5faee6fe:/src/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java diff --git a/src/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java b/src/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java index 50ea4000..4aeff99f 100644 --- a/src/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java +++ b/src/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java @@ -1,24 +1,20 @@ -/* ownCloud Android Library is available under MIT license - * Copyright (C) 2014 ownCloud Inc. - * - * 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. +/** + * ownCloud Android client application + * + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. + * + * 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 . * */ @@ -26,19 +22,17 @@ package com.owncloud.android.operations; import java.util.ArrayList; -import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.methods.HeadMethod; - +import com.owncloud.android.MainApp; import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.OnRemoteOperationListener; 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 com.owncloud.android.lib.resources.files.ExistenceCheckRemoteOperation; import android.content.Context; -import android.net.ConnectivityManager; -import android.util.Log; +import android.net.Uri; /** * Operation to find out what authentication method requires @@ -50,9 +44,7 @@ import android.util.Log; * When successful, the instance of {@link RemoteOperationResult} passed * through {@link OnRemoteOperationListener#onRemoteOperationFinish(RemoteOperation, * RemoteOperationResult)} returns in {@link RemoteOperationResult#getData()} - * a value of {@link AuthenticationMethod}. - * - * @author David A. Velasco + * a value of {@link AuthenticationMethod}. */ public class DetectAuthenticationMethodOperation extends RemoteOperation { @@ -66,55 +58,90 @@ public class DetectAuthenticationMethodOperation extends RemoteOperation { BEARER_TOKEN } - private String mPath; private Context mContext; - private boolean mSuccessIfAbsent; /** * Constructor + * + * @param context Android context of the caller. */ - public DetectAuthenticationMethodOperation() { + 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. + */ @Override protected RemoteOperationResult run(OwnCloudClient client) { - RemoteOperationResult result = new RemoteOperationResult(ResultCode.OK); - ArrayList data = new ArrayList(); - data.add(AuthenticationMethod.UNKNOWN); - result.setData(data); - /* - if (!isOnline()) { - return new RemoteOperationResult(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION); - } RemoteOperationResult result = null; - HeadMethod head = null; - try { - head = new HeadMethod(client.getWebdavUri() + WebdavUtils.encodePath(mPath)); - int status = client.executeMethod(head, TIMEOUT, TIMEOUT); - client.exhaustResponse(head.getResponseBodyAsStream()); - boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) || (status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent); - result = new RemoteOperationResult(success, status, head.getResponseHeaders()); - Log.d(TAG, "Existence check for " + client.getWebdavUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + "finished with HTTP status " + status + (!success?"(FAIL)":"")); - - } catch (Exception e) { - result = new RemoteOperationResult(e); - Log.e(TAG, "Existence check for " + client.getWebdavUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + ": " + result.getLogMessage(), result.getException()); + AuthenticationMethod authMethod = AuthenticationMethod.UNKNOWN; + + RemoteOperation operation = new ExistenceCheckRemoteOperation("", mContext, false); + client.clearCredentials(); + 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 (redirectedLocation != null && redirectedLocation.length() > 0 && + !result.isIdPRedirection()) { + client.setBaseUri(Uri.parse(result.getRedirectedLocation())); + result = operation.execute(client); + redirectedLocation = result.getRedirectedLocation(); + } + + // analyze response + if (result.getCode() == ResultCode.UNAUTHORIZED) { + String authRequest = ((result.getAuthenticateHeader()).trim()).toLowerCase(); + if (authRequest.startsWith("basic")) { + authMethod = AuthenticationMethod.BASIC_HTTP_AUTH; + + } else if (authRequest.startsWith("bearer")) { + authMethod = AuthenticationMethod.BEARER_TOKEN; + } + // else - fall back to UNKNOWN + + } else if (result.isSuccess()) { + authMethod = AuthenticationMethod.NONE; - } finally { - if (head != null) - head.releaseConnection(); + } else if (result.isIdPRedirection()) { + authMethod = AuthenticationMethod.SAML_WEB_SSO; + } + // else - fall back to UNKNOWN + Log_OC.d(TAG, "Authentication method found: " + authenticationMethodToString(authMethod)); + + if (!authMethod.equals(AuthenticationMethod.UNKNOWN)) { + result = new RemoteOperationResult(true, result.getHttpCode(), null); } - */ - return result; + ArrayList data = new ArrayList(); + data.add(authMethod); + result.setData(data); + return result; // same result instance, so that other errors + // can be handled by the caller transparently } - - private boolean isOnline() { - ConnectivityManager cm = (ConnectivityManager) mContext - .getSystemService(Context.CONNECTIVITY_SERVICE); - return cm != null && cm.getActiveNetworkInfo() != null - && cm.getActiveNetworkInfo().isConnectedOrConnecting(); + + + 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"; + } } - }