summaryrefslogtreecommitdiff
path: root/quoins/openid_controllers.py
diff options
context:
space:
mode:
Diffstat (limited to 'quoins/openid_controllers.py')
-rw-r--r--quoins/openid_controllers.py186
1 files changed, 186 insertions, 0 deletions
diff --git a/quoins/openid_controllers.py b/quoins/openid_controllers.py
new file mode 100644
index 0000000..9491195
--- /dev/null
+++ b/quoins/openid_controllers.py
@@ -0,0 +1,186 @@
1# Quoins - A TurboGears blogging system.
2# Copyright (C) 2008-2009 James E. Blair <corvus@gnu.org>
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17from tg import controllers, expose, flash, require, validate, request, redirect, session
18from tg import TGController
19import tg
20import pylons
21from repoze.what import predicates
22import openid.consumer.consumer
23import openid.server.server
24import openid.extensions.sreg
25from openid.store.sqlstore import MySQLStore
26import MySQLdb
27import sqlalchemy.engine.url
28import types
29import os.path
30
31from utils import get_oid_connection
32
33class DecideController(object):
34 def __init__(self, oid_controller):
35 self.oid_controller = oid_controller
36
37 @expose(template="genshi:quoinstemplates.oid_confirm")
38 @require(predicates.not_anonymous())
39 def index(self, **kw):
40 oid_request = request.environ['oid_request']
41 self.oid_controller._validate_identity(oid_request.identity)
42
43 sreg_req = openid.extensions.sreg.SRegRequest.fromOpenIDRequest(oid_request)
44 user = request.identity['user']
45
46 sr_required = [self.oid_controller.getSRegValue(user,x) for x in sreg_req.required]
47 sr_optional = [self.oid_controller.getSRegValue(user,x) for x in sreg_req.optional]
48
49 session['oid_request']=oid_request
50 session.save()
51
52 return dict(openid = self.oid_controller,
53 oid_request = oid_request,
54 required = sr_required,
55 optional = sr_optional,
56 )
57
58class ResponseController(object):
59 def __init__(self, oid_controller):
60 self.oid_controller = oid_controller
61
62 @expose()
63 def index(self, **kw):
64 webresponse = request.environ['oid_webresponse']
65
66 pylons.response.status = webresponse.code
67 pylons.response.headers.update(webresponse.headers)
68 return webresponse.body
69
70
71class OpenIDController(TGController):
72 sreg_friendly = {
73 'nickname': 'Nickname',
74 'email': 'Email address',
75 'fullname': 'Full name',
76 'dob': 'Date of birth',
77 'gender': 'Gender',
78 'postcode': 'Postal code',
79 'country': 'Country',
80 'language': 'Language',
81 'timezone': 'Time zone',
82 }
83
84 def url(self, obj=None):
85 if obj is None:
86 u = tg.url(self.path)
87 elif isinstance(obj, basestring):
88 if obj.startswith('/'): obj = obj[1:]
89 u = tg.url(os.path.join(self.path, obj))
90 return u
91
92 def absolute_url(self, obj):
93 port = tg.config.get('server.webport', '')
94 if port:
95 port = ':'+port
96 return 'http://%s%s%s'%(tg.config.get('server.webhost'), port,
97 self.url(obj))
98
99 def __init__(self, *args, **kw):
100 self.get_name_from_id = kw.pop('get_name_from_id', lambda x: x)
101 self.path = kw.pop('path', '/')
102 super(OpenIDController, self).__init__(*args, **kw)
103
104 def getSRegValue(self, user, field):
105 val = None
106 if field=='nickname': val = user.user_name
107 if field=='fullname': val = user.display_name
108 if field=='email': val = user.email_address
109 return (field, self.sreg_friendly[field], val)
110
111 def isAuthorized(self, id, trust_root):
112 if not request.identity: return False
113 name = self.get_name_from_id(id)
114 if request.identity['user'].user_name == name:
115 # check to see if the user has set preferences for this trust
116 # root, and return True. also, sreg. XXX
117 return False
118 return False
119
120 def _validate_identity(self, id):
121 name = self.get_name_from_id(id)
122 if request.identity['user'].user_name != name:
123 raise Exception("Not your ID")
124
125 @expose()
126 def finish(self, **kw):
127 oid_request=session['oid_request']
128 self._validate_identity(oid_request.identity)
129
130 sreg_req = openid.extensions.sreg.SRegRequest.fromOpenIDRequest(oid_request)
131 user = request.identity['user']
132
133 store = MySQLStore(get_oid_connection())
134 oserver = openid.server.server.Server(store,
135 self.absolute_url('/openid/server'))
136
137 data = {}
138 for field in sreg_req.required+sreg_req.optional:
139 if kw.has_key(field):
140 data[field]=self.getSRegValue(user, field)[2]
141
142 sreg_resp = openid.extensions.sreg.SRegResponse.extractResponse(sreg_req, data)
143
144 if kw.get('continue', None):
145 response = oid_request.answer(True)
146 response.addExtension(sreg_resp)
147 else:
148 response = oid_request.answer(False)
149
150 webresponse = oserver.encodeResponse(response)
151
152 pylons.response.status = webresponse.code
153 pylons.response.headers.update(webresponse.headers)
154
155 del session['oid_request']
156 session.save()
157 return webresponse.body
158
159 @expose()
160 def lookup(self, *remainder):
161 store = MySQLStore(get_oid_connection())
162 oserver = openid.server.server.Server(store,
163 self.absolute_url('/server'))
164 oid_request = oserver.decodeRequest(request.params)
165 request.environ['oid_request']=oid_request
166
167 if oid_request.mode in ['checkid_immediate', 'checkid_setup']:
168 if hasattr(oid_request, 'returnToVerified'):
169 if not (oid_request.trustRootValid()
170 and oid_request.returnToVerified()):
171 raise Exception("Not trusted")
172 else:
173 if not (oid_request.trustRootValid()):
174 raise Exception("Not trusted")
175 if self.isAuthorized(oid_request.identity, oid_request.trust_root):
176 response = oid_request.answer(True)
177 elif oid_request.immediate:
178 response = oid_request.answer(False)
179 else:
180 return (DecideController(self), ())
181 else:
182 response = oserver.handleRequest(oid_request)
183
184 webresponse = oserver.encodeResponse(response)
185 request.environ['oid_webresponse']=webresponse
186 return (ResponseController(self), ())