예제 #1
0
def request_password_reset(request, _form_class=RequestPasswordResetForm):
    if request.authenticated_userid is not None:
        return HTTPSeeOther(request.route_path("index"))

    user_service = request.find_service(IUserService, context=None)
    form = _form_class(request.POST, user_service=user_service)
    if request.method == "POST" and form.validate():
        user = user_service.get_user_by_username(form.username_or_email.data)
        email = None
        if user is None:
            user = user_service.get_user_by_email(form.username_or_email.data)
            email = first(user.emails,
                          key=lambda e: e.email == form.username_or_email.data)

        send_password_reset_email(request, (user, email))
        user_service.record_event(
            user.id,
            tag="account:password:reset:request",
            ip_address=request.remote_addr,
        )

        token_service = request.find_service(ITokenService, name="password")
        n_hours = token_service.max_age // 60 // 60
        return {"n_hours": n_hours}

    return {"form": form}
예제 #2
0
def request_password_reset(request, _form_class=RequestPasswordResetForm):
    if request.authenticated_userid is not None:
        return HTTPSeeOther(request.route_path("index"))

    user_service = request.find_service(IUserService, context=None)
    form = _form_class(request.POST, user_service=user_service)
    if request.method == "POST" and form.validate():
        user = user_service.get_user_by_username(form.username_or_email.data)

        email = None
        if user is None:
            user = user_service.get_user_by_email(form.username_or_email.data)
            email = first(
                user.emails, key=lambda e: e.email == form.username_or_email.data
            )

        if not user_service.ratelimiters["password.reset"].test(user.id):
            raise TooManyPasswordResetRequests(
                resets_in=user_service.ratelimiters["password.reset"].resets_in(user.id)
            )

        if user.can_reset_password:
            send_password_reset_email(request, (user, email))
            user_service.record_event(
                user.id,
                tag="account:password:reset:request",
                ip_address=request.remote_addr,
            )
            user_service.ratelimiters["password.reset"].hit(user.id)

            token_service = request.find_service(ITokenService, name="password")
            n_hours = token_service.max_age // 60 // 60
            return {"n_hours": n_hours}
        else:
            user_service.record_event(
                user.id,
                tag="account:password:reset:attempt",
                ip_address=request.remote_addr,
            )
            request.session.flash(
                request._(
                    (
                        "Automated password reset prohibited for your user. "
                        "Contact a PyPI administrator for assistance"
                    ),
                ),
                queue="error",
            )
            return HTTPSeeOther(request.route_path("accounts.request-password-reset"))

    return {"form": form}
예제 #3
0
    def test_send_password_reset_email(self, pyramid_request, pyramid_config,
                                       token_service, monkeypatch):

        stub_user = pretend.stub(
            id="id",
            email="*****@*****.**",
            username="******",
            name="name_value",
            last_login="******",
            password_date="password_date",
        )
        pyramid_request.method = "POST"
        token_service.dumps = pretend.call_recorder(lambda a: "TOKEN")
        pyramid_request.find_service = pretend.call_recorder(
            lambda *a, **kw: token_service)

        subject_renderer = pyramid_config.testing_add_renderer(
            "email/password-reset.subject.txt")
        subject_renderer.string_response = "Email Subject"
        body_renderer = pyramid_config.testing_add_renderer(
            "email/password-reset.body.txt")
        body_renderer.string_response = "Email Body"

        send_email = pretend.stub(
            delay=pretend.call_recorder(lambda *args, **kwargs: None))
        pyramid_request.task = pretend.call_recorder(
            lambda *args, **kwargs: send_email)
        monkeypatch.setattr(email, "send_email", send_email)

        result = email.send_password_reset_email(pyramid_request,
                                                 user=stub_user)

        assert result == {
            "token": "TOKEN",
            "username": stub_user.username,
            "n_hours": token_service.max_age // 60 // 60,
        }
        subject_renderer.assert_()
        body_renderer.assert_(token="TOKEN", username=stub_user.username)
        assert token_service.dumps.calls == [
            pretend.call({
                "action": "password-reset",
                "user.id": str(stub_user.id),
                "user.last_login": str(stub_user.last_login),
                "user.password_date": str(stub_user.password_date),
            })
        ]
        assert pyramid_request.find_service.calls == [
            pretend.call(ITokenService, name="password")
        ]
        assert pyramid_request.task.calls == [pretend.call(send_email)]
        assert send_email.delay.calls == [
            pretend.call(
                "Email Subject",
                "Email Body",
                recipient="name_value <" + stub_user.email + ">",
            )
        ]
예제 #4
0
def request_password_reset(request, _form_class=RequestPasswordResetForm):
    if request.authenticated_userid is not None:
        return HTTPSeeOther(request.route_path("index"))

    user_service = request.find_service(IUserService, context=None)
    form = _form_class(request.POST, user_service=user_service)
    if request.method == "POST" and form.validate():
        user = user_service.get_user_by_username(form.username_or_email.data)
        if user is None:
            user = user_service.get_user_by_email(form.username_or_email.data)

        send_password_reset_email(request, user)

        token_service = request.find_service(ITokenService, name="password")
        n_hours = token_service.max_age // 60 // 60
        return {"n_hours": n_hours}

    return {"form": form}
예제 #5
0
파일: views.py 프로젝트: ewdurbin/warehouse
def request_password_reset(request, _form_class=RequestPasswordResetForm):
    if request.authenticated_userid is not None:
        return HTTPSeeOther(request.route_path('index'))

    user_service = request.find_service(IUserService, context=None)
    form = _form_class(request.POST, user_service=user_service)
    if request.method == "POST" and form.validate():
        user = user_service.get_user_by_username(form.username_or_email.data)
        if user is None:
            user = user_service.get_user_by_email(form.username_or_email.data)

        send_password_reset_email(request, user)

        token_service = request.find_service(ITokenService, name='password')
        n_hours = token_service.max_age // 60 // 60
        return {"n_hours": n_hours}

    return {"form": form}
예제 #6
0
    def test_send_password_reset_email(self, pyramid_request, pyramid_config,
                                       token_service, monkeypatch):

        stub_user = pretend.stub(
            id='id',
            email='email',
            username='******',
            last_login='******',
            password_date='password_date',
        )
        pyramid_request.method = 'POST'
        token_service.dumps = pretend.call_recorder(lambda a: 'TOKEN')
        pyramid_request.find_service = pretend.call_recorder(
            lambda *a, **kw: token_service)

        subject_renderer = pyramid_config.testing_add_renderer(
            'email/password-reset.subject.txt')
        subject_renderer.string_response = 'Email Subject'
        body_renderer = pyramid_config.testing_add_renderer(
            'email/password-reset.body.txt')
        body_renderer.string_response = 'Email Body'

        send_email = pretend.stub(
            delay=pretend.call_recorder(lambda *args, **kwargs: None))
        pyramid_request.task = pretend.call_recorder(
            lambda *args, **kwargs: send_email)
        monkeypatch.setattr(email, 'send_email', send_email)

        result = email.send_password_reset_email(
            pyramid_request,
            user=stub_user,
        )

        assert result == {
            'token': 'TOKEN',
            'username': stub_user.username,
            'n_hours': token_service.max_age // 60 // 60,
        }
        subject_renderer.assert_()
        body_renderer.assert_(token='TOKEN', username=stub_user.username)
        assert token_service.dumps.calls == [
            pretend.call({
                'action': 'password-reset',
                'user.id': str(stub_user.id),
                'user.last_login': str(stub_user.last_login),
                'user.password_date': str(stub_user.password_date),
            }),
        ]
        assert pyramid_request.find_service.calls == [
            pretend.call(ITokenService, name='password'),
        ]
        assert pyramid_request.task.calls == [
            pretend.call(send_email),
        ]
        assert send_email.delay.calls == [
            pretend.call('Email Body', [stub_user.email], 'Email Subject'),
        ]
예제 #7
0
파일: views.py 프로젝트: gsb-eng/warehouse
def request_password_reset(request, _form_class=RequestPasswordResetForm):
    user_service = request.find_service(IUserService, context=None)
    form = _form_class(request.POST, user_service=user_service)

    if request.method == "POST" and form.validate():
        user = user_service.get_user_by_username(form.username.data)
        fields = send_password_reset_email(request, user)
        return {'n_hours': fields['n_hours']}

    return {"form": form}
예제 #8
0
    def test_send_password_reset_email(
            self, pyramid_request, pyramid_config, token_service, monkeypatch):

        stub_user = pretend.stub(
            id='id',
            email='email',
            username='******',
            last_login='******',
            password_date='password_date',
        )
        pyramid_request.method = 'POST'
        token_service.dumps = pretend.call_recorder(lambda a: 'TOKEN')
        pyramid_request.find_service = pretend.call_recorder(
            lambda *a, **kw: token_service
        )

        subject_renderer = pyramid_config.testing_add_renderer(
            'email/password-reset.subject.txt'
        )
        subject_renderer.string_response = 'Email Subject'
        body_renderer = pyramid_config.testing_add_renderer(
            'email/password-reset.body.txt'
        )
        body_renderer.string_response = 'Email Body'

        send_email = pretend.stub(
            delay=pretend.call_recorder(lambda *args, **kwargs: None)
        )
        pyramid_request.task = pretend.call_recorder(
            lambda *args, **kwargs: send_email
        )
        monkeypatch.setattr(email, 'send_email', send_email)

        result = email.send_password_reset_email(
            pyramid_request,
            user=stub_user,
        )

        assert result == {
            'token': 'TOKEN',
            'username': stub_user.username,
            'n_hours': token_service.max_age // 60 // 60,
        }
        subject_renderer.assert_()
        body_renderer.assert_(token='TOKEN', username=stub_user.username)
        assert token_service.dumps.calls == [
            pretend.call({
                'action': 'password-reset',
                'user.id': str(stub_user.id),
                'user.last_login': str(stub_user.last_login),
                'user.password_date': str(stub_user.password_date),
            }),
        ]
        assert pyramid_request.find_service.calls == [
            pretend.call(ITokenService, name='password'),
        ]
        assert pyramid_request.task.calls == [
            pretend.call(send_email),
        ]
        assert send_email.delay.calls == [
            pretend.call(
                'Email Body',
                'Email Subject',
                recipients=[stub_user.email],
            ),
        ]
예제 #9
0
    def test_send_password_reset_email(
        self,
        verified,
        email_addr,
        pyramid_request,
        pyramid_config,
        token_service,
        monkeypatch,
    ):

        stub_user = pretend.stub(
            id="id",
            email="*****@*****.**",
            primary_email=pretend.stub(email="*****@*****.**",
                                       verified=verified),
            username="******",
            name="name_value",
            last_login="******",
            password_date="password_date",
        )
        if email_addr is None:
            stub_email = None
        else:
            stub_email = pretend.stub(email=email_addr, verified=verified)
        pyramid_request.method = "POST"
        token_service.dumps = pretend.call_recorder(lambda a: "TOKEN")
        pyramid_request.find_service = pretend.call_recorder(
            lambda *a, **kw: token_service)

        subject_renderer = pyramid_config.testing_add_renderer(
            "email/password-reset/subject.txt")
        subject_renderer.string_response = "Email Subject"
        body_renderer = pyramid_config.testing_add_renderer(
            "email/password-reset/body.txt")
        body_renderer.string_response = "Email Body"
        html_renderer = pyramid_config.testing_add_renderer(
            "email/password-reset/body.html")
        html_renderer.string_response = "Email HTML Body"

        send_email = pretend.stub(
            delay=pretend.call_recorder(lambda *args, **kwargs: None))
        pyramid_request.task = pretend.call_recorder(
            lambda *args, **kwargs: send_email)
        monkeypatch.setattr(email, "send_email", send_email)

        result = email.send_password_reset_email(pyramid_request,
                                                 (stub_user, stub_email))

        assert result == {
            "token": "TOKEN",
            "username": stub_user.username,
            "n_hours": token_service.max_age // 60 // 60,
        }
        subject_renderer.assert_()
        body_renderer.assert_(token="TOKEN", username=stub_user.username)
        html_renderer.assert_(token="TOKEN", username=stub_user.username)
        assert token_service.dumps.calls == [
            pretend.call({
                "action": "password-reset",
                "user.id": str(stub_user.id),
                "user.last_login": str(stub_user.last_login),
                "user.password_date": str(stub_user.password_date),
            })
        ]
        assert pyramid_request.find_service.calls == [
            pretend.call(ITokenService, name="password")
        ]
        assert pyramid_request.task.calls == [pretend.call(send_email)]
        assert send_email.delay.calls == [
            pretend.call(
                "name_value <" +
                (stub_user.email if email_addr is None else email_addr) + ">",
                attr.asdict(
                    EmailMessage(
                        subject="Email Subject",
                        body_text="Email Body",
                        body_html=(
                            "<html>\n<head></head>\n"
                            "<body><p>Email HTML Body</p></body>\n</html>\n"),
                    )),
            )
        ]
예제 #10
0
    def test_send_password_reset_email(
        self,
        verified,
        email_addr,
        pyramid_request,
        pyramid_config,
        token_service,
        monkeypatch,
    ):

        stub_user = pretend.stub(
            id="id",
            email="*****@*****.**",
            primary_email=pretend.stub(email="*****@*****.**", verified=verified),
            username="******",
            name="name_value",
            last_login="******",
            password_date="password_date",
        )
        if email_addr is None:
            stub_email = None
        else:
            stub_email = pretend.stub(email=email_addr, verified=verified)
        pyramid_request.method = "POST"
        token_service.dumps = pretend.call_recorder(lambda a: "TOKEN")
        pyramid_request.find_service = pretend.call_recorder(
            lambda *a, **kw: token_service
        )

        subject_renderer = pyramid_config.testing_add_renderer(
            "email/password-reset/subject.txt"
        )
        subject_renderer.string_response = "Email Subject"
        body_renderer = pyramid_config.testing_add_renderer(
            "email/password-reset/body.txt"
        )
        body_renderer.string_response = "Email Body"
        html_renderer = pyramid_config.testing_add_renderer(
            "email/password-reset/body.html"
        )
        html_renderer.string_response = "Email HTML Body"

        send_email = pretend.stub(
            delay=pretend.call_recorder(lambda *args, **kwargs: None)
        )
        pyramid_request.task = pretend.call_recorder(lambda *args, **kwargs: send_email)
        monkeypatch.setattr(email, "send_email", send_email)

        result = email.send_password_reset_email(
            pyramid_request, (stub_user, stub_email)
        )

        assert result == {
            "token": "TOKEN",
            "username": stub_user.username,
            "n_hours": token_service.max_age // 60 // 60,
        }
        subject_renderer.assert_()
        body_renderer.assert_(token="TOKEN", username=stub_user.username)
        html_renderer.assert_(token="TOKEN", username=stub_user.username)
        assert token_service.dumps.calls == [
            pretend.call(
                {
                    "action": "password-reset",
                    "user.id": str(stub_user.id),
                    "user.last_login": str(stub_user.last_login),
                    "user.password_date": str(stub_user.password_date),
                }
            )
        ]
        assert pyramid_request.find_service.calls == [
            pretend.call(ITokenService, name="password")
        ]
        assert pyramid_request.task.calls == [pretend.call(send_email)]
        assert send_email.delay.calls == [
            pretend.call(
                "name_value <"
                + (stub_user.email if email_addr is None else email_addr)
                + ">",
                attr.asdict(
                    EmailMessage(
                        subject="Email Subject",
                        body_text="Email Body",
                        body_html=(
                            "<html>\n<head></head>\n"
                            "<body><p>Email HTML Body</p></body>\n</html>\n"
                        ),
                    )
                ),
            )
        ]