Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1342)

Side by Side Diff: chromium-committers/auth_util.py

Issue 25515004: Add chromium-committers appengine app. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chromium-committers/app.yaml ('k') | chromium-committers/constants.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Utilities for talking to another appengine app with authentication."""
6
7 __author__ = 'agable@google.com (Aaron Gable)'
8
9
10 import datetime
11 import hashlib
12 import hmac
13 import time
14
15 from google.appengine.ext import ndb
16
17
18 class AuthError(Exception):
19 pass
20
21
22 class AuthToken(ndb.Model):
23 """Represents an id/key pair for authentication.
24
25 This app also uses the id field as the id/name (unique datastore key) of the
26 object for easy lookup. The app's own AuthToken is stored with name 'self'.
27
28 Attributes:
29 id: The unique identity for this token.
30 token: The corresponding authentication key.
31 """
32 id = ndb.StringProperty()
33 token = ndb.StringProperty()
34
35
36 def CheckRequest(request):
iannucci 2013/10/03 03:05:02 I would make this a decorator. Or a handler to sub
agable 2013/10/03 15:26:40 Then it couldn't be used the way it is in Chromium
agable 2013/10/03 19:59:03 Ok, decoratorized.
37 """Given an https request, confirms that it is correctly authenticated.
38
39 Expects the request to contain:
40 id: Unique ID of requester, used to get an AuthToken from ndb
41 time: Unix epoch time the request was made (to prevent replay attacks)
42 auth: The hmac(key, id+time+params, sha256), to authenticate the request,
43 where the key is the corresponding token in the ID's AuthToken
44 **params: All of the request GET/POST parameters
45
46 Throws AuthError if things don't check out right.
47 """
48 id = request.get('id')
49 if not id:
50 raise AuthError('No id in request.')
51 authtoken = ndb.Key(AuthToken, id).get()
52 if not authtoken:
53 raise AuthError('No auth token found for id %s.' % id)
54 key = authtoken.token
55
56 time = request.get('time')
57 if not time:
58 raise AuthError('No time in request.')
59 then = datetime.datetime.fromtimestamp(time)
60 now = datetime.datetime.now()
61 if abs(now - then) > datetime.timedelta(minutes=10):
iannucci 2013/10/03 03:05:02 I would make this 10 min a configuration option
62 raise AuthError('Time more than 10 minutes out of sync.')
63
64 auth = request.get('auth')
65 if not auth:
66 raise AuthError('No auth in request.')
67
68 check = hmac.new(key, digestmod=hashlib.sha256)
69 for param, value in sorted(request.params.items()):
70 # Don't include the auth hmac itself in the check.
71 if param == 'auth':
72 continue
73 check.update('%s=%s' % (param, value))
74
75 if check.hexdigest() != auth:
iannucci 2013/10/03 03:05:02 Need to do a constant-time comparison here. Assert
agable 2013/10/03 19:59:03 Done.
76 raise AuthError('Incorrect authentication.')
77
78
79 def CreateRequest(**params):
iannucci 2013/10/03 03:05:02 decorator. Actually... when would this ever be us
agable 2013/10/03 15:26:40 Uh, this is exactly what you, Vadim, and I were di
iannucci 2013/10/03 22:20:51 Right, so the appengine code would never really ca
80 """Given a payload to send, constructs an authenticated request.
81
82 Returns a dictionary containing:
83 id: Unique ID of this app, from the datastore AuthToken 'self'
84 time: Current Unix epoch time
85 auth: The hmac(key, id+time+parms, sha256), to authenticate the request,
86 where the key is the corresponding token in the app's AuthToken
87 **params: All of the GET/POST parameters
88
89 It is up to the calling code to convert this dictionary into valid GET/POST
90 parameters.
91 """
92 authtoken = ndb.Key(AuthToken, 'self').get()
93 if not authtoken:
94 raise AuthError('No AuthToken found for this app.')
95 id = authtoken.id
96 key = authtoken.token
97
98 time = time.mktime(datetime.datetime.now().timetuple())
99
100 auth = hmac.new(key, digestmod=hashlib.sha256)
101 for param, value in sorted(params.items()):
102 auth.update('%s=%s' % (param, value))
Vadim Sh. 2013/10/03 17:04:53 you need to hmac(time + id + all other stuff), and
agable 2013/10/03 17:46:30 That's exactly what .update() does. auth.update(a)
agable 2013/10/03 17:47:13 Oh whoops I see what you mean. Fixing.
103
104 ret = params.copy()
105 ret.update({'id': id, 'time': time, 'auth': auth.hexdigest()})
106 return ret
OLDNEW
« no previous file with comments | « chromium-committers/app.yaml ('k') | chromium-committers/constants.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698