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 |
