Example #1
0
    def edit_profile(self):
        user = self.request.context

        if not user:
            return HTTPNotFound()

        if self.request.method == 'GET':
            username = user.username
            email = user.email

            appstruct = {'username': username, 'email': email if email else ''}
            return render_form(self.request, self.form, appstruct)

        elif self.request.method == 'POST':
            controls = self.request.POST.items()

            try:
                captured = validate_form(controls, self.form)
            except FormValidationFailure as e:
                # We pre-populate username
                return e.result(self.request, username=user.username)

            email = captured.get('email', None)

            if email:
                email_user = self.User.get_by_email(self.request, email)

                if email_user:
                    if email_user.id != user.id:
                        FlashMessage(self.request,
                                     _('That e-mail is already used.'),
                                     kind='error')
                        return HTTPFound(location=self.request.url)

                user.email = email

            password = captured.get('password')

            if password:
                user.password = password

            FlashMessage(self.request,
                         self.Str.edit_profile_done,
                         kind='success')

            self.db.add(user)

            self.request.registry.notify(
                ProfileUpdatedEvent(self.request, user, captured))
            return HTTPFound(location=self.request.url)
Example #2
0
    def create_user(self):
        schema = AdminUserSchema()
        schema = schema.bind(request=self.request)
        form = HorusForm(schema)

        if self.request.method == 'GET':
            if isinstance(self.request.context, RootFactory):
                return dict(form=form)
            else:
                return dict(form=form,
                            appstruct=self.request.context.__json__(
                                self.request))
        else:
            try:
                controls = self.request.POST.items()
                captured = form.validate(controls)
            except deform.ValidationFailure as e:
                return dict(form=e, errors=e.error.children)

            if isinstance(self.request.context, RootFactory):
                user = self.User(username=captured['username'],
                                 email=captured['email'])
            else:
                user = self.request.context

            if captured['password']:
                user.password = captured['password']

            self.db.add(user)

            FlashMessage(self.request, self.Str.admin_create_user_done,
                         'success')

            return HTTPFound(
                location=self.request.route_url('admin_users_index'))
Example #3
0
    def activate(self):
        request = self.request
        schema = request.registry.getUtility(interfaces.IActivateSchema)
        schema = schema().bind(request=self.request)
        form = request.registry.getUtility(interfaces.IActivateForm)(schema)

        appstruct = None
        result = None
        try:
            appstruct = form.validate(request.POST.items())
        except deform.ValidationFailure as e:
            result = dict(form=e.render(), errors=e.error.children)
        else:
            code = appstruct['code']
            activation = self.Activation.get_by_code(request, code)
            user = None
            if activation:
                user = self.User.get_by_activation(request, activation)

            request.user = user
            if user:
                user.password = appstruct['password']
                self.db.add(user)
                self.db.delete(activation)
                FlashMessage(request, self.Str.authenticated, kind='success')
            else:
                form.error = colander.Invalid(
                    form.schema, _('This activation code is not valid.'))
                result = dict(form=form.render(), errors=[form.error])

        return self.respond(result)
Example #4
0
    def login(self):
        if self.request.method == 'GET':
            if self.request.user:
                return HTTPFound(location=self.login_redirect_view)
            return render_form(self.request, self.form)

        elif self.request.method == 'POST':
            controls = self.request.POST.items()

            try:
                captured = validate_form(controls, self.form)
            except FormValidationFailure as e:
                return e.result(self.request)

            username = captured['username']
            password = captured['password']

            try:
                user = self.check_credentials(username, password)
            except AuthenticationFailure as e:
                FlashMessage(self.request, str(e), kind='error')
                return render_form(self.request,
                                   self.form,
                                   captured,
                                   errors=[e])

            self.request.user = user  # Please keep this line, my app needs it

            return authenticated(self.request, user.id_value)
Example #5
0
 def logout(self):
     """Removes the auth cookies and redirects to the view defined in
     horus.logout_redirect, which defaults to a view named 'index'.
     """
     self.request.session.invalidate()
     FlashMessage(self.request, self.Str.logout, kind='success')
     headers = forget(self.request)
     return HTTPFound(location=self.logout_redirect_view, headers=headers)
Example #6
0
    def register(self):
        if self.request.method == 'GET':
            if self.request.user:
                return HTTPFound(location=self.after_register_url)

            return render_form(self.request, self.form)

        elif self.request.method != 'POST':
            return

        # If the request is a POST:
        controls = self.request.POST.items()

        try:
            captured = validate_form(controls, self.form)
        except FormValidationFailure as e:
            return e.result(self.request)

        # With the form validated, we know email and username are unique.
        del captured['csrf_token']
        user = self.persist_user(captured)

        autologin = asbool(self.settings.get('horus.autologin', False))

        if self.require_activation:
            # SEND EMAIL ACTIVATION
            create_activation(self.request, user)
            FlashMessage(self.request,
                         self.Str.activation_check_email,
                         kind='success')
        elif not autologin:
            FlashMessage(self.request,
                         self.Str.registration_done,
                         kind='success')

        self.request.registry.notify(
            NewRegistrationEvent(self.request, user, None, controls))
        if autologin:
            self.db.flush()  # in order to get the id
            return authenticated(self.request, user.id)
        else:  # not autologin: user must log in just after registering.
            return HTTPFound(location=self.after_register_url)
Example #7
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 httpexceptions.HTTPFound(
                    location=self.forgot_password_redirect_view)
            else:
                return {'form': form.render()}

        controls = req.POST.items()
        try:
            captured = form.validate(controls)
        except deform.ValidationFailure as e:
            return {'form': e.render(), 'errors': e.error.children}

        user = self.User.get_by_email(req, captured['email'])
        activation = self.Activation()
        self.db.add(activation)
        user.activation = activation

        mailer = get_mailer(req)
        username = getattr(user, 'short_name', '') or \
            getattr(user, 'full_name', '') or \
            getattr(user, 'username', '') or user.email
        emailtext = ("Hello, {username}!\n\n"
                     "Someone requested resetting your password. If it was "
                     "you, reset your password by using this reset code:\n\n"
                     "{code}\n\n"
                     "Alternatively, you can reset your password by "
                     "clicking on this link:\n\n"
                     "{link}\n\n"
                     "If you don't want to change your password, please "
                     "ignore this email message.\n\n"
                     "Regards,\n"
                     "The Hypothesis Team\n")
        body = emailtext.format(code=user.activation.code,
                                link=route_url('reset_password',
                                               req,
                                               code=user.activation.code),
                                username=username)
        subject = self.Str.reset_password_email_subject
        message = Message(subject=subject, recipients=[user.email], body=body)
        mailer.send(message)
        FlashMessage(self.request,
                     self.Str.reset_password_email_sent,
                     kind='success')
        return httpexceptions.HTTPFound(
            location=self.reset_password_redirect_view)
Example #8
0
def authenticated(request, userid):
    """Sets the auth cookies and redirects to the page defined
    in horus.login_redirect, which defaults to a view named 'index'.
    """
    settings = request.registry.settings
    headers = remember(request, userid)
    autologin = asbool(settings.get('horus.autologin', False))

    if not autologin:
        Str = request.registry.getUtility(IUIStrings)
        FlashMessage(request, Str.authenticated, kind='success')

    location = get_config_route(request, 'horus.login_redirect')

    return HTTPFound(location=location, headers=headers)
Example #9
0
 def respond(self, result):
     errors = isinstance(result, dict) and result.pop('errors', []) or []
     if len(errors):
         for e in errors:
             if isinstance(e, colander.Invalid):
                 msgs = e.messages()
             else:
                 msgs = [str(e)]
             for m in msgs:
                 FlashMessage(self.request, m, kind='error')
         return self.failure(
             _('Your submission is invalid. '
               'Please try again.'))
     else:
         return self.success()
Example #10
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 render_form(req, form)

        # From here on, we know it's a POST. Let's validate the form
        controls = req.POST.items()

        try:
            captured = validate_form(controls, form)
        except FormValidationFailure as e:
            return e.result(req)

        user = self.User.get_by_email(req, captured['email'])
        activation = self.Activation()
        self.db.add(activation)
        user.activation = activation
        self.db.flush()  # initialize activation.code

        Str = self.Str

        # TODO: Generate msg in a separate method so subclasses can override
        mailer = get_mailer(req)
        username = getattr(user, 'short_name', '') or \
            getattr(user, 'full_name', '') or \
            getattr(user, 'username', '') or user.email
        body = Str.reset_password_email_body.format(link=route_url(
            'reset_password', req, code=user.activation.code),
                                                    username=username,
                                                    domain=req.application_url)
        subject = Str.reset_password_email_subject
        message = Message(subject=subject, recipients=[user.email], body=body)
        mailer.send(message)

        FlashMessage(self.request,
                     Str.reset_password_email_sent,
                     kind='success')
        return HTTPFound(location=self.reset_password_redirect_view)
Example #11
0
def update_account(request):
    user = _validate_request(request)

    form = _form_for_update_account(request)
    try:
        appstruct = form.validate(request.POST.items())
    except deform.ValidationFailure:
        return {'form': form}

    # The token is valid and the form validates, so we can go ahead and claim
    # the account:
    user.password = appstruct['password']

    msg = _('Your account has been successfully claimed.')
    FlashMessage(request, msg, kind='success')

    request.registry.notify(LoginEvent(request, user))
    return exc.HTTPFound(location=request.route_url('index'))
Example #12
0
    def reset_password(self):
        schema = self.request.registry.getUtility(IResetPasswordSchema)
        schema = schema().bind(request=self.request)

        form = self.request.registry.getUtility(IResetPasswordForm)
        form = form(schema)

        code = self.request.matchdict.get('code', None)

        activation = self.Activation.get_by_code(self.request, code)

        if activation:
            user = self.User.get_by_activation(self.request, activation)

            if user:
                if self.request.method == 'GET':
                    appstruct = {'username': user.username}
                    return render_form(self.request, form, appstruct)

                elif self.request.method == 'POST':
                    controls = self.request.POST.items()

                    try:
                        captured = validate_form(controls, form)
                    except FormValidationFailure as e:
                        return e.result(self.request)

                    password = captured['password']

                    user.password = password
                    self.db.add(user)
                    self.db.delete(activation)

                    FlashMessage(self.request,
                                 self.Str.reset_password_done,
                                 kind='success')
                    self.request.registry.notify(
                        PasswordResetEvent(self.request, user, password))
                    location = self.reset_password_redirect_view
                    return HTTPFound(location=location)
        return HTTPNotFound()
Example #13
0
    def activate(self):
        """Activate a user and set a password given an activation code.

        This view is different from the activation view in horus because it
        does not require the user id to be passed. It trusts the activation
        code and updates the password.
        """
        request = self.request
        Str = self.Str

        schema = schemas.ActivationSchema.bind(request=request)
        form = forms.ActivateForm(schema)
        appstruct = None

        try:
            appstruct = form.validate(request.POST.items())
        except deform.ValidationFailure as e:
            return dict(errors=e.error.children)

        code = appstruct['code']
        activation = models.Activation.get_by_code(request, code)

        user = None
        if activation:
            user = self.User.get_by_activation(request, activation)

        if user is None:
            return dict(errors=[_('This activation code is not valid.')])

        user.password = appstruct['password']
        self.db.delete(activation)
        self.db.add(user)

        FlashMessage(request, Str.reset_password_done, kind='success')

        # XXX: Horus should maybe do this for us
        event = events.RegistrationActivatedEvent(request, user, activation)
        request.registry.notify(event)

        return {}
Example #14
0
    def disable_user(self):
        request = self.request
        schema = schemas.EditProfileSchema().bind(request=request)
        form = deform.Form(schema)

        try:
            appstruct = form.validate(request.POST.items())
        except deform.ValidationFailure as e:
            return dict(errors=e.error.children)

        username = appstruct['username']
        pwd = appstruct['pwd']

        # Password check
        user = self.User.get_user(request, username, pwd)
        if user:
            # TODO: maybe have an explicit disabled flag in the status
            user.password = self.User.generate_random_password()
            self.db.add(user)
            FlashMessage(self.request, _('Account disabled.'), kind='success')
            return {}
        else:
            return dict(errors=[{'pwd': _('Invalid password')}], code=401)
Example #15
0
    def activate(self):
        code = self.request.matchdict.get('code', None)
        user_id = self.request.matchdict.get('user_id', None)

        activation = self.Activation.get_by_code(self.request, code)

        if activation:
            user = self.User.get_by_id(self.request, user_id)

            if user.activation != activation:
                return HTTPNotFound()

            if user:
                self.db.delete(activation)
                # self.db.add(user)  # not necessary
                self.db.flush()
                FlashMessage(self.request,
                             self.Str.activation_email_verified,
                             kind='success')
                self.request.registry.notify(
                    RegistrationActivatedEvent(self.request, user, activation))
                return HTTPFound(location=self.after_activate_url)
        return HTTPNotFound()
Example #16
0
def _perform_logged_in_redirect(request):
    msg = _('You are already signed in, please log out to claim an account.')
    FlashMessage(request, msg, kind='error')
    raise exc.HTTPFound(location=request.route_url('stream'))
Example #17
0
def _perform_already_claimed_redirect(request):
    msg = _('This account has already been claimed.')
    FlashMessage(request, msg, kind='error')
    raise exc.HTTPFound(location=request.route_url('stream'))