tetratto_core/database/
user_warnings.rs1use oiseau::cache::Cache;
2use crate::model::auth::{Notification, UserWarning};
3use crate::model::moderation::AuditLogEntry;
4use crate::model::{Error, Result, auth::User, permissions::FinePermission};
5use crate::{auto_method, DataManager};
6
7use oiseau::{PostgresRow, execute, get, query_row, query_rows, params};
8
9impl DataManager {
10 pub(crate) fn get_user_warning_from_row(x: &PostgresRow) -> UserWarning {
12 UserWarning {
13 id: get!(x->0(i64)) as usize,
14 created: get!(x->1(i64)) as usize,
15 receiver: get!(x->2(i64)) as usize,
16 moderator: get!(x->3(i64)) as usize,
17 content: get!(x->4(String)),
18 }
19 }
20
21 auto_method!(get_user_warning_by_id(usize)@get_user_warning_from_row -> "SELECT * FROM user_warnings WHERE id = $1" --name="user warning" --returns=UserWarning --cache-key-tmpl="atto.user_warning:{}");
22
23 pub async fn get_user_warnings_by_user(
30 &self,
31 user: usize,
32 batch: usize,
33 page: usize,
34 ) -> Result<Vec<UserWarning>> {
35 let conn = match self.0.connect().await {
36 Ok(c) => c,
37 Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
38 };
39
40 let res = query_rows!(
41 &conn,
42 "SELECT * FROM user_warnings WHERE receiver = $1 ORDER BY created DESC LIMIT $2 OFFSET $3",
43 &[&(user as i64), &(batch as i64), &((page * batch) as i64)],
44 |x| { Self::get_user_warning_from_row(x) }
45 );
46
47 if res.is_err() {
48 return Err(Error::GeneralNotFound("user warning".to_string()));
49 }
50
51 Ok(res.unwrap())
52 }
53
54 pub async fn create_user_warning(&self, data: UserWarning) -> Result<()> {
59 let user = self.get_user_by_id(data.moderator).await?;
60
61 if !user.permissions.check(FinePermission::MANAGE_WARNINGS) {
63 return Err(Error::NotAllowed);
64 }
65
66 let conn = match self.0.connect().await {
67 Ok(c) => c,
68 Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
69 };
70
71 let res = execute!(
72 &conn,
73 "INSERT INTO user_warnings VALUES ($1, $2, $3, $4, $5)",
74 params![
75 &(data.id as i64),
76 &(data.created as i64),
77 &(data.receiver as i64),
78 &(data.moderator as i64),
79 &data.content
80 ]
81 );
82
83 if let Err(e) = res {
84 return Err(Error::DatabaseError(e.to_string()));
85 }
86
87 self.create_audit_log_entry(AuditLogEntry::new(
89 user.id,
90 format!(
91 "invoked `create_user_warning` with x value `{}`",
92 data.receiver
93 ),
94 ))
95 .await?;
96
97 self.create_notification(Notification::new(
99 "You have received a new account warning.".to_string(),
100 data.content,
101 data.receiver,
102 ))
103 .await?;
104
105 Ok(())
107 }
108
109 pub async fn delete_user_warning(&self, id: usize, user: User) -> Result<()> {
110 if !user.permissions.check(FinePermission::MANAGE_WARNINGS) {
112 return Err(Error::NotAllowed);
113 }
114
115 let conn = match self.0.connect().await {
116 Ok(c) => c,
117 Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
118 };
119
120 let res = execute!(
121 &conn,
122 "DELETE FROM user_warnings WHERE id = $1",
123 &[&(id as i64)]
124 );
125
126 if let Err(e) = res {
127 return Err(Error::DatabaseError(e.to_string()));
128 }
129
130 self.0.1.remove(format!("atto.user_warning:{}", id)).await;
131
132 self.create_audit_log_entry(AuditLogEntry::new(
134 user.id,
135 format!("invoked `delete_user_warning` with x value `{id}`"),
136 ))
137 .await?;
138
139 Ok(())
141 }
142}