10552c3330417d1210d0eb8d51722e022734b7d7
[pub/Android/ownCloud.git] / oc_framework / src / com / owncloud / android / lib / network / BearerAuthScheme.java
1 /* ownCloud Android Library is available under MIT license
2 * Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 *
23 */
24
25 package com.owncloud.android.lib.network;
26
27 import java.util.Map;
28
29 import org.apache.commons.httpclient.Credentials;
30 import org.apache.commons.httpclient.HttpMethod;
31 import org.apache.commons.httpclient.auth.AuthChallengeParser;
32 import org.apache.commons.httpclient.auth.AuthScheme;
33 import org.apache.commons.httpclient.auth.AuthenticationException;
34 import org.apache.commons.httpclient.auth.InvalidCredentialsException;
35 import org.apache.commons.httpclient.auth.MalformedChallengeException;
36
37 import android.util.Log;
38
39
40
41 /**
42 * Bearer authentication scheme as defined in RFC 6750.
43 *
44 * @author David A. Velasco
45 */
46
47 public class BearerAuthScheme implements AuthScheme /*extends RFC2617Scheme*/ {
48
49 private static final String TAG = BearerAuthScheme.class.getSimpleName();
50
51 public static final String AUTH_POLICY = "Bearer";
52
53 /** Whether the bearer authentication process is complete */
54 private boolean mComplete;
55
56 /** Authentication parameter map */
57 @SuppressWarnings("rawtypes")
58 private Map mParams = null;
59
60
61 /**
62 * Default constructor for the bearer authentication scheme.
63 */
64 public BearerAuthScheme() {
65 mComplete = false;
66 }
67
68 /**
69 * Constructor for the basic authentication scheme.
70 *
71 * @param challenge Authentication challenge
72 *
73 * @throws MalformedChallengeException Thrown if the authentication challenge is malformed
74 *
75 * @deprecated Use parameterless constructor and {@link AuthScheme#processChallenge(String)} method
76 */
77 public BearerAuthScheme(final String challenge) throws MalformedChallengeException {
78 processChallenge(challenge);
79 mComplete = true;
80 }
81
82 /**
83 * Returns textual designation of the bearer authentication scheme.
84 *
85 * @return "Bearer"
86 */
87 public String getSchemeName() {
88 return "bearer";
89 }
90
91 /**
92 * Processes the Bearer challenge.
93 *
94 * @param challenge The challenge string
95 *
96 * @throws MalformedChallengeException Thrown if the authentication challenge is malformed
97 */
98 public void processChallenge(String challenge) throws MalformedChallengeException {
99 String s = AuthChallengeParser.extractScheme(challenge);
100 if (!s.equalsIgnoreCase(getSchemeName())) {
101 throw new MalformedChallengeException(
102 "Invalid " + getSchemeName() + " challenge: " + challenge);
103 }
104 mParams = AuthChallengeParser.extractParams(challenge);
105 mComplete = true;
106 }
107
108 /**
109 * Tests if the Bearer authentication process has been completed.
110 *
111 * @return 'true' if Bearer authorization has been processed, 'false' otherwise.
112 */
113 public boolean isComplete() {
114 return this.mComplete;
115 }
116
117 /**
118 * Produces bearer authorization string for the given set of
119 * {@link Credentials}.
120 *
121 * @param credentials The set of credentials to be used for authentication
122 * @param method Method name is ignored by the bearer authentication scheme
123 * @param uri URI is ignored by the bearer authentication scheme
124 * @throws InvalidCredentialsException If authentication credentials are not valid or not applicable
125 * for this authentication scheme
126 * @throws AuthenticationException If authorization string cannot be generated due to an authentication failure
127 * @return A bearer authorization string
128 *
129 * @deprecated Use {@link #authenticate(Credentials, HttpMethod)}
130 */
131 public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException {
132 Log.d(TAG, "enter BearerScheme.authenticate(Credentials, String, String)");
133
134 BearerCredentials bearer = null;
135 try {
136 bearer = (BearerCredentials) credentials;
137 } catch (ClassCastException e) {
138 throw new InvalidCredentialsException(
139 "Credentials cannot be used for bearer authentication: "
140 + credentials.getClass().getName());
141 }
142 return BearerAuthScheme.authenticate(bearer);
143 }
144
145
146 /**
147 * Returns 'false'. Bearer authentication scheme is request based.
148 *
149 * @return 'false'.
150 */
151 public boolean isConnectionBased() {
152 return false;
153 }
154
155 /**
156 * Produces bearer authorization string for the given set of {@link Credentials}.
157 *
158 * @param credentials The set of credentials to be used for authentication
159 * @param method The method being authenticated
160 * @throws InvalidCredentialsException If authentication credentials are not valid or not applicable for this authentication
161 * scheme.
162 * @throws AuthenticationException If authorization string cannot be generated due to an authentication failure.
163 *
164 * @return a basic authorization string
165 */
166 public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
167 Log.d(TAG, "enter BearerScheme.authenticate(Credentials, HttpMethod)");
168
169 if (method == null) {
170 throw new IllegalArgumentException("Method may not be null");
171 }
172 BearerCredentials bearer = null;
173 try {
174 bearer = (BearerCredentials) credentials;
175 } catch (ClassCastException e) {
176 throw new InvalidCredentialsException(
177 "Credentials cannot be used for bearer authentication: "
178 + credentials.getClass().getName());
179 }
180 return BearerAuthScheme.authenticate(
181 bearer,
182 method.getParams().getCredentialCharset());
183 }
184
185 /**
186 * @deprecated Use {@link #authenticate(BearerCredentials, String)}
187 *
188 * Returns a bearer Authorization header value for the given
189 * {@link BearerCredentials}.
190 *
191 * @param credentials The credentials to encode.
192 *
193 * @return A bearer authorization string
194 */
195 public static String authenticate(BearerCredentials credentials) {
196 return authenticate(credentials, "ISO-8859-1");
197 }
198
199 /**
200 * Returns a bearer Authorization header value for the given
201 * {@link BearerCredentials} and charset.
202 *
203 * @param credentials The credentials to encode.
204 * @param charset The charset to use for encoding the credentials
205 *
206 * @return A bearer authorization string
207 *
208 * @since 3.0
209 */
210 public static String authenticate(BearerCredentials credentials, String charset) {
211 Log.d(TAG, "enter BearerAuthScheme.authenticate(BearerCredentials, String)");
212
213 if (credentials == null) {
214 throw new IllegalArgumentException("Credentials may not be null");
215 }
216 if (charset == null || charset.length() == 0) {
217 throw new IllegalArgumentException("charset may not be null or empty");
218 }
219 StringBuffer buffer = new StringBuffer();
220 buffer.append(credentials.getAccessToken());
221
222 //return "Bearer " + EncodingUtil.getAsciiString(EncodingUtil.getBytes(buffer.toString(), charset));
223 return "Bearer " + buffer.toString();
224 }
225
226 /**
227 * Returns a String identifying the authentication challenge. This is
228 * used, in combination with the host and port to determine if
229 * authorization has already been attempted or not. Schemes which
230 * require multiple requests to complete the authentication should
231 * return a different value for each stage in the request.
232 *
233 * Additionally, the ID should take into account any changes to the
234 * authentication challenge and return a different value when appropriate.
235 * For example when the realm changes in basic authentication it should be
236 * considered a different authentication attempt and a different value should
237 * be returned.
238 *
239 * This method simply returns the realm for the challenge.
240 *
241 * @return String a String identifying the authentication challenge.
242 *
243 * @deprecated no longer used
244 */
245 @Override
246 public String getID() {
247 return getRealm();
248 }
249
250 /**
251 * Returns authentication parameter with the given name, if available.
252 *
253 * @param name The name of the parameter to be returned
254 *
255 * @return The parameter with the given name
256 */
257 @Override
258 public String getParameter(String name) {
259 if (name == null) {
260 throw new IllegalArgumentException("Parameter name may not be null");
261 }
262 if (mParams == null) {
263 return null;
264 }
265 return (String) mParams.get(name.toLowerCase());
266 }
267
268 /**
269 * Returns authentication realm. The realm may not be null.
270 *
271 * @return The authentication realm
272 */
273 @Override
274 public String getRealm() {
275 return getParameter("realm");
276 }
277
278 }