solid_pod_rs/wac/
resolver.rs1use async_trait::async_trait;
8
9use crate::error::PodError;
10use crate::storage::Storage;
11use crate::wac::document::AclDocument;
12use crate::wac::parse_jsonld_acl;
13use crate::wac::parser::parse_turtle_acl;
14
15#[async_trait]
22pub trait AclResolver: Send + Sync {
23 async fn find_effective_acl(
25 &self,
26 resource_path: &str,
27 ) -> Result<Option<AclDocument>, PodError>;
28}
29
30pub struct StorageAclResolver<S: Storage> {
32 storage: std::sync::Arc<S>,
33}
34
35impl<S: Storage> StorageAclResolver<S> {
36 pub fn new(storage: std::sync::Arc<S>) -> Self {
38 Self { storage }
39 }
40}
41
42#[async_trait]
43impl<S: Storage> AclResolver for StorageAclResolver<S> {
44 async fn find_effective_acl(
46 &self,
47 resource_path: &str,
48 ) -> Result<Option<AclDocument>, PodError> {
49 let mut path = resource_path.to_string();
50 loop {
51 let acl_key = if path == "/" {
52 "/.acl".to_string()
53 } else {
54 format!("{}.acl", path.trim_end_matches('/'))
55 };
56 if let Ok((body, meta)) = self.storage.get(&acl_key).await {
57 match parse_jsonld_acl(&body) {
62 Ok(doc) => return Ok(Some(doc)),
63 Err(PodError::BadRequest(_)) => {
64 return Err(PodError::BadRequest(
65 "ACL document exceeds bounds".into(),
66 ));
67 }
68 Err(PodError::PayloadTooLarge(msg)) => {
69 return Err(PodError::PayloadTooLarge(msg));
70 }
71 Err(_) => {}
72 }
73 let ct = meta.content_type.to_ascii_lowercase();
74 let looks_turtle = ct.starts_with("text/turtle")
75 || ct.starts_with("application/turtle")
76 || ct.starts_with("application/x-turtle");
77 let text = std::str::from_utf8(&body).unwrap_or("");
78 if looks_turtle || text.contains("@prefix") || text.contains("acl:Authorization") {
79 if let Ok(doc) = parse_turtle_acl(text) {
80 return Ok(Some(doc));
81 }
82 }
83 }
84 if path == "/" || path.is_empty() {
85 break;
86 }
87 let trimmed = path.trim_end_matches('/');
88 path = match trimmed.rfind('/') {
89 Some(0) => "/".to_string(),
90 Some(pos) => trimmed[..pos].to_string(),
91 None => "/".to_string(),
92 };
93 }
94 Ok(None)
95 }
96}