tetratto_core2/database/
audit_log.rs1use oiseau::cache::Cache;
2use crate::model::id::Id;
3use crate::model::{Error, Result, auth::User, moderation::AuditLogEntry, permissions::FinePermission};
4use crate::{auto_method, DataManager};
5
6use oiseau::PostgresRow;
7
8use oiseau::{execute, get, query_rows, params};
9
10impl DataManager {
11 pub(crate) fn get_audit_log_entry_from_row(x: &PostgresRow) -> AuditLogEntry {
13 AuditLogEntry {
14 id: Id::deserialize(&get!(x->0(String))),
15 created: get!(x->1(i64)) as u128,
16 moderator: Id::deserialize(&get!(x->2(String))),
17 content: get!(x->3(String)),
18 }
19 }
20
21 auto_method!(get_audit_log_entry_by_id()@get_audit_log_entry_from_row -> "SELECT * FROM audit_log WHERE id = $1" --name="audit log entry" --returns=AuditLogEntry --cache-key-tmpl="atto.audit_log:{}");
22
23 pub async fn get_audit_log_entries(
29 &self,
30 batch: usize,
31 page: usize,
32 ) -> Result<Vec<AuditLogEntry>> {
33 let conn = match self.0.connect().await {
34 Ok(c) => c,
35 Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
36 };
37
38 let res = query_rows!(
39 &conn,
40 "SELECT * FROM audit_log ORDER BY created DESC LIMIT $1 OFFSET $2",
41 &[&(batch as i64), &((page * batch) as i64)],
42 |x| { Self::get_audit_log_entry_from_row(x) }
43 );
44
45 if res.is_err() {
46 return Err(Error::GeneralNotFound("audit log entry".to_string()));
47 }
48
49 Ok(res.unwrap())
50 }
51
52 pub async fn create_audit_log_entry(&self, data: AuditLogEntry) -> Result<()> {
57 let conn = match self.0.connect().await {
58 Ok(c) => c,
59 Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
60 };
61
62 let res = execute!(
63 &conn,
64 "INSERT INTO audit_log VALUES ($1, $2, $3, $4)",
65 params![
66 &data.id.printable(),
67 &(data.created as i64),
68 &data.moderator.printable(),
69 &data.content.as_str(),
70 ]
71 );
72
73 if let Err(e) = res {
74 return Err(Error::DatabaseError(e.to_string()));
75 }
76
77 Ok(())
79 }
80
81 pub async fn delete_audit_log_entry(&self, id: &Id, user: User) -> Result<()> {
82 if !user.permissions.check(FinePermission::ManageAuditLog) {
83 return Err(Error::NotAllowed);
84 }
85
86 let conn = match self.0.connect().await {
87 Ok(c) => c,
88 Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
89 };
90
91 let res = execute!(
92 &conn,
93 "DELETE FROM audit_log WHERE id = $1",
94 &[&id.printable()]
95 );
96
97 if let Err(e) = res {
98 return Err(Error::DatabaseError(e.to_string()));
99 }
100
101 self.0.1.remove(format!("atto.audit_log:{}", id)).await;
102
103 Ok(())
105 }
106}