use crate::organization::types::CreatedOrganizationResponse;
use alibi_core::AuthResult;
use alibi_core::CreateMember;
use alibi_core::CreateOrganization;
use alibi_core::Member;
use alibi_core::Organization;
use alibi_core::UpdateOrganization;
use alibi_core::utils::json::JsValue;
use alibi_core::wire::UserView;
use async_trait::async_trait;
use indexmap::IndexMap;
use serde_json::Map;
use serde_json::Value;
#[derive(Debug, Clone)]
pub struct OrganizationDraftContext {
pub organization: CreateOrganization,
pub user: UserView,
}
#[derive(Debug, Clone)]
pub struct OrganizationMemberDraftContext {
pub organization: Organization,
pub member: CreateMember,
pub user: UserView,
}
#[derive(Debug, Clone)]
pub struct OrganizationCreatedContext {
pub organization: Organization,
pub member: Member,
pub user: UserView,
}
#[derive(Debug, Clone, Default)]
pub struct OrganizationCreatePatch {
pub id: Option<String>,
pub name: Option<String>,
pub slug: Option<String>,
pub logo: Option<Option<String>>,
pub metadata: Option<Option<Map<String, Value>>>,
}
impl OrganizationCreatePatch {
pub(crate) fn apply(self, data: &mut CreateOrganization) {
if let Some(id) = self.id {
data.id = Some(id);
}
if let Some(name) = self.name {
data.name = name;
}
if let Some(slug) = self.slug {
data.slug = slug;
}
if let Some(logo) = self.logo {
data.logo = logo;
}
if let Some(metadata) = self.metadata {
data.metadata = metadata.map(Value::Object);
}
}
}
#[derive(Debug, Clone, Default)]
pub struct OrganizationMemberCreatePatch {
pub organization_id: Option<String>,
pub user_id: Option<String>,
pub role: Option<String>,
}
impl OrganizationMemberCreatePatch {
pub(crate) fn apply(self, data: &mut CreateMember) {
if let Some(id) = self.organization_id {
data.organization_id = id;
}
if let Some(id) = self.user_id {
data.user_id = id;
}
if let Some(role) = self.role {
data.role = role;
}
}
}
#[async_trait]
pub trait OrganizationCreationHooks: std::fmt::Debug + Send + Sync {
async fn before_create(
&self,
_context: &OrganizationDraftContext,
) -> AuthResult<Option<OrganizationCreatePatch>> {
Ok(None)
}
async fn before_add_member(
&self,
_context: &OrganizationMemberDraftContext,
) -> AuthResult<Option<OrganizationMemberCreatePatch>> {
Ok(None)
}
async fn after_add_member(&self, _context: &OrganizationCreatedContext) -> AuthResult<()> {
Ok(())
}
async fn after_create(&self, _context: &OrganizationCreatedContext) -> AuthResult<()> {
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct OrganizationDeleteContext {
pub organization: crate::organization::types::OrganizationResponse,
pub user: UserView,
pub session: alibi_core::wire::SessionView,
pub headers: std::collections::HashMap<String, String>,
pub request: Option<alibi_core::AuthRequest>,
}
pub(crate) struct DeleteInvocation<'a> {
pub headers: &'a std::collections::HashMap<String, String>,
pub request: Option<&'a alibi_core::AuthRequest>,
}
#[async_trait]
pub trait OrganizationDeletionHooks: std::fmt::Debug + Send + Sync {
async fn before_delete(&self, _context: &OrganizationDeleteContext) -> AuthResult<()> {
Ok(())
}
async fn after_delete(&self, _context: &OrganizationDeleteContext) -> AuthResult<()> {
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct OrganizationUpdateInput {
pub name: Option<String>,
pub slug: Option<String>,
pub logo: Option<Option<String>>,
pub metadata: Option<IndexMap<String, JsValue>>,
}
#[derive(Debug, Clone)]
pub struct OrganizationUpdateContext {
pub organization: OrganizationUpdateInput,
pub user: UserView,
pub member: Member,
}
#[derive(Debug, Clone)]
pub struct OrganizationUpdatedContext {
pub organization: Option<CreatedOrganizationResponse>,
pub user: UserView,
pub member: Member,
}
#[derive(Debug, Clone, Default)]
pub struct OrganizationUpdatePatch {
pub name: Option<String>,
pub slug: Option<String>,
pub logo: Option<Option<String>>,
pub metadata: Option<Option<IndexMap<String, JsValue>>>,
}
impl OrganizationUpdatePatch {
pub(crate) fn apply(self, data: &mut UpdateOrganization) -> AuthResult<()> {
if let Some(name) = self.name {
data.name = Some(name);
}
if let Some(slug) = self.slug {
data.slug = Some(slug);
}
if let Some(logo) = self.logo {
data.logo = Some(logo);
}
if let Some(metadata) = self.metadata {
data.metadata = Some(
metadata
.map_or(JsValue::Null, JsValue::Object)
.to_json_value()?,
);
}
Ok(())
}
}
#[async_trait]
pub trait OrganizationUpdateHooks: std::fmt::Debug + Send + Sync {
async fn before_update(
&self,
_context: &OrganizationUpdateContext,
) -> AuthResult<Option<OrganizationUpdatePatch>> {
Ok(None)
}
async fn after_update(&self, _context: &OrganizationUpdatedContext) -> AuthResult<()> {
Ok(())
}
}