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