From: Ian Jackson Date: Fri, 23 Oct 2020 23:27:17 +0000 (+0100) Subject: wip new account etc. X-Git-Tag: otter-0.2.0~602 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=867ad19bec6c00e4cc129c18876f9ccb0da296ad;p=otter.git wip new account etc. Signed-off-by: Ian Jackson --- diff --git a/src/accounts.rs b/src/accounts.rs index 2f5feb1e..998b0e72 100644 --- a/src/accounts.rs +++ b/src/accounts.rs @@ -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 for PermSet

- where I: IntoIterator + impl<'i, + P: Perm, + II: Borrow

, + I: IntoIterator + > + From for PermSet

{ 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(unpacked: PermSet

) -> HashSet

{ + fn unpack(packed: PermSet

) -> HashSet

{ 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 From> for LoadedAcl

{ fn from(acl: Acl

) -> LoadedAcl

{ - 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 From> for Acl

{ fn from(acl: LoadedAcl

) -> Acl

{ 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() } } } } diff --git a/src/spec.rs b/src/spec.rs index ac21b38e..63a389d1 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -64,11 +64,16 @@ pub struct TableSpec { pub acl : Acl } -pub type Acl = Vec>; +type RawAcl = Vec>; + +#[derive(Debug,Clone)] +#[derive(Deserialize)] +#[serde(try_from="RawAcl")] +pub struct Acl { pub ents: RawAcl } #[derive(Debug,Clone,Serialize,Deserialize)] pub struct AclEntry { - pub account_glob: String, + pub account_glob: String, // checked pub allow: HashSet, pub deny: HashSet, } @@ -229,6 +234,22 @@ pub mod implementation { use crate::imports::*; type Insn = crate::commands::MgmtGameInstruction; + impl Default for Acl

{ + fn default() -> Self { Acl { ents: default() } } + } + + impl Serialize for Acl

{ + fn serialize(&self, s: S) -> Result + { self.ents.serialize(s) } + } + + impl From> for Acl

{ + fn from(ents: RawAcl

) -> Self { + // xxx check + Acl { ents } + } + } + impl loaded_acl::Perm for TablePermission { type Auth = InstanceName; const TEST_EXISTENCE : Self = TablePermission::TestExistence;