ufh/docs/acl.rs

75 lines
2 KiB
Rust

// NOTE: THIS MAY NOT BE ACCURATE!!!
// see the real `perms.rs` in server for now, this will be stabalized in the future!
/// pseudocode for validing events
/// the 2 main functions `is_event_visible` and `is_event_sendable`
type Relations = HashMap<ItemRef, (Event, RelInfo)>;
extern "pseudocode" fn is_event_visible(event: &Event, user: &ActorId) -> bool {
let relations = get_relations(event);
// event is visible if user has sent the event
if event.sender == user {
return true;
}
// or if event relates to any visible event
if relations.values().any(|rel| is_event_visible(rel, user)) {
return true;
}
// or if an acl allows a user to view an event
get_acl(&event).is_some_and(|acl| acl.can_view(user))
}
struct Context {
relations: Relations,
event: Event,
user: ActorId,
}
extern "pseudocode" fn is_event_sendable(event: &Event, user: &ActorId) -> bool {
let relations = get_relations(event);
let ctx = Context { relations, event, user };
relations
.values()
.all(|rel| is_relation_valid(rel, &ctx))
}
fn validate_relations(event: &Event, ctx: &Context) -> bool {
let relations = get_relations(event);
// root events always deny
if relations.is_empty() {
return false;
}
relations
.values()
.all(|rel| is_relation_valid(rel, ctx))
}
fn is_relation_valid(relation: &Event, ctx: &Context) -> bool {
if let Some(acl) = get_acl(&relation) {
// a relation is allowed if an acl set on it allows it
acl.can_send(ctx.user, ctx.event, ctx.relations)
} else {
// or if no acl is set, the user has sent that event
if relation.sender == ctx.user {
return true;
}
// or if no acl is set, if all of it's relations are also valid
validate_relations(relation, ctx)
}
}
fn get_relations(_event: &Event) -> Relations {
unimplemented!()
}
fn get_acl(_event: &Event) -> Option<Acl> {
unimplemented!()
}