]> Untitled Git - lemmy.git/blob - crates/db_queries/src/source/person.rs
Mark accounts as bot nutomic (#1565)
[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<PersonForm, PersonId> for Person {
162   fn read(conn: &PgConnection, person_id: PersonId) -> Result<Self, Error> {
163     person
164       .filter(deleted.eq(false))
165       .find(person_id)
166       .first::<Self>(conn)
167   }
168   fn delete(conn: &PgConnection, person_id: PersonId) -> Result<usize, Error> {
169     diesel::delete(person.find(person_id)).execute(conn)
170   }
171   fn create(conn: &PgConnection, form: &PersonForm) -> Result<Self, Error> {
172     insert_into(person).values(form).get_result::<Self>(conn)
173   }
174   fn update(conn: &PgConnection, person_id: PersonId, form: &PersonForm) -> Result<Self, Error> {
175     diesel::update(person.find(person_id))
176       .set(form)
177       .get_result::<Self>(conn)
178   }
179 }
180
181 impl ApubObject<PersonForm> for Person {
182   fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error> {
183     use lemmy_db_schema::schema::person::dsl::*;
184     person
185       .filter(deleted.eq(false))
186       .filter(actor_id.eq(object_id))
187       .first::<Self>(conn)
188   }
189
190   fn upsert(conn: &PgConnection, person_form: &PersonForm) -> Result<Person, Error> {
191     insert_into(person)
192       .values(person_form)
193       .on_conflict(actor_id)
194       .do_update()
195       .set(person_form)
196       .get_result::<Self>(conn)
197   }
198 }
199
200 pub trait Person_ {
201   fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result<Person, Error>;
202   fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result<Person, Error>;
203   fn find_by_name(conn: &PgConnection, name: &str) -> Result<Person, Error>;
204   fn mark_as_updated(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error>;
205   fn delete_account(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error>;
206 }
207
208 impl Person_ for Person {
209   fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result<Self, Error> {
210     diesel::update(person.find(person_id))
211       .set(banned.eq(ban))
212       .get_result::<Self>(conn)
213   }
214
215   fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result<Self, Error> {
216     diesel::update(person.find(person_id))
217       .set(admin.eq(added))
218       .get_result::<Self>(conn)
219   }
220
221   fn find_by_name(conn: &PgConnection, from_name: &str) -> Result<Person, Error> {
222     person
223       .filter(deleted.eq(false))
224       .filter(local.eq(true))
225       .filter(name.ilike(from_name))
226       .first::<Person>(conn)
227   }
228
229   fn mark_as_updated(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error> {
230     diesel::update(person.find(person_id))
231       .set((last_refreshed_at.eq(naive_now()),))
232       .get_result::<Self>(conn)
233   }
234
235   fn delete_account(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error> {
236     use lemmy_db_schema::schema::local_user;
237
238     // Set the local user info to none
239     diesel::update(local_user::table.filter(local_user::person_id.eq(person_id)))
240       .set((local_user::email.eq::<Option<String>>(None),))
241       .execute(conn)?;
242
243     diesel::update(person.find(person_id))
244       .set((
245         display_name.eq::<Option<String>>(None),
246         bio.eq::<Option<String>>(None),
247         matrix_user_id.eq::<Option<String>>(None),
248         deleted.eq(true),
249         updated.eq(naive_now()),
250       ))
251       .get_result::<Self>(conn)
252   }
253 }
254
255 #[cfg(test)]
256 mod tests {
257   use crate::{establish_unpooled_connection, source::person::*};
258
259   #[test]
260   fn test_crud() {
261     let conn = establish_unpooled_connection();
262
263     let new_person = PersonForm {
264       name: "holly".into(),
265       ..PersonForm::default()
266     };
267
268     let inserted_person = Person::create(&conn, &new_person).unwrap();
269
270     let expected_person = Person {
271       id: inserted_person.id,
272       name: "holly".into(),
273       display_name: None,
274       avatar: None,
275       banner: None,
276       banned: false,
277       deleted: false,
278       published: inserted_person.published,
279       updated: None,
280       actor_id: inserted_person.actor_id.to_owned(),
281       bio: None,
282       local: true,
283       bot_account: false,
284       admin: false,
285       private_key: None,
286       public_key: None,
287       last_refreshed_at: inserted_person.published,
288       inbox_url: inserted_person.inbox_url.to_owned(),
289       shared_inbox_url: None,
290       matrix_user_id: None,
291     };
292
293     let read_person = Person::read(&conn, inserted_person.id).unwrap();
294     let updated_person = Person::update(&conn, inserted_person.id, &new_person).unwrap();
295     let num_deleted = Person::delete(&conn, inserted_person.id).unwrap();
296
297     assert_eq!(expected_person, read_person);
298     assert_eq!(expected_person, inserted_person);
299     assert_eq!(expected_person, updated_person);
300     assert_eq!(1, num_deleted);
301   }
302 }