use serde::{Deserialize,Serialize}; use std::collections::{HashMap,HashSet}; use crate::{User,Group,Role}; #[derive(Serialize,Deserialize,Clone,Debug,PartialEq)] pub enum StateValue { String(String), Binary(Vec), // A directory in a readable format to allow for something like `ls` // on clients Directory(HashMap), } impl StateValue { pub fn push_other(&mut self, other: &StateValue) -> Result<(),()> { match (self,other) { (StateValue::String(s),StateValue::String(o)) => s.push_str(o), (StateValue::Binary(b),StateValue::Binary(o)) => b.extend_from_slice(o), _ => return Err(()) } Ok(()) } } #[derive(Serialize,Deserialize,Debug,Clone)] pub enum StateType { Directory, String, Binary } #[derive(Serialize,Deserialize,Clone,Hash,Eq,PartialEq,Debug)] pub enum StatePermissionKey { User(User), Group(Group), Role(Group,Role), // Only the server can edit these. Potentially users with admin permissions // too. Server, // Give everyone a permission. Useful for making a file server readable Everyone, // Give permissions to the room operator/admin. This is kept track of // in the room state. Can operators remove other operators? Operator, //This is a string for now but could get compiled later into an actual regex //should be able to match on name and server UserRegex(String) } #[derive(Serialize,Deserialize,Clone,Debug,PartialEq,Eq)] pub enum StatePermissionValue { None, Read, ReadWrite, // Can only set value, does not allow appending Write, Owner } impl StatePermissionValue { // Binary relation // Maybe could have overloaded a comparison operator for this // // Owner // | // | // ReadWrite // / \ // Read Write pub fn allows(&self, other: &StatePermissionValue) -> bool { use StatePermissionValue::*; match (self,other) { (Read,Read) => true, (ReadWrite,Read) => true, (Write,Write) => true, (ReadWrite,Write) => true, // Owner allows everything (Owner,_) => true, _ => false } } } #[derive(Serialize,Deserialize,Clone,Debug,PartialEq,Eq)] pub struct StatePermission(pub StatePermissionKey,pub StatePermissionValue); #[derive(Serialize,Deserialize,Clone,Debug,PartialEq)] pub struct PermissionTable(pub HashMap); impl PermissionTable { pub fn get_allowed(&self, needed: &StatePermissionValue) -> HashSet { let mut set = HashSet::new(); for (key,perm) in self.0.iter() { if perm.allows(&needed) { set.insert(key.clone()); } } set } } #[derive(Serialize,Deserialize,Clone,Debug,Hash,PartialEq,Eq)] pub struct StatePath(pub Vec);