Mercurial > hg > OKFNAnnotator
annotate AuthTokenGenerator.py @ 6:17bbd5e80d15
method getLoginToken and real authentication support.
author | casties |
---|---|
date | Tue, 30 Oct 2012 20:20:31 +0100 |
parents | 4c6c8835fc5c |
children | 279473355e9b |
rev | line source |
---|---|
0 | 1 from OFS.SimpleItem import SimpleItem |
2 from Products.PageTemplates.PageTemplateFile import PageTemplateFile | |
3 from OFS.PropertyManager import PropertyManager | |
6
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
4 from AccessControl import getSecurityManager |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
5 from zExceptions import Unauthorized |
0 | 6 |
2 | 7 import logging |
0 | 8 import datetime |
2 | 9 import jwt |
0 | 10 |
11 | |
12 ZERO = datetime.timedelta(0) | |
13 class Utc(datetime.tzinfo): | |
14 def utcoffset(self, dt): | |
15 return ZERO | |
16 | |
17 def tzname(self, dt): | |
18 return "UTC" | |
19 | |
20 def dst(self, dt): | |
21 return ZERO | |
22 UTC = Utc() | |
23 | |
24 | |
25 class AuthTokenGenerator(SimpleItem, PropertyManager): | |
26 """Generator of auth tokens for OKFN Annotator""" | |
27 | |
28 meta_type = 'AuthTokenGenerator' | |
2 | 29 _properties = ({'id':'consumer_key', 'type': 'string', 'mode': 'w'}, |
0 | 30 {'id':'consumer_secret', 'type': 'string', 'mode': 'w'}, |
31 ) | |
32 | |
33 manage_options = PropertyManager.manage_options + SimpleItem.manage_options | |
34 | |
35 # Only change this if you're sure you know what you're doing | |
2 | 36 tokenTtl = 86400 |
0 | 37 |
38 def __init__(self, id, consumerKey=None, consumerSecret=None): | |
39 """init document viewer""" | |
2 | 40 self.id = id |
0 | 41 self.consumer_key = consumerKey |
42 self.consumer_secret = consumerSecret | |
43 | |
6
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
44 def index_html(self, user='anonymous'): |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
45 """returns authentication token for user (Zope style)""" |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
46 if self._user_allowed(user=user): |
0 | 47 token = self._generate_token(user) |
2 | 48 # set CORS headers |
0 | 49 origin = self.REQUEST.getHeader("Origin", None) |
50 if origin is not None: | |
51 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Origin", origin) | |
52 else: | |
53 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Origin", "*") | |
54 | |
55 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Credentials", "true") | |
6
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
56 logging.debug("token for user %s: %s"%(user, token)) |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
57 self.REQUEST.RESPONSE.setHeader("Content-Type", "text/plain") |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
58 return token |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
59 else: |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
60 raise Unauthorized |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
61 |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
62 def getLoginToken(self, user='anonymous', password=None): |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
63 """returns authentication token or error code""" |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
64 # set CORS headers |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
65 origin = self.REQUEST.getHeader("Origin", None) |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
66 if origin is not None: |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
67 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Origin", origin) |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
68 else: |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
69 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Origin", "*") |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
70 |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
71 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Credentials", "true") |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
72 if self._user_allowed(user=user, password=password): |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
73 token = self._generate_token(user) |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
74 logging.debug("token for user %s: %s"%(user, token)) |
2 | 75 self.REQUEST.RESPONSE.setHeader("Content-Type", "text/plain") |
76 return token | |
0 | 77 else: |
6
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
78 self.REQUEST.RESPONSE.setStatus('Unauthorized') |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
79 return "Please Authenticate!" |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
80 |
0 | 81 |
6
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
82 def _user_allowed(self, user=None, password=None): |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
83 # check the login |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
84 if user == 'anonymous': |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
85 # everybody can be anonymous |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
86 return user |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
87 |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
88 # get logged in user |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
89 authuser = getSecurityManager().getUser() |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
90 authname = authuser.getUserName() |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
91 logging.debug("token_allowed: user=%s authuser=%s username=%s"%(user, repr(authuser), repr(authname))) |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
92 if authname == user: |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
93 # user is logged in |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
94 return authname |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
95 |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
96 if password: |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
97 logging.debug("trying password") |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
98 # TODO: should we care about aquisition? |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
99 authuser = self.acl_users.authenticate(user, password, None) |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
100 return authuser |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
101 |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
102 return None |
0 | 103 |
104 def _generate_token(self, user_id): | |
105 #return JSON-token | |
2 | 106 issue_time = datetime.datetime.now(UTC).replace(microsecond=0) |
107 | |
108 return jwt.encode({ | |
109 'consumerKey': self.consumer_key, | |
110 'userId': user_id, | |
111 'issuedAt': issue_time.isoformat(), | |
112 'ttl': self.tokenTtl | |
113 }, self.consumer_secret) | |
114 | |
0 | 115 |
116 def manage_addAuthTokenGeneratorForm(self): | |
117 """form for adding AuthTokenGenerator""" | |
118 pt = PageTemplateFile("zpt/manage_addAuthTokenGenerator", globals()).__of__(self) | |
119 return pt() | |
120 | |
121 def manage_addAuthTokenGenerator(context, id, consumerKey=None, consumerSecret=None): | |
122 """ """ | |
123 context._setObject(id, AuthTokenGenerator(id, consumerKey=consumerKey, consumerSecret=consumerSecret)) | |
124 return "AuthTokenGenerator Installed: %s" % id |