Source code for publiforge.views.security

# pylint: disable = C0322
"""Security view callables."""

from colander import Mapping, SchemaNode, String, Boolean, Length

from pyramid.view import view_config
from pyramid.view import notfound_view_config, forbidden_view_config
from pyramid.httpexceptions import HTTPFound, HTTPNotAcceptable
from pyramid.security import forget, remember
from pyramid.security import NO_PERMISSION_REQUIRED

from ..lib.i18n import _
from ..lib.utils import normalize_name
from ..lib.log import log_activity
from ..lib.viewutils import connect_user
from ..lib.form import button, Form
from ..models import ID_LEN, close_dbsession


# =============================================================================
[docs]def login(request): """This view renders a login form and processes the post checking credentials. """ # Maintenance if request.registry.settings.get('maintenance') == 'true': return HTTPFound(request.route_path('maintenance')) # Create form schema = SchemaNode(Mapping()) schema.add(SchemaNode(String(), name='login', validator=Length(min=2))) schema.add(SchemaNode(String(), name='password', validator=Length(min=8))) schema.add(SchemaNode(Boolean(), name='remember', missing=False)) came_from = request.params.get('came_from') \ or (request.url != request.route_url('login') and request.url) \ or request.route_url('home') form = Form(request, schema=schema, defaults={'came_from': came_from}) # Validate form # pylint: disable = E1103 if form.validate(): user_login = normalize_name(form.values['login'])[0:ID_LEN].lower() password = form.values['password'] user = connect_user(request, user_login, password) if not isinstance(user, int): user.setup_environment(request) log_activity(request, 'login') max_age = int(request.registry.settings.get( 'auth.remember', '5184000')) if form.values['remember'] \ else None close_dbsession(request) return HTTPFound( location=came_from, headers=remember(request, user.login, max_age=max_age)) request.session.flash({ 1: _('ID or password is incorrect.'), 2: _('Your account is not active.'), 3: _('Your account has expired.'), 4: _('Your IP is rejected.')}[user], 'alert') close_dbsession(request) return {'form': form}
# =============================================================================
[docs]@view_config(route_name='logout') def logout(request): """This view will clear the credentials of the logged in user and redirect back to the login page. """ if 'login' in request.session: log_activity(request, 'logout') request.session.clear() close_dbsession(request) return HTTPFound( location=request.route_path('login'), headers=forget(request))
# =============================================================================
[docs]class ErrorView(object): """Class to manage error page.""" # ------------------------------------------------------------------------- def __init__(self, request): """Constructor method.""" self._request = request # -------------------------------------------------------------------------
[docs] @notfound_view_config(renderer='../Templates/error.pt') @forbidden_view_config(renderer='../Templates/error.pt') @view_config(context=HTTPNotAcceptable, renderer='../Templates/error.pt', permission=NO_PERMISSION_REQUIRED) @notfound_view_config(renderer='json', xhr=True) @forbidden_view_config(renderer='json', xhr=True) @view_config(context=HTTPNotAcceptable, renderer='json', xhr=True) def error(self): """This view outputs an error message or redirects to login page.""" status = self._request.exception.status_int if self._request.is_xhr: return {'error': status} if status in (401, 403) \ and self._request.authenticated_userid is None: return HTTPFound(self._request.route_path( 'login', _query=(('came_from', self._request.path),))) self._request.response.status = status self._request.breadcrumbs.add(_('Error ${status}', {'status': status})) return { 'button': button, 'message': self._request.exception.comment or { 403: _('Access was denied to this resource.'), 404: _('The resource could not be found.'), 406: _('The server could not comply with the request since' ' it is either malformed or otherwise incorrect.'), 500: _('Internal Server Error.')}.get( status, self._request.exception.explanation)}