PageRenderTime 125ms CodeModel.GetById 40ms app.highlight 24ms RepoModel.GetById 56ms app.codeStats 1ms

/kai/controllers/accounts.py

https://bitbucket.org/bbangert/kai/
Python | 200 lines | 169 code | 26 blank | 5 comment | 21 complexity | 501a18a0c5ae9765f2a881112f534a61 MD5 | raw file
  1from datetime import datetime
  2import logging
  3
  4from pylons import request, response, session, tmpl_context as c, url
  5from pylons.controllers.util import abort, redirect
  6from pylons.decorators import rest, secure, jsonify
  7
  8from kai.lib.base import BaseController, render
  9from kai.lib.decorators import validate
 10from kai.lib.helpers import failure_flash, success_flash
 11from kai.lib.mail import EmailMessage
 12from kai.model import Human, Paste, Traceback, forms
 13
 14log = logging.getLogger(__name__)
 15
 16
 17class AccountsController(BaseController):
 18    def __before__(self):
 19        c.active_tab = True
 20        c.active_sub = True
 21
 22    @rest.dispatch_on(POST='_forgot_password')
 23    def forgot_password(self):
 24        return render('/accounts/forgot_password.mako')
 25    
 26    def verify_email(self, token):
 27        users = list(Human.by_email_token(self.db)[token])
 28        if users:
 29            user = users[0]
 30            
 31            # If there's a email token issue (change email address), verify
 32            # its still valid
 33            if user.email_token_issue:
 34                diff = datetime.utcnow() - user.email_token_issue
 35                if diff.days > 1:
 36                    failure_flash('This e-mail verification token has expired.')
 37                    redirect(url('home'))
 38            
 39            # Valid e-mail token, remove it and log the user in
 40            user.email_token = user.email_token_issue = None
 41            user.process_login()
 42            success_flash('Your email has been verified, and you have been'
 43                          ' logged into PylonsHQ')
 44            redirect(url('home'))
 45        else:
 46            # No valid e-mail token
 47            failure_flash('Invalid e-mail token')
 48            redirect(url('home'))
 49    
 50    @validate(form=forms.forgot_password_form, error_handler='forgot_password')
 51    @secure.authenticate_form
 52    def _forgot_password(self):
 53        user = list(Human.by_email(self.db)[self.form_result['email_address']])[0]
 54        user.password_token = user.generate_token()
 55        c.password_token = user.password_token
 56        user.password_token_issue = datetime.utcnow()
 57        user.store(self.db)
 58        message = EmailMessage(subject="PylonsHQ - Lost Password", 
 59                               body=render('/email/lost_password.mako'),
 60                               from_email="PylonsHQ <pylonshq@groovie.org>",
 61                               to=[self.form_result['email_address']])
 62        message.send(fail_silently=True)
 63        success_flash('An e-mail has been sent to your account to verify the password reset request.')
 64        redirect(url('account_login'))
 65    
 66    @rest.dispatch_on(POST='_change_password')
 67    def change_password(self, token):
 68        c.token = token
 69        users = list(Human.by_password_token(self.db)[token])
 70        if not users:
 71            failure_flash('That password token is no longer valid.')
 72            redirect(url('account_login'))
 73        
 74        user = users[0]
 75        diff = datetime.utcnow() - user.password_token_issue
 76        if diff.days > 1 or diff.seconds > 3600:
 77            failure_flash('Password token is no longer valid, please make a new password reset request.')
 78            redirect(url('forgot_password'))
 79        return render('/accounts/change_password.mako')
 80    
 81    @validate(form=forms.change_password_form, error_handler='change_password')
 82    @secure.authenticate_form
 83    def _change_password(self, token):
 84        users = list(Human.by_password_token(self.db)[token]) or abort(401)
 85        user = users[0]
 86        diff = datetime.utcnow() - user.password_token_issue
 87        if diff.days > 1 or diff.seconds > 3600:
 88            failure_flash('Password token is no longer valid, please make a new password reset request.')
 89            redirect(url('forgot_password'))
 90        user.password_token = user.password_token_issue = None
 91        user.password = user.hash_password(self.form_result['password'])
 92        user.store(self.db)
 93        success_flash('Your password has been reset successfully')
 94        redirect(url('account_login'))
 95
 96    def logout(self):
 97        c.user.session_id = None
 98        c.user.store(self.db)
 99        session.clear()
100        session.expire()
101        session.save()
102        redir = request.GET.get('redir')
103        success_flash('You have logged out of your session')
104        if redir:
105            redirect(url(str(redir)))
106        else:
107            redirect(url('home'))
108    
109    @rest.dispatch_on(POST='_process_login')
110    def login(self):
111        redir = request.GET.get('redir')
112        if redir and redir.startswith('/') and redir != url('account_login'):
113            session['redirect'] = str(redir)
114            session.save()
115        return render('/accounts/login.mako')
116    
117    @validate(form=forms.login_form, error_handler='login')
118    @secure.authenticate_form
119    def _process_login(self):
120        user = self.form_result['user']
121        user.process_login()        
122        success_flash('You have logged into PylonsHQ')
123        if session.get('redirect'):
124            redir_url = session.pop('redirect')
125            session.save()
126            redirect(url(redir_url))
127        redirect(url('home'))
128    
129    @rest.dispatch_on(POST='_process_openid_associate')
130    def openid_associate(self):
131        openid_url = session.get('openid_identity')
132        if not openid_url:
133            redirect(url('account_register'))
134        c.openid = openid_url
135        return render('/accounts/associate.mako')
136    
137    @validate(form=forms.login_form, error_handler='login')
138    def _process_openid_associate(self):
139        openid_url = session.get('openid_identity')
140        user = self.form_result['user']
141        if user.openids:
142            user.openids.append(openid_url)
143        else:
144            user.openids = [openid_url]
145        user.process_login()
146        success_flash('You have associated your OpenID to your account, and signed in')
147        if session.get('redirect'):
148            redir_url = session.pop('redirect')
149            session.save()
150            redirect(url(redir_url))
151        redirect(url('home'))
152    
153    @rest.dispatch_on(POST='_process_openid_registration')
154    def openid_register(self):
155        openid_url = session.get('openid_identity')
156        if not openid_url:
157            redirect(url('account_register'))
158        c.openid = session.get('openid_identity')
159        c.defaults = {}
160        return render('/accounts/register.mako')
161    
162    @validate(form=forms.openid_registration_form, error_handler='openid_register')
163    def _process_openid_registration(self):
164        new_user = Human(displayname=self.form_result['displayname'],
165                         timezone = self.form_result['timezone'],
166                         email=self.form_result['email_address'])
167        new_user.openids = [session['openid_identity']]
168        return self._finish_registration(new_user)
169    
170    @rest.dispatch_on(POST='_process_registration')
171    def register(self):
172        return render('/accounts/register.mako')
173
174    @validate(form=forms.registration_form, error_handler='register')
175    @secure.authenticate_form
176    def _process_registration(self):
177        new_user = Human(displayname=self.form_result['displayname'],
178                         timezone = self.form_result['timezone'],
179                         email=self.form_result['email_address'])
180        new_user.password = Human.hash_password(self.form_result['password'])
181        return self._finish_registration(new_user)
182    
183    def _finish_registration(self, user):
184        user.email_token = c.email_token = user.generate_token()
185        user.email_token_issue = datetime.utcnow()
186        user.store(self.db)
187        
188        Paste.associate_pasties(user)
189        Traceback.associate_tracebacks(user)
190        
191        # Send out the welcome email with the reg token
192        message = EmailMessage(subject="PylonsHQ - Registration Confirmation",
193                               body=render('/email/register.mako'),
194                               from_email="PylonsHQ <pylonshq@groovie.org>",
195                               to=[self.form_result['email_address']])
196        message.send(fail_silently=True)
197        
198        success_flash("User account '%s' created successfully. An e-mail has"
199                      " been sent to activate your account." % user.displayname)
200        redirect(url('home'))