Files
fluxer/fluxer_admin/src/acl.rs
T

300 lines
11 KiB
Rust

// SPDX-License-Identifier: AGPL-3.0-or-later
pub const WILDCARD: &str = "*";
pub const ACL_SET_USER: &str = "acl:set:user";
pub const ADMIN_API_KEY_MANAGE: &str = "admin_api_key:manage";
pub const APPLICATION_LOOKUP: &str = "application:lookup";
pub const APPLICATION_LIST_BY_OWNER: &str = "application:list:by_owner";
pub const APPLICATION_TRANSFER_OWNERSHIP: &str = "application:transfer_ownership";
pub const ARCHIVE_TRIGGER_GUILD: &str = "archive:trigger:guild";
pub const ARCHIVE_TRIGGER_USER: &str = "archive:trigger:user";
pub const ARCHIVE_VIEW_ALL: &str = "archive:view_all";
pub const ASSET_PURGE: &str = "asset:purge";
pub const AUDIT_LOG_VIEW: &str = "audit_log:view";
pub const AUTHENTICATE: &str = "admin:authenticate";
pub const JOBS_VIEW: &str = "jobs:view";
pub const JOBS_CANCEL: &str = "jobs:cancel";
pub const BAN_EMAIL_ADD: &str = "ban:email:add";
pub const BAN_EMAIL_CHECK: &str = "ban:email:check";
pub const BAN_EMAIL_REMOVE: &str = "ban:email:remove";
pub const BAN_PHRASE_ADD: &str = "ban:phrase:add";
pub const BAN_PHRASE_CHECK: &str = "ban:phrase:check";
pub const BAN_PHRASE_REMOVE: &str = "ban:phrase:remove";
pub const BAN_IP_ADD: &str = "ban:ip:add";
pub const BAN_IP_CHECK: &str = "ban:ip:check";
pub const BAN_IP_REMOVE: &str = "ban:ip:remove";
pub const BAN_URL_ADD: &str = "ban:url:add";
pub const BAN_URL_CHECK: &str = "ban:url:check";
pub const BAN_URL_REMOVE: &str = "ban:url:remove";
pub const BAN_URL_DOMAIN_ADD: &str = "ban:url_domain:add";
pub const BAN_URL_DOMAIN_CHECK: &str = "ban:url_domain:check";
pub const BAN_URL_DOMAIN_REMOVE: &str = "ban:url_domain:remove";
pub const BAN_FILE_SHA_ADD: &str = "ban:file_sha:add";
pub const BAN_FILE_SHA_CHECK: &str = "ban:file_sha:check";
pub const BAN_FILE_SHA_REMOVE: &str = "ban:file_sha:remove";
pub const BAN_AVATAR_HASH_ADD: &str = "ban:avatar_hash:add";
pub const BAN_AVATAR_HASH_CHECK: &str = "ban:avatar_hash:check";
pub const BAN_AVATAR_HASH_REMOVE: &str = "ban:avatar_hash:remove";
pub const BAN_PROFILE_SUBSTRING_ADD: &str = "ban:profile_substring:add";
pub const BAN_PROFILE_SUBSTRING_CHECK: &str = "ban:profile_substring:check";
pub const BAN_PROFILE_SUBSTRING_REMOVE: &str = "ban:profile_substring:remove";
pub const BULK_ADD_GUILD_MEMBERS: &str = "bulk:add:guild_members";
pub const BULK_DELETE_USERS: &str = "bulk:delete:users";
pub const BULK_DELETE_USER_MESSAGES: &str = "bulk:delete:user_messages";
pub const BULK_UPDATE_GUILD_FEATURES: &str = "bulk:update:guild_features";
pub const BULK_UPDATE_USER_FLAGS: &str = "bulk:update:user_flags";
pub const DISCOVERY_REMOVE: &str = "discovery:remove";
pub const DISCOVERY_REVIEW: &str = "discovery:review";
pub const ENFORCEMENT_ANNOTATE: &str = "enforcement:annotate";
pub const ENFORCEMENT_VIEW: &str = "enforcement:view";
pub const GATEWAY_MEMORY_STATS: &str = "gateway:memory_stats";
pub const GATEWAY_RELOAD_ALL: &str = "gateway:reload_all";
pub const GIFT_CODES_GENERATE: &str = "gift_codes:generate";
pub const GUILD_AUDIT_LOG_VIEW: &str = "guild:audit_log:view";
pub const GUILD_BAN_MEMBER: &str = "guild:ban_member";
pub const GUILD_DELETE: &str = "guild:delete";
pub const GUILD_FORCE_ADD_MEMBER: &str = "guild:force_add_member";
pub const GUILD_KICK_MEMBER: &str = "guild:kick_member";
pub const GUILD_LIST_MEMBERS: &str = "guild:list:members";
pub const GUILD_LOOKUP: &str = "guild:lookup";
pub const GUILD_RELOAD: &str = "guild:reload";
pub const GUILD_SHUTDOWN: &str = "guild:shutdown";
pub const GUILD_TRANSFER_OWNERSHIP: &str = "guild:transfer_ownership";
pub const GUILD_UPDATE_FEATURES: &str = "guild:update:features";
pub const GUILD_UPDATE_NAME: &str = "guild:update:name";
pub const GUILD_UPDATE_SETTINGS: &str = "guild:update:settings";
pub const GUILD_UPDATE_VANITY: &str = "guild:update:vanity";
pub const INSTANCE_CONFIG_UPDATE: &str = "instance:config:update";
pub const INSTANCE_CONFIG_VIEW: &str = "instance:config:view";
pub const INSTANCE_LIMIT_CONFIG_UPDATE: &str = "instance:limit_config:update";
pub const INSTANCE_LIMIT_CONFIG_VIEW: &str = "instance:limit_config:view";
pub const MESSAGE_DELETE_ALL: &str = "message:delete_all";
pub const MESSAGE_DELETE: &str = "message:delete";
pub const MESSAGE_LOOKUP: &str = "message:lookup";
pub const MESSAGE_SHRED: &str = "message:shred";
pub const REGISTRATION_REVIEW: &str = "registration:review";
pub const REPORT_DELETE: &str = "report:delete";
pub const REPORT_RESOLVE: &str = "report:resolve";
pub const REPORT_VIEW: &str = "report:view";
pub const REPORT_VIEW_REPORTER_PII: &str = "report:view:reporter_pii";
pub const SYSTEM_DM_SEND: &str = "system_dm:send";
pub const USER_CANCEL_BULK_MESSAGE_DELETION: &str = "user:cancel:bulk_message_deletion";
pub const USER_CREATE_PASSWORD_RESET_LINK: &str = "user:create:password_reset_link";
pub const USER_DELETE_RECOVERY_KIT: &str = "user:delete:recovery_kit";
pub const USER_DELETE: &str = "user:delete";
pub const USER_LIST_DM_CHANNELS: &str = "user:list:dm_channels";
pub const USER_LIST_GUILDS: &str = "user:list:guilds";
pub const USER_LIST_RELATIONSHIPS: &str = "user:list:relationships";
pub const USER_LIST_SESSIONS: &str = "user:list:sessions";
pub const USER_LOOKUP: &str = "user:lookup";
pub const USER_REMOVE_RELATIONSHIP: &str = "user:remove:relationship";
pub const USER_VIEW_CONTACT_LOG: &str = "user:view:contact_log";
pub const USER_VIEW_DOB: &str = "user:view:dob";
pub const USER_VIEW_EMAIL: &str = "user:view:email";
pub const USER_VIEW_IP: &str = "user:view:ip";
pub const USER_TEMP_BAN: &str = "user:temp_ban";
pub const USER_UPDATE_BOT_STATUS: &str = "user:update:bot_status";
pub const USER_UPDATE_DOB: &str = "user:update:dob";
pub const USER_UPDATE_EMAIL: &str = "user:update:email";
pub const USER_UPDATE_FLAGS: &str = "user:update:flags";
pub const USER_UPDATE_MFA: &str = "user:update:mfa";
pub const USER_UPDATE_PROFILE: &str = "user:update:profile";
pub const USER_UPDATE_TRAITS: &str = "user:update:traits";
pub const USER_UPDATE_USERNAME: &str = "user:update:username";
pub const VOICE_REGION_CREATE: &str = "voice:region:create";
pub const VOICE_REGION_DELETE: &str = "voice:region:delete";
pub const VOICE_REGION_LIST: &str = "voice:region:list";
pub const VOICE_REGION_UPDATE: &str = "voice:region:update";
pub const VOICE_SERVER_CREATE: &str = "voice:server:create";
pub const VOICE_SERVER_DELETE: &str = "voice:server:delete";
pub const VOICE_SERVER_LIST: &str = "voice:server:list";
pub const VOICE_SERVER_UPDATE: &str = "voice:server:update";
pub const ALL_ACLS: &[&str] = &[
WILDCARD,
ACL_SET_USER,
ADMIN_API_KEY_MANAGE,
APPLICATION_LOOKUP,
APPLICATION_LIST_BY_OWNER,
APPLICATION_TRANSFER_OWNERSHIP,
ARCHIVE_TRIGGER_GUILD,
ARCHIVE_TRIGGER_USER,
ARCHIVE_VIEW_ALL,
ASSET_PURGE,
AUDIT_LOG_VIEW,
AUTHENTICATE,
JOBS_VIEW,
JOBS_CANCEL,
BAN_EMAIL_ADD,
BAN_EMAIL_CHECK,
BAN_EMAIL_REMOVE,
BAN_PHRASE_ADD,
BAN_PHRASE_CHECK,
BAN_PHRASE_REMOVE,
BAN_IP_ADD,
BAN_IP_CHECK,
BAN_IP_REMOVE,
BAN_URL_ADD,
BAN_URL_CHECK,
BAN_URL_REMOVE,
BAN_URL_DOMAIN_ADD,
BAN_URL_DOMAIN_CHECK,
BAN_URL_DOMAIN_REMOVE,
BAN_FILE_SHA_ADD,
BAN_FILE_SHA_CHECK,
BAN_FILE_SHA_REMOVE,
BAN_AVATAR_HASH_ADD,
BAN_AVATAR_HASH_CHECK,
BAN_AVATAR_HASH_REMOVE,
BAN_PROFILE_SUBSTRING_ADD,
BAN_PROFILE_SUBSTRING_CHECK,
BAN_PROFILE_SUBSTRING_REMOVE,
BULK_ADD_GUILD_MEMBERS,
BULK_DELETE_USERS,
BULK_DELETE_USER_MESSAGES,
BULK_UPDATE_GUILD_FEATURES,
BULK_UPDATE_USER_FLAGS,
DISCOVERY_REMOVE,
DISCOVERY_REVIEW,
ENFORCEMENT_ANNOTATE,
ENFORCEMENT_VIEW,
GATEWAY_MEMORY_STATS,
GATEWAY_RELOAD_ALL,
GIFT_CODES_GENERATE,
GUILD_AUDIT_LOG_VIEW,
GUILD_BAN_MEMBER,
GUILD_DELETE,
GUILD_FORCE_ADD_MEMBER,
GUILD_KICK_MEMBER,
GUILD_LIST_MEMBERS,
GUILD_LOOKUP,
GUILD_RELOAD,
GUILD_SHUTDOWN,
GUILD_TRANSFER_OWNERSHIP,
GUILD_UPDATE_FEATURES,
GUILD_UPDATE_NAME,
GUILD_UPDATE_SETTINGS,
GUILD_UPDATE_VANITY,
INSTANCE_CONFIG_UPDATE,
INSTANCE_CONFIG_VIEW,
INSTANCE_LIMIT_CONFIG_UPDATE,
INSTANCE_LIMIT_CONFIG_VIEW,
MESSAGE_DELETE_ALL,
MESSAGE_DELETE,
MESSAGE_LOOKUP,
MESSAGE_SHRED,
REGISTRATION_REVIEW,
REPORT_DELETE,
REPORT_RESOLVE,
REPORT_VIEW,
REPORT_VIEW_REPORTER_PII,
SYSTEM_DM_SEND,
USER_CANCEL_BULK_MESSAGE_DELETION,
USER_CREATE_PASSWORD_RESET_LINK,
USER_DELETE_RECOVERY_KIT,
USER_DELETE,
USER_LIST_DM_CHANNELS,
USER_LIST_GUILDS,
USER_LIST_RELATIONSHIPS,
USER_LIST_SESSIONS,
USER_LOOKUP,
USER_REMOVE_RELATIONSHIP,
USER_VIEW_CONTACT_LOG,
USER_VIEW_DOB,
USER_VIEW_EMAIL,
USER_VIEW_IP,
USER_TEMP_BAN,
USER_UPDATE_BOT_STATUS,
USER_UPDATE_DOB,
USER_UPDATE_EMAIL,
USER_UPDATE_FLAGS,
USER_UPDATE_MFA,
USER_UPDATE_PROFILE,
USER_UPDATE_TRAITS,
USER_UPDATE_USERNAME,
VOICE_REGION_CREATE,
VOICE_REGION_DELETE,
VOICE_REGION_LIST,
VOICE_REGION_UPDATE,
VOICE_SERVER_CREATE,
VOICE_SERVER_DELETE,
VOICE_SERVER_LIST,
VOICE_SERVER_UPDATE,
];
pub fn has_permission(admin_acls: &[String], required: &str) -> bool {
let required_alias = acl_key_alias(required);
admin_acls.iter().any(|acl| {
acl == required || acl == WILDCARD || acl == &required_alias || acl == "WILDCARD"
})
}
pub fn has_any_permission(admin_acls: &[String], required: &[&str]) -> bool {
if required.is_empty() {
return true;
}
required.iter().any(|acl| has_permission(admin_acls, acl))
}
fn acl_key_alias(acl: &str) -> String {
acl.replace(':', "_").to_ascii_uppercase()
}
#[cfg(test)]
mod tests {
use super::*;
fn acls(items: &[&str]) -> Vec<String> {
items.iter().map(|s| s.to_string()).collect()
}
#[test]
fn has_permission_exact_match() {
assert!(has_permission(&acls(&[USER_LOOKUP]), USER_LOOKUP));
}
#[test]
fn has_permission_wildcard() {
assert!(has_permission(&acls(&[WILDCARD]), USER_LOOKUP));
assert!(has_permission(&acls(&[WILDCARD]), GUILD_DELETE));
}
#[test]
fn has_permission_accepts_constant_key_aliases() {
assert!(has_permission(
&acls(&["USER_REMOVE_RELATIONSHIP"]),
USER_REMOVE_RELATIONSHIP
));
assert!(has_permission(&acls(&["WILDCARD"]), GUILD_DELETE));
}
#[test]
fn has_permission_no_match() {
assert!(!has_permission(&acls(&[USER_LOOKUP]), GUILD_LOOKUP));
assert!(!has_permission(&acls(&[]), USER_LOOKUP));
}
#[test]
fn has_any_permission_any_match() {
let user_acls = acls(&[USER_LOOKUP, GUILD_LOOKUP]);
assert!(has_any_permission(
&user_acls,
&[GUILD_DELETE, GUILD_LOOKUP]
));
}
#[test]
fn has_any_permission_empty_required() {
assert!(has_any_permission(&acls(&[USER_LOOKUP]), &[]));
assert!(has_any_permission(&acls(&[]), &[]));
}
#[test]
fn has_any_permission_none_match() {
let user_acls = acls(&[USER_LOOKUP]);
assert!(!has_any_permission(
&user_acls,
&[GUILD_DELETE, GUILD_LOOKUP]
));
}
}