Files
fedichat-lib/src/state.rs
T
uelen c2b7575ff4 Lots of changes
Notable ones are that now every message has a field for the target
server, and that messages have an "optional" ID  in that they dont have it
from client -> server and they do have it from server -> client.
2026-05-24 22:56:15 -07:00

102 lines
2.9 KiB
Rust

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<u8>),
// A directory in a readable format to allow for something like `ls`
// on clients
Directory(HashMap<String,PermissionTable>),
}
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<StatePermissionKey,StatePermissionValue>);
impl PermissionTable {
pub fn get_allowed(&self, needed: &StatePermissionValue) -> HashSet<StatePermissionKey> {
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<String>);