Skip to content

Commit

Permalink
Added a new extension for oauth2 providers that integrates with flask.
Browse files Browse the repository at this point in the history
Modified the existing scopes argument for django provider so that it now will
accept a function as well as a list object. This is done so that scopes can be dynamically
set.
  • Loading branch information
flippmoke committed May 7, 2013
1 parent 2cfcc6a commit 7b00c4d
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ Silas Snider
Tom Christie
Chez
Ondrej Slinták
Mackenzie Thompson
116 changes: 116 additions & 0 deletions oauthlib/oauth2/ext/flask.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import
from flask import abort, g, make_response, redirect, request, session
import functools
import logging
from oauthlib.common import urlencode
from oauthlib.oauth2.draft25 import errors

log = logging.getLogger('oauthlib')


class OAuth2ProviderDecorator(object):

def __init__(self, error_uri, server=None, authorization_endpoint=None,
token_endpoint=None, resource_endpoint=None):
self._authorization_endpoint = authorization_endpoint or server
self._token_endpoint = token_endpoint or server
self._resource_endpoint = resource_endpoint or server
self._error_uri = error_uri

def _extract_params(self):
log.debug('Extracting parameters from request.')
uri = request.url
http_method = request.method
headers = dict(request.headers)
if 'wsgi.input' in headers:
del headers['wsgi.input']
if 'wsgi.errors' in headers:
del headers['wsgi.errors']
if 'HTTP_AUTHORIZATION' in headers:
headers['Authorization'] = headers['HTTP_AUTHORIZATION']
body = urlencode(request.form.items())
return uri, http_method, body, headers

def pre_authorization_view(self, f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
uri, http_method, body, headers = self._extract_params()
redirect_uri = request.args.get('redirect_uri', None)
log.debug('Found redirect uri %s.', redirect_uri)
try:
scopes, credentials = self._authorization_endpoint.validate_authorization_request(
uri, http_method, body, headers)
log.debug('Saving credentials to session, %r.', credentials)
session['oauth2_credentials'] = credentials
kwargs['scopes'] = scopes
kwargs.update(credentials)
log.debug('Invoking view method, %r.', f)
return f(*args, **kwargs)

except errors.FatalClientError as e:
log.debug('Fatal client error, redirecting to error page.')
return redirect(e.in_uri(self._error_uri))
return wrapper

def post_authorization_view(self, f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
uri, http_method, body, headers = self._extract_params()
scopes, credentials = f(*args, **kwargs)
log.debug('Fetched credentials view, %r.', credentials)
credentials.update(request.session.get('oauth2_credentials', {}))
log.debug('Fetched credentials from session, %r.', credentials)
redirect_uri = credentials.get('redirect_uri')
log.debug('Found redirect uri %s.', redirect_uri)
try:
url, headers, body, status = self._authorization_endpoint.create_authorization_response(
uri, http_method, body, headers, scopes, credentials)
log.debug('Authorization successful, redirecting to client.')
return redirect(url)
except errors.FatalClientError as e:
log.debug('Fatal client error, redirecting to error page.')
return redirect(e.in_uri(self._error_uri))
except errors.OAuth2Error as e:
log.debug('Client error, redirecting back to client.')
return redirect(e.in_uri(redirect_uri))

return wrapper

def access_token_view(self, f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
uri, http_method, body, headers = self._extract_params()
credentials = f(*args, **kwargs)
log.debug('Fetched credentials view, %r.', credentials)
url, headers, body, status = self._token_endpoint.create_token_response(
uri, http_method, body, headers, credentials)
response = make_response(body, status)
for k, v in headers.items():
response.headers[k] = v
return response
return wrapper

def protected_resource_view(self, scopes=None, forbidden=None):
def decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
try:
scopes_list = scopes()
except TypeError:
scopes_list = scopes
uri, http_method, body, headers = self._extract_params()
valid, r = self._resource_endpoint.verify_request(
uri, http_method, body, headers, scopes_list)
g.client = r.client
g.user = r.user
g.scopes = r.scopes
g.token_scopes = r.token_scopes
if valid:
return f(*args, **kwargs)
elif forbidden is not None:
return forbidden()
else:
abort(401)
return wrapper
return decorator

0 comments on commit 7b00c4d

Please sign in to comment.