def confirm_login_success(request): session = DBSession() result = session.query(CheckIdRequest)\ .filter_by(key=request.environ.get('repoze.browserid', ''))\ .first() if result is not None: openid_request = result.request session.delete(result) return auth_decision(request, openid_request) raise NotFound('Unknown OpenID request')
class PasswordResetView(object): """Password reset logic.""" def __init__(self, request): self.request = request self.session = DBSession() self.prune_expired() def prune_expired(self): """Prunes password reset requests that have expired.""" self.session.query(PasswordReset)\ .filter(PasswordReset.expires < datetime.now())\ .delete() def render_form(self): """Renders the password reset form.""" return { 'action_url': route_url('reset_password_initiate', self.request), 'title': _(u'Reset password'), } def password_change_form(self): """Renders the form for changing a password for a valid token.""" reset = self.session.query(PasswordReset)\ .filter(PasswordReset.token == self.request.matchdict['token'])\ .filter(PasswordReset.expires >= datetime.now())\ .first() if reset is None: # No matching password reset found raise NotFound() user = self.session.query(User).get(reset.user_id) if user is None: raise NotFound() return { 'action_url': route_url('reset_password_process', self.request), 'title': _(u'Change password'), 'token': reset.token, } def send_confirmation_message(self): """Sends an email confirmation message to the user.""" username = self.request.POST.get('username', '').strip() redirect_url = route_url('reset_password', self.request) if not username: self.request.session.flash(_(u'Please supply a username.')) else: user = self.session.query(User).filter(User.username == username).first() if user is None: self.request.session.flash(_(u'The given username does not match any account.')) else: # Create a password reset request that is valid for 24 hours reset = PasswordReset(user.id, datetime.now() + timedelta(hours=24)) self.session.add(reset) message = self.create_message(user, reset) from_address = self.request.registry.settings['webidentity_from_address'].strip() send_mail(from_address, [user.email], message) self.request.session.flash(_(u'Password retrieval instructions have been emailed to you.')) redirect_url = self.request.application_url return HTTPFound(location=redirect_url) def create_message(self, user, reset): """Returns an email.message.Message object representing the password reset message. """ from_address = self.request.registry.settings['webidentity_from_address'].strip() date_format = self.request.registry.settings['webidentity_date_format'].strip() locale = get_localizer(self.request) subject = locale.translate( _(u'Password reset for ${identity}', mapping={'identity': identity_url(self.request, user.username)})) message = Message() message['From'] = Header(from_address, 'utf-8') message['To'] = Header(u'{0} <{1}>'.format(user.username, user.email), 'utf-8') message['Subject'] = Header(subject, 'utf-8') message.set_payload(locale.translate(_( u'password-reset-email', default=textwrap.dedent(u''' Hi ${username} A password retrieval process has been initiated for your OpenID identity ${identity} If the process was initiated by you you can continue the process of resetting your password by opening the following link in your browser ${reset_url} The link will will expire at ${expiration}. If you did not initiate this request you can just ignore this email. Your password has not been changed. ''').lstrip(), mapping=dict( username=user.username, identity=identity_url(self.request, user.username), expiration=reset.expires.strftime(date_format), reset_url=route_url('reset_password_token', self.request, token=reset.token))))) return message def change_password(self): """Changes the password for a user.""" token = self.request.POST.get('token', '').strip() if token: password = self.request.POST.get('password', '') confirm_password = self.request.POST.get('confirm_password', '') if len(password.strip()) < 5: self.request.session.flash(_(u'Password must be at least five characters long')) return HTTPFound( location=route_url('reset_password_token', self.request, token=token)) elif password != confirm_password: self.request.session.flash(_(u'Given passwords do not match')) return HTTPFound( location=route_url('reset_password_token', self.request, token=token)) else: reset = self.session.query(PasswordReset)\ .filter(PasswordReset.token == token)\ .filter(PasswordReset.expires >= datetime.now())\ .first() if reset is None: raise NotFound() user = self.session.query(User).get(reset.user_id) if user is None: raise NotFound() # Update the user password user.password = password self.session.add(user) self.session.delete(reset) self.request.session.flash(_(u'Password changed.')) headers = remember(self.request, user.username) return HTTPFound(location=self.request.application_url, headers=headers) raise NotFound()
def confirm(request): """Confirmation for an OpenID authentication request.""" user = authenticated_user(request) if user is not None and 'form.submitted' in request.params: if request.POST.get('csrf_token') != request.session.get_csrf_token(): raise Forbidden session = DBSession() result = session.query(CheckIdRequest)\ .filter_by(key=request.environ.get('repoze.browserid', ''))\ .first() if result is not None: openid_request = result.request session.delete(result) else: # TODO: Return an error message return HTTPBadRequest('Invalid confirmation request') if 'accept' in request.params: ax_attributes = get_ax_attributes(request) visit = session.query(VisitedSite)\ .join(User)\ .filter(User.id == user.id)\ .filter(VisitedSite.trust_root == openid_request.trust_root)\ .first() if visit is None: # This is the first time the user is visiting this RP visit = VisitedSite(openid_request.trust_root) user.visited_sites.append(visit) visit.remember = 'remember' in request.params try: persona_id = int(request.params.get('persona')) # Make sure that the referenced persona actually belongs to the user persona = session.query(Persona)\ .join(User)\ .filter(User.id == user.id)\ .filter(Persona.id == persona_id)\ .first() if persona is not None: visit.persona = persona except (TypeError, ValueError): pass session.add(visit) identity = identity_url(request, user.username) openid_response = openid_request.answer(True, identity=identity) add_ax_response(openid_request, openid_response, ax_attributes) add_sreg_response(openid_request, openid_response, ax_attributes) if visit.remember: log_activity(request, Activity.AUTHORIZE, openid_request.trust_root) else: log_activity(request, Activity.AUTHORIZE_ONCE, openid_request.trust_root) else: log_activity(request, Activity.DENY, openid_request.trust_root) openid_response = openid_request.answer(False) store = AlchemyStore(session) openid_server = server.Server(store, route_url('openid_endpoint', request)) response = webob_response(openid_server.encodeResponse(openid_response), request) response.headerlist.extend(forget(request)) return response return HTTPBadRequest('Invalid confirmation request')