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