<filename>terroroftinytown/tracker/account.py
# encoding=utf-8
import logging

from sqlalchemy.exc import IntegrityError
import tornado.gen
from tornado.web import HTTPError
import tornado.web

from terroroftinytown.tracker.base import BaseHandler
from terroroftinytown.tracker.form import (LoginForm, AddUserForm, ConfirmForm,
    ChangePasswordForm)
from terroroftinytown.tracker.model import User, Session
import terroroftinytown.tracker.util


ACCOUNT_COOKIE_NAME = 'tottu'
ACCOUNT_TOKEN_COOKIE_NAME = 'tottt'
logger = logging.getLogger(__name__)


class LoginHandler(BaseHandler):
    def get(self):
        form = LoginForm()
        self.render('admin/account/login.html', form=form)

    @tornado.gen.coroutine
    def post(self):
        form = LoginForm(self.request.arguments)

        if form.validate() \
        and self._login(form.username.data, form.password.data):
            logger.info(self.user_audit_text('User %s logged in.'),
                        form.username.data)
            self.redirect(
                self.get_argument('next', self.reverse_url('admin.overview'))
            )
            return

        yield terroroftinytown.tracker.util.sleep(1)
        self.render('admin/account/login.html', form=form, message='Log in failed.')

    def _login(self, username, password):
        if User.no_users_exist():
            User.save_new_user(username, password)

        if User.check_account(username, password):
            self.set_secure_cookie(
                ACCOUNT_COOKIE_NAME, username, expires_days=30
            )
            self.set_secure_cookie(
                ACCOUNT_TOKEN_COOKIE_NAME, User.get_user_token(username),
                expires_days=30
            )
            return True


class LogoutHandler(BaseHandler):
    def get(self):
        self.clear_cookie(ACCOUNT_COOKIE_NAME)
        self.clear_cookie(ACCOUNT_TOKEN_COOKIE_NAME)
        self.redirect('/')


class AllUsersHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self):
        add_user_form = AddUserForm()

        self.render(
            'admin/account/all.html',
            usernames=User.all_usernames(),
            add_user_form=add_user_form
        )

    @tornado.web.authenticated
    def post(self):
        action = self.get_argument('action')
        message = None

        if action != 'add_user':
            raise HTTPError(400, 'Unknown action')

        add_user_form = AddUserForm(self.request.arguments)

        if add_user_form.validate():
            username = add_user_form.username.data
            password = add_user_form.password.data

            try:
                User.save_new_user(username, password)
            except IntegrityError:
                message = 'User already exists.'
            else:
                logger.info(self.user_audit_text('Added new user %s'),
                            username)
                self.redirect(self.reverse_url('user.overview', username))
                return

        self.render(
            'admin/account/all.html',
            add_user_form=add_user_form,
            usernames=User.all_usernames(),
            message=message
        )


class UserHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self, username):
        delete_form = ConfirmForm()
        password_form = ChangePasswordForm()

        self.render(
            'admin/account/user.html',
            username=username, delete_form=delete_form,
            password_form=password_form
        )

    @tornado.web.authenticated
    def post(self, username):
        action = self.get_argument('action')
        delete_form = ConfirmForm(self.request.arguments)
        password_form = ChangePasswordForm(self.request.arguments)

        if action == 'delete':
            message = self._delete(username, delete_form)
        elif action == 'password':
            message = self._password(username, password_form)
        else:
            raise HTTPError(400, 'Unknown action')

        self.render(
            'admin/account/user.html',
            username=username, delete_form=delete_form,
            password_form=password_form, message=message
        )

    def _delete(self, username, form):
        if form.validate():
            logger.info(self.user_audit_text('Deleted user %s'), username)
            User.delete_user(username)
            self.redirect(self.reverse_url('users.overview'))
        else:
            return 'Error'

    def _password(self, username, form):
        if form.validate():
            if form.username.data != username:
                return 'Wrong username'

            logger.info(self.user_audit_text('Updated user %s password'),
                        username)
            User.update_password(username, form.password.data)
            self.redirect(self.reverse_url('users.overview'))
        else:
            return 'Error'

<filename>terroroftinytown/tracker/account.py
# encoding=utf-8
import logging

from sqlalchemy.exc import IntegrityError
import tornado.gen
from tornado.web import HTTPError
import tornado.web

from terroroftinytown.tracker.base import BaseHandler
from terroroftinytown.tracker.form import (LoginForm, AddUserForm, ConfirmForm,
    ChangePasswordForm)
from terroroftinytown.tracker.model import User, Session
import terroroftinytown.tracker.util


ACCOUNT_COOKIE_NAME = 'tottu'
ACCOUNT_TOKEN_COOKIE_NAME = 'tottt'
logger = logging.getLogger(__name__)


class LoginHandler(BaseHandler):
    def get(self):
        form = LoginForm()
        self.render('admin/account/login.html', form=form)

    @tornado.gen.coroutine
    def post(self):
        form = LoginForm(self.request.arguments)

        if form.validate() \
        and self._login(form.username.data, form.password.data):
            logger.info(self.user_audit_text('User %s logged in.'),
                        form.username.data)
            self.redirect(
                self.get_argument('next', self.reverse_url('admin.overview'))
            )
            return

        yield terroroftinytown.tracker.util.sleep(1)
        self.render('admin/account/login.html', form=form, message='Log in failed.')

    def _login(self, username, password):
        if User.no_users_exist():
            User.save_new_user(username, password)

        if User.check_account(username, password):
            self.set_secure_cookie(
                ACCOUNT_COOKIE_NAME, username, expires_days=30
            )
            self.set_secure_cookie(
                ACCOUNT_TOKEN_COOKIE_NAME, User.get_user_token(username),
                expires_days=30
            )
            return True


class LogoutHandler(BaseHandler):
    def get(self):
        self.clear_cookie(ACCOUNT_COOKIE_NAME)
        self.clear_cookie(ACCOUNT_TOKEN_COOKIE_NAME)
        self.redirect('/')


class AllUsersHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self):
        add_user_form = AddUserForm()

        self.render(
            'admin/account/all.html',
            usernames=User.all_usernames(),
            add_user_form=add_user_form
        )

    @tornado.web.authenticated
    def post(self):
        action = self.get_argument('action')
        message = None

        if action != 'add_user':
            raise HTTPError(400, 'Unknown action')

        add_user_form = AddUserForm(self.request.arguments)

        if add_user_form.validate():
            username = add_user_form.username.data
            password = add_user_form.password.data

            try:
                User.save_new_user(username, password)
            except IntegrityError:
                message = 'User already exists.'
            else:
                logger.info(self.user_audit_text('Added new user %s'),
                            username)
                self.redirect(self.reverse_url('user.overview', username))
                return

        self.render(
            'admin/account/all.html',
            add_user_form=add_user_form,
            usernames=User.all_usernames(),
            message=message
        )


class UserHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self, username):
        delete_form = ConfirmForm()
        password_form = ChangePasswordForm()

        self.render(
            'admin/account/user.html',
            username=username, delete_form=delete_form,
            password_form=password_form
        )

    @tornado.web.authenticated
    def post(self, username):
        action = self.get_argument('action')
        delete_form = ConfirmForm(self.request.arguments)
        password_form = ChangePasswordForm(self.request.arguments)

        if action == 'delete':
            message = self._delete(username, delete_form)
        elif action == 'password':
            message = self._password(username, password_form)
        else:
            raise HTTPError(400, 'Unknown action')

        self.render(
            'admin/account/user.html',
            username=username, delete_form=delete_form,
            password_form=password_form, message=message
        )

    def _delete(self, username, form):
        if form.validate():
            logger.info(self.user_audit_text('Deleted user %s'), username)
            User.delete_user(username)
            self.redirect(self.reverse_url('users.overview'))
        else:
            return 'Error'

    def _password(self, username, form):
        if form.validate():
            if form.username.data != username:
                return 'Wrong username'

            logger.info(self.user_audit_text('Updated user %s password'),
                        username)
            User.update_password(username, form.password.data)
            self.redirect(self.reverse_url('users.overview'))
        else:
            return 'Error'

# encoding=utf-8