def test_hit_ratelimits_as_ip(self) -> None: add_ratelimit_rule(1, 5, domain="api_by_ip") try: RateLimitedIPAddr("127.0.0.1").clear_history() self.do_test_hit_ratelimits(self.send_unauthed_api_request) finally: # We need this in a finally block to ensure the test cleans up after itself # even in case of failure, to avoid polluting the rules state. remove_ratelimit_rule(1, 5, domain="api_by_ip")
def rate_limit_rule(range_seconds: int, num_requests: int, domain: str) -> Iterator[None]: RateLimitedIPAddr("127.0.0.1", domain=domain).clear_history() add_ratelimit_rule(range_seconds, num_requests, domain=domain) try: yield finally: # We need this in a finally block to ensure the test cleans up after itself # even in case of failure, to avoid polluting the rules state. remove_ratelimit_rule(range_seconds, num_requests, domain=domain)
def test_wrong_old_password_rate_limiter(self) -> None: self.login("hamlet") with self.settings(RATE_LIMITING_AUTHENTICATE=True): add_ratelimit_rule(10, 2, domain="authenticate_by_username") start_time = time.time() with mock.patch("time.time", return_value=start_time): result = self.client_patch( "/json/settings", dict( old_password="******", new_password="******", ), ) self.assert_json_error(result, "Wrong password!") result = self.client_patch( "/json/settings", dict( old_password="******", new_password="******", ), ) self.assert_json_error(result, "Wrong password!") # We're over the limit, so we'll get blocked even with the correct password. result = self.client_patch( "/json/settings", dict( old_password=initial_password( self.example_email("hamlet")), new_password="******", ), ) self.assert_json_error( result, "You're making too many attempts! Try again in 10 seconds." ) # After time passes, we should be able to succeed if we give the correct password. with mock.patch("time.time", return_value=start_time + 11): json_result = self.client_patch( "/json/settings", dict( old_password=initial_password( self.example_email("hamlet")), new_password="******", ), ) self.assert_json_success(json_result) remove_ratelimit_rule(10, 2, domain="authenticate_by_username")
def test_thumbnail_redirect_for_spectator(self) -> None: self.login("hamlet") fp = StringIO("zulip!") fp.name = "zulip.jpeg" result = self.client_post("/json/user_uploads", {"file": fp}) self.assert_json_success(result) json = orjson.loads(result.content) uri = json["uri"] add_ratelimit_rule(86400, 1000, domain="spectator_attachment_access_by_file") # Deny file access for non-web-public stream self.subscribe(self.example_user("hamlet"), "Denmark") host = self.example_user("hamlet").realm.host body = f"First message ...[zulip.txt](http://{host}" + uri + ")" self.send_stream_message(self.example_user("hamlet"), "Denmark", body, "test") self.logout() response = self.client_get("/thumbnail", {"url": uri[1:], "size": "full"}) self.assertEqual(response.status_code, 403) # Allow file access for web-public stream self.login("hamlet") self.make_stream("web-public-stream", is_web_public=True) self.subscribe(self.example_user("hamlet"), "web-public-stream") body = f"First message ...[zulip.txt](http://{host}" + uri + ")" self.send_stream_message(self.example_user("hamlet"), "web-public-stream", body, "test") self.logout() response = self.client_get("/thumbnail", {"url": uri[1:], "size": "full"}) self.assertEqual(response.status_code, 302) remove_ratelimit_rule(86400, 1000, domain="spectator_attachment_access_by_file") # Deny file access since rate limited add_ratelimit_rule(86400, 0, domain="spectator_attachment_access_by_file") response = self.client_get("/thumbnail", {"url": uri[1:], "size": "full"}) self.assertEqual(response.status_code, 403) remove_ratelimit_rule(86400, 0, domain="spectator_attachment_access_by_file") # Deny random file access response = self.client_get( "/thumbnail", { "url": "user_uploads/2/71/QYB7LA-ULMYEad-QfLMxmI2e/zulip-non-existent.txt", "size": "full", }, ) self.assertEqual(response.status_code, 403)
def setUp(self) -> None: super().setUp() # Some tests here can be somewhat timing-sensitive in a way # that can't be eliminated, e.g. due to testing things that rely # on redis' internal timing mechanism which we can't mock. # The first API request when running a suite of tests is slow # and can take multiple seconds. This is not a problem when running # multiple tests, but if an individual, time-sensitive test from this class # is run, the first API request it makes taking a lot of time can throw things off # and cause the test to fail. Thus we do a dummy API request here to warm up # the system and allow the tests to assume their requests won't take multiple seconds. user = self.example_user('hamlet') self.api_get(user, "/api/v1/messages") settings.RATE_LIMITING = True add_ratelimit_rule(1, 5)
def test_hit_ratelimits_as_remote_server(self) -> None: add_ratelimit_rule(1, 5, domain="api_by_remote_server") server_uuid = "1234-abcd" server = RemoteZulipServer( uuid=server_uuid, api_key="magic_secret_api_key", hostname="demo.example.com", last_updated=timezone_now(), ) server.save() endpoint = "/api/v1/remotes/push/register" payload = { "user_id": 10, "token": "111222", "token_kind": PushDeviceToken.GCM } try: # Remote servers can only make requests to the root subdomain. original_default_subdomain = self.DEFAULT_SUBDOMAIN self.DEFAULT_SUBDOMAIN = "" RateLimitedRemoteZulipServer(server).clear_history() with self.assertLogs("zerver.lib.rate_limiter", level="WARNING") as m: self.do_test_hit_ratelimits( lambda: self.uuid_post(server_uuid, endpoint, payload)) self.assertEqual( m.output, [ "WARNING:zerver.lib.rate_limiter:Remote server <RemoteZulipServer demo.example.com 1234-abcd> exceeded rate limits on domain api_by_remote_server" ], ) finally: self.DEFAULT_SUBDOMAIN = original_default_subdomain remove_ratelimit_rule(1, 5, domain="api_by_remote_server")
def test_add_remove_rule(self) -> None: user_profile = self.example_user("hamlet") add_ratelimit_rule(1, 2) add_ratelimit_rule(4, 5, domain='some_new_domain') add_ratelimit_rule(10, 100, domain='some_new_domain') obj = RateLimitedUser(user_profile) self.assertEqual(obj.get_rules(), [(1, 2)]) obj.domain = 'some_new_domain' self.assertEqual(obj.get_rules(), [(4, 5), (10, 100)]) remove_ratelimit_rule(10, 100, domain='some_new_domain') self.assertEqual(obj.get_rules(), [(4, 5)])
def setUp(self) -> None: super().setUp() settings.RATE_LIMITING = True add_ratelimit_rule(1, 5)
def setUp(self) -> None: settings.RATE_LIMITING = True add_ratelimit_rule(1, 5)
def setUp(self): # type: () -> None settings.RATE_LIMITING = True add_ratelimit_rule(1, 5)
def setUp(self): settings.RATE_LIMITING = True add_ratelimit_rule(1, 5)