myc_core/domain/dtos/webhook/
mod.rs

1mod responses;
2mod trigger;
3
4pub use responses::*;
5pub use trigger::*;
6
7use super::http_secret::HttpSecret;
8use crate::{domain::dtos::written_by::WrittenBy, models::AccountLifeCycle};
9
10use chrono::{DateTime, Local};
11use mycelium_base::utils::errors::MappedErrors;
12use serde::{Deserialize, Serialize};
13use utoipa::ToSchema;
14use uuid::Uuid;
15
16#[derive(Clone, Debug, Deserialize, Serialize, ToSchema)]
17#[serde(rename_all = "camelCase")]
18pub struct WebHook {
19    /// The webhook id
20    pub id: Option<Uuid>,
21
22    /// The webhook name
23    pub name: String,
24
25    /// The webhook description
26    pub description: Option<String>,
27
28    /// The webhook url
29    pub url: String,
30
31    /// The webhook trigger
32    pub trigger: WebHookTrigger,
33
34    /// The webhook is active
35    pub is_active: bool,
36
37    /// The webhook created date
38    pub created: DateTime<Local>,
39
40    /// The webhook created by
41    ///
42    /// The ID of the account that created the webhook. This is used for
43    /// auditing purposes.
44    ///
45    pub created_by: Option<WrittenBy>,
46
47    /// The webhook updated date
48    pub updated: Option<DateTime<Local>>,
49
50    /// The webhook updated by
51    ///
52    /// The ID of the account that updated the webhook. This is used for
53    /// auditing purposes.
54    ///
55    pub updated_by: Option<WrittenBy>,
56
57    /// The webhook secret
58    ///
59    /// Its important to note that the secret should be encrypted in the
60    /// database and redacted on the response.
61    ///
62    secret: Option<HttpSecret>,
63}
64
65impl WebHook {
66    pub fn new(
67        name: String,
68        description: Option<String>,
69        url: String,
70        trigger: WebHookTrigger,
71        secret: Option<HttpSecret>,
72        created_by: Option<WrittenBy>,
73    ) -> Self {
74        Self {
75            id: None,
76            name,
77            description,
78            url,
79            trigger,
80            is_active: true,
81            created: Local::now(),
82            created_by,
83            updated: None,
84            updated_by: None,
85            secret,
86        }
87    }
88
89    pub async fn new_encrypted(
90        name: String,
91        description: Option<String>,
92        url: String,
93        trigger: WebHookTrigger,
94        secret: Option<HttpSecret>,
95        config: AccountLifeCycle,
96        created_by: Option<WrittenBy>,
97    ) -> Result<Self, MappedErrors> {
98        let encrypted_secret = match secret {
99            None => None,
100            Some(secret) => Some(secret.encrypt_me(config).await?),
101        };
102
103        Ok(Self {
104            id: None,
105            name,
106            description,
107            url,
108            trigger,
109            is_active: true,
110            created: Local::now(),
111            created_by,
112            updated: None,
113            updated_by: None,
114            secret: encrypted_secret,
115        })
116    }
117
118    pub fn redact_secret_token(&mut self) {
119        if let Some(secret) = &mut self.secret {
120            secret.redact_token();
121        }
122    }
123
124    pub fn get_secret(&self) -> Option<HttpSecret> {
125        self.secret.clone()
126    }
127
128    pub async fn set_secret(
129        &mut self,
130        secret: HttpSecret,
131        config: AccountLifeCycle,
132        updated_by: Option<WrittenBy>,
133    ) -> Result<(), MappedErrors> {
134        self.secret = Some(secret.encrypt_me(config).await?);
135        self.updated_by = updated_by;
136        Ok(())
137    }
138}