Source code for flask_dance.consumer.oauth1

from __future__ import unicode_literals, print_function

import logging
from lazy import lazy
from flask import request, url_for, redirect
from urlobject import URLObject
from requests_oauthlib import OAuth1Session as BaseOAuth1Session
from oauthlib.oauth1 import SIGNATURE_HMAC, SIGNATURE_TYPE_AUTH_HEADER
from oauthlib.common import to_unicode
from .base import BaseOAuthConsumerBlueprint, oauth_authorized, oauth_error
from .requests import OAuth1Session

log = logging.getLogger(__name__)


[docs]class OAuth1ConsumerBlueprint(BaseOAuthConsumerBlueprint): """ A subclass of :class:`flask.Blueprint` that sets up OAuth 1 authentication. """
[docs] def __init__(self, name, import_name, client_key=None, client_secret=None, signature_method=SIGNATURE_HMAC, signature_type=SIGNATURE_TYPE_AUTH_HEADER, rsa_key=None, client_class=None, force_include_body=False, static_folder=None, static_url_path=None, template_folder=None, url_prefix=None, subdomain=None, url_defaults=None, root_path=None, login_url=None, authorized_url=None, base_url=None, request_token_url=None, authorization_url=None, access_token_url=None, redirect_url=None, redirect_to=None, session_class=None, backend=None, **kwargs): """ Most of the constructor arguments are forwarded either to the :class:`flask.Blueprint` constructor or the :class:`requests_oauthlib.OAuth1Session` construtor, including ``**kwargs`` (which is forwarded to :class:`~requests_oauthlib.OAuth1Session`). Only the arguments that are relevant to Flask-Dance are documented here. Args: base_url: The base URL of the OAuth provider. If specified, all URLs passed to this instance will be resolved relative to this URL. request_token_url: The URL specified by the OAuth provider for obtaining a `request token <http://oauth.net/core/1.0a/#auth_step1>`_. This can be an fully-qualified URL, or a path that is resolved relative to the ``base_url``. authorization_url: The URL specified by the OAuth provider for the user to `grant token authorization <http://oauth.net/core/1.0a/#auth_step2>`_. This can be an fully-qualified URL, or a path that is resolved relative to the ``base_url``. access_token_url: The URL specified by the OAuth provider for obtaining an `access token <http://oauth.net/core/1.0a/#auth_step3>`_. This can be an fully-qualified URL, or a path that is resolved relative to the ``base_url``. login_url: The URL route for the ``login`` view that kicks off the OAuth dance. This string will be :ref:`formatted <python:formatstrings>` with the instance so that attributes can be interpolated. Defaults to ``/{bp.name}``, so that the URL is based on the name of the blueprint. authorized_url: The URL route for the ``authorized`` view that completes the OAuth dance. This string will be :ref:`formatted <python:formatstrings>` with the instance so that attributes can be interpolated. Defaults to ``/{bp.name}/authorized``, so that the URL is based on the name of the blueprint. redirect_url: When the OAuth dance is complete, redirect the user to this URL. redirect_to: When the OAuth dance is complete, redirect the user to the URL obtained by calling :func:`~flask.url_for` with this argument. If you do not specify either ``redirect_url`` or ``redirect_to``, the user will be redirected to the root path (``/``). session_class: The class to use for creating a Requests session. Defaults to :class:`~flask_dance.consumer.requests.OAuth1Session`. backend: A storage backend class, or an instance of a storage backend class, to use for this blueprint. Defaults to :class:`~flask_dance.consumer.backend.session.SessionBackend`. """ BaseOAuthConsumerBlueprint.__init__( self, name, import_name, static_folder=static_folder, static_url_path=static_url_path, template_folder=template_folder, url_prefix=url_prefix, subdomain=subdomain, url_defaults=url_defaults, root_path=root_path, login_url=login_url, authorized_url=authorized_url, backend=backend, ) self.base_url = base_url self.session_class = session_class or OAuth1Session # passed to OAuth1Session() self.client_key = client_key self.client_secret = client_secret self.signature_method = signature_method self.signature_type = signature_type self.rsa_key = rsa_key self.client_class = client_class self.force_include_body = force_include_body self.kwargs = kwargs # used by view functions self.request_token_url = request_token_url self.authorization_url = authorization_url self.access_token_url = access_token_url self.redirect_url = redirect_url self.redirect_to = redirect_to self.teardown_app_request(self.teardown_session)
@lazy
[docs] def session(self): return self.session_class( client_key=self.client_key, client_secret=self.client_secret, signature_method=self.signature_method, signature_type=self.signature_type, rsa_key=self.rsa_key, client_class=self.client_class, force_include_body=self.force_include_body, blueprint=self, base_url=self.base_url, **self.kwargs )
def teardown_session(self, exception=None): lazy.invalidate(self, "session") def login(self): callback_uri = url_for( ".authorized", next=request.args.get('next'), _external=True, ) self.session._client.client.callback_uri = to_unicode(callback_uri) self.session.fetch_request_token(self.request_token_url) url = self.session.authorization_url(self.authorization_url) return redirect(url) def authorized(self): if "next" in request.args: next_url = request.args["next"] elif self.redirect_url: next_url = self.redirect_url elif self.redirect_to: next_url = url_for(self.redirect_to) else: next_url = "/" self.session.parse_authorization_response(request.url) try: token = self.session.fetch_access_token(self.access_token_url) except ValueError as err: # can't proceed with OAuth, have to just redirect to next_url message = err.args[0] response = getattr(err, "response", None) log.warning("OAuth 1 access token error: %s", message) oauth_error.send(self, message=message, response=response) return redirect(next_url) results = oauth_authorized.send(self, token=token) or [] if not any(ret == False for func, ret in results): self.token = token return redirect(next_url)