#[cfg(feature = "server")]
mod server_impl {
pub use super::account_delete::AccountDeleteService;
pub use super::account_insert::AccountInsertService;
pub use super::account_repository::AccountRepository;
pub use super::errors::{AccountOperation, AccountsError};
#[cfg(any(feature = "storage-seaorm", feature = "storage-seaorm-v2"))]
pub use crate::comma_separated_value::CommaSeparatedValue;
}
#[cfg(feature = "server")]
pub use server_impl::*;
use crate::authz::AccessHierarchy;
use crate::permissions::{PermissionId, Permissions};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[cfg(feature = "server")]
mod account_delete;
#[cfg(feature = "server")]
mod account_insert;
#[cfg(feature = "server")]
mod account_repository;
#[cfg(feature = "server")]
pub mod errors;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Account<R, G>
where
R: AccessHierarchy + Eq,
G: Eq + Clone,
{
pub account_id: Uuid,
pub user_id: String,
pub roles: Vec<R>,
pub groups: Vec<G>,
pub permissions: Permissions,
}
impl<R, G> Account<R, G>
where
R: AccessHierarchy + Eq + Clone,
G: Eq + Clone,
{
pub fn new(user_id: &str, roles: &[R], groups: &[G]) -> Self {
let roles = roles.to_vec();
let groups = groups.to_vec();
Self {
account_id: Uuid::now_v7(),
user_id: user_id.to_owned(),
groups,
roles,
permissions: Permissions::new(),
}
}
#[cfg(any(feature = "storage-seaorm", feature = "storage-seaorm-v2"))]
pub(crate) fn new_with_account_id(
account_id: &Uuid,
user_id: &str,
roles: &[R],
groups: &[G],
) -> Self {
let roles = roles.to_vec();
let groups = groups.to_vec();
Self {
account_id: account_id.to_owned(),
user_id: user_id.to_owned(),
groups,
roles,
permissions: Permissions::new(),
}
}
pub fn with_permissions(self, permissions: Permissions) -> Self {
Self {
permissions,
..self
}
}
pub fn grant_permission<P>(&mut self, permission: P)
where
P: Into<PermissionId>,
{
self.permissions.grant(permission);
}
pub fn revoke_permission<P>(&mut self, permission: P)
where
P: Into<PermissionId>,
{
self.permissions.revoke(permission);
}
pub fn has_role(&self, role: &R) -> bool {
self.roles.contains(role)
}
pub fn is_member_of(&self, group: &G) -> bool {
self.groups.contains(group)
}
pub fn has_permission<P>(&self, permission: P) -> bool
where
P: Into<PermissionId>,
{
self.permissions.has(permission)
}
}
#[cfg(any(feature = "storage-seaorm", feature = "storage-seaorm-v2"))]
impl<R, G> TryFrom<crate::repositories::sea_orm::models::account::Model> for Account<R, G>
where
R: AccessHierarchy + Eq + std::fmt::Display + Clone,
Vec<R>: CommaSeparatedValue,
G: Eq + Clone,
Vec<G>: CommaSeparatedValue,
{
type Error = String;
fn try_from(
value: crate::repositories::sea_orm::models::account::Model,
) -> Result<Self, Self::Error> {
Ok(Self::new_with_account_id(
&value.account_id,
&value.user_id,
&Vec::<R>::from_csv(&value.roles)?,
&Vec::<G>::from_csv(&value.groups)?,
))
}
}