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 |
