Example #1
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('allauth.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('allauth.socialaccount.providers'
                    '.openid.utils.SRegResponse') as sr_mock:
             with patch('allauth.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.assertEqual('http://testserver/accounts/profile/',
                                  resp['location'])
                 get_user_model().objects.get(first_name='raymond')
Example #2
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)
Example #3
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'))
Example #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")
Example #5
0
def mark_user_views_event(event_id, user_id, ip_address):
    if user_id:
        view = View()
        view.event_id = event_id
        view.user_id = user_id
        view.save()

    ipview, created = ViewIP.objects.get_or_create(event_id=event_id, ip_address=ip_address)
    ipview.count = F('count') + 1
    ipview.save()

    # Send info to keen
    staff_status = False
    if user_id:
        try:
            user = get_user_model().objects.get(pk=user_id)
            staff_status = user.is_staff
        except get_user_model().DoesNotExist:
            keen.add_event("Error", {
                "msg": "User.DoesNotExist",
                "id": user_id
            })

    event = Event.objects.get(pk=event_id)

    keen_events = []

    for category in event.category.all():
        keen_events.append({
            'keen': {
                'time_stamp': timezone.now().isoformat(),
                'location': {
                    'coordinates': [float(event.venue.longitude), float(event.venue.latitude)],
                }
            },
            "user": {
                "user_id": user_id,
                "staff": staff_status,
                "ip": ip_address
            },
            "event": {
                "event_id": event_id,
                "category": category.name,
                "min_age": event.min_age,
                "max_age": event.max_age,
                "cost": event.cost,
                "start_date": event.start_date.isoformat(),
                "end_date": event.end_date.isoformat() if event.end_date else None,
                "publish_date": event.published_at.isoformat() if event.published_at else None
            },
            "venue": {
                "venue_id": event.venue.id,
                "name": event.venue.name,
                "city": event.venue.city,
                "neighborhood": event.venue.neighborhood,
            }})

    keen.add_events({"view_single": keen_events})
Example #6
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')
Example #7
0
 def test_login(self):
     with patch('allauth.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.assertEqual('http://testserver/accounts/profile/',
                          resp['location'])
         get_user_model().objects.get(email='*****@*****.**')
Example #8
0
def new_action(event_type, user_id, event_id, session_id=None):
    """
    Create a new event on pio server
    :param event_type:
    :param user_id:
    :param event_id:
    :param session_id:
    :return:
    """

    staff_status = False
    if user_id:
        try:
            user = get_user_model().objects.get(pk=user_id)
            staff_status = user.is_staff
        except get_user_model().DoesNotExist:
            keen.add_event("Error", {
                "msg": "User.DoesNotExist",
                "id": user_id
            })

    try:
        event = Event.objects.get(pk=event_id)

        keen.add_event(event_type, {
            "user": {
                "user_id": user_id,
                "staff": staff_status,
                "session_id": session_id
            },
            "event": {
                "event_id": event_id,
                "categories": list(event.category.all().values_list('name', flat=True)),
                "min_age": event.min_age,
                "max_age": event.max_age,
                "cost": event.cost,
                "start_date": event.start_date.isoformat(),
                "end_date": event.end_date.isoformat() if event.end_date else None,
                "publish_date": event.published_at.isoformat() if event.published_at else None
            },
            "venue": {
                "venue_id": event.venue.id,
                "name": event.venue.name,
                "city": event.venue.city,
                "neighborhood": event.venue.neighborhood,
            }
        }, timezone.now())
    except Event.DoesNotExist:
        keen.add_event("Error", {
            "msg": "Event.DoesNotExist",
            "id": event_id
        })
Example #9
0
    def test_login(self):
        with patch('allauth.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 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)
Example #11
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.html")
        # 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.html")
            # 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.html")
        c.post(reverse("account_confirm_email", args=[confirmation.key]))
        resp = c.post(reverse("account_login"), {"login": "******", "password": "******"})
        self.assertEqual(resp["location"], "http://testserver" + settings.LOGIN_REDIRECT_URL)
Example #12
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.assertEqual(resp["location"], "http://testserver" + settings.LOGIN_REDIRECT_URL)
Example #13
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.')
Example #14
0
    def clean_username(self, username, shallow=False):
        """
        Validates the username. You can hook into this if you want to
        (dynamically) restrict what usernames can be chosen. This copies most of the code from the django-allauth
        DefaultAccountAdapter, but adds support for the CASE_INSENTIVE_IDS setting because the PRESERVE_USERNAME_CASING
        setting in allauth, does not allow you to preserve the username case but check against it in a case-insensitive way
        """
        for validator in app_settings.USERNAME_VALIDATORS:
            validator(username)

        # TODO: Add regexp support to USERNAME_BLACKLIST
        username_blacklist_lower = [ub.lower()
                                    for ub in app_settings.USERNAME_BLACKLIST]
        if username.lower() in username_blacklist_lower:
            raise forms.ValidationError(
                self.error_messages['username_blacklisted'])
        # Skipping database lookups when shallow is True, needed for unique
        # username generation.
        if not shallow:
            from .utils import filter_users_by_username
            if filter_users_by_username(username).exists():
                user_model = get_user_model()
                username_field = app_settings.USER_MODEL_USERNAME_FIELD
                error_message = user_model._meta.get_field(
                    username_field).error_messages.get('unique')
                if not error_message:
                    error_message = self.error_messages['username_taken']
                raise forms.ValidationError(error_message)
        return username
Example #15
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)
        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]
Example #16
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,
                             'http://testserver'+settings.LOGIN_REDIRECT_URL,
                             fetch_redirect_response=False)
Example #17
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
Example #18
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, "http://testserver" + settings.LOGIN_REDIRECT_URL, fetch_redirect_response=False)
Example #19
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"))
Example #20
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
Example #21
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))
Example #22
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"))
Example #23
0
def get_email_field_length():
    if app_settings.USER_MODEL_EMAIL_FIELD is not None:
        User = get_user_model()
        try:
            return User._meta.get_field(app_settings.USER_MODEL_EMAIL_FIELD).max_length
        except FieldDoesNotExist:
            pass
    return 75  # default EmailField max_length in all versions of django
Example #24
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'))
Example #25
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
Example #26
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/")
Example #27
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/')
Example #28
0
 def test_password_forgotten_url_protocol(self):
     user = self._request_new_password()
     body = mail.outbox[0].body
     self.assertGreater(body.find("https://"), 0)
     url = body[body.find("/password/reset/") :].split()[0]
     resp = self.client.get(url)
     self.assertTemplateUsed(resp, "account/password_reset_from_key.html")
     self.client.post(url, {"password1": "newpass123", "password2": "newpass123"})
     user = get_user_model().objects.get(pk=user.pk)
     self.assertTrue(user.check_password("newpass123"))
     return resp
Example #29
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
Example #30
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)
Example #31
0
 def setUp(self):
     self.client = Client()
     self.user = get_user_model().objects.create(username='******', password='******', is_active=True)
     EmailAddress.objects.create(user=self.user, email="*****@*****.**", primary=True, verified=True)
     self.client.force_login(self.user)
     self.response = self.client.get(reverse('contact'))
Example #32
0
 def test_checkout_page(self):
     self.user = get_user_model().objects.create_user(
         'test', '*****@*****.**', 'password')
     page = self.client.get('/accounts/login/?next=/checkout/')
     self.assertEqual(page.status_code, 200)
     self.assertTemplateUsed(page, 'account/login.html')
Example #33
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)
        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'))
        self.assertTrue('form_errors' in data)
        self.assertTrue('__all__' in data['form_errors'])
Example #34
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")
Example #35
0
 def test_user_email_domain_unicode_collision_nonexistent(self):
     User = get_user_model()
     User.objects.create_user('mike123', '*****@*****.**', 'test123')
     data = {'email': 'mike@ıxample.org'}
     form = ResetPasswordForm(data)
     self.assertFalse(form.is_valid())
Example #36
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")
Example #37
0
    def test_email_verification_mandatory(self):
        c = Client()
        # Signup
        resp = c.post(reverse('account_signup'), {
            'username': '******',
            'email': '*****@*****.**',
            'password1': 'johndoe',
            'password2': 'johndoe',
            'country_id': 1,
            'country_name': 'new country',
            'city_id': 1,
            'city_name': 'new city',
            'university_id': 1,
            'university_name': 'new university',
            'phone': '+78005003020'
        },
                      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=app_settings.EMAIL_CONFIRMATION_EXPIRE_DAYS - 1,
                          hours=23))
        # 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,
                             'http://testserver' + settings.LOGIN_REDIRECT_URL,
                             fetch_redirect_response=False)
Example #38
0
def create_user():
    """Creates a test user."""
    user_model_class = get_user_model()
    return user_model_class.objects.create_user(
        username='******', password='******'
    )
Example #39
0
 def test_user_email_domain_unicode_collision_nonexistent(self):
     User = get_user_model()
     User.objects.create_user("mike123", "*****@*****.**", "test123")
     data = {"email": "mike@ıxample.org"}
     form = ResetPasswordForm(data)
     self.assertFalse(form.is_valid())
Example #40
0
 def _create_user(self):
     user = get_user_model().objects.create(username='******', is_active=True)
     user.set_password('doe')
     user.save()
     return user
Example #41
0
    def test_org_member_making_private_note(self):
        """
        Tests creating a private note, moving it to the workspace,
        and having another user set the note back to private
        """
        # Create a user
        alice = get_user_model().objects.create_user(
            username='******',
            password='******',
            email='alice@researchhub_test.com')
        alice_org = alice.organization

        self.client.force_authenticate(alice)

        bob = get_user_model().objects.create_user(
            username='******',
            password='******',
            email='bob@researchhub_test.com')
        # Add Bob as Admin to Alice Org
        content_type = ContentType.objects.get_for_model(Organization)
        Permission.objects.create(access_type='ADMIN',
                                  content_type=content_type,
                                  object_id=alice_org.id,
                                  user=bob)

        response = self.client.post(
            '/api/note/', {
                'grouping': 'PRIVATE',
                'organization_slug': alice_org.slug,
                'title': 'private to workspace to private'
            })
        note = response.data

        # Change note to workspace
        perm_response = self.client.patch(
            f"/api/note/{note['id']}/update_permissions/", {
                'access_type': 'ADMIN',
                'organization': alice_org.id,
            })
        updated_note = self.client.get(f"/api/note/{note['id']}/")
        self.assertEqual(updated_note.data['access'], 'WORKSPACE')

        # Switch to Bob
        self.client.force_authenticate(bob)

        # Make the note private
        response = self.client.post(f"/api/note/{note['id']}/make_private/")
        self.assertEqual(response.data['access'], 'PRIVATE')

        bobs_notes_from_alice_org = self.client.get(
            f'/api/organization/{alice_org.slug}/get_organization_notes/')
        self.assertEqual(
            bobs_notes_from_alice_org.data['results'][0]['access'], 'PRIVATE')

        # Switch to Alice
        self.client.force_authenticate(alice)

        alice_notes_from_alice_org = self.client.get(
            f'/api/organization/{alice_org.slug}/get_organization_notes/')

        self.assertEqual(alice_notes_from_alice_org.data['count'], 0)

        response = self.client.get(f"/api/note/{note['id']}/")
        self.assertEqual(response.status_code, 403)
Example #42
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]
    def handle(self, *args, **options):
        User = get_user_model()
        user_with_duplicates = User.objects.exclude(email='').annotate(
            lemail=Lower('email')).values('lemail').annotate(
                count=Count(Lower('email'))).values(
                    'lemail',
                    'count').filter(count__gt=1).order_by('lemail', 'count')

        csv_path = os.path.join(settings.MEDIA_ROOT, 'duplicated_users.csv')
        links = []

        with open(csv_path, mode='w') as csv_file:
            writer = csv.writer(csv_file,
                                delimiter=',',
                                quotechar='"',
                                quoting=csv.QUOTE_MINIMAL)
            writer.writerow(['Email', 'Count', 'Latest'])
            for duplicate in user_with_duplicates:
                csv_row = [duplicate['lemail'], duplicate['count']]

                users = User.objects.filter(
                    email__iexact=duplicate['lemail']).order_by(
                        'last_login', '-date_joined')

                latest_user = users[0]

                # Get the oldest sass_accredited date from
                sass_accredited_date_from_user = User.objects.filter(
                    email__iexact=duplicate['lemail']).exclude(
                        bims_profile__sass_accredited_date_from__isnull=True
                    ).order_by('bims_profile__sass_accredited_date_from')

                # -- Get the most recent sass_accredited_date_to
                sass_accredited_date_to_user = User.objects.filter(
                    email__iexact=duplicate['lemail']).exclude(
                        bims_profile__sass_accredited_date_to__isnull=True
                    ).order_by('-bims_profile__sass_accredited_date_to')

                date_from = latest_user.bims_profile.sass_accredited_date_from
                date_to = latest_user.bims_profile.sass_accredited_date_to

                try:
                    if sass_accredited_date_from_user.count() > 0:
                        date_from = sass_accredited_date_from_user[
                            0].bims_profile.sass_accredited_date_from
                except Exception as e:
                    pass
                try:
                    if sass_accredited_date_to_user.count() > 0:
                        date_to = sass_accredited_date_to_user[
                            0].bims_profile.sass_accredited_date_to
                except Exception as e:
                    pass

                latest_user.bims_profile.sass_accredited_date_from = date_from
                latest_user.bims_profile.sass_accredited_date_to = date_to
                latest_user.bims_profile.save()

                if not links:
                    links = [
                        rel.get_accessor_name()
                        for rel in latest_user._meta.get_fields()
                        if issubclass(type(rel), ForeignObjectRel)
                    ]

                if links:
                    for user in users[1:]:
                        print('----- {} -----'.format(str(user)))
                        for link in links:
                            try:
                                objects = getattr(user, link).all()
                                if objects.count() > 0:
                                    print('Updating {obj} for User : {user}'.
                                          format(obj=str(
                                              objects.model._meta.label),
                                                 user=str(user)))
                                    update_dict = {
                                        getattr(user, link).field.name:
                                        latest_user
                                    }
                                    objects.update(**update_dict)
                            except Exception as e:  # noqa
                                continue
                        print(''.join(
                            ['-' for i in range(len(str(user)) + 12)]))
                csv_row.append(
                    json.dumps({
                        'username': latest_user.username,
                        'last_login': str(latest_user.last_login),
                        'date_joined': str(latest_user.date_joined),
                        'date_from': str(date_from) if date_from else '-',
                        'date_to': str(date_to) if date_to else '-'
                    }))

                writer.writerow(csv_row)

                users.exclude(id=latest_user.id).delete()
Example #44
0
 def setUp(self):
     self.client = Client()
     self.user = get_user_model().objects.create(username='******', password='******', is_active=True)
     EmailAddress.objects.create(user=self.user, email="*****@*****.**", primary=True, verified=True)
     self.client.force_login(self.user)
     self.album = Album.objects.create(name='TestAlbum', created_by=self.user)
Example #45
0
 def _create_user(self):
     user = get_user_model().objects.create(username='******', is_active=True)
     user.set_password('doe')
     user.save()
     braintree.Customer.delete(user.usermerchantid.customer_id)
     return user
Example #46
0
 def test_username_conflict(self):
     User = get_user_model()
     User.objects.create(username='******')
     self.login(self.get_mocked_response())
     socialaccount = SocialAccount.objects.get(uid='mocked_uid')  # FIXME: mocked uid
     self.assertEqual(socialaccount.user.username, 'askdjango')   # FIXME: mocked username
Example #47
0
 def _create_user_and_login(self):
     user = get_user_model().objects.create(username='******', is_active=True)
     user.set_password('doe')
     user.save()
     self.client.login(username='******', password='******')
     return user
Example #48
0
    def validate(self, attrs, retry=0):
        view = self.context.get('view')
        request = self._get_request()

        if not view:
            error = serializers.ValidationError(
                _("View is not defined, pass it as a context variable"))
            sentry.log_error(error)
            raise error

        adapter_class = getattr(view, 'adapter_class', None)
        if not adapter_class:
            error = serializers.ValidationError(
                _("Define adapter_class in view"))
            sentry.log_error(error)
            raise error

        adapter = adapter_class(request)
        app = adapter.get_provider().get_app(request)

        # More info on code vs access_token
        # http://stackoverflow.com/questions/8666316/facebook-oauth-2-0-code-and-token

        credential = attrs.get('credential')

        # Case 1: We received the access_token
        if attrs.get('access_token') or credential:
            access_token = attrs.get('access_token')
            if credential:
                access_token = credential

        # Case 2: We received the authorization code
        elif attrs.get('code'):
            self.callback_url = getattr(view, 'callback_url', None)
            self.client_class = getattr(view, 'client_class', None)

            if not self.callback_url:
                error = serializers.ValidationError(
                    _("Define callback_url in view"))
                sentry.log_error(error)
                raise error
            if not self.client_class:
                error = serializers.ValidationError(
                    _("Define client_class in view"))
                sentry.log_error(error)
                raise error

            code = attrs.get('code')

            provider = adapter.get_provider()
            scope = provider.get_scope(request)
            client = self.client_class(
                request,
                app.client_id,
                app.secret,
                adapter.access_token_method,
                adapter.access_token_url,
                'postmessage',  # This is the callback url
                scope)
            token = client.get_access_token(code)
            access_token = token['access_token']

        else:
            error = serializers.ValidationError(
                _("Incorrect input. access_token or code is required."))
            sentry.log_error(error)
            raise serializers.ValidationError(
                _("Incorrect input. access_token or code is required."))

        social_token = adapter.parse_token({'access_token': access_token})
        social_token.app = app

        login = None
        try:
            login = self.get_social_login(adapter, app, social_token,
                                          access_token)
            complete_social_login(request, login)
        except ConnectionTimeout:
            pass
        except NoReverseMatch as e:
            if 'account_inactive' in str(e):
                login_user = login.account.user
                tracked_login = events_api.track_login(login_user, '$failure',
                                                       request)
                update_user_risk_score(login_user, tracked_login)
                raise LoginError(None, 'Account is suspended')
        except Exception as e:
            error = LoginError(e, 'Login failed')
            sentry.log_info(error, error=e)
            if login:
                deleted = self._delete_user_account(login.user, error=e)
                if deleted and retry < 3:
                    return self.validate(attrs, retry=retry + 1)
            sentry.log_error(error, base_error=e)
            raise serializers.ValidationError(_("Incorrect value"))

        if login and not login.is_existing:
            # We have an account already signed up in a different flow
            # with the same email address: raise an exception.
            # This needs to be handled in the frontend. We can not just
            # link up the accounts due to security constraints
            if app_settings.UNIQUE_EMAIL:
                # Do we have an account already with this email address?
                account_exists = get_user_model().objects.filter(
                    email=login.user.email, ).exists()
                if account_exists:
                    sentry.log_info('User already registered with this e-mail')
                    deleted = self._delete_user_account(login.user)
                    if deleted and retry < 3:
                        return self.validate(attrs, retry=retry + 1)
                    raise serializers.ValidationError(
                        _("User already registered with this e-mail address."))

            login.lookup()
            login.save(request, connect=True)

        login_user = login.account.user
        attrs['user'] = login_user
        tracked_login = events_api.track_login(login_user, '$success', request)
        update_user_risk_score(login_user, tracked_login)

        try:
            visits = WebsiteVisits.objects.get(uuid=attrs['uuid'])
            visits.user = attrs['user']
            visits.save()
        except Exception as e:
            print(e)
            pass

        try:
            referral_code = attrs.get('referral_code')
            if referral_code:
                referral_user = User.objects.get(referral_code=referral_code)
                user = attrs['user']
                if referral_code and not user.invited_by and referral_user.id != user.id:
                    user.invited_by = referral_user
                    user.save()
        except Exception as e:
            print(e)
            sentry.log_error(e)
            pass

        request = self._get_request()
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')

        user = attrs['user']
        check_user_risk(user)

        if user.is_authenticated and not user.probable_spammer:
            try:
                country = geo.country(ip)
                user.country_code = country.get('country_code')
                user.save()
            except Exception as e:
                print(e)
                sentry.log_error(e)

        return attrs
 def test_username_conflict(self):
     User = get_user_model()
     User.objects.create(username='******')
     self.login(self.get_mocked_response())
     socialaccount = SocialAccount.objects.get(uid='630595557')
     self.assertEqual(socialaccount.user.username, 'raymond')
Example #50
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')
Example #51
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')
Example #52
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
        )
Example #53
0
from django.core.urlresolvers import reverse
from django.test.client import Client
from django.core import mail
from django.contrib.sites.models import Site
from django.test.client import RequestFactory
from django.contrib.auth.models import AnonymousUser

from allauth.account.forms import BaseSignupForm
from allauth.account.models import EmailAddress, EmailConfirmation
from allauth.utils import get_user_model

from . import app_settings

from .adapter import get_adapter

User = get_user_model()


@override_settings(
    ACCOUNT_DEFAULT_HTTP_PROTOCOL='https',
    ACCOUNT_EMAIL_VERIFICATION=app_settings.EmailVerificationMethod.MANDATORY,
    ACCOUNT_AUTHENTICATION_METHOD=app_settings.AuthenticationMethod.USERNAME,
    ACCOUNT_SIGNUP_FORM_CLASS=None,
    ACCOUNT_EMAIL_SUBJECT_PREFIX=None,
    LOGIN_REDIRECT_URL='/accounts/profile/',
    ACCOUNT_ADAPTER='allauth.account.adapter.DefaultAccountAdapter',
    ACCOUNT_USERNAME_REQUIRED=True)
class AccountTests(TestCase):
    def setUp(self):
        if 'allauth.socialaccount' in settings.INSTALLED_APPS:
            # Otherwise ImproperlyConfigured exceptions may occur