mirror of
https://github.com/typesense/typesense.git
synced 2025-05-19 13:12:22 +08:00
When present, use preset config for collection auth.
This commit is contained in:
parent
27d1558954
commit
5401e378e9
@ -167,6 +167,8 @@ bool AuthManager::authenticate(const std::string& action,
|
||||
}
|
||||
|
||||
num_keys_matched++;
|
||||
|
||||
// lengths of embedded_params_vec and collection_keys are guaranteed by upstream to be the same
|
||||
embedded_params_vec[i] = embedded_params;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,13 @@ bool handle_authentication(std::map<std::string, std::string>& req_params,
|
||||
return true;
|
||||
}
|
||||
|
||||
if(collections.size() != embedded_params_vec.size()) {
|
||||
LOG(ERROR) << "Impossible error: size of collections and embedded_params_vec don't match, "
|
||||
<< "collections.size: " << collections.size()
|
||||
<< ", embedded_params_vec.size: " << embedded_params_vec.size();
|
||||
return false;
|
||||
}
|
||||
|
||||
return collectionManager.auth_key_matches(req_auth_key, rpath.action, collections, req_params, embedded_params_vec);
|
||||
}
|
||||
|
||||
@ -56,22 +63,28 @@ void defer_processing(const std::shared_ptr<http_req>& req, const std::shared_pt
|
||||
server->get_message_dispatcher()->send_message(HttpServer::DEFER_PROCESSING_MESSAGE, defer);
|
||||
}
|
||||
|
||||
void get_collections_for_auth(std::map<std::string, std::string>& req_params, const string& body,
|
||||
const route_path& rpath, const string& req_auth_key,
|
||||
std::vector<collection_key_t>& collections,
|
||||
std::vector<nlohmann::json>& embedded_params_vec) {
|
||||
// we cannot return errors here because that will end up as auth failure and won't convey
|
||||
// bad schema errors
|
||||
void get_collections_for_auth(std::map<std::string, std::string>& req_params,
|
||||
const string& body,
|
||||
const route_path& rpath, const string& req_auth_key,
|
||||
std::vector<collection_key_t>& collections,
|
||||
std::vector<nlohmann::json>& embedded_params_vec) {
|
||||
|
||||
if(rpath.handler == post_multi_search) {
|
||||
nlohmann::json obj = nlohmann::json::parse(body, nullptr, false);
|
||||
nlohmann::json req_obj;
|
||||
|
||||
if(obj.is_discarded()) {
|
||||
LOG(ERROR) << "Multi search request body is malformed.";
|
||||
collections.emplace_back("", req_auth_key);
|
||||
embedded_params_vec.emplace_back(nlohmann::json::object());
|
||||
// If a `preset` parameter is present, we've to only load a pre-existing search configuration
|
||||
// and ignore the actual request body.
|
||||
auto preset_it = req_params.find("preset");
|
||||
if(preset_it != req_params.end()) {
|
||||
CollectionManager::get_instance().get_preset(preset_it->second, req_obj);
|
||||
} else {
|
||||
req_obj = nlohmann::json::parse(body, nullptr, false);
|
||||
}
|
||||
|
||||
else if(obj.count("searches") != 0 && obj["searches"].is_array()) {
|
||||
for(auto& el : obj["searches"]) {
|
||||
if(!req_obj.is_discarded() && req_obj.count("searches") != 0 && req_obj["searches"].is_array()) {
|
||||
for(auto& el : req_obj["searches"]) {
|
||||
if(el.is_object()) {
|
||||
std::string coll_name;
|
||||
if(el.count("collection") != 0 && el["collection"].is_string()) {
|
||||
@ -87,8 +100,13 @@ void get_collections_for_auth(std::map<std::string, std::string>& req_params, co
|
||||
|
||||
collections.emplace_back(coll_name, access_key);
|
||||
embedded_params_vec.emplace_back(nlohmann::json::object());
|
||||
} else {
|
||||
collections.emplace_back("", req_auth_key);
|
||||
embedded_params_vec.emplace_back(nlohmann::json::object());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG(ERROR) << "Multi search request body is malformed, body: " << body;
|
||||
}
|
||||
} else {
|
||||
if(rpath.handler == post_create_collection) {
|
||||
@ -96,12 +114,12 @@ void get_collections_for_auth(std::map<std::string, std::string>& req_params, co
|
||||
|
||||
if(obj.is_discarded()) {
|
||||
LOG(ERROR) << "Create collection request body is malformed.";
|
||||
collections.emplace_back("", req_auth_key);
|
||||
} else if(obj.count("name") != 0 && obj["name"].is_string()) {
|
||||
collections.emplace_back(obj["name"].get<std::string>(), req_auth_key);
|
||||
}
|
||||
|
||||
embedded_params_vec.emplace_back(nlohmann::json::object());
|
||||
else if(obj.count("name") != 0 && obj["name"].is_string()) {
|
||||
collections.emplace_back(obj["name"].get<std::string>(), req_auth_key);
|
||||
embedded_params_vec.emplace_back(nlohmann::json::object());
|
||||
}
|
||||
|
||||
} else if(req_params.count("collection") != 0) {
|
||||
collections.emplace_back(req_params.at("collection"), req_auth_key);
|
||||
@ -405,13 +423,11 @@ bool post_multi_search(const std::shared_ptr<http_req>& req, const std::shared_p
|
||||
}
|
||||
|
||||
nlohmann::json req_json;
|
||||
const auto preset_it = req->params.find("preset");
|
||||
|
||||
const auto preset_it = req->params.find("preset");
|
||||
if(preset_it != req->params.end()) {
|
||||
CollectionManager::get_instance().get_preset(preset_it->second, req_json);
|
||||
}
|
||||
|
||||
if(req_json.empty()) {
|
||||
} else {
|
||||
try {
|
||||
req_json = nlohmann::json::parse(req->body);
|
||||
} catch(const std::exception& e) {
|
||||
@ -460,6 +476,14 @@ bool post_multi_search(const std::shared_ptr<http_req>& req, const std::shared_p
|
||||
|
||||
nlohmann::json& searches = req_json["searches"];
|
||||
|
||||
if(searches.size() != req->embedded_params_vec.size()) {
|
||||
LOG(ERROR) << "Embedded params parsing error: length does not match multi search array, searches.size(): "
|
||||
<< searches.size() << ", embedded_params_vec.size: " << req->embedded_params_vec.size()
|
||||
<< ", req_body: " << req->body;
|
||||
res->set_500("Embedded params parsing error.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < searches.size(); i++) {
|
||||
auto& search_params = searches[i];
|
||||
|
||||
|
@ -452,3 +452,48 @@ TEST_F(CoreAPIUtilsTest, ExtractCollectionsFromRequestBodyExtended) {
|
||||
ASSERT_EQ("foo", collections[0].collection);
|
||||
ASSERT_EQ(1, embedded_params_vec.size());
|
||||
}
|
||||
|
||||
TEST_F(CoreAPIUtilsTest, MultiSearchWithPresetShouldUsePresetForAuth) {
|
||||
nlohmann::json preset_value = R"(
|
||||
{"searches":[
|
||||
{"collection":"foo","q":"apple", "query_by": "title"},
|
||||
{"collection":"bar","q":"apple", "query_by": "title"}
|
||||
]}
|
||||
)"_json;
|
||||
|
||||
Option<bool> success_op = collectionManager.upsert_preset("apple", preset_value);
|
||||
|
||||
route_path rpath_multi_search = route_path("POST", {"multi_search"}, post_multi_search, false, false);
|
||||
std::map<std::string, std::string> req_params;
|
||||
|
||||
std::vector<collection_key_t> collections;
|
||||
std::vector<nlohmann::json> embedded_params_vec;
|
||||
|
||||
std::string other_body = R"(
|
||||
{"searches":[
|
||||
{"collection":"foo1","q":"apple", "query_by": "title"},
|
||||
{"collection":"bar1","q":"apple", "query_by": "title"}
|
||||
]}
|
||||
)";
|
||||
|
||||
// without preset parameter, use collections from request body
|
||||
|
||||
get_collections_for_auth(req_params, other_body, rpath_multi_search, "", collections, embedded_params_vec);
|
||||
|
||||
ASSERT_EQ(2, collections.size());
|
||||
ASSERT_EQ("foo1", collections[0].collection);
|
||||
ASSERT_EQ("bar1", collections[1].collection);
|
||||
ASSERT_EQ(2, embedded_params_vec.size());
|
||||
|
||||
// with preset parameter, use collections from preset configuration
|
||||
collections.clear();
|
||||
embedded_params_vec.clear();
|
||||
|
||||
req_params["preset"] = "apple";
|
||||
get_collections_for_auth(req_params, other_body, rpath_multi_search, "", collections, embedded_params_vec);
|
||||
|
||||
ASSERT_EQ(2, collections.size());
|
||||
ASSERT_EQ("foo", collections[0].collection);
|
||||
ASSERT_EQ("bar", collections[1].collection);
|
||||
ASSERT_EQ(2, embedded_params_vec.size());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user