Add path globbing
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing

This commit is contained in:
Pierre HUBERT 2024-04-17 21:41:58 +02:00
parent 1d12d5c9be
commit f03b631b6c

View File

@ -39,10 +39,33 @@ impl TokenRights {
} }
pub fn contains(&self, verb: TokenVerb, path: &str) -> bool { pub fn contains(&self, verb: TokenVerb, path: &str) -> bool {
self.0.contains(&TokenRight { let path_split = path.split('/').collect::<Vec<_>>();
verb,
path: path.to_string(), 'root: for r in &self.0 {
}) if r.verb != verb {
continue 'root;
}
let mut last_idx = 0;
for (idx, part) in r.path.split('/').enumerate() {
if idx >= path_split.len() {
continue 'root;
}
if part != "*" && part != path_split[idx] {
continue 'root;
}
last_idx = idx;
}
// Check we visited the whole path
if last_idx + 1 == path_split.len() {
return true;
}
}
false
} }
} }
@ -233,3 +256,39 @@ pub async fn delete(id: TokenID) -> anyhow::Result<()> {
} }
Ok(()) Ok(())
} }
#[cfg(test)]
mod test {
use crate::api_tokens::{TokenRight, TokenRights, TokenVerb};
#[test]
fn test_rights_patch() {
let rights = TokenRights(vec![
TokenRight {
path: "/api/vm/*".to_string(),
verb: TokenVerb::GET,
},
TokenRight {
path: "/api/vm/a".to_string(),
verb: TokenVerb::PUT,
},
TokenRight {
path: "/api/vm/a/other".to_string(),
verb: TokenVerb::DELETE,
},
TokenRight {
path: "/api/net/create".to_string(),
verb: TokenVerb::POST,
},
]);
assert!(rights.contains(TokenVerb::GET, "/api/vm/ab"));
assert!(!rights.contains(TokenVerb::GET, "/api/vm/ab/c"));
assert!(rights.contains(TokenVerb::PUT, "/api/vm/a"));
assert!(!rights.contains(TokenVerb::PUT, "/api/vm/other"));
assert!(rights.contains(TokenVerb::POST, "/api/net/create"));
assert!(!rights.contains(TokenVerb::GET, "/api/net/create"));
assert!(!rights.contains(TokenVerb::POST, "/api/net/b"));
assert!(!rights.contains(TokenVerb::POST, "/api/net/create/b"));
}
}