def test_db_log_failed_attempt_with_user(self): """ Tests for the EdraakRateLimitMixin.db_log_failed_attempt method. """ backend = EdraakRateLimitModelBackend() omar = UserFactory(email='*****@*****.**') ali = UserFactory(email='*****@*****.**') fake_request = FakeRequest(ip_address='150.0.3.31') with self.assertRaises(RateLimitedIP.DoesNotExist): RateLimitedIP.objects.get(latest_user=omar) backend.db_log_failed_attempt(fake_request, omar.username) omar_limit = RateLimitedIP.objects.get(latest_user=omar) self.assertEquals(omar_limit.ip_address, '150.0.3.31', 'Should log the entry with correct IP') self.assertEquals(omar_limit.lockout_count, 1, 'Only one attempt so far') backend.db_log_failed_attempt(FakeRequest(ip_address='150.0.3.31')) with self.assertRaises(RateLimitedIP.DoesNotExist): # Should clear the user from the record RateLimitedIP.objects.get(latest_user=omar) # Get the user back backend.db_log_failed_attempt(FakeRequest(ip_address='150.0.3.31'), ali.username) ali_limit = RateLimitedIP.objects.get(latest_user=ali) self.assertEquals( ali_limit.lockout_count, 3, 'Three attempts from the same IP so far, regardless of the user')
def test_ip_address(self): """ Tests for the FakeRequest class. """ ip_address = '8.8.8.8' request = FakeRequest(ip_address=ip_address) self.assertEquals(request.META['REMOTE_ADDR'], ip_address)
def delete_model(self, request, obj): """ Delete a model and reset it's attempts in the cache. """ backend = EdraakRateLimitModelBackend() cache_keys = backend.keys_to_check(request=FakeRequest(obj.ip_address)) cache.delete_many(cache_keys) obj.delete()
def test_is_rate_limit_exceeded_method(self, db_log_mock, request_counts, ip_address, expected_calls): """ Tests if `BadRequestRateLimiter.is_rate_limit_exceeded` calls Edraak's `db_log_failed_attempt` correctly. At Edraak we've added the `db_log_failed_attempt` to the BadRequestRateLimiter, to show it on the admin panel. """ limiter = BadRequestRateLimiter() request_counts_mock = Mock(values=Mock(return_value=request_counts, )) with patch.object(limiter, 'get_counters', return_value=request_counts_mock): limiter.is_rate_limit_exceeded(FakeRequest(ip_address=ip_address)) self.assertEquals(db_log_mock.call_count, expected_calls, 'Should only be called when if limit exceeded')
def test_rate_exceeded(self, db_log_failed_attempt): """ Checks if the authenticate method throws the RateLimitException exception. """ mock_counts = Mock(values=Mock(return_value=[500, 500, 500], ), ) with patch('ratelimitbackend.backends.RateLimitMixin.get_counters', return_value=mock_counts): backend = EdraakRateLimitModelBackend() with self.assertRaises(RateLimitException): mock_request = FakeRequest(ip_address='240.1.3.4') backend.authenticate(username='******', password='******', request=mock_request) db_log_failed_attempt.assert_called_once_with( mock_request, 'user1')
def test_rate_not_exceeded(self, db_log_failed_attempt): """ Testing when the rate limit is not exceeded. """ expected_user = UserFactory() # Patch ModelBackend to bypass username and password checks. with patch('django.contrib.auth.backends.ModelBackend.authenticate', return_value=expected_user): backend = EdraakRateLimitModelBackend() mock_request = FakeRequest(ip_address='240.1.3.4') authenticated_user = backend.authenticate(username='******', password='******', request=mock_request) self.assertIs(expected_user, authenticated_user, 'Should authenticate the user') # Ensures that nothing is logged in the database. db_log_failed_attempt.assert_not_called()