def test_reset_user_password_with_updated_user_email(self):
        # set user.last_login, ensures we get same/valid token
        # https://code.djangoproject.com/ticket/10265
        self.user.last_login = now()
        self.user.save()
        new_password = "******"
        uid = urlsafe_base64_encode(
            force_bytes(self.user.pk))
        mhv = default_token_generator
        token = mhv.make_token(self.user)
        data = {'token': token, 'new_password': new_password,
                'uid': uid}
        # check that the token is valid
        valid_token = mhv.check_token(self.user, token)
        self.assertTrue(valid_token)

        # Update user email
        self.user.email = "*****@*****.**"
        self.user.save()
        update_partial_digests(self.user, "bobbob")

        # Token should be invalid as the email was updated
        invalid_token = mhv.check_token(self.user, token)
        self.assertFalse(invalid_token)

        request = self.factory.post('/', data=data)
        response = self.view(request)
        self.assertEqual(response.status_code, 400)
        self.assertTrue(
            'Invalid token' in response.data['non_field_errors'][0])
    def test_user_updates_email(self):
        view = ConnectViewSet.as_view(
            {'get': 'list'},
            authentication_classes=(DigestAuthentication,))

        auth = DigestAuth('*****@*****.**', 'bobbob')
        request = self._get_request_session_with_auth(view, auth)

        response = view(request)
        temp_token = TempToken.objects.get(user__username='******')
        self.data['temp_token'] = temp_token.key
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, self.data)

        self.user.email = "*****@*****.**"
        self.user.save()
        update_partial_digests(self.user, "bobbob")

        auth = DigestAuth('*****@*****.**', 'bobbob')
        request = self._get_request_session_with_auth(view, auth)

        response = view(request)
        temp_token = TempToken.objects.get(user__username='******')
        self.data['temp_token'] = temp_token.key
        self.data['email'] = '*****@*****.**'
        self.assertEqual(response.status_code, 200)
    def test_user_updates_email(self):
        view = ConnectViewSet.as_view(
            {'get': 'list'},
            authentication_classes=(DigestAuthentication,))

        auth = DigestAuth('*****@*****.**', 'bobbob')
        request = self._get_request_session_with_auth(view, auth)

        response = view(request)
        temp_token = TempToken.objects.get(user__username='******')
        self.data['temp_token'] = temp_token.key
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, self.data)

        self.user.email = "*****@*****.**"
        self.user.save()
        update_partial_digests(self.user, "bobbob")

        auth = DigestAuth('*****@*****.**', 'bobbob')
        request = self._get_request_session_with_auth(view, auth)

        response = view(request)
        temp_token = TempToken.objects.get(user__username='******')
        self.data['temp_token'] = temp_token.key
        self.data['email'] = '*****@*****.**'
        self.assertEqual(response.status_code, 200)
Exemple #4
0
    def update(self, instance, validated_data):
        params = validated_data
        password = params.get("password1")
        email = params.get('email')

        # Check password if email is being updated
        if email and not password:
            raise serializers.ValidationError(
                _(u'Your password is required when updating your email '
                  u'address.'))
        if password and not instance.user.check_password(password):
            raise serializers.ValidationError(_(u'Invalid password'))

        # get user
        instance.user.email = email or instance.user.email

        instance.user.first_name = params.get('first_name',
                                              instance.user.first_name)

        instance.user.last_name = params.get('last_name',
                                             instance.user.last_name)

        instance.user.username = params.get('username', instance.user.username)

        instance.user.save()

        if password:
            # force django-digest to regenerate its stored partial digests
            update_partial_digests(instance.user, password)

        return super(UserProfileSerializer, self).update(instance, params)
    def test_user_has_no_profile_bug(self):
        alice = User.objects.create(username='******')
        alice.set_password('alice')
        update_partial_digests(alice, "alice")
        view = ConnectViewSet.as_view(
            {'get': 'list'}, authentication_classes=(DigestAuthentication, ))

        auth = DigestAuth('alice', 'alice')
        request = self._get_request_session_with_auth(view, auth)

        response = view(request)
        self.assertEqual(response.status_code, 200)
    def test_user_has_no_profile_bug(self):
        alice = User.objects.create(username='******')
        alice.set_password('alice')
        update_partial_digests(alice, "alice")
        view = ConnectViewSet.as_view(
            {'get': 'list'},
            authentication_classes=(DigestAuthentication,))

        auth = DigestAuth('alice', 'alice')
        request = self._get_request_session_with_auth(view, auth)

        response = view(request)
        self.assertEqual(response.status_code, 200)
    def update(self, instance, validated_data):
        params = validated_data
        password = params.get("password1")
        email = params.get('email')

        # Check password if email is being updated
        if email and not password:
            raise serializers.ValidationError(
                _(u'Your password is required when updating your email '
                  u'address.'))
        if password and not instance.user.check_password(password):
            raise serializers.ValidationError(_(u'Invalid password'))

        # get user
        instance.user.email = email or instance.user.email

        instance.user.first_name = params.get('first_name',
                                              instance.user.first_name)

        instance.user.last_name = params.get('last_name',
                                             instance.user.last_name)

        instance.user.username = params.get('username', instance.user.username)

        instance.metadata = params.get('metadata', instance.metadata)

        instance.user.save()

        if email:
            instance.metadata.update({"is_email_verified": False})
            instance.save()

            request = self.context.get('request')
            redirect_url = params.get('redirect_url')
            _send_verification_email(redirect_url, instance.user, request)

        if password:
            # force django-digest to regenerate its stored partial digests
            update_partial_digests(instance.user, password)

        return super(UserProfileSerializer, self).update(instance, params)
    def update(self, instance, validated_data):
        params = validated_data
        password = params.get("password1")
        email = params.get('email')

        # Check password if email is being updated
        if email and not password:
            raise serializers.ValidationError(
                _(u'Your password is required when updating your email '
                  u'address.'))
        if password and not instance.user.check_password(password):
            raise serializers.ValidationError(_(u'Invalid password'))

        # get user
        instance.user.email = email or instance.user.email

        instance.user.first_name = params.get('first_name',
                                              instance.user.first_name)

        instance.user.last_name = params.get('last_name',
                                             instance.user.last_name)

        instance.user.username = params.get('username', instance.user.username)

        instance.user.save()

        if email:
            instance.metadata.update({"is_email_verified": False})
            instance.save()

            request = self.context.get('request')
            redirect_url = params.get('redirect_url')
            _send_verification_email(redirect_url, instance.user, request)

        if password:
            # force django-digest to regenerate its stored partial digests
            update_partial_digests(instance.user, password)

        return super(UserProfileSerializer, self).update(instance, params)
Exemple #9
0
    def test_login_attempts(self, send_account_lockout_email):
        view = ConnectViewSet.as_view(
            {'get': 'list'}, authentication_classes=(DigestAuthentication, ))
        auth = DigestAuth('bob', 'bob')
        # clear cache
        cache.clear()

        request = self._get_request_session_with_auth(view, auth)

        # first time it creates a cache
        response = view(request)
        self.assertEqual(response.status_code, 401)
        self.assertEqual(
            response.data['detail'],
            u"Invalid username/password. For security reasons, "
            u"after 9 more failed login attempts you'll have to "
            u"wait 30 minutes before trying again.")
        request_ip = request.META.get('REMOTE_ADDR')
        self.assertEqual(
            cache.get(safe_key(f'login_attempts-{request_ip}-bob')), 1)

        # cache value increments with subsequent attempts
        response = view(request)
        self.assertEqual(response.status_code, 401)
        self.assertEqual(
            response.data['detail'],
            u"Invalid username/password. For security reasons, "
            u"after 8 more failed login attempts you'll have to "
            u"wait 30 minutes before trying again.")
        self.assertEqual(
            cache.get(safe_key(f'login_attempts-{request_ip}-bob')), 2)

        # login attempts are tracked separately for other IPs
        request.META.update({'HTTP_X_REAL_IP': '5.6.7.8'})
        response = view(request)
        self.assertEqual(response.status_code, 401)
        self.assertEqual(
            cache.get(safe_key(f'login_attempts-{request_ip}-bob')), 2)
        self.assertEqual(cache.get(safe_key('login_attempts-5.6.7.8-bob')), 1)

        # login_attempts doesn't increase with correct login
        auth = DigestAuth('bob', 'bobbob')
        request = self._get_request_session_with_auth(view, auth)
        response = view(request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            cache.get(safe_key(f'login_attempts-{request_ip}-bob')), 2)

        # lockout_user cache created upon fifth attempt
        auth = DigestAuth('bob', 'bob')
        request = self._get_request_session_with_auth(view, auth)
        self.assertFalse(send_account_lockout_email.called)
        cache.set(safe_key(f'login_attempts-{request_ip}-bob'), 9)
        self.assertIsNone(cache.get(safe_key(f'lockout_ip-{request_ip}-bob')))
        response = view(request)
        self.assertEqual(response.status_code, 401)
        self.assertEqual(
            response.data['detail'],
            u"Locked out. Too many wrong username/password "
            u"attempts. Try again in 30 minutes.")
        self.assertEqual(
            cache.get(safe_key(f'login_attempts-{request_ip}-bob')), 10)
        self.assertIsNotNone(
            cache.get(safe_key(f'lockout_ip-{request_ip}-bob')))
        lockout = datetime.strptime(
            cache.get(safe_key(f'lockout_ip-{request_ip}-bob')),
            '%Y-%m-%dT%H:%M:%S')
        self.assertIsInstance(lockout, datetime)

        # email sent upon limit being reached with right arguments
        subject_path = 'account_lockout/lockout_email_subject.txt'
        self.assertTrue(send_account_lockout_email.called)
        email_subject = render_to_string(subject_path)
        self.assertIn(email_subject,
                      send_account_lockout_email.call_args[1]['args'])
        self.assertEqual(send_account_lockout_email.call_count, 2,
                         "Called twice")

        # subsequent login fails after lockout even with correct credentials
        auth = DigestAuth('bob', 'bobbob')
        request = self._get_request_session_with_auth(view, auth)
        response = view(request)
        self.assertEqual(response.status_code, 401)
        self.assertEqual(
            response.data['detail'],
            u"Locked out. Too many wrong username/password "
            u"attempts. Try again in 30 minutes.")

        # Other users on same IP not locked out
        alice = User.objects.create(username='******')
        alice.set_password('alice')
        update_partial_digests(alice, "alice")
        auth = DigestAuth('alice', 'alice')

        request = self._get_request_session_with_auth(view, auth)
        response = view(request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(request.META.get('REMOTE_ADDR'), request_ip)
        # clear cache
        cache.clear()