forked from oauthlib/oauthlib
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a new extension for oauth2 providers that integrates with flask.
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
Showing
2 changed files
with
117 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,4 @@ Silas Snider | |
Tom Christie | ||
Chez | ||
Ondrej Slinták | ||
Mackenzie Thompson |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |