import deform from pyramid.httpexceptions import HTTPFound from pyramid.view import view_config from sqlalchemy import func, or_ from ordr.models.account import User, TokenSubject from ordr.events import PasswordResetNotification # below this password length a warning is displayed MIN_PW_LENGTH = 12 @view_config( context='ordr.resources.account.PasswordResetResource', permission='view', request_method='GET', renderer='ordr:templates/account/forgotten_password_form.jinja2' ) def forgotten_password_form(context, request): ''' show forgotten password form ''' return {'formerror': False} @view_config( context='ordr.resources.account.PasswordResetResource', permission='view', request_method='POST', renderer='ordr:templates/account/forgotten_password_form.jinja2' ) def forgotten_password_form_processing(context, request): ''' process forgotten password form ''' if 'cancel' in request.POST: return HTTPFound(request.resource_url(request.root)) identifier = request.POST.get('identifier', '') account = ( request.dbsession .query(User) .filter(or_( func.lower(User.username) == identifier.lower(), func.lower(User.email) == identifier.lower() )) .first() ) if account is None or not account.is_active: return {'formerror': True} # create a verify-new-account token and send email token = account.issue_token(request, TokenSubject.RESET_PASSWORD) notification = PasswordResetNotification( request, account, {'token': token} ) request.registry.notify(notification) return HTTPFound(request.resource_url(context, 'verify')) @view_config( context='ordr.resources.account.PasswordResetResource', name='verify', permission='view', request_method='GET', renderer='ordr:templates/account/forgotten_password_verify.jinja2' ) def verify(context, request): ''' show email verification text ''' return {} @view_config( context='ordr.resources.account.PasswordResetResource', name='completed', permission='view', request_method='GET', renderer='ordr:templates/account/forgotten_password_completed.jinja2' ) def completed(context, request): ''' user is verified, process reset password form ''' return {} @view_config( context='ordr.resources.account.PasswordResetTokenResource', permission='view', request_method='GET', renderer='ordr:templates/account/forgotten_password_reset.jinja2' ) def reset_password_form(context, request): ''' user is verified, show reset password form ''' form = context.get_reset_form() return {'form': form} @view_config( context='ordr.resources.account.PasswordResetTokenResource', permission='view', request_method='POST', renderer='ordr:templates/account/forgotten_password_reset.jinja2' ) def reset_password_form_processing(context, request): ''' process the password reset form ''' if 'change' not in request.POST: return HTTPFound(request.resource_url(request.root)) form = context.get_reset_form() data = request.POST.items() try: appstruct = form.validate(data) except deform.ValidationFailure as e: return {'form': form} # set new password token = context.model account = token.owner account.set_password(appstruct['password']) request.dbsession.delete(token) return HTTPFound(request.resource_url(context.__parent__, 'completed'))