Ejemplo n.º 1
0
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()}
Ejemplo n.º 2
0
 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"))
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
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()
Ejemplo n.º 5
0
    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()}
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
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()
Ejemplo n.º 8
0
    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)
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
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")
Ejemplo n.º 12
0
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")
Ejemplo n.º 13
0
 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)
Ejemplo n.º 14
0
    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"))
Ejemplo n.º 15
0
    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"))
Ejemplo n.º 16
0
    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")
Ejemplo n.º 17
0
    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"))
Ejemplo n.º 18
0
    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)
Ejemplo n.º 19
0
    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"))
Ejemplo n.º 20
0
    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))
Ejemplo n.º 21
0
    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"))
Ejemplo n.º 22
0
    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))
Ejemplo n.º 23
0
    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
Ejemplo n.º 24
0
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}
Ejemplo n.º 25
0
    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)
Ejemplo n.º 26
0
    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)
Ejemplo n.º 27
0
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"))
Ejemplo n.º 28
0
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}
Ejemplo n.º 29
0
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"))
Ejemplo n.º 30
0
    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)
Ejemplo n.º 31
0
    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)
Ejemplo n.º 32
0
    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()
Ejemplo n.º 33
0
    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)
Ejemplo n.º 34
0
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()
Ejemplo n.º 35
0
    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"))
Ejemplo n.º 36
0
    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)
Ejemplo n.º 37
0
    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
Ejemplo n.º 38
0
    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"))
Ejemplo n.º 39
0
    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
Ejemplo n.º 40
0
    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)
Ejemplo n.º 41
0
    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)
Ejemplo n.º 42
0
    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)
Ejemplo n.º 43
0
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"))
Ejemplo n.º 44
0
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)
Ejemplo n.º 45
0
    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")
Ejemplo n.º 46
0
    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")
Ejemplo n.º 47
0
    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)
Ejemplo n.º 48
0
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"))
Ejemplo n.º 49
0
    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()
Ejemplo n.º 50
0
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()
Ejemplo n.º 51
0
    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)
Ejemplo n.º 52
0
 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"))
Ejemplo n.º 53
0
 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")
Ejemplo n.º 54
0
    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"))
Ejemplo n.º 55
0
 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))
Ejemplo n.º 56
0
 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"]))