diff --git a/crates/api/src/community.rs b/crates/api/src/community.rs index f1cf570c0..3e6ae3e47 100644 --- a/crates/api/src/community.rs +++ b/crates/api/src/community.rs @@ -10,11 +10,7 @@ use lemmy_api_common::{ }; use lemmy_apub::{ActorType, CommunityType, UserType}; use lemmy_db_queries::{ - source::{ - comment::Comment_, - community::{CommunityModerator_, Community_}, - post::Post_, - }, + source::{comment::Comment_, community::CommunityModerator_, post::Post_}, Bannable, Crud, Followable, @@ -324,12 +320,6 @@ impl Perform for TransferCommunity { let data: &TransferCommunity = &self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?; - let community_id = data.community_id; - let read_community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; - let site_creator_id = blocking(context.pool(), move |conn| { Site::read(conn, 1).map(|s| s.creator_id) }) @@ -337,7 +327,7 @@ impl Perform for TransferCommunity { let mut admins = blocking(context.pool(), move |conn| PersonViewSafe::admins(conn)).await??; - // Making sure the creator, if an admin, is at the top + // Making sure the site creator, if an admin, is at the top let creator_index = admins .iter() .position(|r| r.person.id == site_creator_id) @@ -345,8 +335,15 @@ impl Perform for TransferCommunity { let creator_person = admins.remove(creator_index); admins.insert(0, creator_person); - // Make sure user is the creator, or an admin - if local_user_view.person.id != read_community.creator_id + // Fetch the community mods + let community_id = data.community_id; + let mut community_mods = blocking(context.pool(), move |conn| { + CommunityModeratorView::for_community(conn, community_id) + }) + .await??; + + // Make sure transferrer is either the top community mod, or an admin + if local_user_view.person.id != community_mods[0].moderator.id && !admins .iter() .map(|a| a.person.id) @@ -355,19 +352,8 @@ impl Perform for TransferCommunity { return Err(ApiError::err("not_an_admin").into()); } - let community_id = data.community_id; - let new_creator = data.person_id; - let update = move |conn: &'_ _| Community::update_creator(conn, community_id, new_creator); - if blocking(context.pool(), update).await?.is_err() { - return Err(ApiError::err("couldnt_update_community").into()); - }; - - // You also have to re-do the community_moderator table, reordering it. - let community_id = data.community_id; - let mut community_mods = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - }) - .await??; + // You have to re-do the community_moderator table, reordering it. + // Add the transferee to the top let creator_index = community_mods .iter() .position(|r| r.moderator.id == data.person_id) @@ -375,6 +361,7 @@ impl Perform for TransferCommunity { let creator_person = community_mods.remove(creator_index); community_mods.insert(0, creator_person); + // Delete all the mods let community_id = data.community_id; blocking(context.pool(), move |conn| { CommunityModerator::delete_for_community(conn, community_id) @@ -382,6 +369,7 @@ impl Perform for TransferCommunity { .await??; // TODO: this should probably be a bulk operation + // Re-add the mods, in the new order for cmod in &community_mods { let community_moderator_form = CommunityModeratorForm { community_id: cmod.community.id, @@ -395,6 +383,8 @@ impl Perform for TransferCommunity { } // Mod tables + // TODO there should probably be another table for transfer community + // Right now, it will just look like it modded them twice let form = ModAddCommunityForm { mod_person_id: local_user_view.person.id, other_person_id: data.person_id, diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs index 656ddf971..31e4f94e4 100644 --- a/crates/api/src/local_user.rs +++ b/crates/api/src/local_user.rs @@ -18,7 +18,6 @@ use lemmy_db_queries::{ diesel_option_overwrite_to_url, source::{ comment::Comment_, - community::Community_, local_user::LocalUser_, password_reset_request::PasswordResetRequest_, person::Person_, @@ -33,7 +32,6 @@ use lemmy_db_schema::{ naive_now, source::{ comment::Comment, - community::*, local_user::{LocalUser, LocalUserForm}, moderator::*, password_reset_request::*, @@ -394,10 +392,9 @@ impl Perform for BanPerson { .await??; // Communities - blocking(context.pool(), move |conn: &'_ _| { - Community::update_removed_for_creator(conn, banned_person_id, true) - }) - .await??; + // Remove all communities where they're the top mod + // TODO couldn't get group by's working in diesel, + // for now, remove the communities manually // Comments blocking(context.pool(), move |conn: &'_ _| { diff --git a/crates/api_crud/src/community/create.rs b/crates/api_crud/src/community/create.rs index bef376f0b..393b3746a 100644 --- a/crates/api_crud/src/community/create.rs +++ b/crates/api_crud/src/community/create.rs @@ -75,7 +75,6 @@ impl PerformCrud for CreateCommunity { description: data.description.to_owned(), icon, banner, - creator_id: local_user_view.person.id, nsfw: data.nsfw, actor_id: Some(community_actor_id.to_owned()), private_key: Some(keypair.private_key), diff --git a/crates/api_crud/src/community/delete.rs b/crates/api_crud/src/community/delete.rs index 9b52660f6..b94c153b2 100644 --- a/crates/api_crud/src/community/delete.rs +++ b/crates/api_crud/src/community/delete.rs @@ -7,7 +7,10 @@ use lemmy_db_schema::source::{ community::*, moderator::{ModRemoveCommunity, ModRemoveCommunityForm}, }; -use lemmy_db_views_actor::community_view::CommunityView; +use lemmy_db_views_actor::{ + community_moderator_view::CommunityModeratorView, + community_view::CommunityView, +}; use lemmy_utils::{utils::naive_from_unix, ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{LemmyContext, UserOperationCrud}; @@ -23,13 +26,15 @@ impl PerformCrud for DeleteCommunity { let data: &DeleteCommunity = &self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?; - // Verify its the creator (only a creator can delete the community) + // Fetch the community mods let community_id = data.community_id; - let read_community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) + let community_mods = blocking(context.pool(), move |conn| { + CommunityModeratorView::for_community(conn, community_id) }) .await??; - if read_community.creator_id != local_user_view.person.id { + + // Make sure deleter is the top mod + if local_user_view.person.id != community_mods[0].moderator.id { return Err(ApiError::err("no_community_edit_allowed").into()); } diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index 0a0540fa7..9e8339fbe 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -61,7 +61,6 @@ impl PerformCrud for EditCommunity { let community_form = CommunityForm { name: read_community.name, title: data.title.to_owned(), - creator_id: read_community.creator_id, description: data.description.to_owned(), icon, banner, diff --git a/crates/api_crud/src/user/create.rs b/crates/api_crud/src/user/create.rs index 63a6474d6..0da10ffa3 100644 --- a/crates/api_crud/src/user/create.rs +++ b/crates/api_crud/src/user/create.rs @@ -177,7 +177,6 @@ impl PerformCrud for Register { name: default_community_name.to_string(), title: "The Default Community".to_string(), description: Some("The Default Community".to_string()), - creator_id: inserted_person.id, actor_id: Some(actor_id.to_owned()), private_key: Some(main_community_keypair.private_key), public_key: Some(main_community_keypair.public_key), diff --git a/crates/apub/src/objects/community.rs b/crates/apub/src/objects/community.rs index acf1f045c..f886fd1b0 100644 --- a/crates/apub/src/objects/community.rs +++ b/crates/apub/src/objects/community.rs @@ -1,6 +1,6 @@ use crate::{ extensions::{context::lemmy_context, group_extension::GroupExtension}, - fetcher::{community::fetch_community_mods, person::get_or_fetch_and_upsert_person}, + fetcher::community::fetch_community_mods, generate_moderators_url, objects::{ check_object_domain, @@ -140,24 +140,7 @@ impl FromApubToForm for CommunityForm { request_counter: &mut i32, _mod_action_allowed: bool, ) -> Result { - let moderator_uris = fetch_community_mods(context, group, request_counter).await?; - let creator = if let Some(creator_uri) = moderator_uris.first() { - get_or_fetch_and_upsert_person(creator_uri, context, request_counter) - } else { - // NOTE: code for compatibility with lemmy v0.9.9 - let creator_uri = group - .inner - .attributed_to() - .map(|a| a.as_many()) - .flatten() - .map(|a| a.first()) - .flatten() - .map(|a| a.as_xsd_any_uri()) - .flatten() - .context(location_info!())?; - get_or_fetch_and_upsert_person(creator_uri, context, request_counter) - } - .await?; + fetch_community_mods(context, group, request_counter).await?; let name = group .inner @@ -215,7 +198,6 @@ impl FromApubToForm for CommunityForm { name, title, description, - creator_id: creator.id, removed: None, published: group.inner.published().map(|u| u.to_owned().naive_local()), updated: group.inner.updated().map(|u| u.to_owned().naive_local()), diff --git a/crates/db_queries/src/aggregates/comment_aggregates.rs b/crates/db_queries/src/aggregates/comment_aggregates.rs index a2bea11ef..412f2e0a2 100644 --- a/crates/db_queries/src/aggregates/comment_aggregates.rs +++ b/crates/db_queries/src/aggregates/comment_aggregates.rs @@ -58,7 +58,6 @@ mod tests { let new_community = CommunityForm { name: "TIL_comment_agg".into(), - creator_id: inserted_person.id, title: "nada".to_owned(), ..CommunityForm::default() }; diff --git a/crates/db_queries/src/aggregates/community_aggregates.rs b/crates/db_queries/src/aggregates/community_aggregates.rs index 25c0b394e..a70412660 100644 --- a/crates/db_queries/src/aggregates/community_aggregates.rs +++ b/crates/db_queries/src/aggregates/community_aggregates.rs @@ -62,7 +62,6 @@ mod tests { let new_community = CommunityForm { name: "TIL_community_agg".into(), - creator_id: inserted_person.id, title: "nada".to_owned(), ..CommunityForm::default() }; @@ -71,7 +70,6 @@ mod tests { let another_community = CommunityForm { name: "TIL_community_agg_2".into(), - creator_id: inserted_person.id, title: "nada".to_owned(), ..CommunityForm::default() }; diff --git a/crates/db_queries/src/aggregates/person_aggregates.rs b/crates/db_queries/src/aggregates/person_aggregates.rs index 953f74ee7..99dcae9a1 100644 --- a/crates/db_queries/src/aggregates/person_aggregates.rs +++ b/crates/db_queries/src/aggregates/person_aggregates.rs @@ -58,7 +58,6 @@ mod tests { let new_community = CommunityForm { name: "TIL_site_agg".into(), - creator_id: inserted_person.id, title: "nada".to_owned(), ..CommunityForm::default() }; diff --git a/crates/db_queries/src/aggregates/post_aggregates.rs b/crates/db_queries/src/aggregates/post_aggregates.rs index fe7381316..de39e3029 100644 --- a/crates/db_queries/src/aggregates/post_aggregates.rs +++ b/crates/db_queries/src/aggregates/post_aggregates.rs @@ -62,7 +62,6 @@ mod tests { let new_community = CommunityForm { name: "TIL_community_agg".into(), - creator_id: inserted_person.id, title: "nada".to_owned(), ..CommunityForm::default() }; diff --git a/crates/db_queries/src/aggregates/site_aggregates.rs b/crates/db_queries/src/aggregates/site_aggregates.rs index 64fbdf7df..32c931c85 100644 --- a/crates/db_queries/src/aggregates/site_aggregates.rs +++ b/crates/db_queries/src/aggregates/site_aggregates.rs @@ -63,7 +63,6 @@ mod tests { let new_community = CommunityForm { name: "TIL_site_agg".into(), - creator_id: inserted_person.id, title: "nada".to_owned(), ..CommunityForm::default() }; diff --git a/crates/db_queries/src/source/comment.rs b/crates/db_queries/src/source/comment.rs index 8d77626aa..1eec0c987 100644 --- a/crates/db_queries/src/source/comment.rs +++ b/crates/db_queries/src/source/comment.rs @@ -254,7 +254,6 @@ mod tests { let new_community = CommunityForm { name: "test community".to_string(), title: "nada".to_owned(), - creator_id: inserted_person.id, ..CommunityForm::default() }; diff --git a/crates/db_queries/src/source/community.rs b/crates/db_queries/src/source/community.rs index 1970eef88..3f1f04767 100644 --- a/crates/db_queries/src/source/community.rs +++ b/crates/db_queries/src/source/community.rs @@ -26,7 +26,6 @@ mod safe_type { name, title, description, - creator_id, removed, published, updated, @@ -46,7 +45,6 @@ mod safe_type { name, title, description, - creator_id, removed, published, updated, @@ -122,16 +120,6 @@ pub trait Community_ { community_id: CommunityId, new_removed: bool, ) -> Result; - fn update_removed_for_creator( - conn: &PgConnection, - for_creator_id: PersonId, - new_removed: bool, - ) -> Result, Error>; - fn update_creator( - conn: &PgConnection, - community_id: CommunityId, - new_creator_id: PersonId, - ) -> Result; fn distinct_federated_communities(conn: &PgConnection) -> Result, Error>; fn read_from_followers_url( conn: &PgConnection, @@ -170,28 +158,6 @@ impl Community_ for Community { .get_result::(conn) } - fn update_removed_for_creator( - conn: &PgConnection, - for_creator_id: PersonId, - new_removed: bool, - ) -> Result, Error> { - use lemmy_db_schema::schema::community::dsl::*; - diesel::update(community.filter(creator_id.eq(for_creator_id))) - .set((removed.eq(new_removed), updated.eq(naive_now()))) - .get_results::(conn) - } - - fn update_creator( - conn: &PgConnection, - community_id: CommunityId, - new_creator_id: PersonId, - ) -> Result { - use lemmy_db_schema::schema::community::dsl::*; - diesel::update(community.find(community_id)) - .set((creator_id.eq(new_creator_id), updated.eq(naive_now()))) - .get_result::(conn) - } - fn distinct_federated_communities(conn: &PgConnection) -> Result, Error> { use lemmy_db_schema::schema::community::dsl::*; community.select(actor_id).distinct().load::(conn) @@ -363,7 +329,6 @@ mod tests { let new_community = CommunityForm { name: "TIL".into(), - creator_id: inserted_person.id, title: "nada".to_owned(), ..CommunityForm::default() }; @@ -372,7 +337,6 @@ mod tests { let expected_community = Community { id: inserted_community.id, - creator_id: inserted_person.id, name: "TIL".into(), title: "nada".to_owned(), description: None, diff --git a/crates/db_queries/src/source/moderator.rs b/crates/db_queries/src/source/moderator.rs index c641fffc7..238ad13be 100644 --- a/crates/db_queries/src/source/moderator.rs +++ b/crates/db_queries/src/source/moderator.rs @@ -224,7 +224,6 @@ mod tests { let new_community = CommunityForm { name: "mod_community".to_string(), title: "nada".to_owned(), - creator_id: inserted_person.id, ..CommunityForm::default() }; @@ -232,7 +231,6 @@ mod tests { let new_post = PostForm { name: "A test post thweep".into(), - creator_id: inserted_person.id, community_id: inserted_community.id, ..PostForm::default() }; diff --git a/crates/db_queries/src/source/person_mention.rs b/crates/db_queries/src/source/person_mention.rs index 5a3a7ea61..2dee6c6e9 100644 --- a/crates/db_queries/src/source/person_mention.rs +++ b/crates/db_queries/src/source/person_mention.rs @@ -105,7 +105,6 @@ mod tests { let new_community = CommunityForm { name: "test community lake".to_string(), title: "nada".to_owned(), - creator_id: inserted_person.id, ..CommunityForm::default() }; @@ -113,7 +112,6 @@ mod tests { let new_post = PostForm { name: "A test post".into(), - creator_id: inserted_person.id, community_id: inserted_community.id, ..PostForm::default() }; diff --git a/crates/db_queries/src/source/post.rs b/crates/db_queries/src/source/post.rs index 169ca18ef..0205dc954 100644 --- a/crates/db_queries/src/source/post.rs +++ b/crates/db_queries/src/source/post.rs @@ -281,7 +281,6 @@ mod tests { let new_community = CommunityForm { name: "test community_3".to_string(), title: "nada".to_owned(), - creator_id: inserted_person.id, ..CommunityForm::default() }; diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs index 5bc55f529..9487da195 100644 --- a/crates/db_schema/src/schema.rs +++ b/crates/db_schema/src/schema.rs @@ -78,7 +78,6 @@ table! { name -> Varchar, title -> Varchar, description -> Nullable, - creator_id -> Int4, removed -> Bool, published -> Timestamp, updated -> Nullable, @@ -532,7 +531,6 @@ joinable!(comment_like -> post (post_id)); joinable!(comment_report -> comment (comment_id)); joinable!(comment_saved -> comment (comment_id)); joinable!(comment_saved -> person (person_id)); -joinable!(community -> person (creator_id)); joinable!(community_aggregates -> community (community_id)); joinable!(community_follower -> community (community_id)); joinable!(community_follower -> person (person_id)); diff --git a/crates/db_schema/src/source/community.rs b/crates/db_schema/src/source/community.rs index 427510270..1581933f0 100644 --- a/crates/db_schema/src/source/community.rs +++ b/crates/db_schema/src/source/community.rs @@ -13,7 +13,6 @@ pub struct Community { pub name: String, pub title: String, pub description: Option, - pub creator_id: PersonId, pub removed: bool, pub published: chrono::NaiveDateTime, pub updated: Option, @@ -39,7 +38,6 @@ pub struct CommunitySafe { pub name: String, pub title: String, pub description: Option, - pub creator_id: PersonId, pub removed: bool, pub published: chrono::NaiveDateTime, pub updated: Option, @@ -57,7 +55,6 @@ pub struct CommunityForm { pub name: String, pub title: String, pub description: Option, - pub creator_id: PersonId, pub removed: Option, pub published: Option, pub updated: Option, diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index 6b13103c0..8b1dc8a10 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -462,7 +462,6 @@ mod tests { let new_community = CommunityForm { name: "test community 5".to_string(), title: "nada".to_owned(), - creator_id: inserted_person.id, ..CommunityForm::default() }; @@ -567,7 +566,6 @@ mod tests { local: true, title: "nada".to_owned(), description: None, - creator_id: inserted_person.id, updated: None, banner: None, published: inserted_community.published, diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index df67d3693..f003904e0 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -263,7 +263,7 @@ impl<'a> PostQueryBuilder<'a> { community_person_ban::table.on( post::community_id .eq(community_person_ban::community_id) - .and(community_person_ban::person_id.eq(community::creator_id)), + .and(community_person_ban::person_id.eq(post::creator_id)), ), ) .inner_join(post_aggregates::table) @@ -462,7 +462,6 @@ mod tests { let new_community = CommunityForm { name: community_name.to_owned(), title: "nada".to_owned(), - creator_id: inserted_person.id, ..CommunityForm::default() }; @@ -568,7 +567,6 @@ mod tests { local: true, title: "nada".to_owned(), description: None, - creator_id: inserted_person.id, updated: None, banner: None, published: inserted_community.published, diff --git a/crates/db_views_actor/src/community_view.rs b/crates/db_views_actor/src/community_view.rs index fe3a80bb7..e1fac7636 100644 --- a/crates/db_views_actor/src/community_view.rs +++ b/crates/db_views_actor/src/community_view.rs @@ -12,11 +12,8 @@ use lemmy_db_queries::{ ViewToVec, }; use lemmy_db_schema::{ - schema::{community, community_aggregates, community_follower, person}, - source::{ - community::{Community, CommunityFollower, CommunitySafe}, - person::{Person, PersonSafe}, - }, + schema::{community, community_aggregates, community_follower}, + source::community::{Community, CommunityFollower, CommunitySafe}, CommunityId, PersonId, }; @@ -25,14 +22,12 @@ use serde::Serialize; #[derive(Debug, Serialize, Clone)] pub struct CommunityView { pub community: CommunitySafe, - pub creator: PersonSafe, pub subscribed: bool, pub counts: CommunityAggregates, } type CommunityViewTuple = ( CommunitySafe, - PersonSafe, CommunityAggregates, Option, ); @@ -46,9 +41,8 @@ impl CommunityView { // The left join below will return None in this case let person_id_join = my_person_id.unwrap_or(PersonId(-1)); - let (community, creator, counts, follower) = community::table + let (community, counts, follower) = community::table .find(community_id) - .inner_join(person::table) .inner_join(community_aggregates::table) .left_join( community_follower::table.on( @@ -59,7 +53,6 @@ impl CommunityView { ) .select(( Community::safe_columns_tuple(), - Person::safe_columns_tuple(), community_aggregates::all_columns, community_follower::all_columns.nullable(), )) @@ -67,7 +60,6 @@ impl CommunityView { Ok(CommunityView { community, - creator, subscribed: follower.is_some(), counts, }) @@ -165,7 +157,6 @@ impl<'a> CommunityQueryBuilder<'a> { let person_id_join = self.my_person_id.unwrap_or(PersonId(-1)); let mut query = community::table - .inner_join(person::table) .inner_join(community_aggregates::table) .left_join( community_follower::table.on( @@ -176,7 +167,6 @@ impl<'a> CommunityQueryBuilder<'a> { ) .select(( Community::safe_columns_tuple(), - Person::safe_columns_tuple(), community_aggregates::all_columns, community_follower::all_columns.nullable(), )) @@ -236,9 +226,8 @@ impl ViewToVec for CommunityView { .iter() .map(|a| Self { community: a.0.to_owned(), - creator: a.1.to_owned(), - counts: a.2.to_owned(), - subscribed: a.3.is_some(), + counts: a.1.to_owned(), + subscribed: a.2.is_some(), }) .collect::>() } diff --git a/migrations/2021-04-02-021422_remove_community_creator/down.sql b/migrations/2021-04-02-021422_remove_community_creator/down.sql new file mode 100644 index 000000000..d015f252b --- /dev/null +++ b/migrations/2021-04-02-021422_remove_community_creator/down.sql @@ -0,0 +1,24 @@ + +-- Add the column back +alter table community add column creator_id int references person on update cascade on delete cascade; + +-- Recreate the index +create index idx_community_creator on community (creator_id); + +-- Add the data, selecting the highest mod +update community +set creator_id = sub.person_id +from ( + select + cm.community_id, + cm.person_id + from + community_moderator cm + limit 1 +) as sub +where id = sub.community_id; + +-- Set to not null +alter table community alter column creator_id set not null; + + diff --git a/migrations/2021-04-02-021422_remove_community_creator/up.sql b/migrations/2021-04-02-021422_remove_community_creator/up.sql new file mode 100644 index 000000000..c3415c6ab --- /dev/null +++ b/migrations/2021-04-02-021422_remove_community_creator/up.sql @@ -0,0 +1,2 @@ +-- Drop the column +alter table community drop column creator_id; diff --git a/src/code_migrations.rs b/src/code_migrations.rs index 144c39f87..d8563b51b 100644 --- a/src/code_migrations.rs +++ b/src/code_migrations.rs @@ -89,7 +89,6 @@ fn community_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> { name: ccommunity.name.to_owned(), title: ccommunity.title.to_owned(), description: ccommunity.description.to_owned(), - creator_id: ccommunity.creator_id, removed: None, deleted: None, nsfw: None,