def activate_by_email(self, activation_code: str, location=None) -> Response: """Active a user after user after the activation email. * User clicks link in the activation email * User enters the activation code on the form by hand """ request = self.request settings = request.registry.settings user_registry = get_user_registry(request) after_activate_url = request.route_url(settings.get('websauna.activate_redirect', 'index')) login_after_activation = asbool(settings.get('websauna.login_after_activation', False)) user = user_registry.activate_user_by_email_token(activation_code) if not user: raise HTTPNotFound("Activation code not found") if login_after_activation: login_service = get_login_service(self.request.registry) return login_service.authenticate(self.request, user) else: self.request.registry.notify(RegistrationActivatedEvent(self.request, user, None)) return HTTPFound(location=location or after_activate_url)
def activate_by_email(self, activation_code: str, location: str = None) -> Response: """Active a user after user after the activation email. * User clicks link in the activation email * User enters the activation code on the form by hand :param activation_code: Activation code for user account. :param location: URL to redirct the user to, after activation. :raise: HTTPNotFound is activation_code is invalid. :return: Redirect to location. """ request = self.request settings = request.registry.settings user_registry = get_user_registry(request) after_activate_url = request.route_url( settings.get('websauna.activate_redirect', 'index')) login_after_activation = asbool( settings.get('websauna.login_after_activation', False)) user = user_registry.activate_user_by_email_token(activation_code) if not user: raise HTTPNotFound("Activation code not found") if login_after_activation: login_service = get_login_service(self.request) return login_service.authenticate_user(user, login_source="email") else: self.request.registry.notify( RegistrationActivatedEvent(self.request, user, None)) return HTTPFound(location=location or after_activate_url)
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 activate_by_email(self, activation_code: str, location=None) -> Response: """Active a user after user after the activation email. * User clicks link in the activation email * User enters the activation code on the form by hand """ request = self.request dbsession = self.request.dbsession settings = request.registry.settings user_registry = get_user_registry(request) after_activate_url = request.route_url( settings.get('horus.activate_redirect', 'index')) login_after_activation = asbool( settings.get('horus.login_after_activation', False)) user = user_registry.activate_user_by_email_token(activation_code) if not user: raise HTTPNotFound("Activation code not found") if login_after_activation: login_service = get_login_service(self.request.registry) return login_service.authenticate(self.request, user) else: self.request.registry.notify( RegistrationActivatedEvent(self.request, user, None)) return HTTPFound(location=location or after_activate_url)
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 logout(request: Request) -> Response: """Logout view. :param request: Pyramid request. :return: Context to be used by the renderer. """ if request.method != "POST": # No GET / CSRF logouts return HTTPMethodNotAllowed() login_service = get_login_service(request) return login_service.logout()
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 verify_email_login(request: Request, token: str): """Verify email login token.""" redis = get_redis(request.registry) def fail(msg="Sign in link invalid. Please try again."): messages.add(request, kind="error", msg=msg, msg_id="msg-bad-email-token") return HTTPFound(request.route_url("login")) # Hackety hacky by our Russian friends again? if len(token) != EMAIL_TOKEN_LENGTH: logger.warn("Bad token: %s", token) return fail() token_data = redis.hget(LOGIN_VERIFICATION_REDIS_HKEY, token) if not token_data: return fail() # Allow use the code only once, then erase redis.hdel(LOGIN_VERIFICATION_REDIS_HKEY, token) data = json.loads(token_data.decode("utf-8")) # Only verify email tokens in this view assert data["token_type"] == "email" if time.time() > data["expires"]: return fail("Sign in link expired. Please try again.") email = data["email"] # Create new user or get existing user based on this email user = get_or_create_email_user(request, email) login_service = get_login_service(request) # next_url was saved to the Redis by the view that rendered login buttons next_url = data.get("next_url") # Restore extra passed parameters request.session["login_extras"] = data.get("extras", {}) # Returns HTTPRedirect taking user to post-login page return login_service.authenticate_user(user, login_source="email", location=next_url)
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 logout(self): # Don't allow <img src="http://server/logout"> assert self.request.method == "POST" check_csrf_token(self.request) login_service = get_login_service(self.request) return login_service.logout()