def forgot_password(request): schema = request.registry.getUtility(IForgotPasswordSchema) schema = schema().bind(request=request) form = request.registry.getUtility(IForgotPasswordForm) form = form(schema) if request.method == 'POST': # From here on, we know it's a POST. Let's validate the form controls = request.POST.items() try: captured = form.validate(controls) except deform.ValidationFailure as e: # This catches if the email does not exist, too. return {'form': e.render(), 'errors': e.error.children} credential_activity_service = get_credential_activity_service(request) # Process valid form email = captured["email"] try: return credential_activity_service.create_forgot_password_request( email) except CannotResetPasswordException as e: messages.add(request, msg=str(e), msg_id="msg-cannot-reset-password", kind="error") return {'form': form.render()} return {'form': form.render()}
def do_success(self): messages.add(self.request, kind="success", msg="Password changed.", msg_id="msg-password-changed") # Redirect back to view page after edit page has succeeded return HTTPFound(self.request.resource_url(self.context, "show"))
def __call__(self, request: Request): user = request.user if user: try: session_created_at = request.session["created_at"] if not user.is_valid_session(session_created_at): request.session.invalidate() messages.add( request, kind="error", msg= "Your have been logged out due to authentication changes. ", msg_id="msg-session-invalidated") return HTTPFound(request.application_url) except sqlalchemy.orm.exc.DetachedInstanceError: if good_reify: # pyramid_tm 2.0 raise # TODO: pyramid_tm 2.0 needed, # now temporary just kill user object instead of failing with an internal error, so that development server doesn't fail with CSS etc. resources request.user = None response = self.handler(request) return response
def detail(request: Request): # Convert base64 encoded UUID string from request path to Python UUID object question_uuid = slug_to_uuid(request.matchdict["question_uuid"]) question = request.dbsession.query(Question).filter_by(uuid=question_uuid).first() if not question: raise HTTPNotFound() if request.method == "POST": # Check that CSRF token was good check_csrf_token(request) question = request.dbsession.query(Question).filter_by(uuid=question_uuid).first() if not question: raise HTTPNotFound() if "choice" in request.POST: # Extracts the form choice and turn it to UUID object chosen_uuid = slug_to_uuid(request.POST["choice"]) selected_choice = question.choices.filter_by(uuid=chosen_uuid).first() selected_choice.votes += 1 messages.add(request, msg="Thank you for your vote", kind="success") return HTTPFound(request.route_url("results", question_uuid=uuid_to_slug(question.uuid))) else: error_message = "You did not select any choice." return locals()
def forgot_password(self): req = self.request schema = req.registry.getUtility(IForgotPasswordSchema) schema = schema().bind(request=req) form = req.registry.getUtility(IForgotPasswordForm) form = form(schema) if req.method == 'GET': if req.user: return HTTPFound(location=self.forgot_password_redirect_view) else: return {'form': form.render()} # From here on, we know it's a POST. Let's validate the form controls = req.POST.items() try: captured = form.validate(controls) except deform.ValidationFailure as e: # This catches if the email does not exist, too. return {'form': e.render(), 'errors': e.error.children} credential_activity_service = get_credential_activity_service(self.request) # Process valid form email = captured["email"] try: return credential_activity_service.create_forgot_password_request(email) except CannotResetPasswordException as e: messages.add(self.request, msg=str(e), msg_id="msg-cannot-reset-password", kind="error") return {'form': form.render()}
def sign_up(self, user_data: dict) -> Response: """Sign up a new user.""" user_registry = get_user_registry(self.request) user = user_registry.sign_up(registration_source="email", user_data=user_data) # Notify site creator to initialize the admin for the first user self.request.registry.notify(UserCreated(self.request, user)) settings = self.request.registry.settings require_activation = asbool(settings.get('websauna.require_activation', True)) autologin = asbool(settings.get('websauna.autologin', False)) if require_activation: self.create_email_activation(user) elif not autologin: messages.add(self.request, msg_id="msg-sign-up-complete", msg="Sign up complete. Welcome!", kind="success") self.request.registry.notify(NewRegistrationEvent(self.request, user, None, user_data)) self.request.dbsession.flush() # in order to get the id if autologin: login_service = get_login_service(self.request.registry) return login_service.authenticate(self.request, user) else: # not autologin: user must log in just after registering. return render_to_response('login/waiting_for_activation.html', {"user": user}, request=self.request)
def detail(request: Request): # Convert base64 encoded UUID string from request path to Python UUID object question_uuid = slug_to_uuid(request.matchdict["question_uuid"]) question = request.dbsession.query(Question).filter_by( uuid=question_uuid).first() if not question: raise HTTPNotFound() if request.method == "POST": question = request.dbsession.query(Question).filter_by( uuid=question_uuid).first() if not question: raise HTTPNotFound() if "choice" in request.POST: # Extracts the form choice and turn it to UUID object chosen_uuid = slug_to_uuid(request.POST['choice']) selected_choice = question.choices.filter_by( uuid=chosen_uuid).first() selected_choice.votes += 1 messages.add(request, msg="Thank you for your vote", kind="success") return HTTPFound( request.route_url("results", question_uuid=uuid_to_slug(question.uuid))) else: error_message = "You did not select any choice." return locals()
def __call__(self, request: Request): user = request.user if user: try: session_authenticated_at = request.session.get( "authenticated_at") # User was deauthenticatd in this request for some reason if session_authenticated_at: if not user.is_valid_session(session_authenticated_at): request.session.invalidate() messages.add( request, kind="error", msg= "Your have been logged out due to authentication changes.", msg_id="msg-session-invalidated") logger.info( "User log out forced due to security sensitive settings change, user %s, session id %s", user, request.session.session_id) return HTTPFound(request.application_url) except sqlalchemy.orm.exc.DetachedInstanceError: if good_reify: # pyramid_tm 2.0 raise # TODO: pyramid_tm 2.0 needed, # now temporary just kill user object instead of failing with an internal error, so that development server doesn't fail with CSS etc. resources request.user = None response = self.handler(request) return response
def create_forgot_password_request(self, email, location=None) -> Response: """Create a new email activation token for a user and produce the following screen. * Sets user password reset token * Sends out reset password email * The existing of user with such email should be validated beforehand :raise: CannotResetPasswordException if there is any reason the password cannot be reset. Usually wrong email. """ request = self.request user_registry = get_user_registry(request) reset_info = user_registry.create_password_reset_token(email) if not reset_info: raise CannotResetPasswordException("Cannot reset password for email: {}".format(email)) user, token, expiration_seconds = reset_info link = request.route_url('reset_password', code=token) context = dict(link=link, user=user, expiration_hours=int(expiration_seconds/3600)) send_templated_mail(request, [email,], "login/email/forgot_password", context=context) messages.add(request, msg="Please check your email to continue password reset.", kind='success', msg_id="msg-check-email") if not location: location = get_config_route(request, 'websauna.request_password_reset_redirect') assert location return HTTPFound(location=location)
def reset_password(self, activation_code: str, password: str, location=None) -> Response: """Perform actual password reset operations. User has following password reset link (GET) or enters the code on a form. """ request = self.request user_registry = get_user_registry(request) user = user_registry.get_user_by_password_reset_token(activation_code) if not user: return HTTPNotFound("Activation code not found") user_registry.reset_password(user, password) messages.add( request, msg= "The password reset complete. Please sign in with your new password.", kind='success', msg_id="msg-password-reset-complete") request.registry.notify( PasswordResetEvent(self.request, user, password)) request.registry.notify( UserAuthSensitiveOperation(self.request, user, "password_reset")) location = location or get_config_route( request, 'horus.reset_password_redirect') return HTTPFound(location=location)
def subscribe_newsletter(request: Request): """Newsletter Subscription view.""" schema = NewsletterSubscriptionSchema().bind(request=request) form = deform.Form(schema) # In case of validation error, we return the user to the form came_from = request.referer or request.route_url('home') if request.method != "POST": return HTTPBadRequest("POST-only endpoint") # User submitted this form if 'subscribe' in request.POST: try: appstruct = form.validate(request.POST.items()) email = appstruct["email"] came_from = appstruct["came_from"] subscribe_email(request, email) # Thank user and take them to the next page msg = "<strong>{email}</strong> has been subscribed to the newsletter.".format(email=email) msg_class = 'info' messages.add(request, kind=msg_class, msg=msg, html=True) except deform.ValidationFailure: # Render a form version where errors are visible next to the fields, # and the submitted values are posted back msg = "Email was not valid." msg_class = 'error' messages.add(request, kind=msg_class, msg=msg) return HTTPFound(came_from) else: # We don't know which control caused form submission return HTTPBadRequest("Unknown form button pressed")
def subscribe_newsletter(request: Request): schema = NewsletterSubscriptionSchema().bind(request=request) form = deform.Form(schema) # User submitted this form if request.method == "POST": if 'subscribe' in request.POST: try: appstruct = form.validate(request.POST.items()) email = appstruct["email"] subscribe_email(request, email) # Thank user and take him/her to the next page messages.add( request, kind="info", html=True, msg= "<strong>{}</strong> has been subscribed to the newsletter." .format(email)) return HTTPFound(request.route_url("home")) except deform.ValidationFailure as e: # Render a form version where errors are visible next to the fields, # and the submitted values are posted back messages.add(request, kind="error", msg="Email was not valid") return HTTPFound(request.route_url("home")) else: # We don't know which control caused form submission return HTTPBadRequest("Unknown form button pressed") return HTTPBadRequest("POST-only endpoint")
def logout(self): # Don't allow <img src="http://server/logout"> assert self.request.method == "POST" check_csrf_token(self.request) self.request.session.invalidate() messages.add(self.request, msg="You are now logged out.", kind="success", msg_id="msg-logged-out") headers = forget(self.request) return HTTPFound(location=self.logout_redirect_view, headers=headers)
def do_success(self, resource: Resource): """Finish action after saving new object. Usually returns HTTP redirect to the next view. """ messages.add(self.request, kind="success", msg="Item added.", msg_id="msg-item-added") # Redirect back to view page after edit page has succeeded return HTTPFound(self.request.resource_url(resource, "show"))
def do_success(self, resource: Resource) -> Response: """Finish action after saving new object. Usually returns HTTP redirect to the next view. """ messages.add(self.request, kind="success", msg="Item added.", msg_id="msg-item-added") # Redirect back to view page after edit page has succeeded return HTTPFound(self.request.resource_url(resource, "show"))
def greet_user(self, user: IUser): """Allow easy overriding of a welcome message. :param user: User object. """ messages.add(self.request, kind="success", msg="You are now logged in.", msg_id="msg-you-are-logged-in")
def do_success(self) -> Response: """Called after the save (objectify) has succeeded.""" messages.add(self.request, kind="success", msg="Changes saved.", msg_id="msg-changes-saved") # Redirect back to view page after edit page has succeeded return HTTPFound(self.request.resource_url(self.context, "show"))
def do_error(self, authomatic_result: LoginResult, e: Exception) -> Response: """Handle getting error from OAuth provider.""" # We got some error result, now let see how it goes if e: # Leave a cue for sysadmins everything is not right. Use INFO level as usually this is just the user pressing Cancel on the OAuth pop up screen. logger.info(e) messages.add(self.request, kind="error", msg=str(e), msg_id="msg-authomatic-login-error") login_url = self.request.route_url("login") return HTTPFound(location=login_url)
def delete_item(self): """User picked YEAH LET'S DO IT.""" if not self.deleter: raise NotImplementedError("The subclass must implement actual delete method or give deleter callback.") self.deleter(self.context, self.request) messages.add(self.request, "Deleted {}".format(self.context.get_title()), msg_id="msg-item-deleted", kind="success") return HTTPFound(self.request.resource_url(self.get_crud(), "listing"))
def do_success(self): super(ConfirmPhoneNumber, self).do_success() wallet = self.context messages.add(self.request, kind="success", msg="Your mobile phone number has been confirmed.", msg_id="msg-phone-confirmed") if check_wallet_creation(self.request): wallet_welcome_page = self.request.registry.settings.get("websauna.wallet.welcome_page", "") return httpexceptions.HTTPFound(self.request.resource_url(wallet, wallet_welcome_page)) else: return httpexceptions.HTTPFound(self.request.resource_url(wallet))
def __call__(self, request:Request): user = request.user if user: session_created_at = request.session["created_at"] if not user.is_valid_session(session_created_at): request.session.invalidate() messages.add(request, kind="error", msg="Your have been logged out due to authentication changes. ", msg_id="msg-session-invalidated") return HTTPFound(request.application_url) response = self.handler(request) return response
def login(request: Request) -> [HTTPFound, dict]: """Default login view implementation. :param request: Pyramid request. :return: Context to be used by the renderer or a HTTPFound redirect if user is already logged in. """ login_redirect_view = get_config_route(request, "websauna.login_redirect") # Create login form schema schema = request.registry.getUtility(ILoginSchema) schema = schema().bind(request=request) # Create login form form = request.registry.getUtility(ILoginForm) form = form(schema) settings = request.registry.settings social_logins = aslist(settings.get("websauna.social_logins", "")) # Process form if request.method == "POST": try: controls = request.POST.items() captured = form.validate(controls) except deform.ValidationFailure as e: return {'form': e.render(), 'errors': e.error.children} username = captured['username'] password = captured['password'] login_service = get_login_service(request) try: return login_service.authenticate_credentials( username, password, login_source="login_form") except AuthenticationFailure as e: # Tell user they cannot login at the moment messages.add(request, msg=str(e), msg_id="msg-authentication-failure", kind="error") return { 'form': form.render(appstruct=captured), 'errors': [e], "social_logins": social_logins } else: # HTTP get, display login form if request.user: # Already logged in return HTTPFound(location=login_redirect_view) # Display login form return {'form': form.render(), "social_logins": social_logins}
def do_error(self, authomatic_result: LoginResult, e: Exception) -> Response: """Handle getting error from OAuth provider.""" # We got some error result, now let see how it goes request = self.request # TODO: Not sure if we shoul log this or now logger.exception(e) messages.add(self.request, kind="error", msg=str(e), msg_id="authomatic-login-error") login_url = self.request.route_url("login") return HTTPFound(location=login_url)
def do_error(self, authomatic_result: LoginResult, e: Exception) -> Response: """Handle getting error from OAuth provider.""" # We got some error result, now let see how it goes request = self.request if e: # Leave a cue for sysadmins everything is not right logger.exception(e) messages.add(self.request, kind="error", msg=str(e), msg_id="msg-authomatic-login-error") login_url = self.request.route_url("login") return HTTPFound(location=login_url)
def clear_history(request): if request.method != "POST": raise HTTPMethodNotAllowed() if not request.user: return HTTPFound(request.route_url("home")) mark_all_seen_by_user(request.user) messages.add(request, kind="info", msg="All notifications marked as seen.") return HTTPFound(request.route_url("notification_history"))
def login(request): """Default login view implementation.""" login_redirect_view = get_config_route(request, "websauna.login_redirect") # Create login form schema schema = request.registry.getUtility(ILoginSchema) schema = schema().bind(request=request) # Create login form form = request.registry.getUtility(ILoginForm) form = form(schema) settings = request.registry.settings social_logins = aslist(settings.get("websauna.social_logins", "")) # Process form if request.method == "POST": try: controls = request.POST.items() captured = form.validate(controls) except deform.ValidationFailure as e: return { 'form': e.render(), 'errors': e.error.children } username = captured['username'] password = captured['password'] login_service = get_login_service(request) try: return login_service.authenticate_credentials(username, password, login_source="login_form") except AuthenticationFailure as e: # Tell user they cannot login at the moment messages.add(request, msg=str(e), msg_id="msg-authentication-failure", kind="error") return { 'form': form.render(appstruct=captured), 'errors': [e], "social_logins": social_logins } else: # HTTP get, display login form if request.user: # Already logged in return HTTPFound(location=login_redirect_view) # Display login form return {'form': form.render(), "social_logins": social_logins}
def change_publish_status(context: PostAdmin.Resource, request: Request): """Change publish status.""" post = context.get_object() if post.published_at: post.published_at = None messages.add(request, kind="info", msg="The post has been retracted.", msg_id="msg-unpublished") else: post.published_at = now() messages.add(request, kind="info", msg="The post has been published.", msg_id="msg-published") # Back to show page return HTTPFound(request.resource_url(context, "show"))
def do_success(self, authomatic_result: LoginResult) -> Response: """Handle we got a valid OAuth login data. Try and log in the user. """ user = self.mapper.capture_social_media_user(self.request, authomatic_result) try: login_service = get_login_service(self.request) return login_service.authenticate_user(user, login_source=self.provider_name) except AuthenticationFailure as e: messages.add(self.request, kind="error", msg=str(e), msg_id="msg-cannot-login-social-media-user") login_url = self.request.route_url("login") return HTTPFound(location=login_url)
def send_confirmation(self): phone_number = self.get_target_phone_number() if not phone_number: messages.add(self.request, type="error", msg="You do not have phone number set. Please set a phone number before proceeding.") return context = { "sms_code": self.manual_confirmation.other_data["sms_code"], } sms_text = self.render_sms(context) send_sms(self.request, phone_number, sms_text) self.manual_confirmation.other_data["sms_sent_at"] = now()
def inner(*args, **kwargs): context, request = args wallet = get_wallet(context) user = request.user if not user: messages.add(request, kind="warning", msg="Please sign in to view the page.") return httpexceptions.HTTPFound(request.route_url("home")) # Redirect user to the phone number confirmation if request.registry.settings.get("websauna.wallet.require_phone_number"): if not UserNewPhoneNumberConfirmation.has_confirmed_phone_number(user): return httpexceptions.HTTPFound(request.resource_url(wallet, "new-phone-number")) return func(*args, **kwargs)
def create_address(wallet: UserWallet, request): """List all addresses.""" schema = CreateAddressSchema().bind(request=request) # Create a styled button with some extra Bootstrap 3 CSS classes b = deform.Button(name='process', title="Create", css_class="btn-primary btn-block btn-lg") form = deform.Form(schema, buttons=(b, )) # User submitted this form if request.method == "POST": if 'process' in request.POST: try: appstruct = form.validate(request.POST.items()) # Save form data from appstruct network = appstruct["network"] name = appstruct["name"] confirmations = get_required_confirmation_count( request.registry, network, CryptoOperationType.create_address) UserCryptoAddress.create_address(wallet.user, network, name, confirmations) # Thank user and take him/her to the next page messages.add(request, kind="info", msg="New account is being created", msg_id="msg-account-created") return HTTPFound(request.resource_url(wallet, "transactions")) except deform.ValidationFailure as e: # Render a form version where errors are visible next to the fields, # and the submitted values are posted back rendered_form = e.render() else: # We don't know which control caused form submission raise HTTPInternalServerError("Unknown form button pressed") else: # Render a form with initial values rendered_form = form.render() title = "Create new account" return locals()
def delete_object(self): """User picked YEAH LET'S DO IT. First try to call ``delete`` callback if one is set. If not then fallback to :py:meth:`websauna.system.crud.CRUD.delete_object`. http://opensourcehacker.com/wp-content/uploads/2013/04/koala.gif """ if self.deleter: self.deleter(self.context, self.request) else: self.get_crud().delete_object(self.get_object()) messages.add(self.request, "Deleted {}".format(self.context.get_title()), msg_id="msg-item-deleted", kind="success") return HTTPFound(self.request.resource_url(self.get_crud(), "listing"))
def __call__(self, request: Request): user = request.user if user: session_created_at = request.session["created_at"] if not user.is_valid_session(session_created_at): request.session.invalidate() messages.add( request, kind="error", msg= "Your have been logged out due to authentication changes. ", msg_id="msg-session-invalidated") return HTTPFound(request.application_url) response = self.handler(request) return response
def __call__(self, request: Request): user = request.user if user: try: session_created_at = request.session["created_at"] if not user.is_valid_session(session_created_at): request.session.invalidate() messages.add(request, kind="error", msg="Your have been logged out due to authentication changes. ", msg_id="msg-session-invalidated") return HTTPFound(request.application_url) except sqlalchemy.orm.exc.DetachedInstanceError: # TODO: pyramid_tm 2.0 needed, # now temporary just kill user object instead of failing with an internal error, so that development server doesn't fail with CSS etc. resources request.user = None response = self.handler(request) return response
def create_forgot_password_request(self, email: str, location: str = None) -> Response: """Create a new email activation token for a user and produce the following screen. * Sets user password reset token * Sends out reset password email * The existing of user with such email should be validated beforehand :param email: User email. :param location: URL to redirect the user after the password request. :return: Redirect to location. :raise: CannotResetPasswordException if there is any reason the password cannot be reset. Usually wrong email. """ request = self.request user_registry = get_user_registry(request) reset_info = user_registry.create_password_reset_token(email) if not reset_info: raise CannotResetPasswordException( "Cannot reset password for email: {email}".format(email=email)) user, token, expiration_seconds = reset_info link = request.route_url('reset_password', code=token) context = dict(link=link, user=user, expiration_hours=int(expiration_seconds / 3600)) send_templated_mail(request, [ email, ], "login/email/forgot_password", context=context) messages.add(request, msg="Please check your email to continue password reset.", kind='success', msg_id="msg-check-email") if not location: location = get_config_route( request, 'websauna.request_password_reset_redirect') assert location return HTTPFound(location=location)
def logout(self, location: str = None) -> Response: """Log out user from the site. * Terminate session * Show logged out message * Redirect the user to post login page :param location: Override the redirect page. If none use ``websauna.login_redirect``. TODO - to be changed. :return: HTTPFound to location. """ # TODO: Horus might go request = self.request logout_redirect_view = get_config_route(request, 'websauna.logout_redirect') location = location or logout_redirect_view messages.add(request, msg="You are now logged out.", kind="success", msg_id="msg-logged-out") headers = forget(request) return HTTPFound(location=location, headers=headers)
def logout(self, location=None) -> Response: """Log out user from the site. * Terminate session * Show logged out message * Redirect the user to post login page """ # TODO: Horus might go request = self.request logout_redirect_view = get_config_route(request, 'websauna.logout_redirect') location = location or logout_redirect_view messages.add(request, msg="You are now logged out.", kind="success", msg_id="msg-logged-out") headers = forget(request) return HTTPFound(location=location, headers=headers)
def example_view_post(request): """Demostrate require_login() decorator for POST views.""" global _was_logged_in global _captured_post_params login_state = pop_login_state(request) params = login_state["params"] if login_state else request.POST _was_logged_in = login_state is None _captured_post_params = params.copy() messages.add( request, kind="info", msg="Succesfully continued POST action after login, params {}".format( params), msg_id="msg-example-post-view-success") return HTTPFound(request.route_url("home"))
def authenticated(request:Request, user:UserMixin, location:str=None) -> HTTPFound: """Logs in the user. TODO: Make this is a registry component for overriding Sets the auth cookies and redirects to the page defined in horus.login_redirect, which defaults to a view named 'index'. Fills in user last login details. :param request: Current request :param user: User model to log in :param location: Override the redirect page. If none use ``horus.login_redirect`` """ # See that our user model matches one we expect from the configuration registry = request.registry User = get_user_class(registry) assert User assert isinstance(user, User) assert user.id, "Cannot login with invalid user object" if not user.can_login(): raise RuntimeError("Got authenticated() request for disabled user - should not happen") headers = remember(request, user.id) # assert headers, "Authentication backend did not give us any session headers" if not user.last_login_at: e = events.FirstLogin(request, user) request.registry.notify(e) # Update user security details user.last_login_at = now() user.last_login_ip = request.client_addr if not location: location = get_config_route(request, 'horus.login_redirect') messages.add(request, kind="success", msg="You are now logged in.", msg_id="msg-you-are-logged-in") return HTTPFound(location=location, headers=headers)
def login(self): social_logins = aslist(self.settings.get("websauna.social_logins", "")) if self.request.method == 'GET': if self.request.user: return HTTPFound(location=self.login_redirect_view) return {'form': self.form.render(), "social_logins": social_logins} elif self.request.method == 'POST': check_csrf_token(self.request) try: controls = self.request.POST.items() captured = self.form.validate(controls) except deform.ValidationFailure as e: return {'form': e.render(), 'errors': e.error.children} username = captured['username'] password = captured['password'] login_service = get_login_service(self.request) try: return login_service.authenticate_credentials( username, password, login_source="login_form") except AuthenticationFailure as e: # Tell user they cannot login at the moment messages.add(self.request, msg=str(e), msg_id="msg-authentication-failure", kind="error") return { 'form': self.form.render(appstruct=captured), 'errors': [e], "social_logins": social_logins } else: raise AssertionError("Unknown HTTP method")
def login(self): social_logins = aslist(self.settings.get("websauna.social_logins", "")) if self.request.method == 'GET': if self.request.user: return HTTPFound(location=self.login_redirect_view) return {'form': self.form.render(), "social_logins": social_logins} elif self.request.method == 'POST': check_csrf_token(self.request) try: controls = self.request.POST.items() captured = self.form.validate(controls) except deform.ValidationFailure as e: return { 'form': e.render(), 'errors': e.error.children } username = captured['username'] password = captured['password'] login_service = get_login_service(self.request) try: return login_service.authenticate_credentials(username, password, login_source="login_form") except AuthenticationFailure as e: # Tell user they cannot login at the moment messages.add(self.request, msg=str(e), msg_id="msg-authentication-failure", kind="error") return { 'form': self.form.render(appstruct=captured), 'errors': [e], "social_logins": social_logins } else: raise AssertionError("Unknown HTTP method")
def reset_password(self, activation_code: str, password: str, location=None) -> Response: """Perform actual password reset operations. User has following password reset link (GET) or enters the code on a form. """ request = self.request user_registry = get_user_registry(request) user = user_registry.get_user_by_password_reset_token(activation_code) if not user: return HTTPNotFound("Activation code not found") user_registry.reset_password(user, password) messages.add(request, msg="The password reset complete. Please sign in with your new password.", kind='success', msg_id="msg-password-reset-complete") request.registry.notify(PasswordResetEvent(self.request, user, password)) request.registry.notify(UserAuthSensitiveOperation(self.request, user, "password_reset")) location = location or get_config_route(request, 'websauna.reset_password_redirect') return HTTPFound(location=location)
def example_view_get(request): """Demostrate require_login() decorator for GET views.""" global _get_url global _was_logged_in _get_url = request.url login_state = pop_login_state(request) params = request.params or login_state _was_logged_in = login_state is None messages.add( request, kind="info", msg="Succesfully continued GET action after login, params {}".format( params), msg_id="msg-example-get-view-success") return HTTPFound(request.route_url("home"))
def send_confirmation(self): phone_number = self.get_target_phone_number() if not phone_number: messages.add( self.request, type="error", msg= "You do not have phone number set. Please set a phone number before proceeding." ) return context = { "sms_code": self.manual_confirmation.other_data["sms_code"], } sms_text = self.render_sms(context) send_sms(self.request, phone_number, sms_text) self.manual_confirmation.other_data["sms_sent_at"] = now()
def create_address(wallet: UserWallet, request): """List all addresses.""" schema = CreateAddressSchema().bind(request=request) # Create a styled button with some extra Bootstrap 3 CSS classes b = deform.Button(name='process', title="Create", css_class="btn-block btn-lg") form = deform.Form(schema, buttons=(b,)) # User submitted this form if request.method == "POST": if 'process' in request.POST: try: appstruct = form.validate(request.POST.items()) # Save form data from appstruct network = appstruct["network"] name = appstruct["name"] confirmations = get_required_confirmation_count(request.registry, network, CryptoOperationType.create_address) UserCryptoAddress.create_address(wallet.user, network, name, confirmations) # Thank user and take him/her to the next page messages.add(request, kind="info", msg="New account is being created", msg_id="msg-account-created") return HTTPFound(request.resource_url(wallet, "transactions")) except deform.ValidationFailure as e: # Render a form version where errors are visible next to the fields, # and the submitted values are posted back rendered_form = e.render() else: # We don't know which control caused form submission raise HTTPInternalServerError("Unknown form button pressed") else: # Render a form with initial values rendered_form = form.render() title = "Create new account" return locals()
def login(self): social_logins = aslist(self.settings.get("websauna.social_logins", "")) if self.request.method == 'GET': if self.request.user: return HTTPFound(location=self.login_redirect_view) return {'form': self.form.render(), "social_logins": social_logins} elif self.request.method == 'POST': try: controls = self.request.POST.items() captured = self.form.validate(controls) except deform.ValidationFailure as e: return { 'form': e.render(), 'errors': e.error.children } username = captured['username'] password = captured['password'] try: user = self.check_credentials(username, password) assert user.password except AuthenticationFailure as e: # Tell user they cannot login at the moment messages.add(self.request, msg=str(e), msg_id="msg-authentication-failure", kind="error") return { 'form': self.form.render(appstruct=captured), 'errors': [e], "social_logins": social_logins } return authenticated(self.request, user)
def greet_user(self, user: IUser): """Allow easy overridingn of a welcome message.""" messages.add(self.request, kind="success", msg="You are now logged in.", msg_id="msg-you-are-logged-in")
def do_cancel(self): super(ConfirmWithdraw, self).do_cancel() wallet = self.context.wallet messages.add(self.request, kind="success", msg="Withdraw cancelled.", msg_id="msg-withdraw-cancelled") return HTTPFound(self.request.resource_url(wallet))
def do_success(self): super(ConfirmWithdraw, self).do_success() wallet = self.context.wallet messages.add(self.request, kind="success", msg="Withdraw on its way.", msg_id="msg-withdraw-confirmed") return HTTPFound(self.request.resource_url(wallet["transactions"]))