Exemplo n.º 1
0
    def test_reset_password_email_configuration_override(self, body_type):
        """
        Tests that the right url domain and platform name is included in
        the reset password email
        """
        req = self.request_factory.post('/password_reset/',
                                        {'email': self.user.email})
        req.get_host = Mock(return_value=None)
        req.site = Mock(domain='example.com')
        req.user = self.user

        with patch('crum.get_current_request', return_value=req):
            password_reset(req)

        sent_message = mail.outbox[0]
        bodies = {
            'plain_text': sent_message.body,
            'html': sent_message.alternatives[0][0],
        }

        body = bodies[body_type]

        reset_msg = u"you requested a password reset for your user account at {}".format(
            fake_get_value('PLATFORM_NAME'))

        self.assertIn(reset_msg, body)

        self.assert_event_emitted(SETTING_CHANGE_INITIATED,
                                  user_id=self.user.id,
                                  setting=u'password',
                                  old=None,
                                  new=None)
        self.assertEqual(sent_message.from_email,
                         "*****@*****.**")
Exemplo n.º 2
0
    def test_ratelimited_from_different_ips_with_same_email(self):
        """
        Test that password reset endpoint allow only one request per minute
        per email address.
        """
        cache.clear()
        good_req = self.request_factory.post('/password_reset/', {'email': '*****@*****.**'})
        good_req.user = AnonymousUser()
        good_resp = password_reset(good_req)
        self.assertEqual(good_resp.status_code, 200)

        # change the IP and verify that the rate limiter should kick in and
        # give a Forbidden response if the request is for same email address.
        new_ip = "8.8.8.8"
        self.assertNotEqual(good_req.META.get('REMOTE_ADDR'), new_ip)

        bad_req = self.request_factory.post(
            '/password_reset/',
            {'email': '*****@*****.**'},
            REMOTE_ADDR=new_ip
        )
        bad_req.user = AnonymousUser()
        bad_resp = password_reset(bad_req)
        self.assertEqual(bad_resp.status_code, 403)
        self.assertEqual(bad_req.META.get('REMOTE_ADDR'), new_ip)

        cache.clear()
Exemplo n.º 3
0
    def test_reset_password_email_site(self, site_name, platform_name):
        """
        Tests that the right url domain and platform name is included in
        the reset password email
        """
        with patch("django.conf.settings.PLATFORM_NAME", platform_name):
            with patch("django.conf.settings.SITE_NAME", site_name):
                req = self.request_factory.post('/password_reset/',
                                                {'email': self.user.email})
                req.user = self.user
                req.site = Mock(domain='example.com')
                password_reset(req)
                sent_message = mail.outbox[0]
                msg = sent_message.body

                reset_msg = u"you requested a password reset for your user account at {}"
                reset_msg = reset_msg.format(site_name)

                self.assertIn(reset_msg, msg)

                sign_off = u"The {} Team".format(platform_name)
                self.assertIn(sign_off, msg)

                self.assert_event_emitted(SETTING_CHANGE_INITIATED,
                                          user_id=self.user.id,
                                          setting=u'password',
                                          old=None,
                                          new=None)
Exemplo n.º 4
0
    def test_reset_password_email_subject(self, platform_name):
        """
        Tests that the right platform name is included in
        the reset password email subject
        """
        with patch("django.conf.settings.PLATFORM_NAME", platform_name):
            req = self.request_factory.post('/password_reset/',
                                            {'email': self.user.email})
            req.user = self.user
            req.site = Mock(domain='example.com')
            password_reset(req)
            sent_message = mail.outbox[0]
            subj = sent_message.subject

            self.assertIn(platform_name, subj)
Exemplo n.º 5
0
    def assert_password_reset_ratelimitted(self, email, user):
        """
        Assert that password reset endpoint allow one request per minute per email.
        """
        cache.clear()
        password_reset_req = self.request_factory.post('/password_reset/', {'email': email})
        password_reset_req.user = user
        password_reset_req.site = Mock(domain='example.com')
        good_resp = password_reset(password_reset_req)
        self.assertEqual(good_resp.status_code, 200)

        # then the rate limiter should kick in and give a HttpForbidden response
        bad_resp = password_reset(password_reset_req)
        self.assertEqual(bad_resp.status_code, 403)

        cache.clear()
Exemplo n.º 6
0
    def test_reset_password_email(self, body_type, expected_output):
        """Tests contents of reset password email, and that user is not active"""
        good_req = self.request_factory.post('/password_reset/',
                                             {'email': self.user.email})
        good_req.user = self.user
        good_req.site = Mock(domain='example.com')
        dot_application = dot_factories.ApplicationFactory(user=self.user)
        dot_access_token = dot_factories.AccessTokenFactory(
            user=self.user, application=dot_application)
        dot_factories.RefreshTokenFactory(user=self.user,
                                          application=dot_application,
                                          access_token=dot_access_token)
        good_resp = password_reset(good_req)
        assert good_resp.status_code == 200
        assert not dot_models.AccessToken.objects.filter(
            user=self.user).exists()
        assert not dot_models.RefreshToken.objects.filter(
            user=self.user).exists()
        obj = json.loads(good_resp.content.decode('utf-8'))
        assert obj['success']
        assert 'e-mailed you instructions for setting your password' in obj[
            'value']

        from_email = configuration_helpers.get_value(
            'email_from_address', settings.DEFAULT_FROM_EMAIL)
        sent_message = mail.outbox[0]

        bodies = {
            'plain_text': sent_message.body,
            'html': sent_message.alternatives[0][0],
        }

        body = bodies[body_type]

        if django.VERSION >= (3, 0) and body_type == 'html':
            expected_output = "You're receiving this e-mail because you requested a password reset"

        assert 'Password reset' in sent_message.subject
        assert expected_output in body
        assert sent_message.from_email == from_email
        assert len(sent_message.to) == 1
        assert self.user.email in sent_message.to

        self.assert_event_emitted(
            SETTING_CHANGE_INITIATED,
            user_id=self.user.id,
            setting='password',
            old=None,
            new=None,
        )

        # Test that the user is not active
        self.user = User.objects.get(pk=self.user.pk)
        assert not self.user.is_active

        assert 'password_reset_confirm/' in body
        re.search(
            r'password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/',
            body).groupdict()
Exemplo n.º 7
0
    def test_ratelimitted_from_same_ip_with_different_email(self):
        """
        Test that password reset endpoint allow only one request per minute per IP.
        """
        cache.clear()
        good_req = self.request_factory.post('/password_reset/', {'email': '*****@*****.**'})
        good_req.user = AnonymousUser()
        good_resp = password_reset(good_req)
        self.assertEqual(good_resp.status_code, 200)

        # change the email ID and verify that the rate limiter should kick in and
        # give a Forbidden response if the request is from same IP.
        bad_req = self.request_factory.post('/password_reset/', {'email': '*****@*****.**'})
        bad_req.user = AnonymousUser()
        bad_resp = password_reset(bad_req)
        self.assertEqual(bad_resp.status_code, 403)

        cache.clear()
Exemplo n.º 8
0
    def test_password_reset_ratelimited(self):
        """
        Test that reset password endpoint only allow one request per minute.
        """
        cache.clear()

        password_reset_req = self.request_factory.post(
            '/password_reset/', {'email': '*****@*****.**'})
        password_reset_req.user = AnonymousUser()
        good_resp = password_reset(password_reset_req)
        self.assertEqual(good_resp.status_code, 200)

        # then the rate limiter should kick in and give a HttpForbidden response
        bad_resp = password_reset(password_reset_req)
        self.assertEqual(bad_resp.status_code, 403)
        self.assert_no_events_were_emitted()

        cache.clear()
Exemplo n.º 9
0
    def test_reset_password_email(self, body_type, expected_output):
        """Tests contents of reset password email, and that user is not active"""
        good_req = self.request_factory.post('/password_reset/',
                                             {'email': self.user.email})
        good_req.user = self.user
        good_req.site = Mock(domain='example.com')
        dot_application = dot_factories.ApplicationFactory(user=self.user)
        dot_access_token = dot_factories.AccessTokenFactory(
            user=self.user, application=dot_application)
        dot_factories.RefreshTokenFactory(user=self.user,
                                          application=dot_application,
                                          access_token=dot_access_token)
        good_resp = password_reset(good_req)
        self.assertEqual(good_resp.status_code, 200)
        self.assertFalse(
            dot_models.AccessToken.objects.filter(user=self.user).exists())
        self.assertFalse(
            dot_models.RefreshToken.objects.filter(user=self.user).exists())
        obj = json.loads(good_resp.content.decode('utf-8'))
        self.assertTrue(obj['success'])
        self.assertIn('e-mailed you instructions for setting your password',
                      obj['value'])

        from_email = configuration_helpers.get_value(
            'email_from_address', settings.DEFAULT_FROM_EMAIL)
        sent_message = mail.outbox[0]

        bodies = {
            'plain_text': sent_message.body,
            'html': sent_message.alternatives[0][0],
        }

        body = bodies[body_type]

        self.assertIn("Password reset", sent_message.subject)
        self.assertIn(expected_output, body)
        self.assertEqual(sent_message.from_email, from_email)
        self.assertEqual(len(sent_message.to), 1)
        self.assertIn(self.user.email, sent_message.to)

        self.assert_event_emitted(
            SETTING_CHANGE_INITIATED,
            user_id=self.user.id,
            setting=u'password',
            old=None,
            new=None,
        )

        # Test that the user is not active
        self.user = User.objects.get(pk=self.user.pk)
        self.assertFalse(self.user.is_active)

        self.assertIn('password_reset_confirm/', body)
        re.search(
            r'password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/',
            body).groupdict()
Exemplo n.º 10
0
    def test_reset_password_email_https(self, is_secure, protocol, send_email):
        """
        Tests that the right url protocol is included in the reset password link
        """
        req = self.request_factory.post(
            '/password_reset/', {'email': self.user.email}
        )
        req.site = Mock(domain='example.com')
        req.is_secure = Mock(return_value=is_secure)
        req.user = self.user
        password_reset(req)
        _, msg, _, _ = send_email.call_args[0]
        expected_msg = "Please go to the following page and choose a new password:\n\n" + protocol

        self.assertIn(expected_msg, msg)

        self.assert_event_emitted(
            SETTING_CHANGE_INITIATED, user_id=self.user.id, setting=u'password', old=None, new=None
        )
Exemplo n.º 11
0
    def test_password_reset_ratelimited(self):
        """
        Try (and fail) resetting password 30 times in a row on an non-existant email address
        """
        cache.clear()

        for i in range(30):
            good_req = self.request_factory.post('/password_reset/', {
                'email': 'thisdoesnotexist{0}@foo.com'.format(i)
            })
            good_resp = password_reset(good_req)
            self.assertEquals(good_resp.status_code, 200)

        # then the rate limiter should kick in and give a HttpForbidden response
        bad_req = self.request_factory.post('/password_reset/', {'email': '*****@*****.**'})
        bad_resp = password_reset(bad_req)
        self.assertEquals(bad_resp.status_code, 403)
        self.assert_no_events_were_emitted()

        cache.clear()
Exemplo n.º 12
0
    def request_password_reset(self, status, new_ip=None):
        extra_args = {}
        if new_ip:
            extra_args = {'REMOTE_ADDR': new_ip}

        reset_request = self.request_factory.post(
            '/password_reset/', {'email': '*****@*****.**'},
            **extra_args)

        if new_ip:
            self.assertEqual(reset_request.META.get('REMOTE_ADDR'), new_ip)

        reset_request.user = AnonymousUser()
        response = password_reset(reset_request)
        self.assertEqual(response.status_code, status)
Exemplo n.º 13
0
    def test_user_bad_password_reset(self):
        """
        Tests password reset behavior for user with password marked UNUSABLE_PASSWORD_PREFIX
        """

        bad_pwd_req = self.request_factory.post('/password_reset/', {'email': self.user_bad_passwd.email})
        bad_pwd_resp = password_reset(bad_pwd_req)
        # If they've got an unusable password, we return a successful response code
        self.assertEquals(bad_pwd_resp.status_code, 200)
        obj = json.loads(bad_pwd_resp.content.decode('utf-8'))
        self.assertEquals(obj, {
            'success': True,
            'value': "('registration/password_reset_done.html', [])",
        })
        self.assert_no_events_were_emitted()
Exemplo n.º 14
0
    def request_password_reset(self, status, new_ip=None):  # lint-amnesty, pylint: disable=missing-function-docstring
        extra_args = {}
        if new_ip:
            extra_args = {'REMOTE_ADDR': new_ip}

        reset_request = self.request_factory.post(
            '/password_reset/', {'email': '*****@*****.**'},
            **extra_args)

        if new_ip:
            assert reset_request.META.get('REMOTE_ADDR') == new_ip

        reset_request.user = AnonymousUser()
        response = password_reset(reset_request)
        assert response.status_code == status
Exemplo n.º 15
0
    def test_nonexist_email_password_reset(self):
        """
        Now test the exception cases with of reset_password called with invalid email.
        """

        bad_email_req = self.request_factory.post('/password_reset/', {'email': self.user.email + "makeItFail"})
        bad_email_resp = password_reset(bad_email_req)
        # Note: even if the email is bad, we return a successful response code
        # This prevents someone potentially trying to "brute-force" find out which
        # emails are and aren't registered with edX
        self.assertEquals(bad_email_resp.status_code, 200)
        obj = json.loads(bad_email_resp.content.decode('utf-8'))
        self.assertEquals(obj, {
            'success': True,
            'value': "('registration/password_reset_done.html', [])",
        })
        self.assert_no_events_were_emitted()