From 88a9662be4f97da5b04a3842c8d0caa2652be355 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Fri, 21 Sep 2012 13:02:35 +0200 Subject: Added client registration caps to OAuth plugin THE MIGRATIONS SUPPLIED WITH THIS COMMIT WILL DROP AND RE-CREATE YOUR oauth__tokens AND oauth__codes TABLES. ALL YOUR OAUTH CODES AND TOKENS WILL BE LOST. - Fixed pylint issues in db/sql/migrations. - Added __repr__ to the User model. - Added _disable_cors option to json_response. - Added crude error handling to the api.tools.api_auth decorator - Updated the OAuth README. - Added client registration, client overview, connection overview, client authorization views and templates. - Added error handling to the OAuthAuth Auth object. - Added AuthorizationForm, ClientRegistrationForm in oauth/forms. - Added migrations for OAuth, added client registration migration. - Added OAuthClient, OAuthUserClient models. - Added oauth/tools with require_client_auth decorator method. --- mediagoblin/plugins/oauth/tools.py | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 mediagoblin/plugins/oauth/tools.py (limited to 'mediagoblin/plugins/oauth/tools.py') diff --git a/mediagoblin/plugins/oauth/tools.py b/mediagoblin/plugins/oauth/tools.py new file mode 100644 index 00000000..d21c8a5b --- /dev/null +++ b/mediagoblin/plugins/oauth/tools.py @@ -0,0 +1,43 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from functools import wraps + +from mediagoblin.plugins.oauth.models import OAuthClient +from mediagoblin.plugins.api.tools import json_response + + +def require_client_auth(controller): + @wraps(controller) + def wrapper(request, *args, **kw): + if not request.GET.get('client_id'): + return json_response({ + 'status': 400, + 'errors': [u'No client identifier in URL']}, + _disable_cors=True) + + client = OAuthClient.query.filter( + OAuthClient.identifier == request.GET.get('client_id')).first() + + if not client: + return json_response({ + 'status': 400, + 'errors': [u'No such client identifier']}, + _disable_cors=True) + + return controller(request, client) + + return wrapper -- cgit v1.2.3 From c121a7d3d0c48d4e3abf43c06047dde3e25616c3 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Sun, 10 Mar 2013 22:52:07 +0100 Subject: OAuth: Support refresh tokens, etc Initially I was going to write a failing test for refresh tokens. Thus this fix includes an orphaned 'expect_failure' method in test utils. I ended up writing support for OAuth refresh tokens, as well as a lot of cleanup (hopefully) in the OAuth plugin code. **Rebase**: While waiting for this stuff to be merged, the testing framework changed, it comes with batteries included regarding fails. Removed legacy nosetest helper. Also added a lot of backref=backref([...], cascade='all, delete-orphan') --- mediagoblin/plugins/oauth/tools.py | 73 +++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) (limited to 'mediagoblin/plugins/oauth/tools.py') diff --git a/mediagoblin/plugins/oauth/tools.py b/mediagoblin/plugins/oauth/tools.py index d21c8a5b..27ff32b4 100644 --- a/mediagoblin/plugins/oauth/tools.py +++ b/mediagoblin/plugins/oauth/tools.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # GNU MediaGoblin -- federated, autonomous media hosting # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. # @@ -14,13 +15,26 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import uuid + +from random import getrandbits + +from datetime import datetime + from functools import wraps -from mediagoblin.plugins.oauth.models import OAuthClient from mediagoblin.plugins.api.tools import json_response def require_client_auth(controller): + ''' + View decorator + + - Requires the presence of ``?client_id`` + ''' + # Avoid circular import + from mediagoblin.plugins.oauth.models import OAuthClient + @wraps(controller) def wrapper(request, *args, **kw): if not request.GET.get('client_id'): @@ -41,3 +55,60 @@ def require_client_auth(controller): return controller(request, client) return wrapper + + +def create_token(client, user): + ''' + Create an OAuthToken and an OAuthRefreshToken entry in the database + + Returns the data structure expected by the OAuth clients. + ''' + from mediagoblin.plugins.oauth.models import OAuthToken, OAuthRefreshToken + + token = OAuthToken() + token.user = user + token.client = client + token.save() + + refresh_token = OAuthRefreshToken() + refresh_token.user = user + refresh_token.client = client + refresh_token.save() + + # expire time of token in full seconds + # timedelta.total_seconds is python >= 2.7 or we would use that + td = token.expires - datetime.now() + exp_in = 86400*td.days + td.seconds # just ignore µsec + + return {'access_token': token.token, 'token_type': 'bearer', + 'refresh_token': refresh_token.token, 'expires_in': exp_in} + + +def generate_identifier(): + ''' Generates a ``uuid.uuid4()`` ''' + return unicode(uuid.uuid4()) + + +def generate_token(): + ''' Uses generate_identifier ''' + return generate_identifier() + + +def generate_refresh_token(): + ''' Uses generate_identifier ''' + return generate_identifier() + + +def generate_code(): + ''' Uses generate_identifier ''' + return generate_identifier() + + +def generate_secret(): + ''' + Generate a long string of pseudo-random characters + ''' + # XXX: We might not want it to use bcrypt, since bcrypt takes its time to + # generate the result. + return unicode(getrandbits(192)) + -- cgit v1.2.3