]> Untitled Git - lemmy.git/blob - crates/db_queries/src/source/person.rs
Rewrite delete activities (#1699)
[lemmy.git] / crates / db_queries / src / source / person.rs
1 use crate::{ApubObject, Crud};
2 use diesel::{dsl::*, result::Error, *};
3 use lemmy_db_schema::{
4   naive_now,
5   schema::person::dsl::*,
6   source::person::{Person, PersonForm},
7   DbUrl,
8   PersonId,
9 };
10
11 mod safe_type {
12   use crate::ToSafe;
13   use lemmy_db_schema::{schema::person::columns::*, source::person::Person};
14
15   type Columns = (
16     id,
17     name,
18     display_name,
19     avatar,
20     banned,
21     published,
22     updated,
23     actor_id,
24     bio,
25     local,
26     banner,
27     deleted,
28     inbox_url,
29     shared_inbox_url,
30     matrix_user_id,
31     admin,
32     bot_account,
33   );
34
35   impl ToSafe for Person {
36     type SafeColumns = Columns;
37     fn safe_columns_tuple() -> Self::SafeColumns {
38       (
39         id,
40         name,
41         display_name,
42         avatar,
43         banned,
44         published,
45         updated,
46         actor_id,
47         bio,
48         local,
49         banner,
50         deleted,
51         inbox_url,
52         shared_inbox_url,
53         matrix_user_id,
54         admin,
55         bot_account,
56       )
57     }
58   }
59 }
60
61 mod safe_type_alias_1 {
62   use crate::ToSafe;
63   use lemmy_db_schema::{schema::person_alias_1::columns::*, source::person::PersonAlias1};
64
65   type Columns = (
66     id,
67     name,
68     display_name,
69     avatar,
70     banned,
71     published,
72     updated,
73     actor_id,
74     bio,
75     local,
76     banner,
77     deleted,
78     inbox_url,
79     shared_inbox_url,
80     matrix_user_id,
81     admin,
82     bot_account,
83   );
84
85   impl ToSafe for PersonAlias1 {
86     type SafeColumns = Columns;
87     fn safe_columns_tuple() -> Self::SafeColumns {
88       (
89         id,
90         name,
91         display_name,
92         avatar,
93         banned,
94         published,
95         updated,
96         actor_id,
97         bio,
98         local,
99         banner,
100         deleted,
101         inbox_url,
102         shared_inbox_url,
103         matrix_user_id,
104         admin,
105         bot_account,
106       )
107     }
108   }
109 }
110
111 mod safe_type_alias_2 {
112   use crate::ToSafe;
113   use lemmy_db_schema::{schema::person_alias_2::columns::*, source::person::PersonAlias2};
114
115   type Columns = (
116     id,
117     name,
118     display_name,
119     avatar,
120     banned,
121     published,
122     updated,
123     actor_id,
124     bio,
125     local,
126     banner,
127     deleted,
128     inbox_url,
129     shared_inbox_url,
130     matrix_user_id,
131     admin,
132     bot_account,
133   );
134
135   impl ToSafe for PersonAlias2 {
136     type SafeColumns = Columns;
137     fn safe_columns_tuple() -> Self::SafeColumns {
138       (
139         id,
140         name,
141         display_name,
142         avatar,
143         banned,
144         published,
145         updated,
146         actor_id,
147         bio,
148         local,
149         banner,
150         deleted,
151         inbox_url,
152         shared_inbox_url,
153         matrix_user_id,
154         admin,
155         bot_account,
156       )
157     }
158   }
159 }
160
161 impl Crud for Person {
162   type Form = PersonForm;
163   type IdType = PersonId;
164   fn read(conn: &PgConnection, person_id: PersonId) -> Result<Self, Error> {
165     person
166       .filter(deleted.eq(false))
167       .find(person_id)
168       .first::<Self>(conn)
169   }
170   fn delete(conn: &PgConnection, person_id: PersonId) -> Result<usize, Error> {
171     diesel::delete(person.find(person_id)).execute(conn)
172   }
173   fn create(conn: &PgConnection, form: &PersonForm) -> Result<Self, Error> {
174     insert_into(person).values(form).get_result::<Self>(conn)
175   }
176   fn update(conn: &PgConnection, person_id: PersonId, form: &PersonForm) -> Result<Self, Error> {
177     diesel::update(person.find(person_id))
178       .set(form)
179       .get_result::<Self>(conn)
180   }
181 }
182
183 impl ApubObject for Person {
184   type Form = PersonForm;
185   fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error> {
186     use lemmy_db_schema::schema::person::dsl::*;
187     person
188       .filter(deleted.eq(false))
189       .filter(actor_id.eq(object_id))
190       .first::<Self>(conn)
191   }
192
193   fn upsert(conn: &PgConnection, person_form: &PersonForm) -> Result<Person, Error> {
194     insert_into(person)
195       .values(person_form)
196       .on_conflict(actor_id)
197       .do_update()
198       .set(person_form)
199       .get_result::<Self>(conn)
200   }
201 }
202
203 pub trait Person_ {
204   fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result<Person, Error>;
205   fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result<Person, Error>;
206   fn find_by_name(conn: &PgConnection, name: &str) -> Result<Person, Error>;
207   fn mark_as_updated(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error>;
208   fn delete_account(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error>;
209 }
210
211 impl Person_ for Person {
212   fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result<Self, Error> {
213     diesel::update(person.find(person_id))
214       .set(banned.eq(ban))
215       .get_result::<Self>(conn)
216   }
217
218   fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result<Self, Error> {
219     diesel::update(person.find(person_id))
220       .set(admin.eq(added))
221       .get_result::<Self>(conn)
222   }
223
224   fn find_by_name(conn: &PgConnection, from_name: &str) -> Result<Person, Error> {
225     person
226       .filter(deleted.eq(false))
227       .filter(local.eq(true))
228       .filter(name.ilike(from_name))
229       .first::<Person>(conn)
230   }
231
232   fn mark_as_updated(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error> {
233     diesel::update(person.find(person_id))
234       .set((last_refreshed_at.eq(naive_now()),))
235       .get_result::<Self>(conn)
236   }
237
238   fn delete_account(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error> {
239     use lemmy_db_schema::schema::local_user;
240
241     // Set the local user info to none
242     diesel::update(local_user::table.filter(local_user::person_id.eq(person_id)))
243       .set((
244         local_user::email.eq::<Option<String>>(None),
245         local_user::validator_time.eq(naive_now()),
246       ))
247       .execute(conn)?;
248
249     diesel::update(person.find(person_id))
250       .set((
251         display_name.eq::<Option<String>>(None),
252         bio.eq::<Option<String>>(None),
253         matrix_user_id.eq::<Option<String>>(None),
254         deleted.eq(true),
255         updated.eq(naive_now()),
256       ))
257       .get_result::<Self>(conn)
258   }
259 }
260
261 #[cfg(test)]
262 mod tests {
263   use crate::{establish_unpooled_connection, source::person::*};
264
265   #[test]
266   fn test_crud() {
267     let conn = establish_unpooled_connection();
268
269     let new_person = PersonForm {
270       name: "holly".into(),
271       ..PersonForm::default()
272     };
273
274     let inserted_person = Person::create(&conn, &new_person).unwrap();
275
276     let expected_person = Person {
277       id: inserted_person.id,
278       name: "holly".into(),
279       display_name: None,
280       avatar: None,
281       banner: None,
282       banned: false,
283       deleted: false,
284       published: inserted_person.published,
285       updated: None,
286       actor_id: inserted_person.actor_id.to_owned(),
287       bio: None,
288       local: true,
289       bot_account: false,
290       admin: false,
291       private_key: None,
292       public_key: None,
293       last_refreshed_at: inserted_person.published,
294       inbox_url: inserted_person.inbox_url.to_owned(),
295       shared_inbox_url: None,
296       matrix_user_id: None,
297     };
298
299     let read_person = Person::read(&conn, inserted_person.id).unwrap();
300     let updated_person = Person::update(&conn, inserted_person.id, &new_person).unwrap();
301     let num_deleted = Person::delete(&conn, inserted_person.id).unwrap();
302
303     assert_eq!(expected_person, read_person);
304     assert_eq!(expected_person, inserted_person);
305     assert_eq!(expected_person, updated_person);
306     assert_eq!(1, num_deleted);
307   }
308 }