Artifact Content
Not logged in

Artifact 52a0c0888d35c3c6ff93c857be4ab1386d6737f8:


/* ownCloud Android Library is available under MIT license
 *   Copyright (C) 2015 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.
 *
 */

package com.owncloud.android.lib.common.network;

import java.util.Map;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.auth.AuthChallengeParser;
import org.apache.commons.httpclient.auth.AuthScheme;
import org.apache.commons.httpclient.auth.AuthenticationException;
import org.apache.commons.httpclient.auth.InvalidCredentialsException;
import org.apache.commons.httpclient.auth.MalformedChallengeException;

import com.owncloud.android.lib.common.utils.Log_OC;



/**
 * Bearer authentication scheme as defined in RFC 6750.
 * 
 * @author David A. Velasco
 */

public class BearerAuthScheme implements AuthScheme /*extends RFC2617Scheme*/ {
    
    private static final String TAG = BearerAuthScheme.class.getSimpleName();

    public static final String AUTH_POLICY = "Bearer";
    
    /** Whether the bearer authentication process is complete */
    private boolean mComplete;
    
    /** Authentication parameter map */
    @SuppressWarnings("rawtypes")
	private Map mParams = null;
    
    
    /**
     * Default constructor for the bearer authentication scheme.
     */
    public BearerAuthScheme() {
        mComplete = false;
    }

    /**
     * Constructor for the basic authentication scheme.
     * 
     * @param   challenge                       Authentication challenge
     * 
     * @throws  MalformedChallengeException     Thrown if the authentication challenge is malformed
     * 
     * @deprecated Use parameterless constructor and {@link AuthScheme#processChallenge(String)} method
     */
    public BearerAuthScheme(final String challenge) throws MalformedChallengeException {
        processChallenge(challenge);
        mComplete = true;
    }

    /**
     * Returns textual designation of the bearer authentication scheme.
     * 
     * @return "Bearer"
     */
    public String getSchemeName() {
        return "bearer";
    }

    /**
     * Processes the Bearer challenge.
     *  
     * @param   challenge                   The challenge string
     * 
     * @throws MalformedChallengeException  Thrown if the authentication challenge is malformed
     */
    public void processChallenge(String challenge) throws MalformedChallengeException {
        String s = AuthChallengeParser.extractScheme(challenge);
        if (!s.equalsIgnoreCase(getSchemeName())) {
            throw new MalformedChallengeException(
              "Invalid " + getSchemeName() + " challenge: " + challenge); 
        }
        mParams = AuthChallengeParser.extractParams(challenge);
        mComplete = true;
    }

    /**
     * Tests if the Bearer authentication process has been completed.
     * 
     * @return 'true' if Bearer authorization has been processed, 'false' otherwise.
     */
    public boolean isComplete() {
        return this.mComplete;
    }

    /**
     * Produces bearer authorization string for the given set of 
     * {@link Credentials}.
     * 
     * @param   credentials                     The set of credentials to be used for authentication
     * @param   method                          Method name is ignored by the bearer authentication scheme
     * @param   uri                             URI is ignored by the bearer authentication scheme
     * @throws  InvalidCredentialsException     If authentication credentials are not valid or not applicable 
     *                                          for this authentication scheme
     * @throws  AuthenticationException         If authorization string cannot be generated due to an authentication failure
     * @return  A bearer authorization string
     * 
     * @deprecated Use {@link #authenticate(Credentials, HttpMethod)}
     */
    public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException {
        Log_OC.d(TAG, "enter BearerScheme.authenticate(Credentials, String, String)");

        BearerCredentials bearer = null;
        try {
            bearer = (BearerCredentials) credentials;
        } catch (ClassCastException e) {
            throw new InvalidCredentialsException(
             "Credentials cannot be used for bearer authentication: " 
              + credentials.getClass().getName());
        }
        return BearerAuthScheme.authenticate(bearer);
    }

    
    /**
     * Returns 'false'. Bearer authentication scheme is request based.
     * 
     * @return 'false'.
     */
    public boolean isConnectionBased() {
        return false;    
    }

    /**
     * Produces bearer authorization string for the given set of {@link Credentials}.
     * 
     * @param   credentials                     The set of credentials to be used for authentication
     * @param   method                          The method being authenticated
     * @throws  InvalidCredentialsException     If authentication credentials are not valid or not applicable for this authentication 
     *                                          scheme.
     * @throws AuthenticationException         If authorization string cannot be generated due to an authentication failure.
     * 
     * @return a basic authorization string
     */
    public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
        Log_OC.d(TAG, "enter BearerScheme.authenticate(Credentials, HttpMethod)");

        if (method == null) {
            throw new IllegalArgumentException("Method may not be null");
        }
        BearerCredentials bearer = null;
        try {
            bearer = (BearerCredentials) credentials;
        } catch (ClassCastException e) {
            throw new InvalidCredentialsException(
                    "Credentials cannot be used for bearer authentication: " 
                    + credentials.getClass().getName());
        }
        return BearerAuthScheme.authenticate(
            bearer, 
            method.getParams().getCredentialCharset());
    }
    
    /**
     * @deprecated Use {@link #authenticate(BearerCredentials, String)}
     * 
     * Returns a bearer Authorization header value for the given 
     * {@link BearerCredentials}.
     * 
     * @param   credentials     The credentials to encode.
     * 
     * @return                  A bearer authorization string
     */
    public static String authenticate(BearerCredentials credentials) {
        return authenticate(credentials, "ISO-8859-1");
    }

    /**
     * Returns a bearer Authorization header value for the given 
     * {@link BearerCredentials} and charset.
     * 
     * @param   credentials         The credentials to encode.
     * @param   charset             The charset to use for encoding the credentials
     * 
     * @return                      A bearer authorization string
     * 
     * @since 3.0
     */
    public static String authenticate(BearerCredentials credentials, String charset) {
        Log_OC.d(TAG, "enter BearerAuthScheme.authenticate(BearerCredentials, String)");

        if (credentials == null) {
            throw new IllegalArgumentException("Credentials may not be null"); 
        }
        if (charset == null || charset.length() == 0) {
            throw new IllegalArgumentException("charset may not be null or empty");
        }
        StringBuffer buffer = new StringBuffer();
        buffer.append(credentials.getAccessToken());
        
        //return "Bearer " + EncodingUtil.getAsciiString(EncodingUtil.getBytes(buffer.toString(), charset));
        return "Bearer " + buffer.toString();
    }

    /**
     * Returns a String identifying the authentication challenge.  This is
     * used, in combination with the host and port to determine if
     * authorization has already been attempted or not.  Schemes which
     * require multiple requests to complete the authentication should
     * return a different value for each stage in the request.
     * 
     * Additionally, the ID should take into account any changes to the
     * authentication challenge and return a different value when appropriate.
     * For example when the realm changes in basic authentication it should be
     * considered a different authentication attempt and a different value should
     * be returned.
     * 
     * This method simply returns the realm for the challenge.
     * 
     * @return String       a String identifying the authentication challenge.
     * 
     * @deprecated no longer used
     */
    @Override
    public String getID() {
        return getRealm();
    }

    /**
     * Returns authentication parameter with the given name, if available.
     * 
     * @param   name    The name of the parameter to be returned
     * 
     * @return          The parameter with the given name
     */
    @Override
    public String getParameter(String name) {
        if (name == null) {
            throw new IllegalArgumentException("Parameter name may not be null"); 
        }
        if (mParams == null) {
            return null;
        }
        return (String) mParams.get(name.toLowerCase());
    }

    /**
     * Returns authentication realm. The realm may not be null.
     * 
     * @return  The authentication realm
     */
    @Override
    public String getRealm() {
        return getParameter("realm");
    }
    
}