2 newtypes::{DbUrl, PersonId},
3 schema::person::dsl::*,
4 source::person::{Person, PersonInsertForm, PersonUpdateForm},
5 traits::{ApubActor, Crud},
6 utils::{functions::lower, get_conn, naive_now, DbPool},
8 use diesel::{dsl::*, result::Error, ExpressionMethods, QueryDsl, TextExpressionMethods};
9 use diesel_async::RunQueryDsl;
12 use crate::{schema::person::columns::*, source::person::Person, traits::ToSafe};
36 impl ToSafe for Person {
37 type SafeColumns = Columns;
38 fn safe_columns_tuple() -> Self::SafeColumns {
65 impl Crud for Person {
66 type InsertForm = PersonInsertForm;
67 type UpdateForm = PersonUpdateForm;
68 type IdType = PersonId;
69 async fn read(pool: &DbPool, person_id: PersonId) -> Result<Self, Error> {
70 let conn = &mut get_conn(pool).await?;
72 .filter(deleted.eq(false))
77 async fn delete(pool: &DbPool, person_id: PersonId) -> Result<usize, Error> {
78 let conn = &mut get_conn(pool).await?;
79 diesel::delete(person.find(person_id)).execute(conn).await
81 async fn create(pool: &DbPool, form: &PersonInsertForm) -> Result<Self, Error> {
82 let conn = &mut get_conn(pool).await?;
85 .on_conflict(actor_id)
88 .get_result::<Self>(conn)
94 form: &PersonUpdateForm,
95 ) -> Result<Self, Error> {
96 let conn = &mut get_conn(pool).await?;
97 diesel::update(person.find(person_id))
99 .get_result::<Self>(conn)
105 pub async fn delete_account(pool: &DbPool, person_id: PersonId) -> Result<Person, Error> {
106 use crate::schema::local_user;
107 let conn = &mut get_conn(pool).await?;
109 // Set the local user info to none
110 diesel::update(local_user::table.filter(local_user::person_id.eq(person_id)))
112 local_user::email.eq::<Option<String>>(None),
113 local_user::validator_time.eq(naive_now()),
118 diesel::update(person.find(person_id))
120 display_name.eq::<Option<String>>(None),
121 avatar.eq::<Option<String>>(None),
122 banner.eq::<Option<String>>(None),
123 bio.eq::<Option<String>>(None),
124 matrix_user_id.eq::<Option<String>>(None),
126 updated.eq(naive_now()),
128 .get_result::<Self>(conn)
133 pub fn is_banned(banned_: bool, expires: Option<chrono::NaiveDateTime>) -> bool {
134 if let Some(expires) = expires {
135 banned_ && expires.gt(&naive_now())
142 impl ApubActor for Person {
143 async fn read_from_apub_id(pool: &DbPool, object_id: &DbUrl) -> Result<Option<Self>, Error> {
144 let conn = &mut get_conn(pool).await?;
147 .filter(deleted.eq(false))
148 .filter(actor_id.eq(object_id))
149 .first::<Person>(conn)
156 async fn read_from_name(
159 include_deleted: bool,
160 ) -> Result<Person, Error> {
161 let conn = &mut get_conn(pool).await?;
164 .filter(local.eq(true))
165 .filter(lower(name).eq(lower(from_name)));
166 if !include_deleted {
167 q = q.filter(deleted.eq(false))
169 q.first::<Self>(conn).await
172 async fn read_from_name_and_domain(
175 protocol_domain: &str,
176 ) -> Result<Person, Error> {
177 let conn = &mut get_conn(pool).await?;
179 .filter(lower(name).eq(lower(person_name)))
180 .filter(actor_id.like(format!("{}%", protocol_domain)))
189 source::{instance::Instance, person::*},
191 utils::build_db_pool_for_tests,
193 use serial_test::serial;
197 async fn test_crud() {
198 let pool = &build_db_pool_for_tests().await;
200 let inserted_instance = Instance::create(pool, "my_domain.tld").await.unwrap();
202 let new_person = PersonInsertForm::builder()
203 .name("holly".into())
204 .public_key("nada".to_owned())
205 .instance_id(inserted_instance.id)
208 let inserted_person = Person::create(pool, &new_person).await.unwrap();
210 let expected_person = Person {
211 id: inserted_person.id,
212 name: "holly".into(),
218 published: inserted_person.published,
220 actor_id: inserted_person.actor_id.to_owned(),
226 public_key: "nada".to_owned(),
227 last_refreshed_at: inserted_person.published,
228 inbox_url: inserted_person.inbox_url.to_owned(),
229 shared_inbox_url: None,
230 matrix_user_id: None,
232 instance_id: inserted_instance.id,
235 let read_person = Person::read(pool, inserted_person.id).await.unwrap();
237 let update_person_form = PersonUpdateForm::builder()
238 .actor_id(Some(inserted_person.actor_id.to_owned()))
240 let updated_person = Person::update(pool, inserted_person.id, &update_person_form)
244 let num_deleted = Person::delete(pool, inserted_person.id).await.unwrap();
245 Instance::delete(pool, inserted_instance.id).await.unwrap();
247 assert_eq!(expected_person, read_person);
248 assert_eq!(expected_person, inserted_person);
249 assert_eq!(expected_person, updated_person);
250 assert_eq!(1, num_deleted);