forked from jmug/stoatchat
feat(core/permissions): initial commit
This commit is contained in:
137
crates/core/permissions/src/models/channel.rs
Normal file
137
crates/core/permissions/src/models/channel.rs
Normal file
@@ -0,0 +1,137 @@
|
||||
use once_cell::sync::Lazy;
|
||||
use std::ops::Add;
|
||||
|
||||
/// Abstract channel type
|
||||
pub enum ChannelType {
|
||||
SavedMessages,
|
||||
DirectMessage,
|
||||
Group,
|
||||
ServerChannel,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
/// Permission value on Revolt
|
||||
///
|
||||
/// This should be restricted to the lower 52 bits to prevent any
|
||||
/// potential issues with Javascript. Also leave empty spaces for
|
||||
/// future permission flags to be added.
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "try-from-primitive", derive(num_enum::TryFromPrimitive))]
|
||||
#[repr(u64)]
|
||||
pub enum ChannelPermission {
|
||||
// * Generic permissions
|
||||
/// Manage the channel or channels on the server
|
||||
ManageChannel = 1 << 0,
|
||||
/// Manage the server
|
||||
ManageServer = 1 << 1,
|
||||
/// Manage permissions on servers or channels
|
||||
ManagePermissions = 1 << 2,
|
||||
/// Manage roles on server
|
||||
ManageRole = 1 << 3,
|
||||
/// Manage server customisation (includes emoji)
|
||||
ManageCustomisation = 1 << 4,
|
||||
|
||||
// % 1 bit reserved
|
||||
|
||||
// * Member permissions
|
||||
/// Kick other members below their ranking
|
||||
KickMembers = 1 << 6,
|
||||
/// Ban other members below their ranking
|
||||
BanMembers = 1 << 7,
|
||||
/// Timeout other members below their ranking
|
||||
TimeoutMembers = 1 << 8,
|
||||
/// Assign roles to members below their ranking
|
||||
AssignRoles = 1 << 9,
|
||||
/// Change own nickname
|
||||
ChangeNickname = 1 << 10,
|
||||
/// Change or remove other's nicknames below their ranking
|
||||
ManageNicknames = 1 << 11,
|
||||
/// Change own avatar
|
||||
ChangeAvatar = 1 << 12,
|
||||
/// Remove other's avatars below their ranking
|
||||
RemoveAvatars = 1 << 13,
|
||||
|
||||
// % 7 bits reserved
|
||||
|
||||
// * Channel permissions
|
||||
/// View a channel
|
||||
ViewChannel = 1 << 20,
|
||||
/// Read a channel's past message history
|
||||
ReadMessageHistory = 1 << 21,
|
||||
/// Send a message in a channel
|
||||
SendMessage = 1 << 22,
|
||||
/// Delete messages in a channel
|
||||
ManageMessages = 1 << 23,
|
||||
/// Manage webhook entries on a channel
|
||||
ManageWebhooks = 1 << 24,
|
||||
/// Create invites to this channel
|
||||
InviteOthers = 1 << 25,
|
||||
/// Send embedded content in this channel
|
||||
SendEmbeds = 1 << 26,
|
||||
/// Send attachments and media in this channel
|
||||
UploadFiles = 1 << 27,
|
||||
/// Masquerade messages using custom nickname and avatar
|
||||
Masquerade = 1 << 28,
|
||||
/// React to messages with emojis
|
||||
React = 1 << 29,
|
||||
|
||||
// * Voice permissions
|
||||
/// Connect to a voice channel
|
||||
Connect = 1 << 30,
|
||||
/// Speak in a voice call
|
||||
Speak = 1 << 31,
|
||||
/// Share video in a voice call
|
||||
Video = 1 << 32,
|
||||
/// Mute other members with lower ranking in a voice call
|
||||
MuteMembers = 1 << 33,
|
||||
/// Deafen other members with lower ranking in a voice call
|
||||
DeafenMembers = 1 << 34,
|
||||
/// Move members between voice channels
|
||||
MoveMembers = 1 << 35,
|
||||
|
||||
// * Misc. permissions
|
||||
// % Bits 36 to 52: free area
|
||||
// % Bits 53 to 64: do not use
|
||||
|
||||
// * Grant all permissions
|
||||
/// Safely grant all permissions
|
||||
GrantAllSafe = 0x000F_FFFF_FFFF_FFFF,
|
||||
|
||||
/// Grant all permissions
|
||||
GrantAll = u64::MAX,
|
||||
}
|
||||
|
||||
impl_op_ex!(+ |a: &ChannelPermission, b: &ChannelPermission| -> u64 { *a as u64 | *b as u64 });
|
||||
impl_op_ex_commutative!(+ |a: &u64, b: &ChannelPermission| -> u64 { *a | *b as u64 });
|
||||
|
||||
pub static ALLOW_IN_TIMEOUT: Lazy<u64> =
|
||||
Lazy::new(|| ChannelPermission::ViewChannel + ChannelPermission::ReadMessageHistory);
|
||||
|
||||
pub static DEFAULT_PERMISSION_VIEW_ONLY: Lazy<u64> =
|
||||
Lazy::new(|| ChannelPermission::ViewChannel + ChannelPermission::ReadMessageHistory);
|
||||
|
||||
pub static DEFAULT_PERMISSION: Lazy<u64> = Lazy::new(|| {
|
||||
DEFAULT_PERMISSION_VIEW_ONLY.add(
|
||||
ChannelPermission::SendMessage
|
||||
+ ChannelPermission::InviteOthers
|
||||
+ ChannelPermission::SendEmbeds
|
||||
+ ChannelPermission::UploadFiles
|
||||
+ ChannelPermission::Connect
|
||||
+ ChannelPermission::Speak,
|
||||
)
|
||||
});
|
||||
|
||||
pub static DEFAULT_PERMISSION_SAVED_MESSAGES: u64 = ChannelPermission::GrantAllSafe as u64;
|
||||
|
||||
pub static DEFAULT_PERMISSION_DIRECT_MESSAGE: Lazy<u64> = Lazy::new(|| {
|
||||
DEFAULT_PERMISSION.add(ChannelPermission::ManageChannel + ChannelPermission::React)
|
||||
});
|
||||
|
||||
pub static DEFAULT_PERMISSION_SERVER: Lazy<u64> = Lazy::new(|| {
|
||||
DEFAULT_PERMISSION.add(
|
||||
ChannelPermission::React
|
||||
+ ChannelPermission::ChangeNickname
|
||||
+ ChannelPermission::ChangeAvatar,
|
||||
)
|
||||
});
|
||||
58
crates/core/permissions/src/models/mod.rs
Normal file
58
crates/core/permissions/src/models/mod.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
mod channel;
|
||||
mod server;
|
||||
mod user;
|
||||
|
||||
pub use channel::*;
|
||||
pub use server::*;
|
||||
pub use user::*;
|
||||
|
||||
/// Holds a permission value to manipulate.
|
||||
#[derive(Debug)]
|
||||
pub struct PermissionValue(u64);
|
||||
|
||||
impl PermissionValue {
|
||||
/// Apply a given override to this value
|
||||
pub fn apply(&mut self, v: Override) {
|
||||
self.allow(v.allow);
|
||||
self.revoke(v.deny);
|
||||
}
|
||||
|
||||
/// Allow given permissions
|
||||
pub fn allow(&mut self, v: u64) {
|
||||
self.0 |= v;
|
||||
}
|
||||
|
||||
/// Revoke given permissions
|
||||
pub fn revoke(&mut self, v: u64) {
|
||||
self.0 &= !v;
|
||||
}
|
||||
|
||||
/// Restrict to given permissions
|
||||
pub fn restrict(&mut self, v: u64) {
|
||||
self.0 &= v;
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for PermissionValue {
|
||||
fn from(v: i64) -> Self {
|
||||
Self(v as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for PermissionValue {
|
||||
fn from(v: u64) -> Self {
|
||||
Self(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PermissionValue> for u64 {
|
||||
fn from(v: PermissionValue) -> Self {
|
||||
v.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ChannelPermission> for PermissionValue {
|
||||
fn from(v: ChannelPermission) -> Self {
|
||||
(v as u64).into()
|
||||
}
|
||||
}
|
||||
56
crates/core/permissions/src/models/server.rs
Normal file
56
crates/core/permissions/src/models/server.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
/// Representation of a single permission override
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Override {
|
||||
/// Allow bit flags
|
||||
pub allow: u64,
|
||||
/// Disallow bit flags
|
||||
pub deny: u64,
|
||||
}
|
||||
|
||||
/// Representation of a single permission override
|
||||
/// as it appears on models and in the database
|
||||
#[derive(/*JsonSchema, */ Debug, Clone, Copy, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct OverrideField {
|
||||
/// Allow bit flags
|
||||
a: i64,
|
||||
/// Disallow bit flags
|
||||
d: i64,
|
||||
}
|
||||
|
||||
impl Override {
|
||||
/// Into allows
|
||||
pub fn allows(&self) -> u64 {
|
||||
self.allow
|
||||
}
|
||||
|
||||
/// Into denies
|
||||
pub fn denies(&self) -> u64 {
|
||||
self.deny
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Override> for OverrideField {
|
||||
fn from(v: Override) -> Self {
|
||||
Self {
|
||||
a: v.allow as i64,
|
||||
d: v.deny as i64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<OverrideField> for Override {
|
||||
fn from(v: OverrideField) -> Self {
|
||||
Self {
|
||||
allow: v.a as u64,
|
||||
deny: v.d as u64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*impl From<OverrideField> for Bson {
|
||||
fn from(v: OverrideField) -> Self {
|
||||
Self::Document(bson::to_document(&v).unwrap())
|
||||
}
|
||||
}*/
|
||||
25
crates/core/permissions/src/models/user.rs
Normal file
25
crates/core/permissions/src/models/user.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
/// User's relationship with another user (or themselves)
|
||||
pub enum RelationshipStatus {
|
||||
None,
|
||||
User,
|
||||
Friend,
|
||||
Outgoing,
|
||||
Incoming,
|
||||
Blocked,
|
||||
BlockedOther,
|
||||
}
|
||||
|
||||
/// User permission definitions
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "try-from-primitive", derive(num_enum::TryFromPrimitive))]
|
||||
#[repr(u32)]
|
||||
pub enum UserPermission {
|
||||
Access = 1 << 0,
|
||||
ViewProfile = 1 << 1,
|
||||
SendMessage = 1 << 2,
|
||||
Invite = 1 << 3,
|
||||
}
|
||||
|
||||
impl_op_ex!(+ |a: &UserPermission, b: &UserPermission| -> u32 { *a as u32 | *b as u32 });
|
||||
impl_op_ex_commutative!(+ |a: &u32, b: &UserPermission| -> u32 { *a | *b as u32 });
|
||||
Reference in New Issue
Block a user