Mercurial > hg > OKFNAnnotator
annotate AuthTokenGenerator.py @ 8:93c835b645af
nicer logging.
author | casties |
---|---|
date | Fri, 09 Nov 2012 18:12:47 +0100 |
parents | 279473355e9b |
children | 41f264620073 |
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 |
7
279473355e9b
authentication works with hierarchy of acl_users now.
root@tuxserve03.mpiwg-berlin.mpg.de
parents:
6
diff
changeset
|
6 from Acquisition import aq_chain |
0 | 7 |
2 | 8 import logging |
0 | 9 import datetime |
2 | 10 import jwt |
0 | 11 |
12 | |
13 ZERO = datetime.timedelta(0) | |
14 class Utc(datetime.tzinfo): | |
15 def utcoffset(self, dt): | |
16 return ZERO | |
17 | |
18 def tzname(self, dt): | |
19 return "UTC" | |
20 | |
21 def dst(self, dt): | |
22 return ZERO | |
23 UTC = Utc() | |
24 | |
25 | |
26 class AuthTokenGenerator(SimpleItem, PropertyManager): | |
27 """Generator of auth tokens for OKFN Annotator""" | |
28 | |
29 meta_type = 'AuthTokenGenerator' | |
2 | 30 _properties = ({'id':'consumer_key', 'type': 'string', 'mode': 'w'}, |
0 | 31 {'id':'consumer_secret', 'type': 'string', 'mode': 'w'}, |
32 ) | |
33 | |
34 manage_options = PropertyManager.manage_options + SimpleItem.manage_options | |
35 | |
36 # Only change this if you're sure you know what you're doing | |
2 | 37 tokenTtl = 86400 |
0 | 38 |
39 def __init__(self, id, consumerKey=None, consumerSecret=None): | |
40 """init document viewer""" | |
2 | 41 self.id = id |
0 | 42 self.consumer_key = consumerKey |
43 self.consumer_secret = consumerSecret | |
44 | |
6
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
45 def index_html(self, user='anonymous'): |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
46 """returns authentication token for user (Zope style)""" |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
47 if self._user_allowed(user=user): |
0 | 48 token = self._generate_token(user) |
2 | 49 # set CORS headers |
0 | 50 origin = self.REQUEST.getHeader("Origin", None) |
51 if origin is not None: | |
52 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Origin", origin) | |
53 else: | |
54 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Origin", "*") | |
55 | |
56 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Credentials", "true") | |
6
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
57 logging.debug("token for user %s: %s"%(user, token)) |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
58 self.REQUEST.RESPONSE.setHeader("Content-Type", "text/plain") |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
59 return token |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
60 else: |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
61 raise Unauthorized |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
62 |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
63 def getLoginToken(self, user='anonymous', password=None): |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
64 """returns authentication token or error code""" |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
65 # set CORS headers |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
66 origin = self.REQUEST.getHeader("Origin", None) |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
67 if origin is not None: |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
68 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Origin", origin) |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
69 else: |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
70 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Origin", "*") |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
71 |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
72 self.REQUEST.RESPONSE.setHeader("Access-Control-Allow-Credentials", "true") |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
73 if self._user_allowed(user=user, password=password): |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
74 token = self._generate_token(user) |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
75 logging.debug("token for user %s: %s"%(user, token)) |
2 | 76 self.REQUEST.RESPONSE.setHeader("Content-Type", "text/plain") |
77 return token | |
0 | 78 else: |
6
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
79 self.REQUEST.RESPONSE.setStatus('Unauthorized') |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
80 return "Please Authenticate!" |
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 |
8 | 88 # get logged in user from Zope |
6
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 if authname == user: |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
92 # user is logged in |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
93 return authname |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
94 |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
95 if password: |
8 | 96 logging.debug("trying password for token for user %s"%user) |
7
279473355e9b
authentication works with hierarchy of acl_users now.
root@tuxserve03.mpiwg-berlin.mpg.de
parents:
6
diff
changeset
|
97 # try all user folders in aq_chain |
279473355e9b
authentication works with hierarchy of acl_users now.
root@tuxserve03.mpiwg-berlin.mpg.de
parents:
6
diff
changeset
|
98 authuser = None |
279473355e9b
authentication works with hierarchy of acl_users now.
root@tuxserve03.mpiwg-berlin.mpg.de
parents:
6
diff
changeset
|
99 userfolder = None |
279473355e9b
authentication works with hierarchy of acl_users now.
root@tuxserve03.mpiwg-berlin.mpg.de
parents:
6
diff
changeset
|
100 for ctx in aq_chain(self): |
279473355e9b
authentication works with hierarchy of acl_users now.
root@tuxserve03.mpiwg-berlin.mpg.de
parents:
6
diff
changeset
|
101 new_uf = getattr(ctx, 'acl_users', None) |
279473355e9b
authentication works with hierarchy of acl_users now.
root@tuxserve03.mpiwg-berlin.mpg.de
parents:
6
diff
changeset
|
102 if new_uf != userfolder: |
279473355e9b
authentication works with hierarchy of acl_users now.
root@tuxserve03.mpiwg-berlin.mpg.de
parents:
6
diff
changeset
|
103 userfolder = new_uf |
279473355e9b
authentication works with hierarchy of acl_users now.
root@tuxserve03.mpiwg-berlin.mpg.de
parents:
6
diff
changeset
|
104 authuser = userfolder.authenticate(user, password, None) |
279473355e9b
authentication works with hierarchy of acl_users now.
root@tuxserve03.mpiwg-berlin.mpg.de
parents:
6
diff
changeset
|
105 if authuser is not None: |
279473355e9b
authentication works with hierarchy of acl_users now.
root@tuxserve03.mpiwg-berlin.mpg.de
parents:
6
diff
changeset
|
106 return authuser |
6
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
107 |
17bbd5e80d15
method getLoginToken and real authentication support.
casties
parents:
2
diff
changeset
|
108 return None |
0 | 109 |
110 def _generate_token(self, user_id): | |
111 #return JSON-token | |
2 | 112 issue_time = datetime.datetime.now(UTC).replace(microsecond=0) |
113 | |
114 return jwt.encode({ | |
115 'consumerKey': self.consumer_key, | |
116 'userId': user_id, | |
117 'issuedAt': issue_time.isoformat(), | |
118 'ttl': self.tokenTtl | |
119 }, self.consumer_secret) | |
120 | |
0 | 121 |
122 def manage_addAuthTokenGeneratorForm(self): | |
123 """form for adding AuthTokenGenerator""" | |
124 pt = PageTemplateFile("zpt/manage_addAuthTokenGenerator", globals()).__of__(self) | |
125 return pt() | |
126 | |
127 def manage_addAuthTokenGenerator(context, id, consumerKey=None, consumerSecret=None): | |
128 """ """ | |
129 context._setObject(id, AuthTokenGenerator(id, consumerKey=consumerKey, consumerSecret=consumerSecret)) | |
130 return "AuthTokenGenerator Installed: %s" % id |