Spline users plugin, focused on OpenID support.
[zzz-spline-users.git] / spline / plugins / users / controllers / accounts.py
1 import logging
2 from openid.consumer.consumer import Consumer
3 from openid.extensions.sreg import SRegRequest, SRegResponse
4 from openid.store.filestore import FileOpenIDStore
5 from sqlalchemy.orm.exc import NoResultFound
6
7 from pylons import config, request, response, session, tmpl_context as c
8 from pylons.controllers.util import abort, redirect_to
9 from routes import url_for, request_config
10
11 from spline import model
12 from spline.model import meta
13 from spline.lib.base import BaseController, render
14
15 log = logging.getLogger(__name__)
16
17 class AccountsController(BaseController):
18
19 openid_store = FileOpenIDStore('/var/tmp')
20
21 def index(self):
22 # Return a rendered template
23 # return render('/template.mako')
24 # or, Return a response
25 return str(request.headers) + request.environ.get('scheme', '')
26
27 def login_begin(self):
28 """Step one of logging in with OpenID; we redirect to the provider"""
29
30 cons = Consumer(session=session, store=self.openid_store)
31 auth_request = cons.begin(request.params['openid'])
32 sreg_req = SRegRequest(optional=['nickname', 'email', 'dob', 'gender',
33 'country', 'language', 'timezone'])
34 auth_request.addExtension(sreg_req)
35
36 host = request.headers['host']
37 protocol = request_config().protocol
38 return_url = url_for(host=host, controller='accounts', action='login_finish')
39 new_url = auth_request.redirectURL(return_to=return_url,
40 realm=protocol + '://' + host)
41 redirect_to(new_url)
42
43 def login_finish(self):
44 """Step two of logging in; the OpenID provider redirects back here."""
45
46 cons = Consumer(session=session, store=self.openid_store)
47 host = request.headers['host']
48 return_url = url_for(host=host, controller='accounts', action='login_finish')
49 res = cons.complete(request.params, return_url)
50
51 if res.status != 'success':
52 return 'Error! %s' % res.message
53
54 try:
55 # Grab an existing user record, if one exists
56 q = meta.Session.query(model.User) \
57 .filter(model.User.openids.any(openid=res.identity_url))
58 user = q.one()
59 except NoResultFound:
60 # Try to pull a name out of the SReg response
61 sreg_res = SRegResponse.fromSuccessResponse(res)
62 try:
63 username = sreg_res['nickname']
64 except KeyError:
65 username = 'Anonymous'
66
67 # Create db records
68 user = model.User(name=username)
69 meta.Session.add(user)
70 openid = model.OpenID(openid=res.identity_url)
71 user.openids.append(openid)
72 meta.Session.commit()
73
74 # Remember who's logged in, and we're good to go
75 session['user_id'] = user.id
76 session.save()
77
78 return "Hello, %s" % user.name