Commit | Line | Data |
---|---|---|
c121a7d3 | 1 | # -*- coding: utf-8 -*- |
88a9662b JW |
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 | ||
c121a7d3 JW |
18 | import uuid |
19 | ||
20 | from random import getrandbits | |
21 | ||
22 | from datetime import datetime | |
23 | ||
88a9662b JW |
24 | from functools import wraps |
25 | ||
88a9662b JW |
26 | from mediagoblin.plugins.api.tools import json_response |
27 | ||
28 | ||
29 | def require_client_auth(controller): | |
c121a7d3 JW |
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 | ||
88a9662b JW |
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 | |
c121a7d3 JW |
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 |