27ff32b488a20411fc796381ac3072cdc4ea4a88
[mediagoblin.git] / mediagoblin / plugins / oauth / tools.py
1 # -*- coding: utf-8 -*-
2 # GNU MediaGoblin -- federated, autonomous media hosting
3 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Affero General Public License for more details.
14 #
15 # You should have received a copy of the GNU Affero General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 import uuid
19
20 from random import getrandbits
21
22 from datetime import datetime
23
24 from functools import wraps
25
26 from mediagoblin.plugins.api.tools import json_response
27
28
29 def require_client_auth(controller):
30 '''
31 View decorator
32
33 - Requires the presence of ``?client_id``
34 '''
35 # Avoid circular import
36 from mediagoblin.plugins.oauth.models import OAuthClient
37
38 @wraps(controller)
39 def wrapper(request, *args, **kw):
40 if not request.GET.get('client_id'):
41 return json_response({
42 'status': 400,
43 'errors': [u'No client identifier in URL']},
44 _disable_cors=True)
45
46 client = OAuthClient.query.filter(
47 OAuthClient.identifier == request.GET.get('client_id')).first()
48
49 if not client:
50 return json_response({
51 'status': 400,
52 'errors': [u'No such client identifier']},
53 _disable_cors=True)
54
55 return controller(request, client)
56
57 return wrapper
58
59
60 def create_token(client, user):
61 '''
62 Create an OAuthToken and an OAuthRefreshToken entry in the database
63
64 Returns the data structure expected by the OAuth clients.
65 '''
66 from mediagoblin.plugins.oauth.models import OAuthToken, OAuthRefreshToken
67
68 token = OAuthToken()
69 token.user = user
70 token.client = client
71 token.save()
72
73 refresh_token = OAuthRefreshToken()
74 refresh_token.user = user
75 refresh_token.client = client
76 refresh_token.save()
77
78 # expire time of token in full seconds
79 # timedelta.total_seconds is python >= 2.7 or we would use that
80 td = token.expires - datetime.now()
81 exp_in = 86400*td.days + td.seconds # just ignore µsec
82
83 return {'access_token': token.token, 'token_type': 'bearer',
84 'refresh_token': refresh_token.token, 'expires_in': exp_in}
85
86
87 def generate_identifier():
88 ''' Generates a ``uuid.uuid4()`` '''
89 return unicode(uuid.uuid4())
90
91
92 def generate_token():
93 ''' Uses generate_identifier '''
94 return generate_identifier()
95
96
97 def generate_refresh_token():
98 ''' Uses generate_identifier '''
99 return generate_identifier()
100
101
102 def generate_code():
103 ''' Uses generate_identifier '''
104 return generate_identifier()
105
106
107 def generate_secret():
108 '''
109 Generate a long string of pseudo-random characters
110 '''
111 # XXX: We might not want it to use bcrypt, since bcrypt takes its time to
112 # generate the result.
113 return unicode(getrandbits(192))
114