3 from openid
.consumer
.consumer
import Consumer
4 from openid
.extensions
.sreg
import SRegRequest
, SRegResponse
5 from openid
.store
.filestore
import FileOpenIDStore
6 from openid
.yadis
.discover
import DiscoveryFailure
7 from sqlalchemy
.orm
.exc
import NoResultFound
9 from pylons
import request
, response
, session
, tmpl_context
as c
, url
10 from pylons
.controllers
.util
import abort
, redirect
, redirect_to
11 from routes
import url_for
, request_config
13 from floof
.lib
.base
import BaseController
, render
14 import floof
.lib
.helpers
as h
15 from floof
.model
.users
import IdentityURL
, User
17 log
= logging
.getLogger(__name__
)
19 from floof
.model
import UserPage
21 class AccountController(BaseController
):
23 openid_store
= FileOpenIDStore('/var/tmp')
26 c
.bogus_identity_url
= request
.params
.get('bogus_identity_url', None)
27 return render('/account/login.mako')
29 def login_begin(self
):
30 """Step one of logging in with OpenID; we redirect to the provider"""
32 identity_url
= request
.params
['identity_url']
33 cons
= Consumer(session
=session
, store
=self
.openid_store
)
35 auth_request
= cons
.begin(identity_url
)
36 except DiscoveryFailure
:
37 redirect_to(controller
='account', action
='login',
38 bogus_identity_url
=identity_url
)
40 sreg_req
= SRegRequest(optional
=['nickname', 'email', 'dob', 'gender',
41 'country', 'language', 'timezone'])
42 auth_request
.addExtension(sreg_req
)
44 host
= request
.headers
['host']
45 protocol
= request_config().protocol
46 return_url
= url_for(host
=host
, controller
='account', action
='login_finish')
47 new_url
= auth_request
.redirectURL(return_to
=return_url
,
48 realm
=protocol
+ '://' + host
)
51 def login_finish(self
):
52 """Step two of logging in; the OpenID provider redirects back here."""
54 cons
= Consumer(session
=session
, store
=self
.openid_store
)
55 host
= request
.headers
['host']
56 return_url
= url_for(host
=host
, controller
='account', action
='login_finish')
57 res
= cons
.complete(request
.params
, return_url
)
59 if res
.status
!= 'success':
60 return 'Error! %s' % res
.message
63 # Grab an existing user record, if one exists
64 q
= User
.query
.filter(User
.identity_urls
.any(url
=res
.identity_url
))
67 # Unrecognized URL. Redirect to a registration page to ask for a
69 session
['register:identity_url'] = res
.identity_url
71 # Try to pull a name out of the SReg response
72 sreg_res
= SRegResponse
.fromSuccessResponse(res
)
73 if sreg_res
and 'nickname' in sreg_res
:
74 session
['register:nickname'] = sreg_res
['nickname']
77 redirect(url('register'))
79 # Remember who's logged in, and we're good to go
80 session
['user_id'] = user
.id
82 h
.flash(u
'You are now logged in.')
84 # XXX send me where I came from
90 if 'user_id' in session
:
91 del session
['user_id']
95 # XXX send me where I came from
99 """Logging in with an unrecognized identity URL redirects here."""
101 c
.identity_url
= session
['register:identity_url']
102 c
.nickname
= session
.get('register:nickname', None)
103 # XXX hey, uh. warn if this name is taken already.
105 return render('/account/register.mako')
107 def register_finish(self
):
108 """Complete a new-user registration. Create the user and log in."""
110 identity_url
= session
['register:identity_url']
111 username
= request
.params
.get('username', None)
114 h
.flash(u
'Please enter a username.')
115 return self
.register()
117 if User
.query
.filter_by(name
=username
).count():
118 h
.flash(u
'This username is already taken.')
119 return self
.register()
121 if not User
.is_valid_name(username
):
122 h
.flash(u
'This username is not valid.')
123 return self
.register()
125 if username
in ['me']:
126 h
.flash(u
'This username is reserved.')
127 return self
.register()
130 user
= User(name
=username
, display_name
=username
)
131 user
.identity_urls
.append(IdentityURL(url
=identity_url
))
133 elixir
.session
.commit()
136 session
['user_id'] = user
.id
138 h
.flash(u
'You are now logged in.')
140 # XXX send me where I came from