From eb45bf2d0a8533c20ccd8c47b98ee0f6473e7715 Mon Sep 17 00:00:00 2001
From: Dessalines <tyhou13@gmx.com>
Date: Mon, 22 Mar 2021 10:28:00 -0400
Subject: [PATCH] Moving admin to person table. Fixes #1515

---
 crates/api/src/lib.rs                              |  2 +-
 crates/api/src/local_user.rs                       |  8 ++++----
 crates/apub/src/objects/person.rs                  |  1 +
 crates/db_queries/src/source/local_user.rs         | 10 ----------
 crates/db_queries/src/source/person.rs             | 14 ++++++++++++++
 crates/db_schema/src/schema.rs                     |  4 +++-
 crates/db_schema/src/source/local_user.rs          |  3 ---
 crates/db_schema/src/source/person.rs              |  7 +++++++
 crates/db_views/src/comment_view.rs                |  1 +
 crates/db_views/src/post_view.rs                   |  1 +
 crates/db_views_actor/src/person_view.rs           |  5 ++---
 .../down.sql                                       |  6 +++++-
 .../up.sql                                         |  6 +++++-
 13 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs
index fc258d6a..dacf46f2 100644
--- a/crates/api/src/lib.rs
+++ b/crates/api/src/lib.rs
@@ -79,7 +79,7 @@ pub(crate) async fn is_mod_or_admin(
 }
 
 pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> {
-  if !local_user_view.local_user.admin {
+  if !local_user_view.person.admin {
     return Err(ApiError::err("not_an_admin").into());
   }
   Ok(())
diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs
index f7072b6e..5fbbdeec 100644
--- a/crates/api/src/local_user.rs
+++ b/crates/api/src/local_user.rs
@@ -204,6 +204,7 @@ impl Perform for Register {
       public_key: Some(Some(actor_keypair.public_key)),
       inbox_url: Some(generate_inbox_url(&actor_id)?),
       shared_inbox_url: Some(Some(generate_shared_inbox_url(&actor_id)?)),
+      admin: Some(no_admins),
       ..PersonForm::default()
     };
 
@@ -224,7 +225,6 @@ impl Perform for Register {
       person_id: inserted_person.id,
       email: Some(data.email.to_owned()),
       password_encrypted: data.password.to_owned(),
-      admin: Some(no_admins),
       show_nsfw: Some(data.show_nsfw),
       theme: Some("browser".into()),
       default_sort_type: Some(SortType::Active as i16),
@@ -455,6 +455,7 @@ impl Perform for SaveUserSettings {
       actor_id: None,
       bio,
       local: None,
+      admin: None,
       private_key: None,
       public_key: None,
       last_refreshed_at: None,
@@ -477,7 +478,6 @@ impl Perform for SaveUserSettings {
       person_id,
       email,
       password_encrypted,
-      admin: None,
       show_nsfw: data.show_nsfw,
       theme: data.theme.to_owned(),
       default_sort_type,
@@ -638,7 +638,7 @@ impl Perform for AddAdmin {
     let added = data.added;
     let added_person_id = data.person_id;
     let added_admin = match blocking(context.pool(), move |conn| {
-      LocalUser::add_admin(conn, added_person_id, added)
+      Person::add_admin(conn, added_person_id, added)
     })
     .await?
     {
@@ -651,7 +651,7 @@ impl Perform for AddAdmin {
     // Mod tables
     let form = ModAddForm {
       mod_person_id: local_user_view.person.id,
-      other_person_id: added_admin.person_id,
+      other_person_id: added_admin.id,
       removed: Some(!data.added),
     };
 
diff --git a/crates/apub/src/objects/person.rs b/crates/apub/src/objects/person.rs
index d1eb6707..c8e3a350 100644
--- a/crates/apub/src/objects/person.rs
+++ b/crates/apub/src/objects/person.rs
@@ -182,6 +182,7 @@ impl FromApubToForm<PersonExt> for PersonForm {
       actor_id: Some(check_object_domain(person, expected_domain)?),
       bio: Some(bio),
       local: Some(false),
+      admin: Some(false),
       private_key: None,
       public_key: Some(Some(person.ext_one.public_key.to_owned().public_key_pem)),
       last_refreshed_at: Some(naive_now()),
diff --git a/crates/db_queries/src/source/local_user.rs b/crates/db_queries/src/source/local_user.rs
index 7e84011b..18720ceb 100644
--- a/crates/db_queries/src/source/local_user.rs
+++ b/crates/db_queries/src/source/local_user.rs
@@ -6,7 +6,6 @@ use lemmy_db_schema::{
   schema::local_user::dsl::*,
   source::local_user::{LocalUser, LocalUserForm},
   LocalUserId,
-  PersonId,
 };
 
 mod safe_settings_type {
@@ -17,7 +16,6 @@ mod safe_settings_type {
     id,
     person_id,
     email,
-    admin,
     show_nsfw,
     theme,
     default_sort_type,
@@ -37,7 +35,6 @@ mod safe_settings_type {
         id,
         person_id,
         email,
-        admin,
         show_nsfw,
         theme,
         default_sort_type,
@@ -58,7 +55,6 @@ pub trait LocalUser_ {
     local_user_id: LocalUserId,
     new_password: &str,
   ) -> Result<LocalUser, Error>;
-  fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result<LocalUser, Error>;
 }
 
 impl LocalUser_ for LocalUser {
@@ -85,12 +81,6 @@ impl LocalUser_ for LocalUser {
       ))
       .get_result::<Self>(conn)
   }
-
-  fn add_admin(conn: &PgConnection, for_person_id: PersonId, added: bool) -> Result<Self, Error> {
-    diesel::update(local_user.filter(person_id.eq(for_person_id)))
-      .set(admin.eq(added))
-      .get_result::<Self>(conn)
-  }
 }
 
 impl Crud<LocalUserForm, LocalUserId> for LocalUser {
diff --git a/crates/db_queries/src/source/person.rs b/crates/db_queries/src/source/person.rs
index 6d5ad9b4..35ed540c 100644
--- a/crates/db_queries/src/source/person.rs
+++ b/crates/db_queries/src/source/person.rs
@@ -28,6 +28,7 @@ mod safe_type {
     inbox_url,
     shared_inbox_url,
     matrix_user_id,
+    admin,
   );
 
   impl ToSafe for Person {
@@ -49,6 +50,7 @@ mod safe_type {
         inbox_url,
         shared_inbox_url,
         matrix_user_id,
+        admin,
       )
     }
   }
@@ -74,6 +76,7 @@ mod safe_type_alias_1 {
     inbox_url,
     shared_inbox_url,
     matrix_user_id,
+    admin,
   );
 
   impl ToSafe for PersonAlias1 {
@@ -95,6 +98,7 @@ mod safe_type_alias_1 {
         inbox_url,
         shared_inbox_url,
         matrix_user_id,
+        admin,
       )
     }
   }
@@ -120,6 +124,7 @@ mod safe_type_alias_2 {
     inbox_url,
     shared_inbox_url,
     matrix_user_id,
+    admin,
   );
 
   impl ToSafe for PersonAlias2 {
@@ -141,6 +146,7 @@ mod safe_type_alias_2 {
         inbox_url,
         shared_inbox_url,
         matrix_user_id,
+        admin,
       )
     }
   }
@@ -187,6 +193,7 @@ impl ApubObject<PersonForm> for Person {
 
 pub trait Person_ {
   fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result<Person, Error>;
+  fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result<Person, Error>;
   fn find_by_name(conn: &PgConnection, name: &str) -> Result<Person, Error>;
   fn mark_as_updated(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error>;
   fn delete_account(conn: &PgConnection, person_id: PersonId) -> Result<Person, Error>;
@@ -199,6 +206,12 @@ impl Person_ for Person {
       .get_result::<Self>(conn)
   }
 
+  fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result<Self, Error> {
+    diesel::update(person.find(person_id))
+      .set(admin.eq(added))
+      .get_result::<Self>(conn)
+  }
+
   fn find_by_name(conn: &PgConnection, from_name: &str) -> Result<Person, Error> {
     person
       .filter(deleted.eq(false))
@@ -261,6 +274,7 @@ mod tests {
       actor_id: inserted_person.actor_id.to_owned(),
       bio: None,
       local: true,
+      admin: false,
       private_key: None,
       public_key: None,
       last_refreshed_at: inserted_person.published,
diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs
index 4c990ec0..5bc55f52 100644
--- a/crates/db_schema/src/schema.rs
+++ b/crates/db_schema/src/schema.rs
@@ -146,7 +146,6 @@ table! {
         person_id -> Int4,
         password_encrypted -> Text,
         email -> Nullable<Text>,
-        admin -> Bool,
         show_nsfw -> Bool,
         theme -> Varchar,
         default_sort_type -> Int2,
@@ -287,6 +286,7 @@ table! {
         inbox_url -> Varchar,
         shared_inbox_url -> Nullable<Varchar>,
         matrix_user_id -> Nullable<Text>,
+        admin -> Bool,
     }
 }
 
@@ -486,6 +486,7 @@ table! {
         inbox_url -> Varchar,
         shared_inbox_url -> Nullable<Varchar>,
         matrix_user_id -> Nullable<Text>,
+        admin -> Bool,
     }
 }
 
@@ -509,6 +510,7 @@ table! {
         inbox_url -> Varchar,
         shared_inbox_url -> Nullable<Varchar>,
         matrix_user_id -> Nullable<Text>,
+        admin -> Bool,
     }
 }
 
diff --git a/crates/db_schema/src/source/local_user.rs b/crates/db_schema/src/source/local_user.rs
index 2f4a9fc2..6f28a8fb 100644
--- a/crates/db_schema/src/source/local_user.rs
+++ b/crates/db_schema/src/source/local_user.rs
@@ -8,7 +8,6 @@ pub struct LocalUser {
   pub person_id: PersonId,
   pub password_encrypted: String,
   pub email: Option<String>,
-  pub admin: bool,
   pub show_nsfw: bool,
   pub theme: String,
   pub default_sort_type: i16,
@@ -26,7 +25,6 @@ pub struct LocalUserForm {
   pub person_id: PersonId,
   pub password_encrypted: String,
   pub email: Option<Option<String>>,
-  pub admin: Option<bool>,
   pub show_nsfw: Option<bool>,
   pub theme: Option<String>,
   pub default_sort_type: Option<i16>,
@@ -43,7 +41,6 @@ pub struct LocalUserSettings {
   pub id: LocalUserId,
   pub person_id: PersonId,
   pub email: Option<String>,
-  pub admin: bool,
   pub show_nsfw: bool,
   pub theme: String,
   pub default_sort_type: i16,
diff --git a/crates/db_schema/src/source/person.rs b/crates/db_schema/src/source/person.rs
index f5f10ac4..2c0e7e8b 100644
--- a/crates/db_schema/src/source/person.rs
+++ b/crates/db_schema/src/source/person.rs
@@ -26,6 +26,7 @@ pub struct Person {
   pub inbox_url: DbUrl,
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
+  pub admin: bool,
 }
 
 /// A safe representation of person, without the sensitive info
@@ -47,6 +48,7 @@ pub struct PersonSafe {
   pub inbox_url: DbUrl,
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
+  pub admin: bool,
 }
 
 #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
@@ -70,6 +72,7 @@ pub struct PersonAlias1 {
   pub inbox_url: DbUrl,
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
+  pub admin: bool,
 }
 
 #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
@@ -90,6 +93,7 @@ pub struct PersonSafeAlias1 {
   pub inbox_url: DbUrl,
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
+  pub admin: bool,
 }
 
 #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
@@ -113,6 +117,7 @@ pub struct PersonAlias2 {
   pub inbox_url: DbUrl,
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
+  pub admin: bool,
 }
 
 #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
@@ -133,6 +138,7 @@ pub struct PersonSafeAlias2 {
   pub inbox_url: DbUrl,
   pub shared_inbox_url: Option<DbUrl>,
   pub matrix_user_id: Option<String>,
+  pub admin: bool,
 }
 
 #[derive(Insertable, AsChangeset, Clone, Default)]
@@ -155,4 +161,5 @@ pub struct PersonForm {
   pub inbox_url: Option<DbUrl>,
   pub shared_inbox_url: Option<Option<DbUrl>>,
   pub matrix_user_id: Option<Option<String>>,
+  pub admin: Option<bool>,
 }
diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs
index e44ddfef..6b13103c 100644
--- a/crates/db_views/src/comment_view.rs
+++ b/crates/db_views/src/comment_view.rs
@@ -526,6 +526,7 @@ mod tests {
         local: true,
         banned: false,
         deleted: false,
+        admin: false,
         bio: None,
         banner: None,
         updated: None,
diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs
index 8e305b48..df67d369 100644
--- a/crates/db_views/src/post_view.rs
+++ b/crates/db_views/src/post_view.rs
@@ -546,6 +546,7 @@ mod tests {
         avatar: None,
         actor_id: inserted_person.actor_id.to_owned(),
         local: true,
+        admin: false,
         banned: false,
         deleted: false,
         bio: None,
diff --git a/crates/db_views_actor/src/person_view.rs b/crates/db_views_actor/src/person_view.rs
index a44a468c..8e292c3f 100644
--- a/crates/db_views_actor/src/person_view.rs
+++ b/crates/db_views_actor/src/person_view.rs
@@ -9,7 +9,7 @@ use lemmy_db_queries::{
   ViewToVec,
 };
 use lemmy_db_schema::{
-  schema::{local_user, person, person_aggregates},
+  schema::{person, person_aggregates},
   source::person::{Person, PersonSafe},
   PersonId,
 };
@@ -36,9 +36,8 @@ impl PersonViewSafe {
   pub fn admins(conn: &PgConnection) -> Result<Vec<Self>, Error> {
     let admins = person::table
       .inner_join(person_aggregates::table)
-      .inner_join(local_user::table)
       .select((Person::safe_columns_tuple(), person_aggregates::all_columns))
-      .filter(local_user::admin.eq(true))
+      .filter(person::admin.eq(true))
       .order_by(person::published)
       .load::<PersonViewSafeTuple>(conn)?;
 
diff --git a/migrations/2021-03-20-185321_move_matrix_id_to_person/down.sql b/migrations/2021-03-20-185321_move_matrix_id_to_person/down.sql
index 70cbe9bf..990d8fe9 100644
--- a/migrations/2021-03-20-185321_move_matrix_id_to_person/down.sql
+++ b/migrations/2021-03-20-185321_move_matrix_id_to_person/down.sql
@@ -1,12 +1,16 @@
 alter table local_user add column matrix_user_id text;
+alter table local_user add column admin boolean default false not null;
 
 update local_user lu
-set matrix_user_id = p.matrix_user_id 
+set 
+  matrix_user_id = p.matrix_user_id,
+  admin = p.admin
 from person p
 where p.id = lu.person_id;
 
 drop view person_alias_1, person_alias_2;
 alter table person drop column matrix_user_id;
+alter table person drop column admin;
 
 -- Regenerate the person_alias views
 create view person_alias_1 as select * from person;
diff --git a/migrations/2021-03-20-185321_move_matrix_id_to_person/up.sql b/migrations/2021-03-20-185321_move_matrix_id_to_person/up.sql
index 92f20c6c..d9ba3dd9 100644
--- a/migrations/2021-03-20-185321_move_matrix_id_to_person/up.sql
+++ b/migrations/2021-03-20-185321_move_matrix_id_to_person/up.sql
@@ -1,11 +1,15 @@
 alter table person add column matrix_user_id text;
+alter table person add column admin boolean default false not null;
 
 update person p
-set matrix_user_id = lu.matrix_user_id 
+set 
+  matrix_user_id = lu.matrix_user_id,
+  admin = lu.admin
 from local_user lu
 where p.id = lu.person_id;
 
 alter table local_user drop column matrix_user_id;
+alter table local_user drop column admin;
 
 -- Regenerate the person_alias views
 drop view person_alias_1, person_alias_2;
-- 
2.44.1