use derive_variants::EnumVariants;
use serde::{Deserialize, Serialize};
use strum::{AsRefStr, Display, EnumString};
use typeshare::typeshare;
use super::{MongoId, ResourceTarget};
#[typeshare]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(
feature = "mongo",
derive(mongo_indexed::derive::MongoIndexed)
)]
#[cfg_attr(feature = "mongo", doc_index({ "user_target.type": 1, "user_target.id": 1 }))]
#[cfg_attr(feature = "mongo", doc_index({ "resource_target.type": 1, "resource_target.id": 1 }))]
#[cfg_attr(feature = "mongo", unique_doc_index({
"user_target.type": 1,
"user_target.id": 1,
"resource_target.type": 1,
"resource_target.id": 1
}))]
pub struct Permission {
#[serde(
default,
rename = "_id",
skip_serializing_if = "String::is_empty",
with = "bson::serde_helpers::hex_string_as_object_id"
)]
pub id: MongoId,
pub user_target: UserTarget,
pub resource_target: ResourceTarget,
#[serde(default)]
pub level: PermissionLevel,
}
#[typeshare]
#[derive(Debug, Clone, Serialize, Deserialize, EnumVariants)]
#[variant_derive(
Debug,
Clone,
Copy,
Serialize,
Deserialize,
AsRefStr
)]
#[serde(tag = "type", content = "id")]
pub enum UserTarget {
User(String),
UserGroup(String),
}
impl UserTarget {
pub fn extract_variant_id(self) -> (UserTargetVariant, String) {
match self {
UserTarget::User(id) => (UserTargetVariant::User, id),
UserTarget::UserGroup(id) => (UserTargetVariant::UserGroup, id),
}
}
}
#[typeshare]
#[derive(
Serialize,
Deserialize,
Debug,
Display,
EnumString,
AsRefStr,
Hash,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Default,
)]
pub enum PermissionLevel {
#[default]
None,
Read,
Execute,
Write,
}
impl Default for &PermissionLevel {
fn default() -> Self {
&PermissionLevel::None
}
}