diff --git a/crates/api/src/site/admin_allow_instance.rs b/crates/api/src/site/admin_allow_instance.rs index ac1b964b0..8cb29a245 100644 --- a/crates/api/src/site/admin_allow_instance.rs +++ b/crates/api/src/site/admin_allow_instance.rs @@ -8,8 +8,9 @@ use lemmy_api_common::{ SuccessResponse, }; use lemmy_db_schema::source::{ - federation_allowlist::{AdminAllowInstance, AdminAllowInstanceForm}, + federation_allowlist::{FederationAllowList, FederationAllowListForm}, instance::Instance, + mod_log::admin::{AdminAllowInstance, AdminAllowInstanceForm}, }; use lemmy_db_views::structs::LocalUserView; use lemmy_utils::error::LemmyResult; @@ -27,17 +28,23 @@ pub async fn admin_allow_instance( Err(LemmyErrorType::CannotCombineFederationBlocklistAndAllowlist)?; } - let instance_block_form = AdminAllowInstanceForm { + let form = FederationAllowListForm { + instance_id: data.instance_id, + updated: None, + }; + if data.allow { + FederationAllowList::allow(&mut context.pool(), &form).await?; + } else { + FederationAllowList::unallow(&mut context.pool(), data.instance_id).await?; + } + + let mod_log_form = AdminAllowInstanceForm { instance_id: data.instance_id, admin_person_id: local_user_view.person.id, reason: data.reason.clone(), + allowed: data.allow, }; - - if data.allow { - AdminAllowInstance::allow(&mut context.pool(), &instance_block_form).await?; - } else { - AdminAllowInstance::unallow(&mut context.pool(), data.instance_id).await?; - } + AdminAllowInstance::insert(&mut context.pool(), &mod_log_form).await?; Ok(Json(SuccessResponse::default())) } diff --git a/crates/api/src/site/admin_block_instance.rs b/crates/api/src/site/admin_block_instance.rs index 087b7f55e..6082f7534 100644 --- a/crates/api/src/site/admin_block_instance.rs +++ b/crates/api/src/site/admin_block_instance.rs @@ -8,8 +8,9 @@ use lemmy_api_common::{ SuccessResponse, }; use lemmy_db_schema::source::{ - federation_blocklist::{AdminBlockInstance, AdminBlockInstanceForm}, + federation_blocklist::{FederationBlockList, FederationBlockListForm}, instance::Instance, + mod_log::admin::{AdminBlockInstance, AdminBlockInstanceForm}, }; use lemmy_db_views::structs::LocalUserView; use lemmy_utils::error::LemmyResult; @@ -27,18 +28,26 @@ pub async fn admin_block_instance( Err(LemmyErrorType::CannotCombineFederationBlocklistAndAllowlist)?; } - let instance_block_form = AdminBlockInstanceForm { + let form = FederationBlockListForm { instance_id: data.instance_id, - admin_person_id: local_user_view.person.id, - reason: data.reason.clone(), expires: data.expires, + updated: None, }; if data.block { - AdminBlockInstance::block(&mut context.pool(), &instance_block_form).await?; + FederationBlockList::block(&mut context.pool(), &form).await?; } else { - AdminBlockInstance::unblock(&mut context.pool(), data.instance_id).await?; + FederationBlockList::unblock(&mut context.pool(), data.instance_id).await?; } + let mod_log_form = AdminBlockInstanceForm { + instance_id: data.instance_id, + admin_person_id: local_user_view.person.id, + blocked: data.block, + reason: data.reason.clone(), + expires: data.expires, + }; + AdminBlockInstance::insert(&mut context.pool(), &mod_log_form).await?; + Ok(Json(SuccessResponse::default())) } diff --git a/crates/db_schema/src/impls/federation_allowlist.rs b/crates/db_schema/src/impls/federation_allowlist.rs index 1c3c98264..fdbeb001a 100644 --- a/crates/db_schema/src/impls/federation_allowlist.rs +++ b/crates/db_schema/src/impls/federation_allowlist.rs @@ -1,10 +1,9 @@ use crate::{ newtypes::InstanceId, schema::{admin_allow_instance, federation_allowlist}, - source::federation_allowlist::{ - AdminAllowInstance, - AdminAllowInstanceForm, - FederationAllowListForm, + source::{ + federation_allowlist::{FederationAllowList, FederationAllowListForm}, + mod_log::admin::{AdminAllowInstance, AdminAllowInstanceForm}, }, utils::{get_conn, DbPool}, }; @@ -12,29 +11,25 @@ use diesel::{delete, dsl::insert_into, result::Error, ExpressionMethods, QueryDs use diesel_async::RunQueryDsl; impl AdminAllowInstance { - pub async fn allow(pool: &mut DbPool<'_>, form: &AdminAllowInstanceForm) -> Result<(), Error> { + pub async fn insert(pool: &mut DbPool<'_>, form: &AdminAllowInstanceForm) -> Result<(), Error> { let conn = &mut get_conn(pool).await?; - conn - .build_transaction() - .run(|conn| { - Box::pin(async move { - insert_into(admin_allow_instance::table) - .values(form) - .execute(conn) - .await?; + insert_into(admin_allow_instance::table) + .values(form) + .execute(conn) + .await?; - let form2 = FederationAllowListForm { - instance_id: form.instance_id, - updated: None, - }; - insert_into(federation_allowlist::table) - .values(form2) - .execute(conn) - .await?; - Ok(()) - }) - }) - .await + Ok(()) + } +} + +impl FederationAllowList { + pub async fn allow(pool: &mut DbPool<'_>, form: &FederationAllowListForm) -> Result<(), Error> { + let conn = &mut get_conn(pool).await?; + insert_into(federation_allowlist::table) + .values(form) + .execute(conn) + .await?; + Ok(()) } pub async fn unallow(pool: &mut DbPool<'_>, instance_id_: InstanceId) -> Result<(), Error> { use federation_allowlist::dsl::instance_id; @@ -50,14 +45,7 @@ impl AdminAllowInstance { mod tests { use super::*; - use crate::{ - source::{ - instance::Instance, - person::{Person, PersonInsertForm}, - }, - traits::Crud, - utils::build_db_pool_for_tests, - }; + use crate::{source::instance::Instance, utils::build_db_pool_for_tests}; use pretty_assertions::assert_eq; use serial_test::serial; @@ -72,19 +60,16 @@ mod tests { Instance::read_or_create(pool, "tld2.xyz".to_string()).await?, Instance::read_or_create(pool, "tld3.xyz".to_string()).await?, ]; - let new_person_3 = PersonInsertForm::test_form(instances[0].id, "xyz"); - let person = Person::create(pool, &new_person_3).await?; let forms: Vec<_> = instances .iter() - .map(|i| AdminAllowInstanceForm { + .map(|i| FederationAllowListForm { instance_id: i.id, - admin_person_id: person.id, - reason: None, + updated: None, }) .collect(); for f in &forms { - AdminAllowInstance::allow(pool, f).await?; + FederationAllowList::allow(pool, f).await?; } let allows = Instance::allowlist(pool).await?; @@ -94,7 +79,7 @@ mod tests { // Now test clearing them for f in forms { - AdminAllowInstance::unallow(pool, f.instance_id).await?; + FederationAllowList::unallow(pool, f.instance_id).await?; } let allows = Instance::allowlist(pool).await?; assert_eq!(0, allows.len()); diff --git a/crates/db_schema/src/impls/federation_blocklist.rs b/crates/db_schema/src/impls/federation_blocklist.rs index f05639d9c..4a42e81b6 100644 --- a/crates/db_schema/src/impls/federation_blocklist.rs +++ b/crates/db_schema/src/impls/federation_blocklist.rs @@ -1,10 +1,9 @@ use crate::{ newtypes::InstanceId, schema::{admin_block_instance, federation_blocklist}, - source::federation_blocklist::{ - AdminBlockInstance, - AdminBlockInstanceForm, - FederationBlockListForm, + source::{ + federation_blocklist::{FederationBlockList, FederationBlockListForm}, + mod_log::admin::{AdminBlockInstance, AdminBlockInstanceForm}, }, utils::{get_conn, DbPool}, }; @@ -12,38 +11,32 @@ use diesel::{delete, dsl::insert_into, result::Error, ExpressionMethods, QueryDs use diesel_async::RunQueryDsl; impl AdminBlockInstance { - pub async fn block(pool: &mut DbPool<'_>, form: &AdminBlockInstanceForm) -> Result<(), Error> { + pub async fn insert(pool: &mut DbPool<'_>, form: &AdminBlockInstanceForm) -> Result<(), Error> { let conn = &mut get_conn(pool).await?; - conn - .build_transaction() - .run(|conn| { - Box::pin(async move { - insert_into(admin_block_instance::table) - .values(form) - .execute(conn) - .await?; + insert_into(admin_block_instance::table) + .values(form) + .execute(conn) + .await?; - let form2 = FederationBlockListForm { - instance_id: form.instance_id, - updated: None, - expires: form.expires, - }; - insert_into(federation_blocklist::table) - .values(form2) - .execute(conn) - .await?; - Ok(()) - }) - }) - .await - } - pub async fn unblock(pool: &mut DbPool<'_>, instance_id: InstanceId) -> Result<(), Error> { - let conn = &mut get_conn(pool).await?; - delete( - federation_blocklist::table.filter(federation_blocklist::dsl::instance_id.eq(instance_id)), - ) - .execute(conn) - .await?; + Ok(()) + } +} + +impl FederationBlockList { + pub async fn block(pool: &mut DbPool<'_>, form: &FederationBlockListForm) -> Result<(), Error> { + let conn = &mut get_conn(pool).await?; + insert_into(federation_blocklist::table) + .values(form) + .execute(conn) + .await?; + Ok(()) + } + pub async fn unblock(pool: &mut DbPool<'_>, instance_id_: InstanceId) -> Result<(), Error> { + use federation_blocklist::dsl::instance_id; + let conn = &mut get_conn(pool).await?; + delete(federation_blocklist::table.filter(instance_id.eq(instance_id_))) + .execute(conn) + .await?; Ok(()) } } diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs index 1ed8e3075..1b98937ea 100644 --- a/crates/db_schema/src/schema.rs +++ b/crates/db_schema/src/schema.rs @@ -47,6 +47,7 @@ diesel::table! { id -> Int4, instance_id -> Int4, admin_person_id -> Int4, + allowed -> Bool, reason -> Nullable, published -> Timestamptz, } @@ -57,6 +58,7 @@ diesel::table! { id -> Int4, instance_id -> Int4, admin_person_id -> Int4, + blocked -> Bool, reason -> Nullable, expires -> Nullable, published -> Timestamptz, diff --git a/crates/db_schema/src/source/federation_allowlist.rs b/crates/db_schema/src/source/federation_allowlist.rs index 56afea4b4..cc66bcad8 100644 --- a/crates/db_schema/src/source/federation_allowlist.rs +++ b/crates/db_schema/src/source/federation_allowlist.rs @@ -1,12 +1,9 @@ -use crate::newtypes::{InstanceId, PersonId}; +use crate::newtypes::InstanceId; +#[cfg(feature = "full")] +use crate::schema::federation_allowlist; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::fmt::Debug; -#[cfg(feature = "full")] -use { - crate::schema::{admin_allow_instance, federation_allowlist}, - ts_rs::TS, -}; #[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] #[cfg_attr( @@ -29,38 +26,7 @@ pub struct FederationAllowList { #[derive(Clone, Default)] #[cfg_attr(feature = "full", derive(Insertable, AsChangeset))] #[cfg_attr(feature = "full", diesel(table_name = federation_allowlist))] -pub(crate) struct FederationAllowListForm { +pub struct FederationAllowListForm { pub instance_id: InstanceId, pub updated: Option>, } - -#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] -#[cfg_attr( - feature = "full", - derive(TS, Queryable, Selectable, Associations, Identifiable) -)] -#[cfg_attr( - feature = "full", - diesel(belongs_to(crate::source::instance::Instance)) -)] -#[cfg_attr(feature = "full", diesel(table_name = admin_allow_instance))] -#[cfg_attr(feature = "full", diesel(primary_key(instance_id)))] -#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))] -#[cfg_attr(feature = "full", ts(export))] -pub struct AdminAllowInstance { - pub id: i32, - pub instance_id: InstanceId, - pub admin_person_id: PersonId, - #[cfg_attr(feature = "full", ts(optional))] - pub reason: Option, - pub published: DateTime, -} - -#[derive(Clone, Default)] -#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))] -#[cfg_attr(feature = "full", diesel(table_name = admin_allow_instance))] -pub struct AdminAllowInstanceForm { - pub instance_id: InstanceId, - pub admin_person_id: PersonId, - pub reason: Option, -} diff --git a/crates/db_schema/src/source/federation_blocklist.rs b/crates/db_schema/src/source/federation_blocklist.rs index 79567662f..df877facf 100644 --- a/crates/db_schema/src/source/federation_blocklist.rs +++ b/crates/db_schema/src/source/federation_blocklist.rs @@ -1,12 +1,9 @@ -use crate::newtypes::{InstanceId, PersonId}; +use crate::newtypes::InstanceId; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::fmt::Debug; #[cfg(feature = "full")] -use { - crate::schema::{admin_block_instance, federation_blocklist}, - ts_rs::TS, -}; +use {crate::schema::federation_blocklist, ts_rs::TS}; #[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] #[cfg_attr( @@ -33,42 +30,8 @@ pub struct FederationBlockList { #[derive(Clone, Default)] #[cfg_attr(feature = "full", derive(Insertable, AsChangeset))] #[cfg_attr(feature = "full", diesel(table_name = federation_blocklist))] -pub(crate) struct FederationBlockListForm { +pub struct FederationBlockListForm { pub instance_id: InstanceId, pub updated: Option>, pub expires: Option>, } - -#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] -#[cfg_attr( - feature = "full", - derive(TS, Queryable, Selectable, Associations, Identifiable) -)] -#[cfg_attr( - feature = "full", - diesel(belongs_to(crate::source::instance::Instance)) -)] -#[cfg_attr(feature = "full", diesel(table_name = admin_block_instance))] -#[cfg_attr(feature = "full", diesel(primary_key(instance_id)))] -#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))] -#[cfg_attr(feature = "full", ts(export))] -pub struct AdminBlockInstance { - pub id: i32, - pub instance_id: InstanceId, - pub admin_person_id: PersonId, - #[cfg_attr(feature = "full", ts(optional))] - pub reason: Option, - #[cfg_attr(feature = "full", ts(optional))] - pub expires: Option>, - pub published: DateTime, -} - -#[derive(Clone, Default)] -#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))] -#[cfg_attr(feature = "full", diesel(table_name = admin_block_instance))] -pub struct AdminBlockInstanceForm { - pub instance_id: InstanceId, - pub admin_person_id: PersonId, - pub reason: Option, - pub expires: Option>, -} diff --git a/crates/db_schema/src/source/mod_log/admin.rs b/crates/db_schema/src/source/mod_log/admin.rs index 0e95edccd..3fd397441 100644 --- a/crates/db_schema/src/source/mod_log/admin.rs +++ b/crates/db_schema/src/source/mod_log/admin.rs @@ -1,6 +1,8 @@ -use crate::newtypes::{CommunityId, PersonId, PostId}; +use crate::newtypes::{CommunityId, InstanceId, PersonId, PostId}; #[cfg(feature = "full")] use crate::schema::{ + admin_allow_instance, + admin_block_instance, admin_purge_comment, admin_purge_community, admin_purge_person, @@ -103,3 +105,72 @@ pub struct AdminPurgeCommentForm { pub post_id: PostId, pub reason: Option, } + +#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[cfg_attr( + feature = "full", + derive(TS, Queryable, Selectable, Associations, Identifiable) +)] +#[cfg_attr( + feature = "full", + diesel(belongs_to(crate::source::instance::Instance)) +)] +#[cfg_attr(feature = "full", diesel(table_name = admin_allow_instance))] +#[cfg_attr(feature = "full", diesel(primary_key(instance_id)))] +#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))] +#[cfg_attr(feature = "full", ts(export))] +pub struct AdminAllowInstance { + pub id: i32, + pub instance_id: InstanceId, + pub admin_person_id: PersonId, + pub allowed: bool, + #[cfg_attr(feature = "full", ts(optional))] + pub reason: Option, + pub published: DateTime, +} + +#[derive(Clone, Default)] +#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))] +#[cfg_attr(feature = "full", diesel(table_name = admin_allow_instance))] +pub struct AdminAllowInstanceForm { + pub instance_id: InstanceId, + pub admin_person_id: PersonId, + pub allowed: bool, + pub reason: Option, +} + +#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[cfg_attr( + feature = "full", + derive(TS, Queryable, Selectable, Associations, Identifiable) +)] +#[cfg_attr( + feature = "full", + diesel(belongs_to(crate::source::instance::Instance)) +)] +#[cfg_attr(feature = "full", diesel(table_name = admin_block_instance))] +#[cfg_attr(feature = "full", diesel(primary_key(instance_id)))] +#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))] +#[cfg_attr(feature = "full", ts(export))] +pub struct AdminBlockInstance { + pub id: i32, + pub instance_id: InstanceId, + pub admin_person_id: PersonId, + pub blocked: bool, + #[cfg_attr(feature = "full", ts(optional))] + pub reason: Option, + #[cfg_attr(feature = "full", ts(optional))] + pub expires: Option>, + pub published: DateTime, +} + +#[derive(Clone, Default)] +#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))] +#[cfg_attr(feature = "full", diesel(table_name = admin_block_instance))] +pub struct AdminBlockInstanceForm { + pub instance_id: InstanceId, + pub admin_person_id: PersonId, + pub blocked: bool, + pub reason: Option, + pub expires: Option>, +} diff --git a/crates/db_views_moderator/src/structs.rs b/crates/db_views_moderator/src/structs.rs index a85828bd4..06e9f099a 100644 --- a/crates/db_views_moderator/src/structs.rs +++ b/crates/db_views_moderator/src/structs.rs @@ -5,11 +5,16 @@ use lemmy_db_schema::{ source::{ comment::Comment, community::Community, - federation_allowlist::AdminAllowInstance, - federation_blocklist::AdminBlockInstance, instance::Instance, mod_log::{ - admin::{AdminPurgeComment, AdminPurgeCommunity, AdminPurgePerson, AdminPurgePost}, + admin::{ + AdminAllowInstance, + AdminBlockInstance, + AdminPurgeComment, + AdminPurgeCommunity, + AdminPurgePerson, + AdminPurgePost, + }, moderator::{ ModAdd, ModAddCommunity, diff --git a/crates/federate/src/lib.rs b/crates/federate/src/lib.rs index eed13d36b..dbb92949e 100644 --- a/crates/federate/src/lib.rs +++ b/crates/federate/src/lib.rs @@ -201,8 +201,8 @@ mod test { use chrono::DateTime; use lemmy_db_schema::{ source::{ - federation_allowlist::{AdminAllowInstance, AdminAllowInstanceForm}, - federation_blocklist::{AdminBlockInstance, AdminBlockInstanceForm}, + federation_allowlist::{FederationAllowList, FederationAllowListForm}, + federation_blocklist::{FederationBlockList, FederationBlockListForm}, instance::InstanceForm, person::{Person, PersonInsertForm}, }, @@ -325,13 +325,12 @@ mod test { let instance_id = data.instances[0].id; let form = PersonInsertForm::new("tim".to_string(), String::new(), instance_id); let person = Person::create(&mut data.context.pool(), &form).await?; - let form = AdminBlockInstanceForm { + let form = FederationBlockListForm { instance_id, - admin_person_id: person.id, - reason: None, + updated: None, expires: None, }; - AdminBlockInstance::block(&mut data.context.pool(), &form).await?; + FederationBlockList::block(&mut data.context.pool(), &form).await?; data.run().await?; let workers = &data.send_manager.workers; assert_eq!(2, workers.len()); @@ -352,12 +351,11 @@ mod test { let instance_id = data.instances[0].id; let form = PersonInsertForm::new("tim".to_string(), String::new(), instance_id); let person = Person::create(&mut data.context.pool(), &form).await?; - let form = AdminAllowInstanceForm { + let form = FederationAllowListForm { instance_id: data.instances[0].id, - admin_person_id: person.id, - reason: None, + updated: None, }; - AdminAllowInstance::allow(&mut data.context.pool(), &form).await?; + FederationAllowList::allow(&mut data.context.pool(), &form).await?; data.run().await?; let workers = &data.send_manager.workers; assert_eq!(1, workers.len()); diff --git a/migrations/2024-11-19-142005_instance-block-mod-log/up.sql b/migrations/2024-11-19-142005_instance-block-mod-log/up.sql index e02312547..9cb9fa021 100644 --- a/migrations/2024-11-19-142005_instance-block-mod-log/up.sql +++ b/migrations/2024-11-19-142005_instance-block-mod-log/up.sql @@ -5,6 +5,7 @@ CREATE TABLE admin_block_instance ( id serial PRIMARY KEY, instance_id int NOT NULL REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE, admin_person_id int NOT NULL REFERENCES person (id) ON UPDATE CASCADE ON DELETE CASCADE, + blocked bool not null, reason text, expires timestamptz, published timestamptz NOT NULL DEFAULT now() @@ -14,6 +15,7 @@ CREATE TABLE admin_allow_instance ( id serial PRIMARY KEY, instance_id int NOT NULL REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE, admin_person_id int NOT NULL REFERENCES person (id) ON UPDATE CASCADE ON DELETE CASCADE, + allowed bool not null, reason text, published timestamptz NOT NULL DEFAULT now() );