Source

Chronr / chronr / chronr / controllers / account.py

from datetime import datetime
import hashlib
import logging
from urllib import quote

from pylons import request, response, session, tmpl_context as c, url
from pylons.controllers.util import abort, redirect_to

import tw.forms

from chronr.lib.base import BaseController, render
from chronr.lib import helpers as h
from chronr.model import User, UserActivation
from chronr.model.meta import Session
from chronr.model.forms.build import RegisterUserForm


CAME_FROM_EXCLUDE = (
    '/account/activation',
)

log = logging.getLogger(__name__)

register_user_form = RegisterUserForm(
    'register_account',
    # action=url(),
    # method="post",
)

class State(object):
    """A container for passing state to validators.
    """


class AccountController(BaseController):

    def login(self):
        identity = request.environ.get('repoze.who.identity')
        if identity is not None:
            came_from = request.params.get('came_from', None)
            if came_from:
                if came_from in CAME_FROM_EXCLUDE:
                    redirect_to('/')
                else:
                    redirect_to(str(came_from))
        
        return render('/account/login.mako')
    
    def register(self):
        if request.method == 'POST':
            state = State()
            state.session = Session
            try:
                params = register_user_form.validate(request.params, state=state)
            except tw.forms.core.Invalid, e:
                c.form_error = e.error_dict or {}
            else:
                # Create the new account in database
                user = User(
                    user_name = params['user_name'],
                    email_address = params['email_address'],
                    display_name = params['display_name'],
                    password = params['password'],
                    activated = False,
                )
                Session.add(user)
                
                activation = UserActivation()
                activation.user = user
                key_seed = "%s%s%s" %(user.user_name, user.email_address, datetime.now().ctime())
                activation.key = hashlib.sha512(key_seed).hexdigest()   # psuedo-random hashed key
                Session.add(activation)
                
                activation_url = "%s%s?u=%s&key=%s" %(
                    request.environ['HTTP_ORIGIN'],
                    url(controller='account', action='activation'),
                    quote(user.user_name),
                    quote(activation.key)
                )
                
                from turbomail import Message
                message = Message("from@example.com", user.email_address, "Welcome to Chronr")
                message.plain = "Your Chronr account is ready to use. Your username is '%s'.  Activate your account at %s" %(user.user_name, activation_url)
                message.send()
                
                Session.commit()
                
                h.flash_info(u"A confirmation email has been sent to %s containing a link to activate your account." %(user.email_address,))
                redirect_to(url('/'))
        
        c.register_user_form = register_user_form
        
        return render('/account/register.mako')
    
    def activation(self):
        success = False
        
        user_name = request.params.get('u')
        if user_name:
            user = Session.query(User).filter_by(user_name=user_name).first()
            if user is not None:
                key = request.params.get('key')
                if key and user.activation and user.activation[0]:
                    activation = user.activation[0]
                    if activation.key == key:
                        Session.delete(activation)
                        user.activated = True
                        Session.commit()
                        success = True
        
        if success:                    
            h.flash_ok(u"Your account has been activated.  You may now login with username '%s'" %(user.user_name))
        else:
            h.flash_alert(u"Activation failed. The specified username or key may not be correct.")
        
        redirect_to("/account/login")