mirror of
https://github.com/typesense/typesense.git
synced 2025-05-18 20:52:50 +08:00
* Rate limit procedure updates & improvements * Review changes * Update for adding support to delete temp throttles * Review Changes II * Review Changes III
820 lines
40 KiB
C++
820 lines
40 KiB
C++
#include <gtest/gtest.h>
|
|
#include <string>
|
|
#include <thread>
|
|
#include "ratelimit_manager.h"
|
|
#include "logger.h"
|
|
#include "core_api.h"
|
|
|
|
// Google test for RateLimitManager
|
|
class RateLimitManagerTest : public ::testing::Test
|
|
{
|
|
protected:
|
|
RateLimitManager *manager = RateLimitManager::getInstance();
|
|
Store *store;
|
|
|
|
|
|
void changeBaseTimestamp(const uint64_t new_base_timestamp) {
|
|
manager->_set_base_timestamp(new_base_timestamp);
|
|
}
|
|
|
|
|
|
|
|
RateLimitManagerTest() {
|
|
|
|
}
|
|
|
|
virtual ~RateLimitManagerTest() {
|
|
// You can do clean-up work that doesn't throw exceptions here.
|
|
manager->clear_all();
|
|
|
|
}
|
|
|
|
// If the constructor and destructor are not enough for setting up
|
|
// and cleaning up each test, you can define the following methods:
|
|
|
|
virtual void SetUp() {
|
|
std::string state_dir_path = "/tmp/typesense_test/rate_limit_manager_test_db";
|
|
system(("rm -rf "+state_dir_path+" && mkdir -p "+state_dir_path).c_str());
|
|
|
|
store = new Store(state_dir_path);
|
|
manager->init(store);
|
|
}
|
|
|
|
virtual void TearDown() {
|
|
delete store;
|
|
}
|
|
|
|
// Objects declared here can be used by all tests in the test case for Foo.
|
|
};
|
|
|
|
TEST_F(RateLimitManagerTest, TestAddRateLimitApiKey) {
|
|
auto res = manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"max_requests_1m", 10},
|
|
{"max_requests_1h", 100},
|
|
{"auto_ban_1m_threshold", 10},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
|
|
|
|
EXPECT_EQ(manager->get_all_rules().size(), 1);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestAddRateLimitIp) {
|
|
auto res = manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})},
|
|
{"max_requests_1m", 10},
|
|
{"max_requests_1h", 100},
|
|
{"auto_ban_1m_threshold", 10},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
|
|
EXPECT_EQ(manager->get_all_rules().size(), 1);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestGetBannedIps) {
|
|
manager->add_rule({
|
|
{"action", "block"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})}
|
|
});
|
|
EXPECT_EQ(manager->get_banned_entities(RateLimitedEntityType::ip).size(), 1);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestGetTrackedIps) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})},
|
|
{"max_requests_1m", 10},
|
|
{"max_requests_1h", 100},
|
|
{"auto_ban_1m_threshold", 10},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
auto rules = manager->get_all_rules();
|
|
bool found = rules[0].action == RateLimitAction::throttle && rules[0].max_requests.minute_threshold == 10 && rules[0].max_requests.hour_threshold == 100;
|
|
found = found && rules[0].entities[0].entity_type == RateLimitedEntityType::ip && rules[0].entities[0].entity_id == "0.0.0.1";
|
|
EXPECT_TRUE(found);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestGetTrackedApiKeys) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"max_requests_1m", 10},
|
|
{"max_requests_1h", 100},
|
|
{"auto_ban_1m_threshold", 10},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
auto rules = manager->get_all_rules();
|
|
bool found = rules[0].action == RateLimitAction::throttle && rules[0].max_requests.minute_threshold == 10 && rules[0].max_requests.hour_threshold == 100;
|
|
found = found && rules[0].entities[0].entity_type == RateLimitedEntityType::api_key && rules[0].entities[0].entity_id == "test";
|
|
EXPECT_TRUE(found);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestBanIpPermanently) {
|
|
manager->add_rule({
|
|
{"action", "block"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})}
|
|
});
|
|
auto rules = manager->get_all_rules();
|
|
bool found = rules[0].action == RateLimitAction::block && rules[0].entities[0].entity_type == RateLimitedEntityType::ip && rules[0].entities[0].entity_id == "0.0.0.1";
|
|
EXPECT_TRUE(found);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestIsBannedIp) {
|
|
manager->add_rule({
|
|
{"action", "block"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})}
|
|
});
|
|
EXPECT_TRUE(manager->get_banned_entities(RateLimitedEntityType::ip).size() == 1);
|
|
auto banned_entities = manager->get_banned_entities(RateLimitedEntityType::ip);
|
|
bool found = banned_entities[0].entity.entity_type == RateLimitedEntityType::ip && banned_entities[0].entity.entity_id == "0.0.0.1";
|
|
EXPECT_EQ(banned_entities[0].and_entity.ok(), false);
|
|
EXPECT_TRUE(found);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestIsBannedIpTemp) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})},
|
|
{"max_requests_1m", 1},
|
|
{"max_requests_1h", 1}
|
|
});
|
|
EXPECT_TRUE(manager->get_all_rules().size() == 1);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"},{RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"},{RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestIsBannedAPIKeyPermanently) {
|
|
manager->add_rule({
|
|
{"action", "block"},
|
|
{"api_keys", nlohmann::json::array({"test"})}
|
|
});
|
|
EXPECT_TRUE(manager->get_banned_entities(RateLimitedEntityType::api_key).size() == 1);
|
|
auto banned_entities = manager->get_banned_entities(RateLimitedEntityType::api_key);
|
|
bool found = banned_entities[0].entity.entity_type == RateLimitedEntityType::api_key && banned_entities[0].entity.entity_id == "test";
|
|
EXPECT_TRUE(found);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestIsBannedAPIKeyTemp) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"max_requests_1m", 1},
|
|
{"max_requests_1h", 1}
|
|
});
|
|
EXPECT_TRUE(manager->get_all_rules().size() == 1);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"},{RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"},{RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestAllowAPIKey) {
|
|
manager->add_rule({
|
|
{"action", "allow"},
|
|
{"api_keys", nlohmann::json::array({"test"})}
|
|
});
|
|
EXPECT_TRUE(manager->get_all_rules().size() == 1);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test_"},{RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestAllowIp) {
|
|
manager->add_rule({
|
|
{"action", "allow"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})}
|
|
});
|
|
EXPECT_TRUE(manager->get_all_rules().size() == 1);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"},{RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestThrottleAPIKey) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"max_requests_1m", 1},
|
|
{"max_requests_1h", 1}
|
|
});
|
|
EXPECT_TRUE(manager->get_all_rules().size() == 1);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestDeleteRuleByID) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"max_requests_1m", 1},
|
|
{"max_requests_1h", 1}
|
|
});
|
|
EXPECT_TRUE(manager->get_all_rules().size() == 1);
|
|
auto rules = manager->get_all_rules();
|
|
manager->delete_rule_by_id(rules[0].id);
|
|
EXPECT_EQ(manager->get_all_rules().size(), 0);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestMinuteRateLimitAPIKey) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"max_requests_1m", 5},
|
|
{"max_requests_1h", -1}
|
|
});
|
|
EXPECT_TRUE(manager->get_all_rules().size() == 1);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestHourRateLimitAPIKey) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"max_requests_1m", -1},
|
|
{"max_requests_1h", 5}
|
|
});
|
|
EXPECT_TRUE(manager->get_all_rules().size() == 1);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestMinuteRateLimitIp) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})},
|
|
{"max_requests_1m", 5},
|
|
{"max_requests_1h", -1}
|
|
});
|
|
EXPECT_TRUE(manager->get_all_rules().size() == 1);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestHourRateLimitIp) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})},
|
|
{"max_requests_1m", -1},
|
|
{"max_requests_1h", 5}
|
|
});
|
|
EXPECT_TRUE(manager->get_all_rules().size() == 1);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestGetAllRules) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})},
|
|
{"max_requests_1m", -1},
|
|
{"max_requests_1h", 5}
|
|
});
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"max_requests_1m", 5},
|
|
{"max_requests_1h", -1}
|
|
});
|
|
EXPECT_TRUE(manager->get_all_rules().size() == 2);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestGetAllRulesEmpty) {
|
|
auto rules = manager->get_all_rules();
|
|
EXPECT_EQ(rules.size(), 0);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestGetAllRulesJSON) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"max_requests_1m", 5},
|
|
{"max_requests_1h", -1}
|
|
});
|
|
nlohmann::json rules = manager->get_all_rules_json();
|
|
EXPECT_EQ(rules.is_array(), true);
|
|
EXPECT_EQ(rules.size(), 1);
|
|
EXPECT_EQ(rules.at(0).is_object(), true);
|
|
EXPECT_EQ(rules.at(0).at("id").is_number(), true);
|
|
EXPECT_EQ(rules.at(0).at("api_keys").is_array(), true);
|
|
EXPECT_EQ(rules.at(0).at("api_keys").size(), 1);
|
|
EXPECT_EQ(rules.at(0).at("api_keys").at(0).is_string(), true);
|
|
EXPECT_EQ(rules.at(0).count("ip_addresses"), 0);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestAutoBan) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"max_requests_1m", 5},
|
|
{"max_requests_1h", -1},
|
|
{"auto_ban_1m_threshold", 2},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
this->changeBaseTimestamp(120);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
this->changeBaseTimestamp(240);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
this->changeBaseTimestamp(60*59);
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
this->changeBaseTimestamp(60*60*2);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|
|
|
|
|
|
TEST_F(RateLimitManagerTest, TestWildcardAPIKeyWithFlag) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({".*"})},
|
|
{"max_requests_1m", 5},
|
|
{"max_requests_1h", -1},
|
|
{"apply_limit_per_entity", true}
|
|
});
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestWildcardAPIKeyWithoutFlag) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({".*"})},
|
|
{"max_requests_1m", 5},
|
|
{"max_requests_1h", -1},
|
|
});
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestPriority) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({".*"})},
|
|
{"max_requests_1m", 2},
|
|
{"max_requests_1h", -1},
|
|
{"priority", 3},
|
|
{"apply_limit_per_entity", true}
|
|
});
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"max_requests_1m", 5},
|
|
{"max_requests_1h", -1},
|
|
{"priority", 1}
|
|
});
|
|
manager->add_rule({
|
|
{"action", "block"},
|
|
{"api_keys", nlohmann::json::array({"test1"})},
|
|
{"priority", 4}
|
|
});
|
|
manager->add_rule({
|
|
{"action", "allow"},
|
|
{"api_keys", nlohmann::json::array({"test2"})},
|
|
{"priority", 0}
|
|
});
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test2"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test2"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test2"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestAndRule) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})},
|
|
{"max_requests_1m", 5},
|
|
{"max_requests_1h", -1},
|
|
{"priority", 3}
|
|
});
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
}
|
|
|
|
|
|
TEST_F(RateLimitManagerTest, TestExceedCounter) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"api_keys", nlohmann::json::array({".*"})},
|
|
{"priority", 3},
|
|
{"apply_limit_per_entity", true},
|
|
{"max_requests_1m", 3},
|
|
{"max_requests_1h", -1}
|
|
});
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
|
|
|
|
const auto exceeds = manager->get_exceeded_entities_json();
|
|
EXPECT_EQ(exceeds.size(), 2);
|
|
|
|
EXPECT_EQ(exceeds[0]["api_key"], ".*");
|
|
EXPECT_EQ(exceeds[0]["ip"], "0.0.0.2");
|
|
EXPECT_EQ(exceeds[0]["request_count"], 10);
|
|
|
|
EXPECT_EQ(exceeds[1]["api_key"], ".*");
|
|
EXPECT_EQ(exceeds[1]["ip"], "0.0.0.1");
|
|
EXPECT_EQ(exceeds[1]["request_count"], 9);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestActiveThrottles) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})},
|
|
{"priority", 3},
|
|
{"max_requests_1m", 3},
|
|
{"max_requests_1h", -1},
|
|
{"auto_ban_1m_threshold", 1},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
manager->_set_base_timestamp(120);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
const auto throttles = manager->get_throttled_entities_json();
|
|
EXPECT_EQ(throttles.size(), 1);
|
|
EXPECT_EQ(throttles[0]["ip_address"], "0.0.0.1");
|
|
EXPECT_EQ(throttles[0].count("api_key"), 0);
|
|
EXPECT_EQ(throttles[0].count("throttling_from"), 1);
|
|
EXPECT_EQ(throttles[0].count("throttling_to"), 1);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestMultiSearchRateLimiting) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({".*"})},
|
|
{"priority", 3},
|
|
{"max_requests_1m", 3},
|
|
{"max_requests_1h", -1},
|
|
{"apply_limit_per_entity", true}
|
|
});
|
|
|
|
std::shared_ptr<http_req> req = std::make_shared<http_req>();
|
|
std::shared_ptr<http_res> res = std::make_shared<http_res>(nullptr);
|
|
nlohmann::json body;
|
|
body["searches"] = nlohmann::json::array();
|
|
nlohmann::json search;
|
|
search["collection"] = "players";
|
|
search["filter_by"] = "score: > 100";
|
|
body["searches"].push_back(search);
|
|
body["searches"].push_back(search);
|
|
body["searches"].push_back(search);
|
|
body["searches"].push_back(search);
|
|
body["searches"].push_back(search);
|
|
|
|
req->embedded_params_vec.push_back(nlohmann::json::object());
|
|
req->embedded_params_vec.push_back(nlohmann::json::object());
|
|
req->embedded_params_vec.push_back(nlohmann::json::object());
|
|
req->embedded_params_vec.push_back(nlohmann::json::object());
|
|
req->embedded_params_vec.push_back(nlohmann::json::object());
|
|
req->body = body.dump();
|
|
req->metadata = "4:test0.0.0.1";
|
|
|
|
EXPECT_FALSE(post_multi_search(req, res));
|
|
EXPECT_EQ(res->status_code, 429);
|
|
EXPECT_EQ(res->body, "{\"message\": \"Rate limit exceeded or blocked\"}");
|
|
|
|
body.erase("searches");
|
|
body["searches"] = nlohmann::json::array();
|
|
body["searches"].push_back(search);
|
|
body["searches"].push_back(search);
|
|
|
|
req->embedded_params_vec.pop_back();
|
|
req->embedded_params_vec.pop_back();
|
|
req->embedded_params_vec.pop_back();
|
|
|
|
req->body = body.dump();
|
|
req->metadata = "4:test0.0.0.2";
|
|
|
|
EXPECT_TRUE(post_multi_search(req, res));
|
|
EXPECT_EQ(res->status_code, 200);
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestDeleteBanByID) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({".*"})},
|
|
{"priority", 3},
|
|
{"max_requests_1m", 3},
|
|
{"max_requests_1h", -1},
|
|
{"apply_limit_per_entity", true},
|
|
{"auto_ban_1m_threshold", 1},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
manager->_set_base_timestamp(120);
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
const auto throttles = manager->get_throttled_entities_json();
|
|
EXPECT_EQ(throttles.size(), 1);
|
|
EXPECT_EQ(throttles[0]["ip_address"], "0.0.0.1");
|
|
EXPECT_EQ(throttles[0].count("api_key"), 0);
|
|
EXPECT_EQ(throttles[0].count("throttling_from"), 1);
|
|
EXPECT_EQ(throttles[0].count("throttling_to"), 1);
|
|
|
|
EXPECT_TRUE(manager->delete_ban_by_id(throttles[0]["id"]));
|
|
EXPECT_EQ(manager->get_throttled_entities_json().size(), 0);
|
|
}
|
|
|
|
|
|
TEST_F(RateLimitManagerTest, TestInvalidRules) {
|
|
auto res = manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1", "0.0.0.2"})},
|
|
{"api_keys", nlohmann::json::array({"test1", "test2"})},
|
|
{"priority", 3},
|
|
{"max_requests_1m", 3},
|
|
{"max_requests_1h", -1},
|
|
{"apply_limit_per_entity", true},
|
|
{"auto_ban_1m_threshold", 1},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
|
|
EXPECT_FALSE(res.ok());
|
|
EXPECT_EQ(400, res.code());
|
|
EXPECT_EQ("Many to many rule is not supported.", res.error());
|
|
|
|
res = manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"priority", 3},
|
|
{"max_requests_1m", 3},
|
|
{"max_requests_1h", -1},
|
|
{"apply_limit_per_entity", true},
|
|
{"auto_ban_1m_threshold", 1},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
|
|
EXPECT_FALSE(res.ok());
|
|
EXPECT_EQ(400, res.code());
|
|
EXPECT_EQ("Parameter `ip_addresses` or `api_keys` is required.", res.error());
|
|
|
|
|
|
res = manager->add_rule({
|
|
{"ip_addresses", nlohmann::json::array({".*"})},
|
|
{"priority", 3},
|
|
{"max_requests_1m", 3},
|
|
{"max_requests_1h", -1},
|
|
{"apply_limit_per_entity", true},
|
|
{"auto_ban_1m_threshold", 1},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
|
|
EXPECT_FALSE(res.ok());
|
|
EXPECT_EQ(400, res.code());
|
|
EXPECT_EQ("Parameter `action` is required.", res.error());
|
|
|
|
res = manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", ".*"},
|
|
{"priority", 3},
|
|
{"max_requests_1m", 3},
|
|
{"max_requests_1h", -1},
|
|
{"apply_limit_per_entity", true},
|
|
{"auto_ban_1m_threshold", 1},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
|
|
EXPECT_FALSE(res.ok());
|
|
EXPECT_EQ(400, res.code());
|
|
EXPECT_EQ("Parameter `ip_addresses` must be an array of strings.", res.error());
|
|
|
|
res = manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({".*"})},
|
|
{"priority", 3}
|
|
});
|
|
|
|
EXPECT_FALSE(res.ok());
|
|
EXPECT_EQ(400, res.code());
|
|
EXPECT_EQ("At least one of `max_requests_1m` or `max_requests_1h` is required.", res.error());
|
|
|
|
res = manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({".*"})},
|
|
{"priority", 3},
|
|
{"max_requests_1m", "aa"}
|
|
});
|
|
|
|
EXPECT_FALSE(res.ok());
|
|
EXPECT_EQ(400, res.code());
|
|
EXPECT_EQ("Parameter `max_requests_1m` must be an integer.", res.error());
|
|
|
|
res = manager->add_rule({
|
|
{"action", "invalid"},
|
|
{"ip_addresses", nlohmann::json::array({".*"})},
|
|
{"priority", 3},
|
|
{"max_requests_1m", 3},
|
|
{"max_requests_1h", 3},
|
|
{"apply_limit_per_entity", true},
|
|
{"auto_ban_1m_threshold", 1},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
|
|
EXPECT_FALSE(res.ok());
|
|
EXPECT_EQ(400, res.code());
|
|
EXPECT_EQ("Invalid action.", res.error());
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestOneToManyRule) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1", "0.0.0.2"})},
|
|
{"api_keys", nlohmann::json::array({"test"})},
|
|
{"priority", 3},
|
|
{"max_requests_1m", 2},
|
|
{"max_requests_1h", -1},
|
|
{"apply_limit_per_entity", true},
|
|
{"auto_ban_1m_threshold", 1},
|
|
{"auto_ban_1m_duration_hours", 1}
|
|
});
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.2"}));
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestDeleteThrottleByID) {
|
|
manager->add_rule({
|
|
{"action", "throttle"},
|
|
{"ip_addresses", nlohmann::json::array({".*"})},
|
|
{"priority", 3},
|
|
{"max_requests_1m", 3},
|
|
{"max_requests_1h", -1},
|
|
{"apply_limit_per_entity", true}
|
|
});
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
auto exceeds = manager->get_exceeded_entities_json();
|
|
EXPECT_EQ(1, exceeds.size());
|
|
auto id = exceeds[0]["id"];
|
|
auto res = manager->delete_throttle_by_id(id);
|
|
EXPECT_TRUE(res);
|
|
exceeds = manager->get_exceeded_entities_json();
|
|
EXPECT_EQ(0, exceeds.size());
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
}
|
|
|
|
TEST_F(RateLimitManagerTest, TestOneToManyFillTest) {
|
|
manager->add_rule({
|
|
{"action", "block"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})},
|
|
{"api_keys", nlohmann::json::array({"test", "test1", "test2"})},
|
|
{"priority", 3},
|
|
});
|
|
|
|
EXPECT_TRUE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
|
|
auto rules = manager->get_all_rules_json();
|
|
EXPECT_EQ(1, rules.size());
|
|
manager->delete_rule_by_id(rules[0]["id"]);
|
|
EXPECT_EQ(0, manager->get_all_rules_json().size());
|
|
|
|
manager->add_rule({
|
|
{"action", "block"},
|
|
{"ip_addresses", nlohmann::json::array({"0.0.0.1"})},
|
|
{"api_keys", nlohmann::json::array({"test", "test2"})},
|
|
{"priority", 3},
|
|
});
|
|
|
|
LOG(INFO) << manager->get_all_rules_json();
|
|
|
|
EXPECT_FALSE(manager->is_rate_limited({RateLimitedEntityType::api_key, "test1"}, {RateLimitedEntityType::ip, "0.0.0.1"}));
|
|
}
|