chiark / gitweb /
wip new account etc.
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 23 Oct 2020 23:27:17 +0000 (00:27 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 23 Oct 2020 23:27:17 +0000 (00:27 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/accounts.rs
src/spec.rs

index 2f5feb1e4950268e5920bd6d7e763481a0bba5eb..998b0e72a6ab706b4a50805044fc2311bfd83025 100644 (file)
@@ -268,36 +268,56 @@ pub mod loaded_acl {
         if allow != 0 { needed &= !(allow | test_existence) }
         if needed == 0 { return Authorisation::authorise_any() }
       }
-      throw!(if needed & test_existence != 0 {
+      Err(if needed & test_existence != 0 {
         P::NOT_FOUND
       } else {
         MgmtError::AuthorisationError
-      })
+      })?
     }
   }
 
-  impl<'i, P:Perm, I> From<I> for PermSet<P>
-  where I: IntoIterator<Item=&'i P>
+  impl<'i,
+       P: Perm,
+       II: Borrow<P>,
+       I: IntoIterator<Item=II>
+       >
+    From<I> for PermSet<P>
   {
     fn from(i: I) -> Self {
-      i.into_iter().fold(0, |b, i| b | i.to_u64().unwrap())
+      PermSet(
+        i.into_iter().fold(0, |b, i| b | i.borrow().to_u64().unwrap()),
+        PhantomData,
+      )
     }
   }
 
-  fn unpack<P:Perm>(unpacked: PermSet<P>) -> HashSet<P> {
+  fn unpack<P:Perm>(packed: PermSet<P>) -> HashSet<P> {
     let mut s = HashSet::new();
     for n in 0.. {
       let v = match FromPrimitive::from_u64(n) { Some(v) => v, None => break };
-      if unpacked & n != 0 { s.insert(v) }
+      if packed.0 & n != 0 { s.insert(v); }
     }
     s
   }
 
   impl<P:Perm> From<Acl<P>> for LoadedAcl<P> {
     fn from(acl: Acl<P>) -> LoadedAcl<P> {
-      let ents = acl.into_iter().map(
+      let ents = acl.ents.into_iter().filter_map(
         |AclEntry { account_glob, allow, deny }|
-        LoadedAclEntry { account_glob, allow: allow.into(), deny: deny.into() }
+        {
+          let pat = glob::Pattern::new(&account_glob)
+            .ok().or_else(||{
+              eprintln!("discarding malformed acl glob pattern {:?}",
+                        account_glob);
+              None
+            })?;
+          Some(LoadedAclEntry {
+            pat,
+            allow: allow.into(),
+            deny: deny.into(),
+            ptype: PhantomData,
+          })
+        }
       ).collect();
       LoadedAcl(ents)
     }
@@ -306,10 +326,14 @@ pub mod loaded_acl {
   impl<P:Perm> From<LoadedAcl<P>> for Acl<P> {
     fn from(acl: LoadedAcl<P>) -> Acl<P> {
       let LoadedAcl(ents) = acl;
-      ents.into_iter().map(
-        |LoadedAclEntry { account_glob, allow, deny }|
-        AclEntry { account_glob, allow: unpack(allow), deny: unpack(deny) }
-      ).collect()
+      Acl { ents: ents.into_iter().map(
+        |LoadedAclEntry { pat, allow, deny, .. }|
+        AclEntry {
+          account_glob: pat.to_string(),
+          allow: unpack(allow),
+          deny: unpack(deny),
+        }
+      ).collect() }
     }
   }
 }
index ac21b38e9f4ef019d943715d27c3c1c14bec3865..63a389d1632292a62a92b07cf2e0a046ec4a2a41 100644 (file)
@@ -64,11 +64,16 @@ pub struct TableSpec {
   pub acl : Acl<TablePermission>
 }
 
-pub type Acl<Perm> = Vec<AclEntry<Perm>>;
+type RawAcl<Perm> = Vec<AclEntry<Perm>>;
+
+#[derive(Debug,Clone)]
+#[derive(Deserialize)]
+#[serde(try_from="RawAcl<Perm>")]
+pub struct Acl<Perm: Eq + Hash> { pub ents: RawAcl<Perm> }
 
 #[derive(Debug,Clone,Serialize,Deserialize)]
 pub struct AclEntry<Perm: Eq + Hash> {
-  pub account_glob: String,
+  pub account_glob: String, // checked
   pub allow: HashSet<Perm>,
   pub deny: HashSet<Perm>,
 }
@@ -229,6 +234,22 @@ pub mod implementation {
   use crate::imports::*;
   type Insn = crate::commands::MgmtGameInstruction;
 
+  impl<P: Eq + Hash> Default for Acl<P> {
+    fn default() -> Self { Acl { ents: default() } }
+  }
+
+  impl<P: Eq + Hash + Serialize> Serialize for Acl<P> {
+    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error>
+    { self.ents.serialize(s) }
+  }
+
+  impl<P: Eq + Hash> From<RawAcl<P>> for Acl<P> {
+    fn from(ents: RawAcl<P>) -> Self {
+      // xxx check
+      Acl { ents }
+    }
+  }
+
   impl loaded_acl::Perm for TablePermission {
     type Auth = InstanceName;
     const TEST_EXISTENCE : Self = TablePermission::TestExistence;