예제 #1
0
    def test_login_on_confirm(self):
        user = self._create_user()
        email = EmailAddress.objects.create(
            user=user,
            email='*****@*****.**',
            verified=False,
            primary=True)
        key = EmailConfirmationHMAC(email).key

        receiver_mock = Mock()  # we've logged if signal was called
        user_logged_in.connect(receiver_mock)

        # fake post-signup account_user stash
        session = self.client.session
        session['account_user'] = user_pk_to_url_str(user)
        session.save()

        resp = self.client.post(
            reverse('account_confirm_email',
                    args=[key]))
        email = EmailAddress.objects.get(pk=email.pk)
        self.assertTrue(email.verified)

        receiver_mock.assert_called_once_with(
            sender=get_user_model(),
            request=resp.wsgi_request,
            response=resp,
            user=get_user_model().objects.get(username='******'),
            signal=user_logged_in,
        )

        user_logged_in.disconnect(receiver_mock)
예제 #2
0
    def test_login_inactive_account(self):
        """
        Tests login behavior with inactive accounts.

        Inactive user accounts should be prevented from performing any actions,
        regardless of their verified state.
        """
        # Inactive and verified user account
        user = get_user_model().objects.create(username='******',
                                               is_active=False)
        user.set_password('doe')
        user.save()
        EmailAddress.objects.create(user=user,
                                    email='*****@*****.**',
                                    primary=True,
                                    verified=True)
        resp = self.client.post(reverse('account_login'),
                                {'login': '******',
                                 'password': '******'})
        self.assertRedirects(resp, reverse('account_inactive'))

        # Inactive and unverified user account
        user = get_user_model().objects.create(username='******', is_active=False)
        user.set_password('john')
        user.save()
        EmailAddress.objects.create(user=user,
                                    email="*****@*****.**",
                                    primary=True,
                                    verified=False)
        resp = self.client.post(reverse('account_login'),
                                {'login': '******',
                                 'password': '******'})
        self.assertRedirects(resp, reverse('account_inactive'))
예제 #3
0
 def test_login(self):
     resp = self.client.post(reverse(views.login),
                             dict(openid='http://me.yahoo.com'))
     assert 'login.yahooapis' in resp['location']
     with patch('authentication.socialaccount.providers'
                '.openid.views._openid_consumer') as consumer_mock:
         client = Mock()
         complete = Mock()
         consumer_mock.return_value = client
         client.complete = complete
         complete_response = Mock()
         complete.return_value = complete_response
         complete_response.status = consumer.SUCCESS
         complete_response.identity_url = 'http://dummy/john/'
         with patch('authentication.socialaccount.providers'
                    '.openid.utils.SRegResponse') as sr_mock:
             with patch('authentication.socialaccount.providers'
                        '.openid.utils.FetchResponse') as fr_mock:
                 sreg_mock = Mock()
                 ax_mock = Mock()
                 sr_mock.fromSuccessResponse = sreg_mock
                 fr_mock.fromSuccessResponse = ax_mock
                 sreg_mock.return_value = {}
                 ax_mock.return_value = {
                     AXAttribute.PERSON_FIRST_NAME: ['raymond']
                 }
                 resp = self.client.post(reverse('openid_callback'))
                 self.assertRedirects(resp,
                                      "/accounts/profile/",
                                      fetch_redirect_response=False)
                 get_user_model().objects.get(first_name='raymond')
예제 #4
0
 def test_ajax_password_reset(self):
     get_user_model().objects.create(
         username='******', email="*****@*****.**", is_active=True)
     resp = self.client.post(
         reverse('account_reset_password'),
         data={'email': '*****@*****.**'},
         HTTP_X_REQUESTED_WITH='XMLHttpRequest')
     self.assertEqual(len(mail.outbox), 1)
     self.assertEqual(mail.outbox[0].to, ["*****@*****.**"])
     self.assertEqual(resp['content-type'], 'application/json')
예제 #5
0
    def test_login(self):
        with patch('authentication.socialaccount.providers.persona.views'
                   '.requests') as requests_mock:
            requests_mock.post.return_value.json.return_value = {
                'status': 'okay',
                'email': '*****@*****.**'
            }

            resp = self.client.post(reverse('persona_login'),
                                    dict(assertion='dummy'))
            self.assertRedirects(resp,
                                 '/accounts/profile/',
                                 fetch_redirect_response=False)
            get_user_model().objects.get(email='*****@*****.**')
예제 #6
0
 def test_login_failed_attempts_exceeded(self):
     user = get_user_model().objects.create(username='******')
     user.set_password('doe')
     user.save()
     EmailAddress.objects.create(user=user,
                                 email="*****@*****.**",
                                 primary=True,
                                 verified=False)
     for i in range(5):
         is_valid_attempt = (i == 4)
         is_locked = (i >= 3)
         resp = self.client.post(
             reverse('account_login'),
             {'login': '******',
              'password': (
                  'doe' if is_valid_attempt
                  else 'wrong')})
         self.assertFormError(
             resp,
             'form',
             None,
             'Too many failed login attempts. Try again later.'
             if is_locked
             else
             'The username and/or password you specified are not correct.')
예제 #7
0
 def get_users_with_multiple_primary_email(self):
     user_pks = []
     for email_address_dict in EmailAddress.objects.filter(
             primary=True).values('user').annotate(
                 Count('user')).filter(user__count__gt=1):
         user_pks.append(email_address_dict['user'])
     return get_user_model().objects.filter(pk__in=user_pks)
예제 #8
0
 def _logout_view(self, method):
     c = Client()
     user = get_user_model().objects.create(username='******', is_active=True)
     user.set_password('doe')
     user.save()
     c = Client()
     c.login(username='******', password='******')
     return c, getattr(c, method)(reverse('account_logout'))
예제 #9
0
 def setUp(self):
     user = get_user_model().objects.create(
         is_active=True,
         email='*****@*****.**',
         username='******')
     user.set_password(user.username)
     user.save()
     self.user = user
예제 #10
0
    def test_email_verification_mandatory(self):
        c = Client()
        # Signup
        resp = c.post(reverse('account_signup'),
                      {'username': '******',
                       'email': '*****@*****.**',
                       'password1': 'johndoe',
                       'password2': 'johndoe'},
                      follow=True)
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(mail.outbox[0].to, ['*****@*****.**'])
        self.assertGreater(mail.outbox[0].body.find('https://'), 0)
        self.assertEqual(len(mail.outbox), 1)
        self.assertTemplateUsed(
            resp,
            'account/verification_sent.%s' % app_settings.TEMPLATE_EXTENSION)
        # Attempt to login, unverified
        for attempt in [1, 2]:
            resp = c.post(reverse('account_login'),
                          {'login': '******',
                           'password': '******'},
                          follow=True)
            # is_active is controlled by the admin to manually disable
            # users. I don't want this flag to flip automatically whenever
            # users verify their email adresses.
            self.assertTrue(get_user_model().objects.filter(
                username='******', is_active=True).exists())

            self.assertTemplateUsed(
                resp,
                'account/verification_sent.' + app_settings.TEMPLATE_EXTENSION)
            # Attempt 1: no mail is sent due to cool-down ,
            # but there was already a mail in the outbox.
            self.assertEqual(len(mail.outbox), attempt)
            self.assertEqual(
                EmailConfirmation.objects.filter(
                    email_address__email='*****@*****.**').count(),
                attempt)
            # Wait for cooldown
            EmailConfirmation.objects.update(sent=now() - timedelta(days=1))
        # Verify, and re-attempt to login.
        confirmation = EmailConfirmation \
            .objects \
            .filter(email_address__user__username='******')[:1] \
            .get()
        resp = c.get(reverse('account_confirm_email',
                             args=[confirmation.key]))
        self.assertTemplateUsed(
            resp,
            'account/email_confirm.%s' % app_settings.TEMPLATE_EXTENSION)
        c.post(reverse('account_confirm_email',
                       args=[confirmation.key]))
        resp = c.post(reverse('account_login'),
                      {'login': '******',
                       'password': '******'})
        self.assertRedirects(resp,
                             settings.LOGIN_REDIRECT_URL,
                             fetch_redirect_response=False)
예제 #11
0
 def _create_user(self, username='******', password='******'):
     user = get_user_model().objects.create(
         username=username,
         is_active=True)
     if password:
         user.set_password(password)
     else:
         user.set_unusable_password()
     user.save()
     return user
예제 #12
0
 def test_email_escaping(self):
     site = Site.objects.get_current()
     site.name = '<enc&"test>'
     site.save()
     u = get_user_model().objects.create(
         username='******',
         email="*****@*****.**")
     request = RequestFactory().get('/')
     EmailAddress.objects.add_email(request, u, u.email, confirm=True)
     self.assertTrue(mail.outbox[0].subject[1:].startswith(site.name))
예제 #13
0
 def test_user_display(self):
     user = get_user_model()(username='******')
     expected_name = 'john&lt;br/&gt;doe'
     templates = [
         '{% load account %}{% user_display user %}',
         '{% load account %}{% user_display user as x %}{{ x }}'
     ]
     for template in templates:
         t = Template(template)
         content = t.render(Context({'user': user}))
         self.assertEqual(content, expected_name)
예제 #14
0
 def test_ajax_login_success(self):
     user = get_user_model().objects.create(username='******', is_active=True)
     user.set_password('doe')
     user.save()
     resp = self.client.post(reverse('account_login'),
                             {'login': '******',
                              'password': '******'},
                             HTTP_X_REQUESTED_WITH='XMLHttpRequest')
     self.assertEqual(resp.status_code, 200)
     data = json.loads(resp.content.decode('utf8'))
     self.assertEqual(data['location'], '/accounts/profile/')
예제 #15
0
    def test_logout_view_on_post(self):
        c, resp = self._logout_view('get')
        self.assertTemplateUsed(
            resp,
            'account/logout.%s' % app_settings.TEMPLATE_EXTENSION)

        receiver_mock = Mock()
        user_logged_out.connect(receiver_mock)

        resp = c.post(reverse('account_logout'))

        self.assertTemplateUsed(resp, 'account/messages/logged_out.txt')
        receiver_mock.assert_called_once_with(
            sender=get_user_model(),
            request=resp.wsgi_request,
            user=get_user_model().objects.get(username='******'),
            signal=user_logged_out,
        )

        user_logged_out.disconnect(receiver_mock)
예제 #16
0
 def _request_new_password(self):
     user = get_user_model().objects.create(
         username='******', email="*****@*****.**", is_active=True)
     user.set_password('doe')
     user.save()
     self.client.post(
         reverse('account_reset_password'),
         data={'email': '*****@*****.**'})
     self.assertEqual(len(mail.outbox), 1)
     self.assertEqual(mail.outbox[0].to, ["*****@*****.**"])
     return user
예제 #17
0
 def test_login_unverified_account_mandatory(self):
     """Tests login behavior when email verification is mandatory."""
     user = get_user_model().objects.create(username='******')
     user.set_password('doe')
     user.save()
     EmailAddress.objects.create(user=user,
                                 email="*****@*****.**",
                                 primary=True,
                                 verified=False)
     resp = self.client.post(reverse('account_login'),
                             {'login': '******',
                              'password': '******'})
     self.assertRedirects(resp, reverse('account_email_verification_sent'))
예제 #18
0
 def test_username_containing_at(self):
     user = get_user_model().objects.create(username='******')
     user.set_password('psst')
     user.save()
     EmailAddress.objects.create(user=user,
                                 email="*****@*****.**",
                                 primary=True,
                                 verified=True)
     resp = self.client.post(reverse('account_login'),
                             {'login': '******',
                              'password': '******'})
     self.assertRedirects(resp,
                          settings.LOGIN_REDIRECT_URL,
                          fetch_redirect_response=False)
예제 #19
0
 def test_login_unverified_account_optional(self):
     """Tests login behavior when email verification is optional."""
     user = get_user_model().objects.create(username='******')
     user.set_password('doe')
     user.save()
     EmailAddress.objects.create(user=user,
                                 email="*****@*****.**",
                                 primary=True,
                                 verified=False)
     resp = self.client.post(reverse('account_login'),
                             {'login': '******',
                              'password': '******'})
     self.assertRedirects(resp,
                          settings.LOGIN_REDIRECT_URL,
                          fetch_redirect_response=False)
예제 #20
0
 def test_signup_email_twice(self):
     request = RequestFactory().post(reverse('account_signup'),
                                     {'username': '******',
                                      'email': '*****@*****.**',
                                      'email2': '*****@*****.**',
                                      'password1': 'johndoe',
                                      'password2': 'johndoe'})
     from django.contrib.messages.middleware import MessageMiddleware
     from django.contrib.sessions.middleware import SessionMiddleware
     SessionMiddleware().process_request(request)
     MessageMiddleware().process_request(request)
     request.user = AnonymousUser()
     from .views import signup
     signup(request)
     user = get_user_model().objects.get(username='******')
     self.assertEqual(user.email, "*****@*****.**")
예제 #21
0
 def setUp(self):
     User = get_user_model()
     self.user = User.objects.create(username='******',
                                     email="*****@*****.**")
     self.user.set_password('doe')
     self.user.save()
     self.email_address = EmailAddress.objects.create(
         user=self.user,
         email=self.user.email,
         verified=True,
         primary=True)
     self.email_address2 = EmailAddress.objects.create(
         user=self.user,
         email="*****@*****.**",
         verified=False,
         primary=False)
     self.client.login(username='******', password='******')
예제 #22
0
    def USERNAME_VALIDATORS(self):
        from django.core.exceptions import ImproperlyConfigured
        from authentication.utils import import_attribute
        from authentication.utils import get_user_model

        path = self._setting('USERNAME_VALIDATORS', None)
        if path:
            ret = import_attribute(path)
            if not isinstance(ret, list):
                raise ImproperlyConfigured(
                    'ACCOUNT_USERNAME_VALIDATORS is expected to be a list')
        else:
            if self.USER_MODEL_USERNAME_FIELD is not None:
                ret = get_user_model()._meta.get_field(
                    self.USER_MODEL_USERNAME_FIELD).validators
            else:
                ret = []
        return ret
예제 #23
0
 def deserialize(cls, data):
     deserialize_instance = get_adapter().deserialize_instance
     account = deserialize_instance(SocialAccount, data['account'])
     user = deserialize_instance(get_user_model(), data['user'])
     if 'token' in data:
         token = deserialize_instance(SocialToken, data['token'])
     else:
         token = None
     email_addresses = []
     for ea in data['email_addresses']:
         email_address = deserialize_instance(EmailAddress, ea)
         email_addresses.append(email_address)
     ret = SocialLogin()
     ret.token = token
     ret.account = account
     ret.user = user
     ret.email_addresses = email_addresses
     ret.state = data['state']
     return ret
예제 #24
0
 def _test_signup_email_verified_externally(self, signup_email,
                                            verified_email):
     username = '******'
     request = RequestFactory().post(reverse('account_signup'),
                                     {'username': username,
                                      'email': signup_email,
                                      'password1': 'johndoe',
                                      'password2': 'johndoe'})
     # Fake stash_verified_email
     from django.contrib.messages.middleware import MessageMiddleware
     from django.contrib.sessions.middleware import SessionMiddleware
     SessionMiddleware().process_request(request)
     MessageMiddleware().process_request(request)
     request.user = AnonymousUser()
     request.session['account_verified_email'] = verified_email
     from .views import signup
     resp = signup(request)
     self.assertEqual(resp.status_code, 302)
     self.assertEqual(resp['location'],
                      get_adapter().get_login_redirect_url(request))
     self.assertEqual(len(mail.outbox), 0)
     return get_user_model().objects.get(username=username)
예제 #25
0
 def test_username_lower_cased(self):
     user = get_user_model()()
     user_username(user, 'CamelCase')
     self.assertEqual(user_username(user), 'camelcase')
     # TODO: Actually test something
     filter_users_by_username('CamelCase', 'FooBar')
예제 #26
0
 def test_username_case_preserved(self):
     user = get_user_model()()
     user_username(user, 'CamelCase')
     self.assertEqual(user_username(user), 'CamelCase')
     # TODO: Actually test something
     filter_users_by_username('camelcase', 'foobar')
예제 #27
0
    def test_password_reset_flow(self):
        """
        Tests the password reset flow: requesting a new password,
        receiving the reset link via email and finally resetting the
        password to a new value.
        """
        # Request new password
        user = self._request_new_password()
        body = mail.outbox[0].body
        self.assertGreater(body.find('https://'), 0)

        # Extract URL for `password_reset_from_key` view and access it
        url = body[body.find('/password/reset/'):].split()[0]
        resp = self.client.get(url)
        # Follow the redirect the actual password reset page with the key
        # hidden.
        url = resp.url
        resp = self.client.get(url)
        self.assertTemplateUsed(
            resp,
            'account/password_reset_from_key.%s' %
            app_settings.TEMPLATE_EXTENSION)
        self.assertFalse('token_fail' in resp.context_data)

        # Reset the password
        resp = self.client.post(url,
                                {'password1': 'newpass123',
                                 'password2': 'newpass123'})
        self.assertRedirects(resp,
                             reverse('account_reset_password_from_key_done'))

        # Check the new password is in effect
        user = get_user_model().objects.get(pk=user.pk)
        self.assertTrue(user.check_password('newpass123'))

        # Trying to reset the password against the same URL (or any other
        # invalid/obsolete URL) returns a bad token response
        resp = self.client.post(url,
                                {'password1': 'newpass123',
                                 'password2': 'newpass123'})
        self.assertTemplateUsed(
            resp,
            'account/password_reset_from_key.%s' %
            app_settings.TEMPLATE_EXTENSION)
        self.assertTrue(resp.context_data['token_fail'])

        # Same should happen when accessing the page directly
        response = self.client.get(url)
        self.assertTemplateUsed(
            response,
            'account/password_reset_from_key.%s' %
            app_settings.TEMPLATE_EXTENSION)
        self.assertTrue(response.context_data['token_fail'])

        # When in XHR views, it should respond with a 400 bad request
        # code, and the response body should contain the JSON-encoded
        # error from the adapter
        response = self.client.post(url,
                                    {'password1': 'newpass123',
                                     'password2': 'newpass123'},
                                    HTTP_X_REQUESTED_WITH='XMLHttpRequest')
        self.assertEqual(response.status_code, 400)
        data = json.loads(response.content.decode('utf8'))
        assert 'invalid' in data['form']['errors'][0]