authomatic/providers/oauth2.py
def create_request_elements(
            cls, request_type, credentials, url, method='GET', params=None,
            headers=None, body='', secret=None, redirect_uri='', scope='',
            csrf='', user_state=''
    ):
        """
        Creates |oauth2| request elements.
        """

        headers = headers or {}
        params = params or {}

        consumer_key = credentials.consumer_key or ''
        consumer_secret = credentials.consumer_secret or ''
        token = credentials.token or ''
        refresh_token = credentials.refresh_token or credentials.token or ''

        # Separate url base and query parameters.
        url, base_params = cls._split_url(url)

        # Add params extracted from URL.
        params.update(dict(base_params))

        if request_type == cls.USER_AUTHORIZATION_REQUEST_TYPE:
            # User authorization request.
            # TODO: Raise error for specific message for each missing argument.
            if consumer_key and redirect_uri and (
                    csrf or not cls.supports_csrf_protection):
                params['client_id'] = consumer_key
                params['redirect_uri'] = redirect_uri
                params['scope'] = scope
                if cls.supports_user_state:
                    params['state'] = base64.urlsafe_b64encode(
                        json.dumps(
                            {"csrf": csrf, "user_state": user_state}
                        ).encode('utf-8')
                    )
                else:
                    params['state'] = csrf
                params['response_type'] = 'code'

                # Add authorization header
                headers.update(cls._authorization_header(credentials))
            else:
                raise OAuth2Error(
                    'Credentials with valid consumer_key and arguments '
                    'redirect_uri, scope and state are required to create '
                    'OAuth 2.0 user authorization request elements!')

        elif request_type == cls.ACCESS_TOKEN_REQUEST_TYPE:
            # Access token request.
            if consumer_key and consumer_secret:
                params['code'] = token
                params['client_id'] = consumer_key
                params['client_secret'] = consumer_secret
                params['redirect_uri'] = redirect_uri
                params['grant_type'] = 'authorization_code'

                # TODO: Check whether all providers accept it
                headers.update(cls._authorization_header(credentials))
            else:
                raise OAuth2Error(
                    'Credentials with valid token, consumer_key, '
                    'consumer_secret and argument redirect_uri are required '
                    'to create OAuth 2.0 access token request elements!')

        elif request_type == cls.REFRESH_TOKEN_REQUEST_TYPE:
            # Refresh access token request.
            if refresh_token and consumer_key and consumer_secret:
                params['refresh_token'] = refresh_token
                params['client_id'] = consumer_key
                params['client_secret'] = consumer_secret
                params['grant_type'] = 'refresh_token'
            else:
                raise OAuth2Error(
                    'Credentials with valid refresh_token, consumer_key, '
                    'consumer_secret are required to create OAuth 2.0 '
                    'refresh token request elements!')

        elif request_type == cls.PROTECTED_RESOURCE_REQUEST_TYPE:
            # Protected resource request.

            # Add Authorization header. See:
            # http://tools.ietf.org/html/rfc6749#section-7.1
            if credentials.token_type == cls.BEARER:
                # http://tools.ietf.org/html/rfc6750#section-2.1
                headers.update(
                    {'Authorization': 'Bearer {0}'.format(credentials.token)})

            elif token:
                params['access_token'] = token
            else:
                raise OAuth2Error(
                    'Credentials with valid token are required to create '
                    'OAuth 2.0 protected resources request elements!')

        request_elements = core.RequestElements(
            url, method, params, headers, body)

        return cls._x_request_elements_filter(
            request_type, request_elements, credentials)
def create_request_elements(
            cls, request_type, credentials, url, method='GET', params=None,
            headers=None, body='', secret=None, redirect_uri='', scope='',
            csrf='', user_state=''
    ):
        """
        Creates |oauth2| request elements.
        """

        headers = headers or {}
        params = params or {}

        consumer_key = credentials.consumer_key or ''
        consumer_secret = credentials.consumer_secret or ''
        token = credentials.token or ''
        refresh_token = credentials.refresh_token or credentials.token or ''

        # Separate url base and query parameters.
        url, base_params = cls._split_url(url)

        # Add params extracted from URL.
        params.update(dict(base_params))

        if request_type == cls.USER_AUTHORIZATION_REQUEST_TYPE:
            # User authorization request.
            # TODO: Raise error for specific message for each missing argument.
            if consumer_key and redirect_uri and (
                    csrf or not cls.supports_csrf_protection):
                params['client_id'] = consumer_key
                params['redirect_uri'] = redirect_uri
                params['scope'] = scope
                if cls.supports_user_state:
                    params['state'] = base64.urlsafe_b64encode(
                        json.dumps(
                            {"csrf": csrf, "user_state": user_state}
                        ).encode('utf-8')
                    )
                else:
                    params['state'] = csrf
                params['response_type'] = 'code'

                # Add authorization header
                headers.update(cls._authorization_header(credentials))
            else:
                raise OAuth2Error(
                    'Credentials with valid consumer_key and arguments '
                    'redirect_uri, scope and state are required to create '
                    'OAuth 2.0 user authorization request elements!')

        elif request_type == cls.ACCESS_TOKEN_REQUEST_TYPE:
            # Access token request.
            if consumer_key and consumer_secret:
                params['code'] = token
                params['client_id'] = consumer_key
                params['client_secret'] = consumer_secret
                params['redirect_uri'] = redirect_uri
                params['grant_type'] = 'authorization_code'

                # TODO: Check whether all providers accept it
                headers.update(cls._authorization_header(credentials))
            else:
                raise OAuth2Error(
                    'Credentials with valid token, consumer_key, '
                    'consumer_secret and argument redirect_uri are required '
                    'to create OAuth 2.0 access token request elements!')

        elif request_type == cls.REFRESH_TOKEN_REQUEST_TYPE:
            # Refresh access token request.
            if refresh_token and consumer_key and consumer_secret:
                params['refresh_token'] = refresh_token
                params['client_id'] = consumer_key
                params['client_secret'] = consumer_secret
                params['grant_type'] = 'refresh_token'
            else:
                raise OAuth2Error(
                    'Credentials with valid refresh_token, consumer_key, '
                    'consumer_secret are required to create OAuth 2.0 '
                    'refresh token request elements!')

        elif request_type == cls.PROTECTED_RESOURCE_REQUEST_TYPE:
            # Protected resource request.

            # Add Authorization header. See:
            # http://tools.ietf.org/html/rfc6749#section-7.1
            if credentials.token_type == cls.BEARER:
                # http://tools.ietf.org/html/rfc6750#section-2.1
                headers.update(
                    {'Authorization': 'Bearer {0}'.format(credentials.token)})

            elif token:
                params['access_token'] = token
            else:
                raise OAuth2Error(
                    'Credentials with valid token are required to create '
                    'OAuth 2.0 protected resources request elements!')

        request_elements = core.RequestElements(
            url, method, params, headers, body)

        return cls._x_request_elements_filter(
            request_type, request_elements, credentials)
Creates |oauth2| request elements.