Add path globbing
This commit is contained in:
		@@ -39,10 +39,33 @@ impl TokenRights {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn contains(&self, verb: TokenVerb, path: &str) -> bool {
 | 
			
		||||
        self.0.contains(&TokenRight {
 | 
			
		||||
            verb,
 | 
			
		||||
            path: path.to_string(),
 | 
			
		||||
        })
 | 
			
		||||
        let path_split = path.split('/').collect::<Vec<_>>();
 | 
			
		||||
 | 
			
		||||
        '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(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[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"));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user