2 newtypes::{DbUrl, PersonId},
3 schema::person::dsl::*,
4 source::person::{Person, PersonForm},
5 traits::{ApubActor, Crud},
6 utils::{functions::lower, naive_now},
15 TextExpressionMethods,
19 use crate::{schema::person::columns::*, source::person::Person, traits::ToSafe};
42 impl ToSafe for Person {
43 type SafeColumns = Columns;
44 fn safe_columns_tuple() -> Self::SafeColumns {
69 impl Crud for Person {
70 type Form = PersonForm;
71 type IdType = PersonId;
72 fn read(conn: &mut PgConnection, person_id: PersonId) -> Result<Self, Error> {
74 .filter(deleted.eq(false))
78 fn delete(conn: &mut PgConnection, person_id: PersonId) -> Result<usize, Error> {
79 diesel::delete(person.find(person_id)).execute(conn)
81 fn create(conn: &mut PgConnection, form: &PersonForm) -> Result<Self, Error> {
82 insert_into(person).values(form).get_result::<Self>(conn)
85 conn: &mut PgConnection,
88 ) -> Result<Self, Error> {
89 diesel::update(person.find(person_id))
91 .get_result::<Self>(conn)
97 conn: &mut PgConnection,
100 expires: Option<chrono::NaiveDateTime>,
101 ) -> Result<Self, Error> {
102 diesel::update(person.find(person_id))
103 .set((banned.eq(ban), ban_expires.eq(expires)))
104 .get_result::<Self>(conn)
108 conn: &mut PgConnection,
111 ) -> Result<Self, Error> {
112 diesel::update(person.find(person_id))
113 .set(admin.eq(added))
114 .get_result::<Self>(conn)
117 pub fn mark_as_updated(conn: &mut PgConnection, person_id: PersonId) -> Result<Person, Error> {
118 diesel::update(person.find(person_id))
119 .set((last_refreshed_at.eq(naive_now()),))
120 .get_result::<Self>(conn)
123 pub fn delete_account(conn: &mut PgConnection, person_id: PersonId) -> Result<Person, Error> {
124 use crate::schema::local_user;
126 // Set the local user info to none
127 diesel::update(local_user::table.filter(local_user::person_id.eq(person_id)))
129 local_user::email.eq::<Option<String>>(None),
130 local_user::validator_time.eq(naive_now()),
134 diesel::update(person.find(person_id))
136 display_name.eq::<Option<String>>(None),
137 avatar.eq::<Option<String>>(None),
138 banner.eq::<Option<String>>(None),
139 bio.eq::<Option<String>>(None),
140 matrix_user_id.eq::<Option<String>>(None),
142 updated.eq(naive_now()),
144 .get_result::<Self>(conn)
147 pub fn upsert(conn: &mut PgConnection, person_form: &PersonForm) -> Result<Person, Error> {
150 .on_conflict(actor_id)
153 .get_result::<Self>(conn)
156 pub fn update_deleted(
157 conn: &mut PgConnection,
160 ) -> Result<Person, Error> {
161 use crate::schema::person::dsl::*;
162 diesel::update(person.find(person_id))
163 .set(deleted.eq(new_deleted))
164 .get_result::<Self>(conn)
167 pub fn leave_admin(conn: &mut PgConnection, person_id: PersonId) -> Result<Self, Error> {
168 diesel::update(person.find(person_id))
169 .set(admin.eq(false))
170 .get_result::<Self>(conn)
173 pub fn remove_avatar_and_banner(
174 conn: &mut PgConnection,
176 ) -> Result<Self, Error> {
177 diesel::update(person.find(person_id))
179 avatar.eq::<Option<String>>(None),
180 banner.eq::<Option<String>>(None),
182 .get_result::<Self>(conn)
186 pub fn is_banned(banned_: bool, expires: Option<chrono::NaiveDateTime>) -> bool {
187 if let Some(expires) = expires {
188 banned_ && expires.gt(&naive_now())
194 impl ApubActor for Person {
195 fn read_from_apub_id(conn: &mut PgConnection, object_id: &DbUrl) -> Result<Option<Self>, Error> {
196 use crate::schema::person::dsl::*;
199 .filter(deleted.eq(false))
200 .filter(actor_id.eq(object_id))
201 .first::<Person>(conn)
208 conn: &mut PgConnection,
210 include_deleted: bool,
211 ) -> Result<Person, Error> {
214 .filter(local.eq(true))
215 .filter(lower(name).eq(lower(from_name)));
216 if !include_deleted {
217 q = q.filter(deleted.eq(false))
219 q.first::<Self>(conn)
222 fn read_from_name_and_domain(
223 conn: &mut PgConnection,
225 protocol_domain: &str,
226 ) -> Result<Person, Error> {
227 use crate::schema::person::dsl::*;
229 .filter(lower(name).eq(lower(person_name)))
230 .filter(actor_id.like(format!("{}%", protocol_domain)))
237 use crate::{source::person::*, traits::Crud, utils::establish_unpooled_connection};
238 use serial_test::serial;
243 let conn = &mut establish_unpooled_connection();
245 let new_person = PersonForm {
246 name: "holly".into(),
247 public_key: Some("nada".to_owned()),
248 ..PersonForm::default()
251 let inserted_person = Person::create(conn, &new_person).unwrap();
253 let expected_person = Person {
254 id: inserted_person.id,
255 name: "holly".into(),
261 published: inserted_person.published,
263 actor_id: inserted_person.actor_id.to_owned(),
269 public_key: "nada".to_owned(),
270 last_refreshed_at: inserted_person.published,
271 inbox_url: inserted_person.inbox_url.to_owned(),
272 shared_inbox_url: None,
273 matrix_user_id: None,
277 let read_person = Person::read(conn, inserted_person.id).unwrap();
278 let updated_person = Person::update(conn, inserted_person.id, &new_person).unwrap();
279 let num_deleted = Person::delete(conn, inserted_person.id).unwrap();
281 assert_eq!(expected_person, read_person);
282 assert_eq!(expected_person, inserted_person);
283 assert_eq!(expected_person, updated_person);
284 assert_eq!(1, num_deleted);