use std::collections::HashSet; use uuid::Uuid; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum TokenScope { RepoRead, RepoWrite, RepoAdmin, } impl TokenScope { pub fn implies(self, other: TokenScope) -> bool { matches!( (self, other), (TokenScope::RepoAdmin, _) | (TokenScope::RepoWrite, TokenScope::RepoWrite) | (TokenScope::RepoWrite, TokenScope::RepoRead) | (TokenScope::RepoRead, TokenScope::RepoRead) ) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RepoAccess { None, Read, Write, Admin, } impl RepoAccess { pub fn at_least(self, other: RepoAccess) -> bool { match (self, other) { (RepoAccess::Admin, _) => true, (RepoAccess::Write, RepoAccess::Read | RepoAccess::Write) => true, (RepoAccess::Read, RepoAccess::Read) => true, _ => false, } } } #[derive(Debug, Clone)] pub struct ActorContext { pub user_id: Option, pub scopes: HashSet, pub is_site_admin: bool, pub channel_role: Option, pub space_role: Option, } impl Default for ActorContext { fn default() -> Self { Self::anonymous() } } impl ActorContext { pub fn anonymous() -> Self { Self { user_id: None, scopes: HashSet::new(), is_site_admin: false, channel_role: None, space_role: None, } } pub fn for_user(user_id: Uuid) -> Self { let mut scopes = HashSet::new(); scopes.insert(TokenScope::RepoRead); Self { user_id: Some(user_id), scopes, is_site_admin: false, channel_role: None, space_role: None, } } pub fn has_scope(&self, scope: TokenScope) -> bool { self.is_site_admin || self.scopes.iter().any(|s| s.implies(scope)) } pub fn is_authenticated(&self) -> bool { self.user_id.is_some() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ChannelRole { Viewer, Member, Moderator, Owner, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum SpaceRole { Member, Admin, Owner, }