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)
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'))
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')
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')
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='*****@*****.**')
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.')
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)
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'))
def setUp(self): user = get_user_model().objects.create( is_active=True, email='*****@*****.**', username='******') user.set_password(user.username) user.save() self.user = user
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)
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
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))
def test_user_display(self): user = get_user_model()(username='******') expected_name = 'john<br/>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)
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/')
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)
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
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'))
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)
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)
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, "*****@*****.**")
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='******')
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
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
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)
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')
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')
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]