2 * ownCloud Android client application
4 * @author David A. Velasco
5 * Copyright (C) 2015 ownCloud Inc.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2,
9 * as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 package com
.owncloud
.android
.operations
;
23 import java
.util
.ArrayList
;
25 import com
.owncloud
.android
.MainApp
;
26 import com
.owncloud
.android
.lib
.common
.OwnCloudClient
;
27 import com
.owncloud
.android
.lib
.common
.operations
.OnRemoteOperationListener
;
28 import com
.owncloud
.android
.lib
.common
.operations
.RemoteOperation
;
29 import com
.owncloud
.android
.lib
.common
.operations
.RemoteOperationResult
;
30 import com
.owncloud
.android
.lib
.common
.operations
.RemoteOperationResult
.ResultCode
;
31 import com
.owncloud
.android
.lib
.common
.utils
.Log_OC
;
32 import com
.owncloud
.android
.lib
.resources
.files
.ExistenceCheckRemoteOperation
;
34 import android
.content
.Context
;
35 import android
.net
.Uri
;
38 * Operation to find out what authentication method requires
39 * the server to access files.
41 * Basically, tries to access to the root folder without authorization
42 * and analyzes the response.
44 * When successful, the instance of {@link RemoteOperationResult} passed
45 * through {@link OnRemoteOperationListener#onRemoteOperationFinish(RemoteOperation,
46 * RemoteOperationResult)} returns in {@link RemoteOperationResult#getData()}
47 * a value of {@link AuthenticationMethod}.
49 public class DetectAuthenticationMethodOperation
extends RemoteOperation
{
51 private static final String TAG
= DetectAuthenticationMethodOperation
.class.getSimpleName();
53 public enum AuthenticationMethod
{
61 private Context mContext
;
66 * @param context Android context of the caller.
68 public DetectAuthenticationMethodOperation(Context context
) {
74 * Performs the operation.
76 * Triggers a check of existence on the root folder of the server, granting
77 * that the request is not authenticated.
79 * Analyzes the result of check to find out what authentication method, if
80 * any, is requested by the server.
83 protected RemoteOperationResult
run(OwnCloudClient client
) {
84 RemoteOperationResult result
= null
;
85 AuthenticationMethod authMethod
= AuthenticationMethod
.UNKNOWN
;
87 RemoteOperation operation
= new ExistenceCheckRemoteOperation("", mContext
, false
);
88 client
.clearCredentials();
89 client
.setFollowRedirects(false
);
91 // try to access the root folder, following redirections but not SAML SSO redirections
92 result
= operation
.execute(client
);
93 String redirectedLocation
= result
.getRedirectedLocation();
94 while (redirectedLocation
!= null
&& redirectedLocation
.length() > 0 &&
95 !result
.isIdPRedirection()) {
96 client
.setBaseUri(Uri
.parse(result
.getRedirectedLocation()));
97 result
= operation
.execute(client
);
98 redirectedLocation
= result
.getRedirectedLocation();
102 if (result
.getCode() == ResultCode
.UNAUTHORIZED
) {
103 String authRequest
= ((result
.getAuthenticateHeader()).trim()).toLowerCase();
104 if (authRequest
.startsWith("basic")) {
105 authMethod
= AuthenticationMethod
.BASIC_HTTP_AUTH
;
107 } else if (authRequest
.startsWith("bearer")) {
108 authMethod
= AuthenticationMethod
.BEARER_TOKEN
;
110 // else - fall back to UNKNOWN
112 } else if (result
.isSuccess()) {
113 authMethod
= AuthenticationMethod
.NONE
;
115 } else if (result
.isIdPRedirection()) {
116 authMethod
= AuthenticationMethod
.SAML_WEB_SSO
;
118 // else - fall back to UNKNOWN
119 Log_OC
.d(TAG
, "Authentication method found: " + authenticationMethodToString(authMethod
));
121 if (!authMethod
.equals(AuthenticationMethod
.UNKNOWN
)) {
122 result
= new RemoteOperationResult(true
, result
.getHttpCode(), null
);
124 ArrayList
<Object
> data
= new ArrayList
<Object
>();
125 data
.add(authMethod
);
126 result
.setData(data
);
127 return result
; // same result instance, so that other errors
128 // can be handled by the caller transparently
132 private String
authenticationMethodToString(AuthenticationMethod value
) {
136 case BASIC_HTTP_AUTH
:
137 return "BASIC_HTTP_AUTH";
139 return "BEARER_TOKEN";
141 return "SAML_WEB_SSO";