mirror of
https://github.com/LemmyNet/lemmy.git
synced 2025-09-02 03:03:57 +00:00
Add ability to block all users of an instance. (#5784)
* Fixing a few optionals. * Fixing note. * Starting to work on instance user blocking. * Finishing up user instance blocking * SQL fmt * fmt. * Fixing search_combined * Fixing API tests. * Fixing api-common imports. * Fixing merge issues. * Update crates/api/api_utils/src/utils.rs Co-authored-by: Nutomic <me@nutomic.com> * Making clearer alias names * Submodules * Submodules 2 * Format * Remove api misc. * Upgrading lemmy js client, fixing merge * Prettier * Fixing merge. * Addressing PR comment. * Fix some stack overflows. * Fixing api tests. * Fixing notification joins. * Adding alias. * Fixing api test files. * Remove some tmp files. * Change back to localhost. * Remove instance_person and instance_communities actions from views. These are only used for internal filtering, blocks and bans anyway. * Removing a few unused joins. * Fix API tests. * Some lints. * Updating js-client * Try fixing test. * Update crates/db_views/site/src/api.rs Co-authored-by: dullbananas <dull.bananas0@gmail.com> * Fixing blocked_instances save_user_settings. --------- Co-authored-by: Nutomic <me@nutomic.com> Co-authored-by: dullbananas <dull.bananas0@gmail.com>
This commit is contained in:
parent
df76935fa7
commit
f1ba2a2dbf
43 changed files with 1811 additions and 1681 deletions
|
@ -22,20 +22,20 @@
|
|||
"api-test-tags": "jest -i tags.spec.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.26.0",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^22.15.14",
|
||||
"@typescript-eslint/eslint-plugin": "^8.32.0",
|
||||
"@typescript-eslint/parser": "^8.32.0",
|
||||
"eslint": "^9.26.0",
|
||||
"eslint-plugin-prettier": "^5.4.0",
|
||||
"jest": "^29.5.0",
|
||||
"@eslint/js": "^9.29.0",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/node": "^24.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^8.34.1",
|
||||
"@typescript-eslint/parser": "^8.34.1",
|
||||
"eslint": "^9.29.0",
|
||||
"eslint-plugin-prettier": "^5.5.0",
|
||||
"jest": "^30.0.0",
|
||||
"joi": "^17.13.3",
|
||||
"lemmy-js-client": "1.0.0-post-tags.3",
|
||||
"lemmy-js-client": "1.0.0-instance-user-blocking.8",
|
||||
"prettier": "^3.5.3",
|
||||
"ts-jest": "^29.3.2",
|
||||
"ts-jest": "^29.4.0",
|
||||
"tsoa": "^6.6.0",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.32.0"
|
||||
"typescript-eslint": "^8.34.1"
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
2
api_tests/pnpm-workspace.yaml
Normal file
2
api_tests/pnpm-workspace.yaml
Normal file
|
@ -0,0 +1,2 @@
|
|||
onlyBuiltDependencies:
|
||||
- unrs-resolver
|
|
@ -30,7 +30,7 @@ import {
|
|||
editCommunity,
|
||||
unfollows,
|
||||
getMyUser,
|
||||
userBlockInstance,
|
||||
userBlockInstanceCommunities,
|
||||
resolveBetaCommunity,
|
||||
reportCommunity,
|
||||
randomString,
|
||||
|
@ -41,7 +41,6 @@ import { AdminAllowInstanceParams } from "lemmy-js-client/dist/types/AdminAllowI
|
|||
import {
|
||||
CommunityReport,
|
||||
CommunityReportView,
|
||||
CommunityView,
|
||||
EditCommunity,
|
||||
FollowMultiCommunity,
|
||||
GetPosts,
|
||||
|
@ -431,7 +430,11 @@ test("User blocks instance, communities are hidden", async () => {
|
|||
expect(listing_ids).toContain(postRes.post_view.post.ap_id);
|
||||
|
||||
// block the beta instance
|
||||
await userBlockInstance(alpha, alphaPost!.community.instance_id, true);
|
||||
await userBlockInstanceCommunities(
|
||||
alpha,
|
||||
alphaPost!.community.instance_id,
|
||||
true,
|
||||
);
|
||||
|
||||
// after blocking, post should not be in listing
|
||||
let listing2 = await getPosts(alpha, "All");
|
||||
|
@ -439,7 +442,11 @@ test("User blocks instance, communities are hidden", async () => {
|
|||
expect(listing_ids2.indexOf(postRes.post_view.post.ap_id)).toBe(-1);
|
||||
|
||||
// unblock instance again
|
||||
await userBlockInstance(alpha, alphaPost!.community.instance_id, false);
|
||||
await userBlockInstanceCommunities(
|
||||
alpha,
|
||||
alphaPost!.community.instance_id,
|
||||
false,
|
||||
);
|
||||
|
||||
// post should be included in listing
|
||||
let listing3 = await getPosts(alpha, "All");
|
||||
|
|
|
@ -40,7 +40,6 @@ import {
|
|||
getMyUser,
|
||||
listNotifications,
|
||||
getModlog,
|
||||
getCommunity,
|
||||
} from "./shared";
|
||||
import { PostView } from "lemmy-js-client/dist/types/PostView";
|
||||
import { AdminBlockInstanceParams } from "lemmy-js-client/dist/types/AdminBlockInstanceParams";
|
||||
|
@ -371,7 +370,11 @@ test("Delete a post", async () => {
|
|||
|
||||
// Make sure lemmy beta sees post is deleted
|
||||
// This will be undefined because of the tombstone
|
||||
await waitForPost(beta, postRes.post_view.post, p => !p || p.post.deleted);
|
||||
await waitForPost(
|
||||
beta,
|
||||
postRes.post_view.post,
|
||||
p => p?.post?.deleted || p == undefined,
|
||||
);
|
||||
|
||||
// Undelete
|
||||
let undeletedPost = await deletePost(alpha, false, postRes.post_view.post);
|
||||
|
@ -531,7 +534,7 @@ test("Enforce site ban federation for local user", async () => {
|
|||
// alpha ban should be federated to beta
|
||||
let alphaUserOnBeta1 = await waitUntil(
|
||||
() => resolvePerson(beta, alphaUserActorId!),
|
||||
res => res?.creator_banned!,
|
||||
res => res?.creator_banned == true,
|
||||
);
|
||||
expect(alphaUserOnBeta1?.creator_banned).toBe(true);
|
||||
|
||||
|
@ -624,15 +627,6 @@ test("Enforce site ban federation for federated user", async () => {
|
|||
let alphaPerson2 = (await getMyUser(alphaUserHttp)).local_user_view;
|
||||
expect(alphaPerson2.banned).toBe(false);
|
||||
|
||||
// but the ban should be indicated by beta community on alpha
|
||||
let communityWithBan = await getCommunity(
|
||||
alphaUserHttp,
|
||||
betaCommunity.community.id,
|
||||
);
|
||||
expect(
|
||||
communityWithBan.community_view.instance_actions?.received_ban_at,
|
||||
).toBeDefined();
|
||||
|
||||
// post to beta community is rejected
|
||||
await expect(
|
||||
createPost(alphaUserHttp, betaCommunity.community.id),
|
||||
|
@ -830,7 +824,7 @@ test("Report a post", async () => {
|
|||
() =>
|
||||
listReports(beta).then(p =>
|
||||
p.reports.find(r => {
|
||||
return checkPostReportName(r, gammaReport) && r.resolver != null;
|
||||
return checkPostReportName(r, gammaReport) && !!r.resolver;
|
||||
}),
|
||||
),
|
||||
res => !!res,
|
||||
|
|
|
@ -20,18 +20,18 @@ import {
|
|||
PostView,
|
||||
PrivateMessageReportResponse,
|
||||
SuccessResponse,
|
||||
UserBlockInstanceParams,
|
||||
ListPersonContentResponse,
|
||||
ListPersonContent,
|
||||
PersonContentType,
|
||||
InboxDataType,
|
||||
GetModlogResponse,
|
||||
GetModlog,
|
||||
CommunityView,
|
||||
CommentView,
|
||||
PersonView,
|
||||
UserBlockInstanceCommunitiesParams,
|
||||
ListNotifications,
|
||||
ListNotificationsResponse,
|
||||
NotificationDataType,
|
||||
} from "lemmy-js-client";
|
||||
import { CreatePost } from "lemmy-js-client/dist/types/CreatePost";
|
||||
import { DeletePost } from "lemmy-js-client/dist/types/DeletePost";
|
||||
|
@ -386,7 +386,7 @@ export async function getUnreadCount(
|
|||
|
||||
export async function listNotifications(
|
||||
api: LemmyHttp,
|
||||
type_?: InboxDataType,
|
||||
type_?: NotificationDataType,
|
||||
unread_only: boolean = false,
|
||||
): Promise<ListNotificationsResponse> {
|
||||
let form: ListNotifications = {
|
||||
|
@ -880,16 +880,16 @@ export function getPosts(
|
|||
return api.getPosts(form);
|
||||
}
|
||||
|
||||
export function userBlockInstance(
|
||||
export function userBlockInstanceCommunities(
|
||||
api: LemmyHttp,
|
||||
instance_id: InstanceId,
|
||||
block: boolean,
|
||||
): Promise<SuccessResponse> {
|
||||
let form: UserBlockInstanceParams = {
|
||||
let form: UserBlockInstanceCommunitiesParams = {
|
||||
instance_id,
|
||||
block,
|
||||
};
|
||||
return api.userBlockInstance(form);
|
||||
return api.userBlockInstanceCommunities(form);
|
||||
}
|
||||
|
||||
export function blockCommunity(
|
||||
|
|
|
@ -18,7 +18,7 @@ import {
|
|||
} from "./shared";
|
||||
import { CreateCommunityTag } from "lemmy-js-client/dist/types/CreateCommunityTag";
|
||||
import { DeleteCommunityTag } from "lemmy-js-client/dist/types/DeleteCommunityTag";
|
||||
import { AddModToCommunity, EditPost } from "lemmy-js-client";
|
||||
import { AddModToCommunity } from "lemmy-js-client";
|
||||
|
||||
beforeAll(setupLogins);
|
||||
afterAll(unfollows);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"declarationDir": "./dist",
|
||||
"module": "CommonJS",
|
||||
"noImplicitAny": true,
|
||||
"lib": ["es2017", "es7", "es6", "dom"],
|
||||
"lib": ["es2022", "es7", "es6", "dom"],
|
||||
"outDir": "./dist",
|
||||
"target": "ES2020",
|
||||
"strictNullChecks": true,
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
use activitypub_federation::config::Data;
|
||||
use actix_web::web::Json;
|
||||
use lemmy_api_utils::context::LemmyContext;
|
||||
use lemmy_db_schema::{
|
||||
source::instance::{InstanceActions, InstanceBlockForm},
|
||||
traits::Blockable,
|
||||
use lemmy_db_schema::source::instance::{
|
||||
InstanceActions,
|
||||
InstanceCommunitiesBlockForm,
|
||||
InstancePersonsBlockForm,
|
||||
};
|
||||
use lemmy_db_views_local_user::LocalUserView;
|
||||
use lemmy_db_views_site::api::{SuccessResponse, UserBlockInstanceParams};
|
||||
use lemmy_db_views_site::api::{
|
||||
SuccessResponse,
|
||||
UserBlockInstanceCommunitiesParams,
|
||||
UserBlockInstancePersonsParams,
|
||||
};
|
||||
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
||||
|
||||
pub async fn user_block_instance(
|
||||
data: Json<UserBlockInstanceParams>,
|
||||
pub async fn user_block_instance_communities(
|
||||
data: Json<UserBlockInstanceCommunitiesParams>,
|
||||
local_user_view: LocalUserView,
|
||||
context: Data<LemmyContext>,
|
||||
) -> LemmyResult<Json<SuccessResponse>> {
|
||||
|
@ -20,12 +25,34 @@ pub async fn user_block_instance(
|
|||
return Err(LemmyErrorType::CantBlockLocalInstance)?;
|
||||
}
|
||||
|
||||
let instance_block_form = InstanceBlockForm::new(person_id, instance_id);
|
||||
let block_form = InstanceCommunitiesBlockForm::new(person_id, instance_id);
|
||||
|
||||
if data.block {
|
||||
InstanceActions::block(&mut context.pool(), &instance_block_form).await?;
|
||||
InstanceActions::block_communities(&mut context.pool(), &block_form).await?;
|
||||
} else {
|
||||
InstanceActions::unblock(&mut context.pool(), &instance_block_form).await?;
|
||||
InstanceActions::unblock_communities(&mut context.pool(), &block_form).await?;
|
||||
}
|
||||
|
||||
Ok(Json(SuccessResponse::default()))
|
||||
}
|
||||
|
||||
pub async fn user_block_instance_persons(
|
||||
data: Json<UserBlockInstancePersonsParams>,
|
||||
local_user_view: LocalUserView,
|
||||
context: Data<LemmyContext>,
|
||||
) -> LemmyResult<Json<SuccessResponse>> {
|
||||
let instance_id = data.instance_id;
|
||||
let person_id = local_user_view.person.id;
|
||||
if local_user_view.person.instance_id == instance_id {
|
||||
return Err(LemmyErrorType::CantBlockLocalInstance)?;
|
||||
}
|
||||
|
||||
let block_form = InstancePersonsBlockForm::new(person_id, instance_id);
|
||||
|
||||
if data.block {
|
||||
InstanceActions::block_persons(&mut context.pool(), &block_form).await?;
|
||||
} else {
|
||||
InstanceActions::unblock_persons(&mut context.pool(), &block_form).await?;
|
||||
}
|
||||
|
||||
Ok(Json(SuccessResponse::default()))
|
||||
|
|
|
@ -14,7 +14,8 @@ pub use lemmy_db_views_site::api::{
|
|||
GetFederatedInstancesResponse,
|
||||
InstanceWithFederationState,
|
||||
ResolveObject,
|
||||
UserBlockInstanceParams,
|
||||
UserBlockInstanceCommunitiesParams,
|
||||
UserBlockInstancePersonsParams,
|
||||
};
|
||||
|
||||
pub mod administration {
|
||||
|
|
|
@ -30,7 +30,8 @@ pub async fn get_my_user(
|
|||
let (
|
||||
follows,
|
||||
community_blocks,
|
||||
instance_blocks,
|
||||
instance_communities_blocks,
|
||||
instance_persons_blocks,
|
||||
person_blocks,
|
||||
moderates,
|
||||
keyword_blocks,
|
||||
|
@ -38,7 +39,8 @@ pub async fn get_my_user(
|
|||
) = lemmy_db_schema::try_join_with_pool!(pool => (
|
||||
|pool| CommunityFollowerView::for_person(pool, person_id),
|
||||
|pool| CommunityActions::read_blocks_for_person(pool, person_id),
|
||||
|pool| InstanceActions::read_blocks_for_person(pool, person_id),
|
||||
|pool| InstanceActions::read_communities_block_for_person(pool, person_id),
|
||||
|pool| InstanceActions::read_persons_block_for_person(pool, person_id),
|
||||
|pool| PersonActions::read_blocks_for_person(pool, person_id),
|
||||
|pool| CommunityModeratorView::for_person(pool, person_id, Some(&local_user_view.local_user)),
|
||||
|pool| LocalUserKeywordBlock::read(pool, local_user_id),
|
||||
|
@ -50,7 +52,8 @@ pub async fn get_my_user(
|
|||
follows,
|
||||
moderates,
|
||||
community_blocks,
|
||||
instance_blocks,
|
||||
instance_communities_blocks,
|
||||
instance_persons_blocks,
|
||||
person_blocks,
|
||||
keyword_blocks,
|
||||
discussion_languages,
|
||||
|
|
|
@ -102,7 +102,10 @@ impl NotifyData {
|
|||
let pool = &mut context.pool();
|
||||
// TODO: this needs too many queries for each user
|
||||
PersonActions::read_block(pool, potential_blocker_id, self.post.creator_id).await?;
|
||||
InstanceActions::read_block(pool, potential_blocker_id, self.community.instance_id).await?;
|
||||
InstanceActions::read_communities_block(pool, potential_blocker_id, self.community.instance_id)
|
||||
.await?;
|
||||
InstanceActions::read_persons_block(pool, potential_blocker_id, self.creator.instance_id)
|
||||
.await?;
|
||||
CommunityActions::read_block(pool, potential_blocker_id, self.post.community_id).await?;
|
||||
let post_notifications = PostActions::read(pool, self.post.id, potential_blocker_id)
|
||||
.await
|
||||
|
@ -284,7 +287,7 @@ mod tests {
|
|||
source::{
|
||||
comment::{Comment, CommentInsertForm},
|
||||
community::{Community, CommunityInsertForm},
|
||||
instance::{Instance, InstanceActions, InstanceBlockForm},
|
||||
instance::{Instance, InstanceActions, InstancePersonsBlockForm},
|
||||
notification::{Notification, NotificationInsertForm},
|
||||
person::{Person, PersonActions, PersonBlockForm, PersonInsertForm, PersonUpdateForm},
|
||||
post::{Post, PostInsertForm},
|
||||
|
@ -716,16 +719,19 @@ mod tests {
|
|||
|
||||
// Make sure instance_blocks are working
|
||||
let timmy_blocks_instance_form =
|
||||
InstanceBlockForm::new(data.timmy.person.id, data.sara.person.instance_id);
|
||||
InstancePersonsBlockForm::new(data.timmy.person.id, data.sara.person.instance_id);
|
||||
|
||||
let inserted_instance_block = InstanceActions::block(pool, &timmy_blocks_instance_form).await?;
|
||||
let inserted_instance_block =
|
||||
InstanceActions::block_persons(pool, &timmy_blocks_instance_form).await?;
|
||||
|
||||
assert_eq!(data.timmy.person.id, inserted_instance_block.person_id);
|
||||
assert_eq!(
|
||||
data.sara.person.instance_id,
|
||||
inserted_instance_block.instance_id
|
||||
(data.timmy.person.id, data.sara.person.instance_id, true),
|
||||
(
|
||||
inserted_instance_block.person_id,
|
||||
inserted_instance_block.instance_id,
|
||||
inserted_instance_block.blocked_persons_at.is_some()
|
||||
)
|
||||
);
|
||||
assert!(inserted_instance_block.blocked_at.is_some());
|
||||
|
||||
let timmy_messages: Vec<_> = NotificationQuery {
|
||||
unread_only: Some(true),
|
||||
|
|
|
@ -13,7 +13,7 @@ use lemmy_db_schema::{
|
|||
source::{
|
||||
comment::{CommentActions, CommentSavedForm},
|
||||
community::{CommunityActions, CommunityBlockForm, CommunityFollowerForm},
|
||||
instance::{Instance, InstanceActions, InstanceBlockForm},
|
||||
instance::{Instance, InstanceActions, InstanceCommunitiesBlockForm, InstancePersonsBlockForm},
|
||||
local_user::{LocalUser, LocalUserUpdateForm},
|
||||
person::{Person, PersonActions, PersonBlockForm, PersonUpdateForm},
|
||||
post::{PostActions, PostSavedForm},
|
||||
|
@ -98,7 +98,8 @@ pub async fn import_settings(
|
|||
let url_count = data.followed_communities.len()
|
||||
+ data.blocked_communities.len()
|
||||
+ data.blocked_users.len()
|
||||
+ data.blocked_instances.len()
|
||||
+ data.blocked_instances_communities.len()
|
||||
+ data.blocked_instances_persons.len()
|
||||
+ data.saved_posts.len()
|
||||
+ data.saved_comments.len();
|
||||
check_api_elements_count(url_count)?;
|
||||
|
@ -197,10 +198,23 @@ pub async fn import_settings(
|
|||
)
|
||||
.await?;
|
||||
|
||||
try_join_all(data.blocked_instances.iter().map(|domain| async {
|
||||
try_join_all(
|
||||
data
|
||||
.blocked_instances_communities
|
||||
.iter()
|
||||
.map(|domain| async {
|
||||
let instance = Instance::read_or_create(&mut context.pool(), domain.clone()).await?;
|
||||
let form = InstanceCommunitiesBlockForm::new(person_id, instance.id);
|
||||
InstanceActions::block_communities(&mut context.pool(), &form).await?;
|
||||
LemmyResult::Ok(())
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
|
||||
try_join_all(data.blocked_instances_persons.iter().map(|domain| async {
|
||||
let instance = Instance::read_or_create(&mut context.pool(), domain.clone()).await?;
|
||||
let form = InstanceBlockForm::new(person_id, instance.id);
|
||||
InstanceActions::block(&mut context.pool(), &form).await?;
|
||||
let form = InstancePersonsBlockForm::new(person_id, instance.id);
|
||||
InstanceActions::block_persons(&mut context.pool(), &form).await?;
|
||||
LemmyResult::Ok(())
|
||||
}))
|
||||
.await?;
|
||||
|
|
|
@ -3,9 +3,16 @@ use crate::{
|
|||
newtypes::{InstanceId, PersonId},
|
||||
source::{
|
||||
federation_queue_state::FederationQueueState,
|
||||
instance::{Instance, InstanceActions, InstanceBanForm, InstanceBlockForm, InstanceForm},
|
||||
instance::{
|
||||
Instance,
|
||||
InstanceActions,
|
||||
InstanceBanForm,
|
||||
InstanceCommunitiesBlockForm,
|
||||
InstanceForm,
|
||||
InstancePersonsBlockForm,
|
||||
},
|
||||
},
|
||||
traits::{Bannable, Blockable},
|
||||
traits::Bannable,
|
||||
utils::{
|
||||
functions::{coalesce, lower},
|
||||
get_conn,
|
||||
|
@ -206,12 +213,11 @@ impl Instance {
|
|||
}
|
||||
}
|
||||
|
||||
impl Blockable for InstanceActions {
|
||||
type Form = InstanceBlockForm;
|
||||
type ObjectIdType = InstanceId;
|
||||
type ObjectType = Instance;
|
||||
|
||||
async fn block(pool: &mut DbPool<'_>, form: &Self::Form) -> LemmyResult<Self> {
|
||||
impl InstanceActions {
|
||||
pub async fn block_communities(
|
||||
pool: &mut DbPool<'_>,
|
||||
form: &InstanceCommunitiesBlockForm,
|
||||
) -> LemmyResult<Self> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
insert_into(instance_actions::table)
|
||||
.values(form)
|
||||
|
@ -221,27 +227,31 @@ impl Blockable for InstanceActions {
|
|||
.returning(Self::as_select())
|
||||
.get_result::<Self>(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::InstanceBlockAlreadyExists)
|
||||
.with_lemmy_type(LemmyErrorType::InstanceBlockCommunitiesAlreadyExists)
|
||||
}
|
||||
|
||||
async fn unblock(pool: &mut DbPool<'_>, form: &Self::Form) -> LemmyResult<UpleteCount> {
|
||||
pub async fn unblock_communities(
|
||||
pool: &mut DbPool<'_>,
|
||||
form: &InstanceCommunitiesBlockForm,
|
||||
) -> LemmyResult<UpleteCount> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
uplete(instance_actions::table.find((form.person_id, form.instance_id)))
|
||||
.set_null(instance_actions::blocked_at)
|
||||
.set_null(instance_actions::blocked_communities_at)
|
||||
.get_result(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::InstanceBlockAlreadyExists)
|
||||
.with_lemmy_type(LemmyErrorType::InstanceBlockCommunitiesAlreadyExists)
|
||||
}
|
||||
|
||||
async fn read_block(
|
||||
/// Checks to see if there's a block for the instances communities
|
||||
pub async fn read_communities_block(
|
||||
pool: &mut DbPool<'_>,
|
||||
person_id: PersonId,
|
||||
instance_id: Self::ObjectIdType,
|
||||
instance_id: InstanceId,
|
||||
) -> LemmyResult<()> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
let find_action = instance_actions::table
|
||||
.find((person_id, instance_id))
|
||||
.filter(instance_actions::blocked_at.is_not_null());
|
||||
.filter(instance_actions::blocked_communities_at.is_not_null());
|
||||
select(not(exists(find_action)))
|
||||
.get_result::<bool>(conn)
|
||||
.await?
|
||||
|
@ -249,24 +259,83 @@ impl Blockable for InstanceActions {
|
|||
.ok_or(LemmyErrorType::InstanceIsBlocked.into())
|
||||
}
|
||||
|
||||
async fn read_blocks_for_person(
|
||||
pub async fn read_communities_block_for_person(
|
||||
pool: &mut DbPool<'_>,
|
||||
person_id: PersonId,
|
||||
) -> LemmyResult<Vec<Self::ObjectType>> {
|
||||
) -> LemmyResult<Vec<Instance>> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
instance_actions::table
|
||||
.filter(instance_actions::blocked_at.is_not_null())
|
||||
.filter(instance_actions::blocked_communities_at.is_not_null())
|
||||
.inner_join(instance::table)
|
||||
.select(instance::all_columns)
|
||||
.filter(instance_actions::person_id.eq(person_id))
|
||||
.order_by(instance_actions::blocked_at)
|
||||
.order_by(instance_actions::blocked_communities_at)
|
||||
.load::<Instance>(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::NotFound)
|
||||
}
|
||||
|
||||
pub async fn block_persons(
|
||||
pool: &mut DbPool<'_>,
|
||||
form: &InstancePersonsBlockForm,
|
||||
) -> LemmyResult<Self> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
insert_into(instance_actions::table)
|
||||
.values(form)
|
||||
.on_conflict((instance_actions::person_id, instance_actions::instance_id))
|
||||
.do_update()
|
||||
.set(form)
|
||||
.returning(Self::as_select())
|
||||
.get_result::<Self>(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::InstanceBlockPersonsAlreadyExists)
|
||||
}
|
||||
|
||||
pub async fn unblock_persons(
|
||||
pool: &mut DbPool<'_>,
|
||||
form: &InstancePersonsBlockForm,
|
||||
) -> LemmyResult<UpleteCount> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
uplete(instance_actions::table.find((form.person_id, form.instance_id)))
|
||||
.set_null(instance_actions::blocked_persons_at)
|
||||
.get_result(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::InstanceBlockPersonsAlreadyExists)
|
||||
}
|
||||
|
||||
/// Checks to see if there's a block either from the instance person.
|
||||
pub async fn read_persons_block(
|
||||
pool: &mut DbPool<'_>,
|
||||
person_id: PersonId,
|
||||
instance_id: InstanceId,
|
||||
) -> LemmyResult<()> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
let find_action = instance_actions::table
|
||||
.find((person_id, instance_id))
|
||||
.filter(instance_actions::blocked_persons_at.is_not_null());
|
||||
select(not(exists(find_action)))
|
||||
.get_result::<bool>(conn)
|
||||
.await?
|
||||
.then_some(())
|
||||
.ok_or(LemmyErrorType::InstanceIsBlocked.into())
|
||||
}
|
||||
|
||||
pub async fn read_persons_block_for_person(
|
||||
pool: &mut DbPool<'_>,
|
||||
person_id: PersonId,
|
||||
) -> LemmyResult<Vec<Instance>> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
instance_actions::table
|
||||
.filter(instance_actions::blocked_persons_at.is_not_null())
|
||||
.inner_join(instance::table)
|
||||
.select(instance::all_columns)
|
||||
.filter(instance_actions::person_id.eq(person_id))
|
||||
.order_by(instance_actions::blocked_persons_at)
|
||||
.load::<Instance>(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::NotFound)
|
||||
}
|
||||
}
|
||||
|
||||
impl InstanceActions {
|
||||
pub async fn check_ban(
|
||||
pool: &mut DbPool<'_>,
|
||||
person_id: PersonId,
|
||||
|
|
|
@ -211,8 +211,16 @@ impl LocalUser {
|
|||
.get_results(conn)
|
||||
.await?;
|
||||
|
||||
let blocked_instances = instance_actions::table
|
||||
.filter(instance_actions::blocked_at.is_not_null())
|
||||
let blocked_instances_communities = instance_actions::table
|
||||
.filter(instance_actions::blocked_communities_at.is_not_null())
|
||||
.filter(instance_actions::person_id.eq(person_id_))
|
||||
.inner_join(instance::table)
|
||||
.select(instance::domain)
|
||||
.get_results(conn)
|
||||
.await?;
|
||||
|
||||
let blocked_instances_persons = instance_actions::table
|
||||
.filter(instance_actions::blocked_persons_at.is_not_null())
|
||||
.filter(instance_actions::person_id.eq(person_id_))
|
||||
.inner_join(instance::table)
|
||||
.select(instance::domain)
|
||||
|
@ -227,7 +235,8 @@ impl LocalUser {
|
|||
saved_comments,
|
||||
blocked_communities,
|
||||
blocked_users,
|
||||
blocked_instances,
|
||||
blocked_instances_communities,
|
||||
blocked_instances_persons,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -382,7 +391,8 @@ pub struct UserBackupLists {
|
|||
pub saved_comments: Vec<DbUrl>,
|
||||
pub blocked_communities: Vec<DbUrl>,
|
||||
pub blocked_users: Vec<DbUrl>,
|
||||
pub blocked_instances: Vec<String>,
|
||||
pub blocked_instances_communities: Vec<String>,
|
||||
pub blocked_instances_persons: Vec<String>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -542,7 +542,7 @@ impl PostActions {
|
|||
pub fn build_many_read_forms(post_ids: &[PostId], person_id: PersonId) -> Vec<PostReadForm> {
|
||||
post_ids
|
||||
.iter()
|
||||
.map(|post_id| (PostReadForm::new(*post_id, person_id)))
|
||||
.map(|post_id| PostReadForm::new(*post_id, person_id))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ pub mod aliases {
|
|||
instance_actions as creator_home_instance_actions: CreatorHomeInstanceActions,
|
||||
instance_actions as creator_community_instance_actions: CreatorCommunityInstanceActions,
|
||||
instance_actions as creator_local_instance_actions: CreatorLocalInstanceActions,
|
||||
instance_actions as my_instance_persons_actions: MyInstancePersonsActions,
|
||||
local_user as creator_local_user: CreatorLocalUser,
|
||||
person as person1: Person1,
|
||||
person as person2: Person2,
|
||||
|
@ -33,7 +34,10 @@ pub mod utils;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use strum::{Display, EnumString};
|
||||
#[cfg(feature = "full")]
|
||||
use {diesel::query_source::AliasedField, lemmy_db_schema_file::schema::person};
|
||||
use {
|
||||
diesel::query_source::AliasedField,
|
||||
lemmy_db_schema_file::schema::{instance_actions, person},
|
||||
};
|
||||
|
||||
#[derive(
|
||||
EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default, Hash,
|
||||
|
@ -233,3 +237,14 @@ pub type Person2AliasAllColumnsTuple = (
|
|||
AliasedField<aliases::Person2, person::comment_count>,
|
||||
AliasedField<aliases::Person2, person::comment_score>,
|
||||
);
|
||||
|
||||
#[cfg(feature = "full")]
|
||||
/// A helper tuple for more my instance persons actions
|
||||
pub type MyInstancePersonsActionsAllColumnsTuple = (
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::person_id>,
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::instance_id>,
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::blocked_communities_at>,
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::received_ban_at>,
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::ban_expires_at>,
|
||||
AliasedField<aliases::MyInstancePersonsActions, instance_actions::blocked_persons_at>,
|
||||
);
|
||||
|
|
|
@ -59,22 +59,34 @@ pub struct InstanceActions {
|
|||
pub person_id: PersonId,
|
||||
#[serde(skip)]
|
||||
pub instance_id: InstanceId,
|
||||
/// When the instance was blocked.
|
||||
pub blocked_at: Option<DateTime<Utc>>,
|
||||
/// When the instance's communities were blocked.
|
||||
pub blocked_communities_at: Option<DateTime<Utc>>,
|
||||
/// When this user received a site ban.
|
||||
pub received_ban_at: Option<DateTime<Utc>>,
|
||||
/// When their ban expires.
|
||||
pub ban_expires_at: Option<DateTime<Utc>>,
|
||||
/// When the instance's persons were blocked.
|
||||
pub blocked_persons_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[derive(derive_new::new)]
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = instance_actions))]
|
||||
pub struct InstanceBlockForm {
|
||||
pub struct InstanceCommunitiesBlockForm {
|
||||
pub person_id: PersonId,
|
||||
pub instance_id: InstanceId,
|
||||
#[new(value = "Utc::now()")]
|
||||
pub blocked_at: DateTime<Utc>,
|
||||
pub blocked_communities_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(derive_new::new)]
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = instance_actions))]
|
||||
pub struct InstancePersonsBlockForm {
|
||||
pub person_id: PersonId,
|
||||
pub instance_id: InstanceId,
|
||||
#[new(value = "Utc::now()")]
|
||||
pub blocked_persons_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(derive_new::new)]
|
||||
|
|
|
@ -5,17 +5,19 @@ use crate::{
|
|||
creator_home_instance_actions,
|
||||
creator_local_instance_actions,
|
||||
creator_local_user,
|
||||
my_instance_persons_actions,
|
||||
person1,
|
||||
person2,
|
||||
},
|
||||
newtypes::{InstanceId, PersonId},
|
||||
MyInstancePersonsActionsAllColumnsTuple,
|
||||
Person1AliasAllColumnsTuple,
|
||||
Person2AliasAllColumnsTuple,
|
||||
};
|
||||
use diesel::{
|
||||
dsl::{case_when, exists, not},
|
||||
expression::SqlLiteral,
|
||||
helper_types::{Eq, NotEq},
|
||||
helper_types::{Eq, NotEq, Nullable},
|
||||
sql_types::Json,
|
||||
BoolExpressionMethods,
|
||||
ExpressionMethods,
|
||||
|
@ -50,11 +52,16 @@ use lemmy_db_schema_file::{
|
|||
/// hidden, unless the user followed the community explicitly.
|
||||
#[diesel::dsl::auto_type]
|
||||
pub fn filter_blocked() -> _ {
|
||||
instance_actions::blocked_at
|
||||
instance_actions::blocked_communities_at
|
||||
.is_null()
|
||||
.or(community_actions::followed_at.is_not_null())
|
||||
.and(community_actions::blocked_at.is_null())
|
||||
.and(person_actions::blocked_at.is_null())
|
||||
.and(
|
||||
my_instance_persons_actions
|
||||
.field(instance_actions::blocked_persons_at)
|
||||
.is_null(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Checks that the creator_local_user is an admin.
|
||||
|
@ -336,7 +343,7 @@ pub fn creator_local_instance_actions_join(local_instance_id: InstanceId) -> _ {
|
|||
|
||||
/// Your instance actions for the community's instance.
|
||||
#[diesel::dsl::auto_type]
|
||||
pub fn my_instance_actions_community_join(my_person_id: Option<PersonId>) -> _ {
|
||||
pub fn my_instance_communities_actions_join(my_person_id: Option<PersonId>) -> _ {
|
||||
instance_actions::table.on(
|
||||
instance_actions::instance_id
|
||||
.eq(community::instance_id)
|
||||
|
@ -346,7 +353,7 @@ pub fn my_instance_actions_community_join(my_person_id: Option<PersonId>) -> _ {
|
|||
|
||||
/// Your instance actions for the person's instance.
|
||||
#[diesel::dsl::auto_type]
|
||||
pub fn my_instance_actions_person_join(my_person_id: Option<PersonId>) -> _ {
|
||||
pub fn my_instance_persons_actions_join(my_person_id: Option<PersonId>) -> _ {
|
||||
instance_actions::table.on(
|
||||
instance_actions::instance_id
|
||||
.eq(person::instance_id)
|
||||
|
@ -354,6 +361,29 @@ pub fn my_instance_actions_person_join(my_person_id: Option<PersonId>) -> _ {
|
|||
)
|
||||
}
|
||||
|
||||
/// The select for the my_instance_persons_actions alias
|
||||
pub fn my_instance_persons_actions_select() -> Nullable<MyInstancePersonsActionsAllColumnsTuple> {
|
||||
my_instance_persons_actions
|
||||
.fields(instance_actions::all_columns)
|
||||
.nullable()
|
||||
}
|
||||
|
||||
/// Your instance actions for the person's instance.
|
||||
/// A dupe of the above function, but aliased
|
||||
#[diesel::dsl::auto_type]
|
||||
pub fn my_instance_persons_actions_join_1(my_person_id: Option<PersonId>) -> _ {
|
||||
my_instance_persons_actions.on(
|
||||
my_instance_persons_actions
|
||||
.field(instance_actions::instance_id)
|
||||
.eq(person::instance_id)
|
||||
.and(
|
||||
my_instance_persons_actions
|
||||
.field(instance_actions::person_id)
|
||||
.nullable()
|
||||
.eq(my_person_id),
|
||||
),
|
||||
)
|
||||
}
|
||||
#[diesel::dsl::auto_type]
|
||||
pub fn image_details_join() -> _ {
|
||||
image_details::table.on(post::thumbnail_url.eq(image_details::link.nullable()))
|
||||
|
|
|
@ -411,9 +411,10 @@ diesel::table! {
|
|||
instance_actions (person_id, instance_id) {
|
||||
person_id -> Int4,
|
||||
instance_id -> Int4,
|
||||
blocked_at -> Nullable<Timestamptz>,
|
||||
blocked_communities_at -> Nullable<Timestamptz>,
|
||||
received_ban_at -> Nullable<Timestamptz>,
|
||||
ban_expires_at -> Nullable<Timestamptz>,
|
||||
blocked_persons_at -> Nullable<Timestamptz>,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,8 @@ use lemmy_db_schema::{
|
|||
filter_blocked,
|
||||
my_comment_actions_join,
|
||||
my_community_actions_join,
|
||||
my_instance_actions_community_join,
|
||||
my_instance_communities_actions_join,
|
||||
my_instance_persons_actions_join_1,
|
||||
my_local_user_admin_join,
|
||||
my_person_actions_join,
|
||||
suggested_communities,
|
||||
|
@ -78,8 +79,10 @@ impl CommentView {
|
|||
my_community_actions_join(my_person_id);
|
||||
let my_comment_actions_join: my_comment_actions_join = my_comment_actions_join(my_person_id);
|
||||
let my_local_user_admin_join: my_local_user_admin_join = my_local_user_admin_join(my_person_id);
|
||||
let my_instance_actions_community_join: my_instance_actions_community_join =
|
||||
my_instance_actions_community_join(my_person_id);
|
||||
let my_instance_communities_actions_join: my_instance_communities_actions_join =
|
||||
my_instance_communities_actions_join(my_person_id);
|
||||
let my_instance_persons_actions_join_1: my_instance_persons_actions_join_1 =
|
||||
my_instance_persons_actions_join_1(my_person_id);
|
||||
let my_person_actions_join: my_person_actions_join = my_person_actions_join(my_person_id);
|
||||
let creator_local_instance_actions_join: creator_local_instance_actions_join =
|
||||
creator_local_instance_actions_join(local_instance_id);
|
||||
|
@ -88,15 +91,16 @@ impl CommentView {
|
|||
.inner_join(person::table)
|
||||
.inner_join(post::table)
|
||||
.inner_join(community_join)
|
||||
.left_join(creator_home_instance_actions_join())
|
||||
.left_join(creator_community_instance_actions_join())
|
||||
.left_join(creator_community_actions_join())
|
||||
.left_join(creator_local_instance_actions_join)
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_comment_actions_join)
|
||||
.left_join(my_person_actions_join)
|
||||
.left_join(my_local_user_admin_join)
|
||||
.left_join(my_instance_actions_community_join)
|
||||
.left_join(creator_home_instance_actions_join())
|
||||
.left_join(creator_community_instance_actions_join())
|
||||
.left_join(creator_local_instance_actions_join)
|
||||
.left_join(creator_community_actions_join())
|
||||
.left_join(my_instance_communities_actions_join)
|
||||
.left_join(my_instance_persons_actions_join_1)
|
||||
}
|
||||
|
||||
pub async fn read(
|
||||
|
@ -138,7 +142,6 @@ impl CommentView {
|
|||
creator: self.creator,
|
||||
comment_actions: self.comment_actions,
|
||||
person_actions: self.person_actions,
|
||||
instance_actions: self.instance_actions,
|
||||
creator_is_admin: self.creator_is_admin,
|
||||
can_mod: self.can_mod,
|
||||
creator_banned: self.creator_banned,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use lemmy_db_schema::source::{
|
||||
comment::{Comment, CommentActions},
|
||||
community::{Community, CommunityActions},
|
||||
instance::InstanceActions,
|
||||
person::{Person, PersonActions},
|
||||
post::Post,
|
||||
tag::TagsView,
|
||||
|
@ -14,13 +13,11 @@ use {
|
|||
lemmy_db_schema::utils::queries::{
|
||||
comment_creator_is_admin,
|
||||
comment_select_remove_deletes,
|
||||
local_user_can_mod_comment,
|
||||
post_tags_fragment,
|
||||
},
|
||||
lemmy_db_schema::utils::queries::{
|
||||
creator_banned_from_community,
|
||||
creator_banned_within_community,
|
||||
creator_is_moderator,
|
||||
local_user_can_mod_comment,
|
||||
post_tags_fragment,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -54,8 +51,6 @@ pub struct CommentView {
|
|||
pub comment_actions: Option<CommentActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub person_actions: Option<PersonActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub instance_actions: Option<InstanceActions>,
|
||||
#[cfg_attr(feature = "full",
|
||||
diesel(
|
||||
select_expression = comment_creator_is_admin()
|
||||
|
@ -106,7 +101,6 @@ pub struct CommentSlimView {
|
|||
pub creator: Person,
|
||||
pub comment_actions: Option<CommentActions>,
|
||||
pub person_actions: Option<PersonActions>,
|
||||
pub instance_actions: Option<InstanceActions>,
|
||||
pub creator_is_admin: bool,
|
||||
pub can_mod: bool,
|
||||
pub creator_banned: bool,
|
||||
|
|
|
@ -20,7 +20,7 @@ use lemmy_db_schema::{
|
|||
filter_is_subscribed,
|
||||
filter_not_unlisted_or_is_subscribed,
|
||||
my_community_actions_join,
|
||||
my_instance_actions_community_join,
|
||||
my_instance_communities_actions_join,
|
||||
my_local_user_admin_join,
|
||||
suggested_communities,
|
||||
},
|
||||
|
@ -48,8 +48,8 @@ impl CommunityView {
|
|||
#[diesel::dsl::auto_type(no_type_alias)]
|
||||
fn joins(person_id: Option<PersonId>) -> _ {
|
||||
let community_actions_join: my_community_actions_join = my_community_actions_join(person_id);
|
||||
let instance_actions_community_join: my_instance_actions_community_join =
|
||||
my_instance_actions_community_join(person_id);
|
||||
let instance_actions_community_join: my_instance_communities_actions_join =
|
||||
my_instance_communities_actions_join(person_id);
|
||||
let my_local_user_admin_join: my_local_user_admin_join = my_local_user_admin_join(person_id);
|
||||
|
||||
community::table
|
||||
|
@ -150,7 +150,7 @@ impl CommunityQuery<'_> {
|
|||
|
||||
// Don't show blocked communities and communities on blocked instances. nsfw communities are
|
||||
// also hidden (based on profile setting)
|
||||
query = query.filter(instance_actions::blocked_at.is_null());
|
||||
query = query.filter(instance_actions::blocked_communities_at.is_null());
|
||||
query = query.filter(community_actions::blocked_at.is_null());
|
||||
if !(o.local_user.show_nsfw(site) || o.show_nsfw.unwrap_or_default()) {
|
||||
query = query.filter(community::nsfw.eq(false));
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use lemmy_db_schema::source::{
|
||||
community::{Community, CommunityActions},
|
||||
instance::InstanceActions,
|
||||
multi_community::MultiCommunity,
|
||||
person::Person,
|
||||
tag::TagsView,
|
||||
|
@ -29,8 +28,6 @@ pub struct CommunityView {
|
|||
pub community: Community,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub community_actions: Option<CommunityActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub instance_actions: Option<InstanceActions>,
|
||||
#[cfg_attr(feature = "full",
|
||||
diesel(
|
||||
select_expression = local_user_community_can_mod()
|
||||
|
|
|
@ -28,10 +28,12 @@ use lemmy_db_schema::{
|
|||
creator_home_instance_actions_join,
|
||||
creator_local_instance_actions_join,
|
||||
creator_local_user_admin_join,
|
||||
filter_blocked,
|
||||
image_details_join,
|
||||
my_comment_actions_join,
|
||||
my_community_actions_join,
|
||||
my_instance_actions_person_join,
|
||||
my_instance_communities_actions_join,
|
||||
my_instance_persons_actions_join_1,
|
||||
my_local_user_admin_join,
|
||||
my_person_actions_join,
|
||||
my_post_actions_join,
|
||||
|
@ -42,15 +44,7 @@ use lemmy_db_schema::{
|
|||
};
|
||||
use lemmy_db_schema_file::{
|
||||
enums::NotificationTypes,
|
||||
schema::{
|
||||
comment,
|
||||
instance_actions,
|
||||
notification,
|
||||
person,
|
||||
person_actions,
|
||||
post,
|
||||
private_message,
|
||||
},
|
||||
schema::{comment, notification, person, post, private_message},
|
||||
};
|
||||
use lemmy_db_views_post::PostView;
|
||||
use lemmy_db_views_private_message::PrivateMessageView;
|
||||
|
@ -107,8 +101,10 @@ impl NotificationView {
|
|||
my_comment_actions_join(Some(my_person.id));
|
||||
let my_local_user_admin_join: my_local_user_admin_join =
|
||||
my_local_user_admin_join(Some(my_person.id));
|
||||
let my_instance_actions_person_join: my_instance_actions_person_join =
|
||||
my_instance_actions_person_join(Some(my_person.id));
|
||||
let my_instance_communities_actions_join: my_instance_communities_actions_join =
|
||||
my_instance_communities_actions_join(Some(my_person.id));
|
||||
let my_instance_persons_actions_join_1: my_instance_persons_actions_join_1 =
|
||||
my_instance_persons_actions_join_1(Some(my_person.id));
|
||||
let my_person_actions_join: my_person_actions_join = my_person_actions_join(Some(my_person.id));
|
||||
let creator_local_instance_actions_join: creator_local_instance_actions_join =
|
||||
creator_local_instance_actions_join(my_person.instance_id);
|
||||
|
@ -122,12 +118,13 @@ impl NotificationView {
|
|||
.inner_join(recipient_join)
|
||||
.left_join(image_details_join())
|
||||
.left_join(creator_community_actions_join())
|
||||
.left_join(my_local_user_admin_join)
|
||||
.left_join(creator_local_user_admin_join())
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_instance_actions_person_join)
|
||||
.left_join(creator_home_instance_actions_join())
|
||||
.left_join(creator_local_instance_actions_join)
|
||||
.left_join(my_local_user_admin_join)
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_instance_communities_actions_join)
|
||||
.left_join(my_instance_persons_actions_join_1)
|
||||
.left_join(my_post_actions_join)
|
||||
.left_join(my_person_actions_join)
|
||||
.left_join(my_comment_actions_join)
|
||||
|
@ -150,8 +147,7 @@ impl NotificationView {
|
|||
// Filter unreads
|
||||
.filter(unread_filter)
|
||||
// Don't count replies from blocked users
|
||||
.filter(person_actions::blocked_at.is_null())
|
||||
.filter(instance_actions::blocked_at.is_null())
|
||||
.filter(filter_blocked())
|
||||
.select(count(notification::id))
|
||||
.into_boxed();
|
||||
|
||||
|
@ -242,9 +238,7 @@ impl NotificationQuery {
|
|||
};
|
||||
|
||||
// Dont show replies from blocked users or instances
|
||||
query = query
|
||||
.filter(person_actions::blocked_at.is_null())
|
||||
.filter(instance_actions::blocked_at.is_null());
|
||||
query = query.filter(filter_blocked());
|
||||
|
||||
if let Some(type_) = self.type_ {
|
||||
query = match type_ {
|
||||
|
@ -294,7 +288,6 @@ fn map_to_enum(v: NotificationViewInternal) -> Option<NotificationView> {
|
|||
community,
|
||||
creator: v.creator,
|
||||
community_actions: v.community_actions,
|
||||
instance_actions: v.instance_actions,
|
||||
person_actions: v.person_actions,
|
||||
comment_actions: v.comment_actions,
|
||||
creator_is_admin: v.creator_is_admin,
|
||||
|
@ -311,7 +304,6 @@ fn map_to_enum(v: NotificationViewInternal) -> Option<NotificationView> {
|
|||
creator: v.creator,
|
||||
image_details: v.image_details,
|
||||
community_actions: v.community_actions,
|
||||
instance_actions: v.instance_actions,
|
||||
post_actions: v.post_actions,
|
||||
person_actions: v.person_actions,
|
||||
creator_is_admin: v.creator_is_admin,
|
||||
|
|
|
@ -4,7 +4,6 @@ use lemmy_db_schema::{
|
|||
comment::{Comment, CommentActions},
|
||||
community::{Community, CommunityActions},
|
||||
images::ImageDetails,
|
||||
instance::InstanceActions,
|
||||
notification::Notification,
|
||||
person::{Person, PersonActions},
|
||||
post::{Post, PostActions},
|
||||
|
@ -22,9 +21,15 @@ use serde_with::skip_serializing_none;
|
|||
use {
|
||||
diesel::{Queryable, Selectable},
|
||||
lemmy_db_schema::{
|
||||
utils::queries::person1_select,
|
||||
utils::queries::{creator_banned, creator_is_admin, local_user_can_mod, post_tags_fragment},
|
||||
utils::queries::{creator_banned_from_community, creator_is_moderator},
|
||||
utils::queries::{
|
||||
creator_banned,
|
||||
creator_banned_from_community,
|
||||
creator_is_admin,
|
||||
creator_is_moderator,
|
||||
local_user_can_mod,
|
||||
person1_select,
|
||||
post_tags_fragment,
|
||||
},
|
||||
Person1AliasAllColumnsTuple,
|
||||
},
|
||||
};
|
||||
|
@ -61,8 +66,6 @@ struct NotificationViewInternal {
|
|||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
community_actions: Option<CommunityActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
instance_actions: Option<InstanceActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
post_actions: Option<PostActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
person_actions: Option<PersonActions>,
|
||||
|
|
|
@ -33,7 +33,6 @@ use lemmy_db_schema::{
|
|||
image_details_join,
|
||||
my_comment_actions_join,
|
||||
my_community_actions_join,
|
||||
my_instance_actions_person_join,
|
||||
my_local_user_admin_join,
|
||||
my_person_actions_join,
|
||||
my_post_actions_join,
|
||||
|
@ -76,8 +75,6 @@ impl PersonContentCombinedViewInternal {
|
|||
let my_post_actions_join: my_post_actions_join = my_post_actions_join(my_person_id);
|
||||
let my_comment_actions_join: my_comment_actions_join = my_comment_actions_join(my_person_id);
|
||||
let my_local_user_admin_join: my_local_user_admin_join = my_local_user_admin_join(my_person_id);
|
||||
let my_instance_actions_person_join: my_instance_actions_person_join =
|
||||
my_instance_actions_person_join(my_person_id);
|
||||
let my_person_actions_join: my_person_actions_join = my_person_actions_join(my_person_id);
|
||||
let creator_local_instance_actions_join: creator_local_instance_actions_join =
|
||||
creator_local_instance_actions_join(local_instance_id);
|
||||
|
@ -87,17 +84,16 @@ impl PersonContentCombinedViewInternal {
|
|||
.inner_join(post_join)
|
||||
.inner_join(item_creator_join)
|
||||
.inner_join(community_join())
|
||||
.left_join(image_details_join())
|
||||
.left_join(creator_community_actions_join())
|
||||
.left_join(my_local_user_admin_join)
|
||||
.left_join(creator_local_user_admin_join())
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_instance_actions_person_join)
|
||||
.left_join(creator_home_instance_actions_join())
|
||||
.left_join(creator_local_instance_actions_join)
|
||||
.left_join(my_local_user_admin_join)
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_post_actions_join)
|
||||
.left_join(my_person_actions_join)
|
||||
.left_join(my_comment_actions_join)
|
||||
.left_join(image_details_join())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,7 +236,6 @@ impl InternalToCombinedView for PersonContentCombinedViewInternal {
|
|||
community_actions: v.community_actions,
|
||||
comment_actions: v.comment_actions,
|
||||
person_actions: v.person_actions,
|
||||
instance_actions: v.instance_actions,
|
||||
creator_is_admin: v.item_creator_is_admin,
|
||||
post_tags: v.post_tags,
|
||||
can_mod: v.can_mod,
|
||||
|
@ -257,7 +252,6 @@ impl InternalToCombinedView for PersonContentCombinedViewInternal {
|
|||
community_actions: v.community_actions,
|
||||
post_actions: v.post_actions,
|
||||
person_actions: v.person_actions,
|
||||
instance_actions: v.instance_actions,
|
||||
creator_is_admin: v.item_creator_is_admin,
|
||||
tags: v.post_tags,
|
||||
can_mod: v.can_mod,
|
||||
|
|
|
@ -5,7 +5,6 @@ use lemmy_db_schema::{
|
|||
comment::{Comment, CommentActions},
|
||||
community::{Community, CommunityActions},
|
||||
images::ImageDetails,
|
||||
instance::InstanceActions,
|
||||
person::{Person, PersonActions},
|
||||
post::{Post, PostActions},
|
||||
tag::TagsView,
|
||||
|
@ -21,11 +20,13 @@ use {
|
|||
diesel::{Queryable, Selectable},
|
||||
lemmy_db_schema::utils::queries::{
|
||||
creator_banned,
|
||||
creator_banned_from_community,
|
||||
creator_is_admin,
|
||||
creator_is_moderator,
|
||||
local_user_can_mod,
|
||||
post_tags_fragment,
|
||||
},
|
||||
lemmy_db_schema::utils::queries::{creator_banned_from_community, creator_is_moderator},
|
||||
|
||||
lemmy_db_views_local_user::LocalUserView,
|
||||
};
|
||||
|
||||
|
@ -50,8 +51,6 @@ pub(crate) struct PersonContentCombinedViewInternal {
|
|||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub community_actions: Option<CommunityActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub instance_actions: Option<InstanceActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub post_actions: Option<PostActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub person_actions: Option<PersonActions>,
|
||||
|
|
|
@ -33,7 +33,6 @@ use lemmy_db_schema::{
|
|||
image_details_join,
|
||||
my_comment_actions_join,
|
||||
my_community_actions_join,
|
||||
my_instance_actions_person_join,
|
||||
my_local_user_admin_join,
|
||||
my_person_actions_join,
|
||||
my_post_actions_join,
|
||||
|
@ -122,8 +121,6 @@ impl PersonLikedCombinedViewInternal {
|
|||
my_comment_actions_join(Some(my_person_id));
|
||||
let my_local_user_admin_join: my_local_user_admin_join =
|
||||
my_local_user_admin_join(Some(my_person_id));
|
||||
let my_instance_actions_person_join: my_instance_actions_person_join =
|
||||
my_instance_actions_person_join(Some(my_person_id));
|
||||
let my_person_actions_join: my_person_actions_join = my_person_actions_join(Some(my_person_id));
|
||||
let creator_local_instance_actions_join: creator_local_instance_actions_join =
|
||||
creator_local_instance_actions_join(local_instance_id);
|
||||
|
@ -131,20 +128,20 @@ impl PersonLikedCombinedViewInternal {
|
|||
person_liked_combined::table
|
||||
.left_join(comment_join)
|
||||
.inner_join(post_join)
|
||||
.inner_join(item_creator_join)
|
||||
.inner_join(community_join())
|
||||
.inner_join(item_creator_join)
|
||||
.left_join(image_details_join())
|
||||
.left_join(creator_community_actions_join())
|
||||
.left_join(my_local_user_admin_join)
|
||||
.left_join(creator_local_user_admin_join())
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_instance_actions_person_join)
|
||||
.left_join(creator_home_instance_actions_join())
|
||||
.left_join(creator_community_instance_actions_join())
|
||||
.left_join(creator_local_instance_actions_join)
|
||||
// The my_'s have to come last to avoid stack overflows
|
||||
.left_join(my_post_actions_join)
|
||||
.left_join(my_person_actions_join)
|
||||
.left_join(my_comment_actions_join)
|
||||
.left_join(image_details_join())
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_local_user_admin_join)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,7 +226,6 @@ impl InternalToCombinedView for PersonLikedCombinedViewInternal {
|
|||
community_actions: v.community_actions,
|
||||
comment_actions: v.comment_actions,
|
||||
person_actions: v.person_actions,
|
||||
instance_actions: v.instance_actions,
|
||||
creator_is_admin: v.item_creator_is_admin,
|
||||
post_tags: v.post_tags,
|
||||
can_mod: v.can_mod,
|
||||
|
@ -246,7 +242,6 @@ impl InternalToCombinedView for PersonLikedCombinedViewInternal {
|
|||
community_actions: v.community_actions,
|
||||
post_actions: v.post_actions,
|
||||
person_actions: v.person_actions,
|
||||
instance_actions: v.instance_actions,
|
||||
creator_is_admin: v.item_creator_is_admin,
|
||||
tags: v.post_tags,
|
||||
can_mod: v.can_mod,
|
||||
|
|
|
@ -5,7 +5,6 @@ use lemmy_db_schema::{
|
|||
comment::{Comment, CommentActions},
|
||||
community::{Community, CommunityActions},
|
||||
images::ImageDetails,
|
||||
instance::InstanceActions,
|
||||
person::{Person, PersonActions},
|
||||
post::{Post, PostActions},
|
||||
tag::TagsView,
|
||||
|
@ -23,9 +22,11 @@ use {
|
|||
lemmy_db_schema::utils::queries::{
|
||||
creator_banned_from_community,
|
||||
creator_banned_within_community,
|
||||
creator_is_admin,
|
||||
creator_is_moderator,
|
||||
local_user_can_mod,
|
||||
post_tags_fragment,
|
||||
},
|
||||
lemmy_db_schema::utils::queries::{creator_is_admin, local_user_can_mod, post_tags_fragment},
|
||||
lemmy_db_views_local_user::LocalUserView,
|
||||
};
|
||||
|
||||
|
@ -50,8 +51,6 @@ pub(crate) struct PersonLikedCombinedViewInternal {
|
|||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub community_actions: Option<CommunityActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub instance_actions: Option<InstanceActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub post_actions: Option<PostActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub person_actions: Option<PersonActions>,
|
||||
|
|
|
@ -33,7 +33,6 @@ use lemmy_db_schema::{
|
|||
image_details_join,
|
||||
my_comment_actions_join,
|
||||
my_community_actions_join,
|
||||
my_instance_actions_person_join,
|
||||
my_local_user_admin_join,
|
||||
my_person_actions_join,
|
||||
my_post_actions_join,
|
||||
|
@ -120,8 +119,6 @@ impl PersonSavedCombinedViewInternal {
|
|||
my_comment_actions_join(Some(my_person_id));
|
||||
let my_local_user_admin_join: my_local_user_admin_join =
|
||||
my_local_user_admin_join(Some(my_person_id));
|
||||
let my_instance_actions_person_join: my_instance_actions_person_join =
|
||||
my_instance_actions_person_join(Some(my_person_id));
|
||||
let my_person_actions_join: my_person_actions_join = my_person_actions_join(Some(my_person_id));
|
||||
let creator_local_instance_actions_join: creator_local_instance_actions_join =
|
||||
creator_local_instance_actions_join(local_instance_id);
|
||||
|
@ -131,18 +128,17 @@ impl PersonSavedCombinedViewInternal {
|
|||
.inner_join(post_join)
|
||||
.inner_join(item_creator_join)
|
||||
.inner_join(community_join())
|
||||
.left_join(image_details_join())
|
||||
.left_join(creator_community_actions_join())
|
||||
.left_join(my_local_user_admin_join)
|
||||
.left_join(creator_local_user_admin_join())
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_instance_actions_person_join)
|
||||
.left_join(creator_home_instance_actions_join())
|
||||
.left_join(creator_community_instance_actions_join())
|
||||
.left_join(creator_local_instance_actions_join)
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_local_user_admin_join)
|
||||
.left_join(my_post_actions_join)
|
||||
.left_join(my_person_actions_join)
|
||||
.left_join(my_comment_actions_join)
|
||||
.left_join(image_details_join())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,7 +215,6 @@ impl InternalToCombinedView for PersonSavedCombinedViewInternal {
|
|||
community_actions: v.community_actions,
|
||||
comment_actions: v.comment_actions,
|
||||
person_actions: v.person_actions,
|
||||
instance_actions: v.instance_actions,
|
||||
creator_is_admin: v.item_creator_is_admin,
|
||||
post_tags: v.post_tags,
|
||||
can_mod: v.can_mod,
|
||||
|
@ -236,7 +231,6 @@ impl InternalToCombinedView for PersonSavedCombinedViewInternal {
|
|||
community_actions: v.community_actions,
|
||||
post_actions: v.post_actions,
|
||||
person_actions: v.person_actions,
|
||||
instance_actions: v.instance_actions,
|
||||
creator_is_admin: v.item_creator_is_admin,
|
||||
tags: v.post_tags,
|
||||
can_mod: v.can_mod,
|
||||
|
|
|
@ -5,7 +5,6 @@ use lemmy_db_schema::{
|
|||
comment::{Comment, CommentActions},
|
||||
community::{Community, CommunityActions},
|
||||
images::ImageDetails,
|
||||
instance::InstanceActions,
|
||||
person::{Person, PersonActions},
|
||||
post::{Post, PostActions},
|
||||
tag::TagsView,
|
||||
|
@ -22,9 +21,12 @@ use {
|
|||
lemmy_db_schema::utils::queries::{
|
||||
creator_banned_from_community,
|
||||
creator_banned_within_community,
|
||||
creator_is_admin,
|
||||
creator_is_moderator,
|
||||
local_user_can_mod,
|
||||
post_tags_fragment,
|
||||
},
|
||||
lemmy_db_schema::utils::queries::{creator_is_admin, local_user_can_mod, post_tags_fragment},
|
||||
|
||||
lemmy_db_views_local_user::LocalUserView,
|
||||
};
|
||||
|
||||
|
@ -49,8 +51,6 @@ pub(crate) struct PersonSavedCombinedViewInternal {
|
|||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub community_actions: Option<CommunityActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub instance_actions: Option<InstanceActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub post_actions: Option<PostActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub person_actions: Option<PersonActions>,
|
||||
|
|
|
@ -41,7 +41,8 @@ use lemmy_db_schema::{
|
|||
filter_not_unlisted_or_is_subscribed,
|
||||
image_details_join,
|
||||
my_community_actions_join,
|
||||
my_instance_actions_community_join,
|
||||
my_instance_communities_actions_join,
|
||||
my_instance_persons_actions_join_1,
|
||||
my_local_user_admin_join,
|
||||
my_person_actions_join,
|
||||
my_post_actions_join,
|
||||
|
@ -98,8 +99,10 @@ impl PostView {
|
|||
my_community_actions_join(my_person_id);
|
||||
let my_post_actions_join: my_post_actions_join = my_post_actions_join(my_person_id);
|
||||
let my_local_user_admin_join: my_local_user_admin_join = my_local_user_admin_join(my_person_id);
|
||||
let my_instance_actions_community_join: my_instance_actions_community_join =
|
||||
my_instance_actions_community_join(my_person_id);
|
||||
let my_instance_communities_actions_join: my_instance_communities_actions_join =
|
||||
my_instance_communities_actions_join(my_person_id);
|
||||
let my_instance_persons_actions_join_1: my_instance_persons_actions_join_1 =
|
||||
my_instance_persons_actions_join_1(my_person_id);
|
||||
let my_person_actions_join: my_person_actions_join = my_person_actions_join(my_person_id);
|
||||
let creator_local_instance_actions_join: creator_local_instance_actions_join =
|
||||
creator_local_instance_actions_join(local_instance_id);
|
||||
|
@ -108,15 +111,16 @@ impl PostView {
|
|||
.inner_join(person::table)
|
||||
.inner_join(community::table)
|
||||
.left_join(image_details_join())
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_person_actions_join)
|
||||
.left_join(my_post_actions_join)
|
||||
.left_join(my_instance_actions_community_join)
|
||||
.left_join(my_local_user_admin_join)
|
||||
.left_join(creator_home_instance_actions_join())
|
||||
.left_join(creator_community_instance_actions_join())
|
||||
.left_join(creator_local_instance_actions_join)
|
||||
.left_join(creator_community_actions_join())
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_person_actions_join)
|
||||
.left_join(my_post_actions_join)
|
||||
.left_join(my_instance_communities_actions_join)
|
||||
.left_join(my_instance_persons_actions_join_1)
|
||||
.left_join(my_local_user_admin_join)
|
||||
}
|
||||
|
||||
pub async fn read(
|
||||
|
@ -583,7 +587,13 @@ mod tests {
|
|||
CommunityPersonBanForm,
|
||||
CommunityUpdateForm,
|
||||
},
|
||||
instance::{Instance, InstanceActions, InstanceBanForm, InstanceBlockForm},
|
||||
instance::{
|
||||
Instance,
|
||||
InstanceActions,
|
||||
InstanceBanForm,
|
||||
InstanceCommunitiesBlockForm,
|
||||
InstancePersonsBlockForm,
|
||||
},
|
||||
keyword_block::LocalUserKeywordBlock,
|
||||
language::Language,
|
||||
local_site::{LocalSite, LocalSiteUpdateForm},
|
||||
|
@ -1541,10 +1551,12 @@ mod tests {
|
|||
#[test_context(Data)]
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn post_listing_instance_block(data: &mut Data) -> LemmyResult<()> {
|
||||
const POST_FROM_BLOCKED_INSTANCE: &str = "post on blocked instance";
|
||||
const POST_LISTING_WITH_BLOCKED: [&str; 4] = [
|
||||
POST_FROM_BLOCKED_INSTANCE,
|
||||
async fn post_listing_instance_block_communities(data: &mut Data) -> LemmyResult<()> {
|
||||
const POST_FROM_BLOCKED_INSTANCE_COMMS: &str = "post on blocked instance";
|
||||
const HOWARD_POST: &str = "howard post";
|
||||
const POST_LISTING_WITH_BLOCKED: [&str; 5] = [
|
||||
HOWARD_POST,
|
||||
POST_FROM_BLOCKED_INSTANCE_COMMS,
|
||||
POST_WITH_TAGS,
|
||||
POST_BY_BOT,
|
||||
POST,
|
||||
|
@ -1553,10 +1565,11 @@ mod tests {
|
|||
let pool = &data.pool();
|
||||
let pool = &mut pool.into();
|
||||
|
||||
let blocked_instance = Instance::read_or_create(pool, "another_domain.tld".to_string()).await?;
|
||||
let blocked_instance_comms =
|
||||
Instance::read_or_create(pool, "another_domain.tld".to_string()).await?;
|
||||
|
||||
let community_form = CommunityInsertForm::new(
|
||||
blocked_instance.id,
|
||||
blocked_instance_comms.id,
|
||||
"test_community_4".to_string(),
|
||||
"none".to_owned(),
|
||||
"pubkey".to_string(),
|
||||
|
@ -1566,25 +1579,37 @@ mod tests {
|
|||
let post_form = PostInsertForm {
|
||||
language_id: Some(LanguageId(1)),
|
||||
..PostInsertForm::new(
|
||||
POST_FROM_BLOCKED_INSTANCE.to_string(),
|
||||
POST_FROM_BLOCKED_INSTANCE_COMMS.to_string(),
|
||||
data.bot.person.id,
|
||||
inserted_community.id,
|
||||
)
|
||||
};
|
||||
let post_from_blocked_instance = Post::create(pool, &post_form).await?;
|
||||
|
||||
// Create a person on that comm-blocked instance,
|
||||
// have them create a post from a non-instance-comm blocked community.
|
||||
// Make sure others can see it.
|
||||
let howard_form = PersonInsertForm::test_form(blocked_instance_comms.id, "howard");
|
||||
let howard = Person::create(pool, &howard_form).await?;
|
||||
let howard_post_form = PostInsertForm {
|
||||
language_id: Some(LanguageId(1)),
|
||||
..PostInsertForm::new(HOWARD_POST.to_string(), howard.id, data.community.id)
|
||||
};
|
||||
let _post_from_blocked_instance_user = Post::create(pool, &howard_post_form).await?;
|
||||
|
||||
// no instance block, should return all posts
|
||||
let post_listings_all = data.default_post_query().list(&data.site, pool).await?;
|
||||
assert_eq!(POST_LISTING_WITH_BLOCKED, *names(&post_listings_all));
|
||||
|
||||
// block the instance
|
||||
let block_form = InstanceBlockForm::new(data.tegan.person.id, blocked_instance.id);
|
||||
InstanceActions::block(pool, &block_form).await?;
|
||||
// block the instance communities
|
||||
let block_form =
|
||||
InstanceCommunitiesBlockForm::new(data.tegan.person.id, blocked_instance_comms.id);
|
||||
InstanceActions::block_communities(pool, &block_form).await?;
|
||||
|
||||
// now posts from communities on that instance should be hidden
|
||||
let post_listings_blocked = data.default_post_query().list(&data.site, pool).await?;
|
||||
assert_eq!(
|
||||
vec![POST_WITH_TAGS, POST_BY_BOT, POST],
|
||||
vec![HOWARD_POST, POST_WITH_TAGS, POST_BY_BOT, POST],
|
||||
names(&post_listings_blocked)
|
||||
);
|
||||
assert!(post_listings_blocked
|
||||
|
@ -1603,11 +1628,92 @@ mod tests {
|
|||
CommunityActions::unfollow(pool, data.tegan.person.id, inserted_community.id).await?;
|
||||
|
||||
// after unblocking it should return all posts again
|
||||
InstanceActions::unblock(pool, &block_form).await?;
|
||||
InstanceActions::unblock_communities(pool, &block_form).await?;
|
||||
let post_listings_blocked = data.default_post_query().list(&data.site, pool).await?;
|
||||
assert_eq!(POST_LISTING_WITH_BLOCKED, *names(&post_listings_blocked));
|
||||
|
||||
Instance::delete(pool, blocked_instance.id).await?;
|
||||
Instance::delete(pool, blocked_instance_comms.id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_context(Data)]
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn post_listing_instance_block_persons(data: &mut Data) -> LemmyResult<()> {
|
||||
const POST_FROM_BLOCKED_INSTANCE_USERS: &str = "post from blocked instance user";
|
||||
const POST_TO_UNBLOCKED_COMM: &str = "post to unblocked comm";
|
||||
const POST_LISTING_WITH_BLOCKED: [&str; 5] = [
|
||||
POST_TO_UNBLOCKED_COMM,
|
||||
POST_FROM_BLOCKED_INSTANCE_USERS,
|
||||
POST_WITH_TAGS,
|
||||
POST_BY_BOT,
|
||||
POST,
|
||||
];
|
||||
|
||||
let pool = &data.pool();
|
||||
let pool = &mut pool.into();
|
||||
|
||||
let blocked_instance_persons =
|
||||
Instance::read_or_create(pool, "another_domain.tld".to_string()).await?;
|
||||
|
||||
let howard_form = PersonInsertForm::test_form(blocked_instance_persons.id, "howard");
|
||||
let howard = Person::create(pool, &howard_form).await?;
|
||||
|
||||
let community_form = CommunityInsertForm::new(
|
||||
blocked_instance_persons.id,
|
||||
"test_community_8".to_string(),
|
||||
"none".to_owned(),
|
||||
"pubkey".to_string(),
|
||||
);
|
||||
let inserted_community = Community::create(pool, &community_form).await?;
|
||||
|
||||
// Create a post from the blocked user on a safe community
|
||||
let blocked_post_form = PostInsertForm {
|
||||
language_id: Some(LanguageId(1)),
|
||||
..PostInsertForm::new(
|
||||
POST_FROM_BLOCKED_INSTANCE_USERS.to_string(),
|
||||
howard.id,
|
||||
data.community.id,
|
||||
)
|
||||
};
|
||||
let post_from_blocked_instance = Post::create(pool, &blocked_post_form).await?;
|
||||
|
||||
// Also create a post from an unblocked user
|
||||
let unblocked_post_form = PostInsertForm {
|
||||
language_id: Some(LanguageId(1)),
|
||||
..PostInsertForm::new(
|
||||
POST_TO_UNBLOCKED_COMM.to_string(),
|
||||
data.bot.person.id,
|
||||
inserted_community.id,
|
||||
)
|
||||
};
|
||||
let _post_to_unblocked_comm = Post::create(pool, &unblocked_post_form).await?;
|
||||
|
||||
// no instance block, should return all posts
|
||||
let post_listings_all = data.default_post_query().list(&data.site, pool).await?;
|
||||
assert_eq!(POST_LISTING_WITH_BLOCKED, *names(&post_listings_all));
|
||||
|
||||
// block the instance communities
|
||||
let block_form =
|
||||
InstancePersonsBlockForm::new(data.tegan.person.id, blocked_instance_persons.id);
|
||||
InstanceActions::block_persons(pool, &block_form).await?;
|
||||
|
||||
// now posts from users on that instance should be hidden
|
||||
let post_listings_blocked = data.default_post_query().list(&data.site, pool).await?;
|
||||
assert_eq!(
|
||||
vec![POST_TO_UNBLOCKED_COMM, POST_WITH_TAGS, POST_BY_BOT, POST],
|
||||
names(&post_listings_blocked)
|
||||
);
|
||||
assert!(post_listings_blocked
|
||||
.iter()
|
||||
.all(|p| p.post.id != post_from_blocked_instance.id));
|
||||
|
||||
// after unblocking it should return all posts again
|
||||
InstanceActions::unblock_persons(pool, &block_form).await?;
|
||||
let post_listings_blocked = data.default_post_query().list(&data.site, pool).await?;
|
||||
assert_eq!(POST_LISTING_WITH_BLOCKED, *names(&post_listings_blocked));
|
||||
|
||||
Instance::delete(pool, blocked_instance_persons.id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -2011,11 +2117,6 @@ mod tests {
|
|||
|
||||
assert!(post_view.creator_banned);
|
||||
|
||||
// This should be none, since john wasn't banned, only the creator.
|
||||
assert!(post_view.instance_actions.is_none());
|
||||
|
||||
assert!(post_view.creator_banned);
|
||||
|
||||
Person::delete(pool, banned_person.id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use lemmy_db_schema::source::{
|
||||
community::{Community, CommunityActions},
|
||||
images::ImageDetails,
|
||||
instance::InstanceActions,
|
||||
person::{Person, PersonActions},
|
||||
post::{Post, PostActions},
|
||||
tag::TagsView,
|
||||
|
@ -16,8 +15,6 @@ use {
|
|||
lemmy_db_schema::utils::queries::{
|
||||
creator_banned_from_community,
|
||||
creator_banned_within_community,
|
||||
},
|
||||
lemmy_db_schema::utils::queries::{
|
||||
creator_is_moderator,
|
||||
local_user_can_mod_post,
|
||||
post_creator_is_admin,
|
||||
|
@ -50,8 +47,6 @@ pub struct PostView {
|
|||
pub person_actions: Option<PersonActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub post_actions: Option<PostActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub instance_actions: Option<InstanceActions>,
|
||||
#[cfg_attr(feature = "full",
|
||||
diesel(
|
||||
select_expression = post_creator_is_admin()
|
||||
|
|
|
@ -43,7 +43,6 @@ use lemmy_db_schema::{
|
|||
image_details_join,
|
||||
my_comment_actions_join,
|
||||
my_community_actions_join,
|
||||
my_instance_actions_person_join,
|
||||
my_local_user_admin_join,
|
||||
my_person_actions_join,
|
||||
my_post_actions_join,
|
||||
|
@ -133,8 +132,6 @@ impl SearchCombinedViewInternal {
|
|||
let my_post_actions_join: my_post_actions_join = my_post_actions_join(my_person_id);
|
||||
let my_comment_actions_join: my_comment_actions_join = my_comment_actions_join(my_person_id);
|
||||
let my_local_user_admin_join: my_local_user_admin_join = my_local_user_admin_join(my_person_id);
|
||||
let my_instance_actions_person_join: my_instance_actions_person_join =
|
||||
my_instance_actions_person_join(my_person_id);
|
||||
let my_person_actions_join: my_person_actions_join = my_person_actions_join(my_person_id);
|
||||
let creator_local_instance_actions_join: creator_local_instance_actions_join =
|
||||
creator_local_instance_actions_join(local_instance_id);
|
||||
|
@ -145,17 +142,16 @@ impl SearchCombinedViewInternal {
|
|||
.left_join(multi_community_join)
|
||||
.left_join(item_creator_join)
|
||||
.left_join(community_join)
|
||||
.left_join(image_details_join())
|
||||
.left_join(creator_community_actions_join())
|
||||
.left_join(my_local_user_admin_join)
|
||||
.left_join(creator_local_user_admin_join())
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_instance_actions_person_join)
|
||||
.left_join(creator_home_instance_actions_join())
|
||||
.left_join(creator_local_instance_actions_join)
|
||||
.left_join(my_local_user_admin_join)
|
||||
.left_join(my_community_actions_join)
|
||||
.left_join(my_post_actions_join)
|
||||
.left_join(my_person_actions_join)
|
||||
.left_join(my_comment_actions_join)
|
||||
.left_join(image_details_join())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,7 +424,6 @@ impl InternalToCombinedView for SearchCombinedViewInternal {
|
|||
community,
|
||||
creator,
|
||||
community_actions: v.community_actions,
|
||||
instance_actions: v.instance_actions,
|
||||
person_actions: v.person_actions,
|
||||
comment_actions: v.comment_actions,
|
||||
creator_is_admin: v.item_creator_is_admin,
|
||||
|
@ -448,7 +443,6 @@ impl InternalToCombinedView for SearchCombinedViewInternal {
|
|||
creator_is_admin: v.item_creator_is_admin,
|
||||
image_details: v.image_details,
|
||||
community_actions: v.community_actions,
|
||||
instance_actions: v.instance_actions,
|
||||
person_actions: v.person_actions,
|
||||
post_actions: v.post_actions,
|
||||
tags: v.post_tags,
|
||||
|
@ -461,7 +455,6 @@ impl InternalToCombinedView for SearchCombinedViewInternal {
|
|||
Some(SearchCombinedView::Community(CommunityView {
|
||||
community,
|
||||
community_actions: v.community_actions,
|
||||
instance_actions: v.instance_actions,
|
||||
can_mod: v.can_mod,
|
||||
post_tags: v.community_post_tags,
|
||||
}))
|
||||
|
|
|
@ -5,7 +5,6 @@ use lemmy_db_schema::{
|
|||
comment::{Comment, CommentActions},
|
||||
community::{Community, CommunityActions},
|
||||
images::ImageDetails,
|
||||
instance::InstanceActions,
|
||||
multi_community::MultiCommunity,
|
||||
person::{Person, PersonActions},
|
||||
post::{Post, PostActions},
|
||||
|
@ -58,8 +57,6 @@ pub(crate) struct SearchCombinedViewInternal {
|
|||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub community_actions: Option<CommunityActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub instance_actions: Option<InstanceActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub post_actions: Option<PostActions>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub person_actions: Option<PersonActions>,
|
||||
|
|
|
@ -439,7 +439,8 @@ pub struct MyUserInfo {
|
|||
pub follows: Vec<CommunityFollowerView>,
|
||||
pub moderates: Vec<CommunityModeratorView>,
|
||||
pub community_blocks: Vec<Community>,
|
||||
pub instance_blocks: Vec<Instance>,
|
||||
pub instance_communities_blocks: Vec<Instance>,
|
||||
pub instance_persons_blocks: Vec<Instance>,
|
||||
pub person_blocks: Vec<Person>,
|
||||
pub keyword_blocks: Vec<String>,
|
||||
pub discussion_languages: Vec<LanguageId>,
|
||||
|
@ -561,8 +562,17 @@ pub struct UpdateTotpResponse {
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
/// Block an instance as user
|
||||
pub struct UserBlockInstanceParams {
|
||||
/// Block an instance's persons.
|
||||
pub struct UserBlockInstancePersonsParams {
|
||||
pub instance_id: InstanceId,
|
||||
pub block: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
/// Block an instance's communities.
|
||||
pub struct UserBlockInstanceCommunitiesParams {
|
||||
pub instance_id: InstanceId,
|
||||
pub block: bool,
|
||||
}
|
||||
|
@ -713,6 +723,7 @@ pub enum PostOrCommentOrPrivateMessage {
|
|||
/// Be careful with any changes to this struct, to avoid breaking changes which could prevent
|
||||
/// importing older backups.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
pub struct UserSettingsBackup {
|
||||
|
@ -736,7 +747,10 @@ pub struct UserSettingsBackup {
|
|||
#[serde(default)]
|
||||
pub blocked_users: Vec<Url>,
|
||||
#[serde(default)]
|
||||
pub blocked_instances: Vec<String>,
|
||||
#[serde(alias = "blocked_instances")] // the name used by v0.19
|
||||
pub blocked_instances_communities: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub blocked_instances_persons: Vec<String>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
|
|
|
@ -62,7 +62,8 @@ pub fn user_backup_list_to_user_settings_backup(
|
|||
settings: Some(local_user_view.local_user),
|
||||
followed_communities: vec_into(lists.followed_communities),
|
||||
blocked_communities: vec_into(lists.blocked_communities),
|
||||
blocked_instances: lists.blocked_instances,
|
||||
blocked_instances_communities: lists.blocked_instances_communities,
|
||||
blocked_instances_persons: lists.blocked_instances_persons,
|
||||
blocked_users: vec_into(lists.blocked_users),
|
||||
saved_posts: vec_into(lists.saved_posts),
|
||||
saved_comments: vec_into(lists.saved_comments),
|
||||
|
|
|
@ -151,7 +151,7 @@ impl<T: DataSource> CommunityInboxCollector<T> {
|
|||
// happens much later - by doing it here, we can ensure that in the happy case, this
|
||||
// function returns 0 urls which means the system doesn't have to create a tokio
|
||||
// task for sending at all (since that task has a fair amount of overhead)
|
||||
.filter(|&u| (u.domain() == Some(&self.domain)))
|
||||
.filter(|&u| u.domain() == Some(&self.domain))
|
||||
.map(|u| u.inner().clone()),
|
||||
);
|
||||
tracing::trace!(
|
||||
|
|
|
@ -129,7 +129,8 @@ pub enum LemmyErrorType {
|
|||
InvalidUrlScheme,
|
||||
CouldntSendWebmention,
|
||||
ContradictingFilters,
|
||||
InstanceBlockAlreadyExists,
|
||||
InstanceBlockCommunitiesAlreadyExists,
|
||||
InstanceBlockPersonsAlreadyExists,
|
||||
/// Thrown when an API call is submitted with more than 1000 array elements, see
|
||||
/// [[MAX_API_PARAM_ELEMENTS]]
|
||||
TooManyItems,
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE instance_actions RENAME COLUMN blocked_communities_at TO blocked_at;
|
||||
|
||||
ALTER TABLE instance_actions
|
||||
DROP COLUMN blocked_persons_at;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
-- Currently, the instance.blocked_at columns only blocks communities from the given instance.
|
||||
--
|
||||
-- This creates a new block type, to also be able to block persons.
|
||||
-- Also changes the name of blocked_at to blocked_communities_at
|
||||
ALTER TABLE instance_actions RENAME COLUMN blocked_at TO blocked_communities_at;
|
||||
|
||||
ALTER TABLE instance_actions
|
||||
ADD COLUMN blocked_persons_at timestamptz;
|
||||
|
|
@ -52,7 +52,7 @@ use lemmy_api::{
|
|||
reset_password::reset_password,
|
||||
save_settings::save_user_settings,
|
||||
update_totp::update_totp,
|
||||
user_block_instance::user_block_instance,
|
||||
user_block_instance::{user_block_instance_communities, user_block_instance_persons},
|
||||
validate_auth::validate_auth,
|
||||
verify_email::verify_email,
|
||||
},
|
||||
|
@ -382,7 +382,11 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimit) {
|
|||
scope("/block")
|
||||
.route("/person", post().to(user_block_person))
|
||||
.route("/community", post().to(user_block_community))
|
||||
.route("/instance", post().to(user_block_instance)),
|
||||
.route(
|
||||
"/instance/communities",
|
||||
post().to(user_block_instance_communities),
|
||||
)
|
||||
.route("/instance/persons", post().to(user_block_instance_persons)),
|
||||
)
|
||||
.route("/saved", get().to(list_person_saved))
|
||||
.route("/read", get().to(list_person_read))
|
||||
|
|
Loading…
Reference in a new issue