meta(auth): Enhance tests on authorization

Enhance auth tests in order to be able to add new action without changing tests
This commit is contained in:
ManyTheFish 2022-01-24 15:06:31 +01:00
parent f9f075bca2
commit 2b766a2f26

View File

@ -1,56 +1,61 @@
use crate::common::Server; use crate::common::Server;
use chrono::{Duration, Utc}; use chrono::{Duration, Utc};
use maplit::hashmap; use maplit::{hashmap, hashset};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use serde_json::{json, Value}; use serde_json::{json, Value};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
static AUTHORIZATIONS: Lazy<HashMap<(&'static str, &'static str), &'static str>> = static AUTHORIZATIONS: Lazy<HashMap<(&'static str, &'static str), HashSet<&'static str>>> =
Lazy::new(|| { Lazy::new(|| {
hashmap! { hashmap! {
("POST", "/indexes/products/search") => "search", ("POST", "/indexes/products/search") => hashset!{"search", "*"},
("GET", "/indexes/products/search") => "search", ("GET", "/indexes/products/search") => hashset!{"search", "*"},
("POST", "/indexes/products/documents") => "documents.add", ("POST", "/indexes/products/documents") => hashset!{"documents.add", "*"},
("GET", "/indexes/products/documents") => "documents.get", ("GET", "/indexes/products/documents") => hashset!{"documents.get", "*"},
("GET", "/indexes/products/documents/0") => "documents.get", ("GET", "/indexes/products/documents/0") => hashset!{"documents.get", "*"},
("DELETE", "/indexes/products/documents/0") => "documents.delete", ("DELETE", "/indexes/products/documents/0") => hashset!{"documents.delete", "*"},
("GET", "/tasks") => "tasks.get", ("GET", "/tasks") => hashset!{"tasks.get", "*"},
("GET", "/indexes/products/tasks") => "tasks.get", ("GET", "/indexes/products/tasks") => hashset!{"tasks.get", "*"},
("GET", "/indexes/products/tasks/0") => "tasks.get", ("GET", "/indexes/products/tasks/0") => hashset!{"tasks.get", "*"},
("PUT", "/indexes/products/") => "indexes.update", ("PUT", "/indexes/products/") => hashset!{"indexes.update", "*"},
("GET", "/indexes/products/") => "indexes.get", ("GET", "/indexes/products/") => hashset!{"indexes.get", "*"},
("DELETE", "/indexes/products/") => "indexes.delete", ("DELETE", "/indexes/products/") => hashset!{"indexes.delete", "*"},
("POST", "/indexes") => "indexes.create", ("POST", "/indexes") => hashset!{"indexes.create", "*"},
("GET", "/indexes") => "indexes.get", ("GET", "/indexes") => hashset!{"indexes.get", "*"},
("GET", "/indexes/products/settings") => "settings.get", ("GET", "/indexes/products/settings") => hashset!{"settings.get", "*"},
("GET", "/indexes/products/settings/displayed-attributes") => "settings.get", ("GET", "/indexes/products/settings/displayed-attributes") => hashset!{"settings.get", "*"},
("GET", "/indexes/products/settings/distinct-attribute") => "settings.get", ("GET", "/indexes/products/settings/distinct-attribute") => hashset!{"settings.get", "*"},
("GET", "/indexes/products/settings/filterable-attributes") => "settings.get", ("GET", "/indexes/products/settings/filterable-attributes") => hashset!{"settings.get", "*"},
("GET", "/indexes/products/settings/ranking-rules") => "settings.get", ("GET", "/indexes/products/settings/ranking-rules") => hashset!{"settings.get", "*"},
("GET", "/indexes/products/settings/searchable-attributes") => "settings.get", ("GET", "/indexes/products/settings/searchable-attributes") => hashset!{"settings.get", "*"},
("GET", "/indexes/products/settings/sortable-attributes") => "settings.get", ("GET", "/indexes/products/settings/sortable-attributes") => hashset!{"settings.get", "*"},
("GET", "/indexes/products/settings/stop-words") => "settings.get", ("GET", "/indexes/products/settings/stop-words") => hashset!{"settings.get", "*"},
("GET", "/indexes/products/settings/synonyms") => "settings.get", ("GET", "/indexes/products/settings/synonyms") => hashset!{"settings.get", "*"},
("DELETE", "/indexes/products/settings") => "settings.update", ("DELETE", "/indexes/products/settings") => hashset!{"settings.update", "*"},
("POST", "/indexes/products/settings") => "settings.update", ("POST", "/indexes/products/settings") => hashset!{"settings.update", "*"},
("POST", "/indexes/products/settings/displayed-attributes") => "settings.update", ("POST", "/indexes/products/settings/displayed-attributes") => hashset!{"settings.update", "*"},
("POST", "/indexes/products/settings/distinct-attribute") => "settings.update", ("POST", "/indexes/products/settings/distinct-attribute") => hashset!{"settings.update", "*"},
("POST", "/indexes/products/settings/filterable-attributes") => "settings.update", ("POST", "/indexes/products/settings/filterable-attributes") => hashset!{"settings.update", "*"},
("POST", "/indexes/products/settings/ranking-rules") => "settings.update", ("POST", "/indexes/products/settings/ranking-rules") => hashset!{"settings.update", "*"},
("POST", "/indexes/products/settings/searchable-attributes") => "settings.update", ("POST", "/indexes/products/settings/searchable-attributes") => hashset!{"settings.update", "*"},
("POST", "/indexes/products/settings/sortable-attributes") => "settings.update", ("POST", "/indexes/products/settings/sortable-attributes") => hashset!{"settings.update", "*"},
("POST", "/indexes/products/settings/stop-words") => "settings.update", ("POST", "/indexes/products/settings/stop-words") => hashset!{"settings.update", "*"},
("POST", "/indexes/products/settings/synonyms") => "settings.update", ("POST", "/indexes/products/settings/synonyms") => hashset!{"settings.update", "*"},
("GET", "/indexes/products/stats") => "stats.get", ("GET", "/indexes/products/stats") => hashset!{"stats.get", "*"},
("GET", "/stats") => "stats.get", ("GET", "/stats") => hashset!{"stats.get", "*"},
("POST", "/dumps") => "dumps.create", ("POST", "/dumps") => hashset!{"dumps.create", "*"},
("GET", "/dumps/0/status") => "dumps.get", ("GET", "/dumps/0/status") => hashset!{"dumps.get", "*"},
("GET", "/version") => "version", ("GET", "/version") => hashset!{"version", "*"},
} }
}); });
static ALL_ACTIONS: Lazy<HashSet<&'static str>> = static ALL_ACTIONS: Lazy<HashSet<&'static str>> = Lazy::new(|| {
Lazy::new(|| AUTHORIZATIONS.values().cloned().collect()); AUTHORIZATIONS
.values()
.cloned()
.reduce(|l, r| l.union(&r).cloned().collect())
.unwrap()
});
static INVALID_RESPONSE: Lazy<Value> = Lazy::new(|| { static INVALID_RESPONSE: Lazy<Value> = Lazy::new(|| {
json!({"message": "The provided API key is invalid.", json!({"message": "The provided API key is invalid.",
@ -147,7 +152,7 @@ async fn error_access_unauthorized_action() {
// Patch API key letting all rights but the needed one. // Patch API key letting all rights but the needed one.
let content = json!({ let content = json!({
"actions": ALL_ACTIONS.iter().cloned().filter(|a| a != action).collect::<Vec<_>>(), "actions": ALL_ACTIONS.difference(action).collect::<Vec<_>>(),
}); });
let (_, code) = server.patch_api_key(&key, content).await; let (_, code) = server.patch_api_key(&key, content).await;
assert_eq!(code, 200); assert_eq!(code, 200);
@ -179,7 +184,8 @@ async fn access_authorized_restricted_index() {
let key = response["key"].as_str().unwrap(); let key = response["key"].as_str().unwrap();
server.use_api_key(&key); server.use_api_key(&key);
for ((method, route), action) in AUTHORIZATIONS.iter() { for ((method, route), actions) in AUTHORIZATIONS.iter() {
for action in actions {
// Patch API key letting only the needed action. // Patch API key letting only the needed action.
let content = json!({ let content = json!({
"actions": [action], "actions": [action],
@ -194,21 +200,7 @@ async fn access_authorized_restricted_index() {
assert_ne!(response, INVALID_RESPONSE.clone()); assert_ne!(response, INVALID_RESPONSE.clone());
assert_ne!(code, 403); assert_ne!(code, 403);
}
// Patch API key using action all action.
let content = json!({
"actions": ["*"],
});
server.use_api_key("MASTER_KEY");
let (_, code) = server.patch_api_key(&key, content).await;
assert_eq!(code, 200);
server.use_api_key(&key);
let (response, code) = server.dummy_request(method, route).await;
assert_ne!(response, INVALID_RESPONSE.clone());
assert_ne!(code, 403);
} }
} }
@ -231,7 +223,8 @@ async fn access_authorized_no_index_restriction() {
let key = response["key"].as_str().unwrap(); let key = response["key"].as_str().unwrap();
server.use_api_key(&key); server.use_api_key(&key);
for ((method, route), action) in AUTHORIZATIONS.iter() { for ((method, route), actions) in AUTHORIZATIONS.iter() {
for action in actions {
server.use_api_key("MASTER_KEY"); server.use_api_key("MASTER_KEY");
// Patch API key letting only the needed action. // Patch API key letting only the needed action.
@ -246,21 +239,7 @@ async fn access_authorized_no_index_restriction() {
assert_ne!(response, INVALID_RESPONSE.clone()); assert_ne!(response, INVALID_RESPONSE.clone());
assert_ne!(code, 403); assert_ne!(code, 403);
}
// Patch API key using action all action.
let content = json!({
"actions": ["*"],
});
server.use_api_key("MASTER_KEY");
let (_, code) = server.patch_api_key(&key, content).await;
assert_eq!(code, 200);
server.use_api_key(&key);
let (response, code) = server.dummy_request(method, route).await;
assert_ne!(response, INVALID_RESPONSE.clone());
assert_ne!(code, 403);
} }
} }
@ -514,7 +493,8 @@ async fn error_creating_index_without_action() {
// create key with access on all indexes. // create key with access on all indexes.
let content = json!({ let content = json!({
"indexes": ["*"], "indexes": ["*"],
"actions": ALL_ACTIONS.iter().cloned().filter(|a| *a != "indexes.create").collect::<Vec<_>>(), // Give all action but the ones allowing to create an index.
"actions": ALL_ACTIONS.iter().cloned().filter(|a| !AUTHORIZATIONS.get(&("POST","/indexes")).unwrap().contains(a)).collect::<Vec<_>>(),
"expiresAt": "2050-11-13T00:00:00Z" "expiresAt": "2050-11-13T00:00:00Z"
}); });
let (response, code) = server.add_api_key(content).await; let (response, code) = server.add_api_key(content).await;