mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-10-01 01:36:12 -04:00
Merge remote-tracking branch 'origin/main' into reject_federated_votes
This commit is contained in:
commit
a3b7a46e93
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2538,6 +2538,7 @@ dependencies = [
|
|||||||
"actix-web",
|
"actix-web",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bcrypt",
|
"bcrypt",
|
||||||
|
"chrono",
|
||||||
"futures",
|
"futures",
|
||||||
"lemmy_api_common",
|
"lemmy_api_common",
|
||||||
"lemmy_db_schema",
|
"lemmy_db_schema",
|
||||||
|
@ -21,16 +21,16 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
"@types/node": "^22.0.2",
|
"@types/node": "^22.3.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
"@typescript-eslint/eslint-plugin": "^8.1.0",
|
||||||
"@typescript-eslint/parser": "^8.0.0",
|
"@typescript-eslint/parser": "^8.1.0",
|
||||||
"eslint": "^9.8.0",
|
"eslint": "^9.9.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"jest": "^29.5.0",
|
"jest": "^29.5.0",
|
||||||
"lemmy-js-client": "0.20.0-alpha.4",
|
"lemmy-js-client": "0.20.0-alpha.11",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"ts-jest": "^29.1.0",
|
"ts-jest": "^29.1.0",
|
||||||
"typescript": "^5.5.4",
|
"typescript": "^5.5.4",
|
||||||
"typescript-eslint": "^8.0.0"
|
"typescript-eslint": "^8.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,16 +12,16 @@ importers:
|
|||||||
specifier: ^29.5.12
|
specifier: ^29.5.12
|
||||||
version: 29.5.12
|
version: 29.5.12
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.0.2
|
specifier: ^22.3.0
|
||||||
version: 22.3.0
|
version: 22.3.0
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ^8.0.0
|
specifier: ^8.1.0
|
||||||
version: 8.1.0(@typescript-eslint/parser@8.1.0(eslint@9.9.0)(typescript@5.5.4))(eslint@9.9.0)(typescript@5.5.4)
|
version: 8.1.0(@typescript-eslint/parser@8.1.0(eslint@9.9.0)(typescript@5.5.4))(eslint@9.9.0)(typescript@5.5.4)
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: ^8.0.0
|
specifier: ^8.1.0
|
||||||
version: 8.1.0(eslint@9.9.0)(typescript@5.5.4)
|
version: 8.1.0(eslint@9.9.0)(typescript@5.5.4)
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^9.8.0
|
specifier: ^9.9.0
|
||||||
version: 9.9.0
|
version: 9.9.0
|
||||||
eslint-plugin-prettier:
|
eslint-plugin-prettier:
|
||||||
specifier: ^5.1.3
|
specifier: ^5.1.3
|
||||||
@ -30,8 +30,8 @@ importers:
|
|||||||
specifier: ^29.5.0
|
specifier: ^29.5.0
|
||||||
version: 29.7.0(@types/node@22.3.0)
|
version: 29.7.0(@types/node@22.3.0)
|
||||||
lemmy-js-client:
|
lemmy-js-client:
|
||||||
specifier: 0.20.0-alpha.4
|
specifier: 0.20.0-alpha.11
|
||||||
version: 0.20.0-alpha.4
|
version: 0.20.0-alpha.11
|
||||||
prettier:
|
prettier:
|
||||||
specifier: ^3.2.5
|
specifier: ^3.2.5
|
||||||
version: 3.3.3
|
version: 3.3.3
|
||||||
@ -42,7 +42,7 @@ importers:
|
|||||||
specifier: ^5.5.4
|
specifier: ^5.5.4
|
||||||
version: 5.5.4
|
version: 5.5.4
|
||||||
typescript-eslint:
|
typescript-eslint:
|
||||||
specifier: ^8.0.0
|
specifier: ^8.1.0
|
||||||
version: 8.1.0(eslint@9.9.0)(typescript@5.5.4)
|
version: 8.1.0(eslint@9.9.0)(typescript@5.5.4)
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
@ -1175,8 +1175,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
|
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
lemmy-js-client@0.20.0-alpha.4:
|
lemmy-js-client@0.20.0-alpha.11:
|
||||||
resolution: {integrity: sha512-MuVE8u/IFz59ks2vxOUXMRU8x6SIz3Keu4zRhmhNt+n+gI25JAggsTDrtxVCBtrqBhFEe+a3PdXdwm+fXbs0Dw==}
|
resolution: {integrity: sha512-iRSG4xHMjPDIreQqVIoJ5JrMY71uk07G0Zbgyf068xKbib22J3+i1x/XgCTs6tiHlqTnw1Ig/KRq7p7qJoA4uw==}
|
||||||
|
|
||||||
leven@3.1.0:
|
leven@3.1.0:
|
||||||
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
|
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
|
||||||
@ -3107,7 +3107,7 @@ snapshots:
|
|||||||
|
|
||||||
kleur@3.0.3: {}
|
kleur@3.0.3: {}
|
||||||
|
|
||||||
lemmy-js-client@0.20.0-alpha.4: {}
|
lemmy-js-client@0.20.0-alpha.11: {}
|
||||||
|
|
||||||
leven@3.1.0: {}
|
leven@3.1.0: {}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ test("Create a comment", async () => {
|
|||||||
|
|
||||||
test("Create a comment in a non-existent post", async () => {
|
test("Create a comment in a non-existent post", async () => {
|
||||||
await expect(createComment(alpha, -1)).rejects.toStrictEqual(
|
await expect(createComment(alpha, -1)).rejects.toStrictEqual(
|
||||||
Error("couldnt_find_post"),
|
Error("not_found"),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ test("Delete a comment", async () => {
|
|||||||
await waitUntil(
|
await waitUntil(
|
||||||
() =>
|
() =>
|
||||||
resolveComment(gamma, commentRes.comment_view.comment).catch(e => e),
|
resolveComment(gamma, commentRes.comment_view.comment).catch(e => e),
|
||||||
r => r.message !== "couldnt_find_object",
|
r => r.message !== "not_found",
|
||||||
)
|
)
|
||||||
).comment;
|
).comment;
|
||||||
if (!gammaComment) {
|
if (!gammaComment) {
|
||||||
@ -161,13 +161,13 @@ test("Delete a comment", async () => {
|
|||||||
// Make sure that comment is undefined on beta
|
// Make sure that comment is undefined on beta
|
||||||
await waitUntil(
|
await waitUntil(
|
||||||
() => resolveComment(beta, commentRes.comment_view.comment).catch(e => e),
|
() => resolveComment(beta, commentRes.comment_view.comment).catch(e => e),
|
||||||
e => e.message == "couldnt_find_object",
|
e => e.message == "not_found",
|
||||||
);
|
);
|
||||||
|
|
||||||
// Make sure that comment is undefined on gamma after delete
|
// Make sure that comment is undefined on gamma after delete
|
||||||
await waitUntil(
|
await waitUntil(
|
||||||
() => resolveComment(gamma, commentRes.comment_view.comment).catch(e => e),
|
() => resolveComment(gamma, commentRes.comment_view.comment).catch(e => e),
|
||||||
e => e.message === "couldnt_find_object",
|
e => e.message === "not_found",
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test undeleting the comment
|
// Test undeleting the comment
|
||||||
@ -182,7 +182,7 @@ test("Delete a comment", async () => {
|
|||||||
let betaComment2 = (
|
let betaComment2 = (
|
||||||
await waitUntil(
|
await waitUntil(
|
||||||
() => resolveComment(beta, commentRes.comment_view.comment).catch(e => e),
|
() => resolveComment(beta, commentRes.comment_view.comment).catch(e => e),
|
||||||
e => e.message !== "couldnt_find_object",
|
e => e.message !== "not_found",
|
||||||
)
|
)
|
||||||
).comment;
|
).comment;
|
||||||
expect(betaComment2?.comment.deleted).toBe(false);
|
expect(betaComment2?.comment.deleted).toBe(false);
|
||||||
|
@ -527,12 +527,12 @@ test("Content in local-only community doesn't federate", async () => {
|
|||||||
// cant resolve the community from another instance
|
// cant resolve the community from another instance
|
||||||
await expect(
|
await expect(
|
||||||
resolveCommunity(beta, communityRes.actor_id),
|
resolveCommunity(beta, communityRes.actor_id),
|
||||||
).rejects.toStrictEqual(Error("couldnt_find_object"));
|
).rejects.toStrictEqual(Error("not_found"));
|
||||||
|
|
||||||
// create a post, also cant resolve it
|
// create a post, also cant resolve it
|
||||||
let postRes = await createPost(alpha, communityRes.id);
|
let postRes = await createPost(alpha, communityRes.id);
|
||||||
await expect(resolvePost(beta, postRes.post_view.post)).rejects.toStrictEqual(
|
await expect(resolvePost(beta, postRes.post_view.post)).rejects.toStrictEqual(
|
||||||
Error("couldnt_find_object"),
|
Error("not_found"),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -125,12 +125,12 @@ test("Create a post", async () => {
|
|||||||
// Delta only follows beta, so it should not see an alpha ap_id
|
// Delta only follows beta, so it should not see an alpha ap_id
|
||||||
await expect(
|
await expect(
|
||||||
resolvePost(delta, postRes.post_view.post),
|
resolvePost(delta, postRes.post_view.post),
|
||||||
).rejects.toStrictEqual(Error("couldnt_find_object"));
|
).rejects.toStrictEqual(Error("not_found"));
|
||||||
|
|
||||||
// Epsilon has alpha blocked, it should not see the alpha post
|
// Epsilon has alpha blocked, it should not see the alpha post
|
||||||
await expect(
|
await expect(
|
||||||
resolvePost(epsilon, postRes.post_view.post),
|
resolvePost(epsilon, postRes.post_view.post),
|
||||||
).rejects.toStrictEqual(Error("couldnt_find_object"));
|
).rejects.toStrictEqual(Error("not_found"));
|
||||||
|
|
||||||
// remove added allow/blocklists
|
// remove added allow/blocklists
|
||||||
editSiteForm.allowed_instances = [];
|
editSiteForm.allowed_instances = [];
|
||||||
@ -140,9 +140,7 @@ test("Create a post", async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("Create a post in a non-existent community", async () => {
|
test("Create a post in a non-existent community", async () => {
|
||||||
await expect(createPost(alpha, -2)).rejects.toStrictEqual(
|
await expect(createPost(alpha, -2)).rejects.toStrictEqual(Error("not_found"));
|
||||||
Error("couldnt_find_community"),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Unlike a post", async () => {
|
test("Unlike a post", async () => {
|
||||||
@ -630,7 +628,7 @@ test("Enforce community ban for federated user", async () => {
|
|||||||
// Alpha tries to make post on beta, but it fails because of ban
|
// Alpha tries to make post on beta, but it fails because of ban
|
||||||
await expect(
|
await expect(
|
||||||
createPost(alpha, betaCommunity.community.id),
|
createPost(alpha, betaCommunity.community.id),
|
||||||
).rejects.toStrictEqual(Error("banned_from_community"));
|
).rejects.toStrictEqual(Error("person_is_banned_from_community"));
|
||||||
|
|
||||||
// Unban alpha
|
// Unban alpha
|
||||||
let unBanAlpha = await banPersonFromCommunity(
|
let unBanAlpha = await banPersonFromCommunity(
|
||||||
|
@ -690,7 +690,7 @@ export async function saveUserSettingsBio(
|
|||||||
blur_nsfw: false,
|
blur_nsfw: false,
|
||||||
auto_expand: true,
|
auto_expand: true,
|
||||||
theme: "darkly",
|
theme: "darkly",
|
||||||
default_sort_type: "Active",
|
default_post_sort_type: "Active",
|
||||||
default_listing_type: "All",
|
default_listing_type: "All",
|
||||||
interface_language: "en",
|
interface_language: "en",
|
||||||
show_avatars: true,
|
show_avatars: true,
|
||||||
@ -710,7 +710,7 @@ export async function saveUserSettingsFederated(
|
|||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
blur_nsfw: true,
|
blur_nsfw: true,
|
||||||
auto_expand: false,
|
auto_expand: false,
|
||||||
default_sort_type: "Hot",
|
default_post_sort_type: "Hot",
|
||||||
default_listing_type: "All",
|
default_listing_type: "All",
|
||||||
interface_language: "",
|
interface_language: "",
|
||||||
avatar,
|
avatar,
|
||||||
|
@ -22,8 +22,7 @@ pub async fn distinguish_comment(
|
|||||||
data.comment_id,
|
data.comment_id,
|
||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
|
|
||||||
check_community_user_action(
|
check_community_user_action(
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
@ -60,8 +59,7 @@ pub async fn distinguish_comment(
|
|||||||
data.comment_id,
|
data.comment_id,
|
||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
|
|
||||||
Ok(Json(CommentResponse {
|
Ok(Json(CommentResponse {
|
||||||
comment_view,
|
comment_view,
|
||||||
|
@ -40,8 +40,7 @@ pub async fn like_comment(
|
|||||||
comment_id,
|
comment_id,
|
||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
|
|
||||||
check_community_user_action(
|
check_community_user_action(
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
@ -54,8 +53,7 @@ pub async fn like_comment(
|
|||||||
let comment_reply = CommentReply::read_by_comment(&mut context.pool(), comment_id).await;
|
let comment_reply = CommentReply::read_by_comment(&mut context.pool(), comment_id).await;
|
||||||
if let Ok(Some(reply)) = comment_reply {
|
if let Ok(Some(reply)) = comment_reply {
|
||||||
let recipient_id = reply.recipient_id;
|
let recipient_id = reply.recipient_id;
|
||||||
if let Ok(Some(local_recipient)) =
|
if let Ok(local_recipient) = LocalUserView::read_person(&mut context.pool(), recipient_id).await
|
||||||
LocalUserView::read_person(&mut context.pool(), recipient_id).await
|
|
||||||
{
|
{
|
||||||
recipient_ids.push(local_recipient.local_user.id);
|
recipient_ids.push(local_recipient.local_user.id);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use lemmy_api_common::{
|
|||||||
utils::is_mod_or_admin,
|
utils::is_mod_or_admin,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{CommentView, LocalUserView, VoteView};
|
use lemmy_db_views::structs::{CommentView, LocalUserView, VoteView};
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
/// Lists likes for a comment
|
/// Lists likes for a comment
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
@ -19,8 +19,7 @@ pub async fn list_comment_likes(
|
|||||||
data.comment_id,
|
data.comment_id,
|
||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
|
|
||||||
is_mod_or_admin(
|
is_mod_or_admin(
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
|
@ -37,8 +37,7 @@ pub async fn save_comment(
|
|||||||
comment_id,
|
comment_id,
|
||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
|
|
||||||
Ok(Json(CommentResponse {
|
Ok(Json(CommentResponse {
|
||||||
comment_view,
|
comment_view,
|
||||||
|
@ -40,8 +40,7 @@ pub async fn create_comment_report(
|
|||||||
comment_id,
|
comment_id,
|
||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
|
|
||||||
check_community_user_action(
|
check_community_user_action(
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
@ -64,9 +63,8 @@ pub async fn create_comment_report(
|
|||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntCreateReport)?;
|
.with_lemmy_type(LemmyErrorType::CouldntCreateReport)?;
|
||||||
|
|
||||||
let comment_report_view = CommentReportView::read(&mut context.pool(), report.id, person_id)
|
let comment_report_view =
|
||||||
.await?
|
CommentReportView::read(&mut context.pool(), report.id, person_id).await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommentReport)?;
|
|
||||||
|
|
||||||
// Email the admins
|
// Email the admins
|
||||||
if local_site.reports_email_admins {
|
if local_site.reports_email_admins {
|
||||||
|
@ -17,9 +17,7 @@ pub async fn resolve_comment_report(
|
|||||||
) -> LemmyResult<Json<CommentReportResponse>> {
|
) -> LemmyResult<Json<CommentReportResponse>> {
|
||||||
let report_id = data.report_id;
|
let report_id = data.report_id;
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let report = CommentReportView::read(&mut context.pool(), report_id, person_id)
|
let report = CommentReportView::read(&mut context.pool(), report_id, person_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommentReport)?;
|
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
check_community_mod_action(
|
check_community_mod_action(
|
||||||
@ -41,9 +39,8 @@ pub async fn resolve_comment_report(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let report_id = data.report_id;
|
let report_id = data.report_id;
|
||||||
let comment_report_view = CommentReportView::read(&mut context.pool(), report_id, person_id)
|
let comment_report_view =
|
||||||
.await?
|
CommentReportView::read(&mut context.pool(), report_id, person_id).await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommentReport)?;
|
|
||||||
|
|
||||||
Ok(Json(CommentReportResponse {
|
Ok(Json(CommentReportResponse {
|
||||||
comment_report_view,
|
comment_report_view,
|
||||||
|
@ -46,23 +46,18 @@ pub async fn add_mod_to_community(
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let community = Community::read(&mut context.pool(), community_id)
|
let community = Community::read(&mut context.pool(), community_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
// If user is admin and community is remote, explicitly check that he is a
|
// If user is admin and community is remote, explicitly check that he is a
|
||||||
// moderator. This is necessary because otherwise the action would be rejected
|
// moderator. This is necessary because otherwise the action would be rejected
|
||||||
// by the community's home instance.
|
// by the community's home instance.
|
||||||
if local_user_view.local_user.admin && !community.local {
|
if local_user_view.local_user.admin && !community.local {
|
||||||
let is_mod = CommunityModeratorView::is_community_moderator(
|
CommunityModeratorView::check_is_community_moderator(
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
community.id,
|
community.id,
|
||||||
local_user_view.person.id,
|
local_user_view.person.id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
if !is_mod {
|
|
||||||
Err(LemmyErrorType::NotAModerator)?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update in local database
|
// Update in local database
|
||||||
|
@ -111,9 +111,7 @@ pub async fn ban_from_community(
|
|||||||
|
|
||||||
ModBanFromCommunity::create(&mut context.pool(), &form).await?;
|
ModBanFromCommunity::create(&mut context.pool(), &form).await?;
|
||||||
|
|
||||||
let person_view = PersonView::read(&mut context.pool(), data.person_id)
|
let person_view = PersonView::read(&mut context.pool(), data.person_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?;
|
|
||||||
|
|
||||||
ActivityChannel::submit_activity(
|
ActivityChannel::submit_activity(
|
||||||
SendActivityData::BanFromCommunity {
|
SendActivityData::BanFromCommunity {
|
||||||
|
@ -56,8 +56,7 @@ pub async fn block_community(
|
|||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
ActivityChannel::submit_activity(
|
ActivityChannel::submit_activity(
|
||||||
SendActivityData::FollowCommunity(
|
SendActivityData::FollowCommunity(
|
||||||
|
@ -23,9 +23,7 @@ pub async fn follow_community(
|
|||||||
context: Data<LemmyContext>,
|
context: Data<LemmyContext>,
|
||||||
local_user_view: LocalUserView,
|
local_user_view: LocalUserView,
|
||||||
) -> LemmyResult<Json<CommunityResponse>> {
|
) -> LemmyResult<Json<CommunityResponse>> {
|
||||||
let community = Community::read(&mut context.pool(), data.community_id)
|
let community = Community::read(&mut context.pool(), data.community_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
let mut community_follower_form = CommunityFollowerForm {
|
let mut community_follower_form = CommunityFollowerForm {
|
||||||
community_id: community.id,
|
community_id: community.id,
|
||||||
person_id: local_user_view.person.id,
|
person_id: local_user_view.person.id,
|
||||||
@ -68,8 +66,7 @@ pub async fn follow_community(
|
|||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
let discussion_languages = CommunityLanguage::read(&mut context.pool(), community_id).await?;
|
let discussion_languages = CommunityLanguage::read(&mut context.pool(), community_id).await?;
|
||||||
|
|
||||||
|
@ -82,13 +82,10 @@ pub async fn transfer_community(
|
|||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id)
|
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(Json(GetCommunityResponse {
|
Ok(Json(GetCommunityResponse {
|
||||||
|
@ -258,17 +258,13 @@ pub async fn local_user_view_from_jwt(
|
|||||||
let local_user_id = Claims::validate(jwt, context)
|
let local_user_id = Claims::validate(jwt, context)
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::NotLoggedIn)?;
|
.with_lemmy_type(LemmyErrorType::NotLoggedIn)?;
|
||||||
let local_user_view = LocalUserView::read(&mut context.pool(), local_user_id)
|
let local_user_view = LocalUserView::read(&mut context.pool(), local_user_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindLocalUser)?;
|
|
||||||
check_user_valid(&local_user_view.person)?;
|
check_user_valid(&local_user_view.person)?;
|
||||||
|
|
||||||
Ok(local_user_view)
|
Ok(local_user_view)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
#[allow(clippy::indexing_slicing)]
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -36,8 +36,8 @@ pub async fn add_admin(
|
|||||||
|
|
||||||
// Make sure that the person_id added is local
|
// Make sure that the person_id added is local
|
||||||
let added_local_user = LocalUserView::read_person(&mut context.pool(), data.person_id)
|
let added_local_user = LocalUserView::read_person(&mut context.pool(), data.person_id)
|
||||||
.await?
|
.await
|
||||||
.ok_or(LemmyErrorType::ObjectNotLocal)?;
|
.map_err(|_| LemmyErrorType::ObjectNotLocal)?;
|
||||||
|
|
||||||
LocalUser::update(
|
LocalUser::update(
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
|
@ -60,7 +60,7 @@ pub async fn ban_from_site(
|
|||||||
|
|
||||||
// if its a local user, invalidate logins
|
// if its a local user, invalidate logins
|
||||||
let local_user = LocalUserView::read_person(&mut context.pool(), person.id).await;
|
let local_user = LocalUserView::read_person(&mut context.pool(), person.id).await;
|
||||||
if let Ok(Some(local_user)) = local_user {
|
if let Ok(local_user) = local_user {
|
||||||
LoginToken::invalidate_all(&mut context.pool(), local_user.local_user.id).await?;
|
LoginToken::invalidate_all(&mut context.pool(), local_user.local_user.id).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,9 +84,7 @@ pub async fn ban_from_site(
|
|||||||
|
|
||||||
ModBan::create(&mut context.pool(), &form).await?;
|
ModBan::create(&mut context.pool(), &form).await?;
|
||||||
|
|
||||||
let person_view = PersonView::read(&mut context.pool(), person.id)
|
let person_view = PersonView::read(&mut context.pool(), person.id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?;
|
|
||||||
|
|
||||||
ban_nonlocal_user_from_local_communities(
|
ban_nonlocal_user_from_local_communities(
|
||||||
&local_user_view,
|
&local_user_view,
|
||||||
|
@ -32,8 +32,7 @@ pub async fn block_person(
|
|||||||
|
|
||||||
let target_user = LocalUserView::read_person(&mut context.pool(), target_id)
|
let target_user = LocalUserView::read_person(&mut context.pool(), target_id)
|
||||||
.await
|
.await
|
||||||
.ok()
|
.ok();
|
||||||
.flatten();
|
|
||||||
|
|
||||||
if target_user.is_some_and(|t| t.local_user.admin) {
|
if target_user.is_some_and(|t| t.local_user.admin) {
|
||||||
Err(LemmyErrorType::CantBlockAdmin)?
|
Err(LemmyErrorType::CantBlockAdmin)?
|
||||||
@ -49,9 +48,7 @@ pub async fn block_person(
|
|||||||
.with_lemmy_type(LemmyErrorType::PersonBlockAlreadyExists)?;
|
.with_lemmy_type(LemmyErrorType::PersonBlockAlreadyExists)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let person_view = PersonView::read(&mut context.pool(), target_id)
|
let person_view = PersonView::read(&mut context.pool(), target_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?;
|
|
||||||
Ok(Json(BlockPersonResponse {
|
Ok(Json(BlockPersonResponse {
|
||||||
person_view,
|
person_view,
|
||||||
blocked: data.block,
|
blocked: data.block,
|
||||||
|
@ -21,7 +21,6 @@ pub async fn change_password_after_reset(
|
|||||||
let token = data.token.clone();
|
let token = data.token.clone();
|
||||||
let local_user_id = PasswordResetRequest::read_and_delete(&mut context.pool(), &token)
|
let local_user_id = PasswordResetRequest::read_and_delete(&mut context.pool(), &token)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::TokenNotFound)?
|
|
||||||
.local_user_id;
|
.local_user_id;
|
||||||
|
|
||||||
password_length_check(&data.password)?;
|
password_length_check(&data.password)?;
|
||||||
|
@ -24,9 +24,7 @@ pub async fn login(
|
|||||||
// Fetch that username / email
|
// Fetch that username / email
|
||||||
let username_or_email = data.username_or_email.clone();
|
let username_or_email = data.username_or_email.clone();
|
||||||
let local_user_view =
|
let local_user_view =
|
||||||
LocalUserView::find_by_email_or_name(&mut context.pool(), &username_or_email)
|
LocalUserView::find_by_email_or_name(&mut context.pool(), &username_or_email).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::IncorrectLogin)?;
|
|
||||||
|
|
||||||
// Verify the password
|
// Verify the password
|
||||||
let valid: bool = local_user_view
|
let valid: bool = local_user_view
|
||||||
|
@ -18,9 +18,7 @@ pub async fn mark_person_mention_as_read(
|
|||||||
local_user_view: LocalUserView,
|
local_user_view: LocalUserView,
|
||||||
) -> LemmyResult<Json<PersonMentionResponse>> {
|
) -> LemmyResult<Json<PersonMentionResponse>> {
|
||||||
let person_mention_id = data.person_mention_id;
|
let person_mention_id = data.person_mention_id;
|
||||||
let read_person_mention = PersonMention::read(&mut context.pool(), person_mention_id)
|
let read_person_mention = PersonMention::read(&mut context.pool(), person_mention_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPersonMention)?;
|
|
||||||
|
|
||||||
if local_user_view.person.id != read_person_mention.recipient_id {
|
if local_user_view.person.id != read_person_mention.recipient_id {
|
||||||
Err(LemmyErrorType::CouldntUpdateComment)?
|
Err(LemmyErrorType::CouldntUpdateComment)?
|
||||||
@ -39,9 +37,7 @@ pub async fn mark_person_mention_as_read(
|
|||||||
let person_mention_id = read_person_mention.id;
|
let person_mention_id = read_person_mention.id;
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let person_mention_view =
|
let person_mention_view =
|
||||||
PersonMentionView::read(&mut context.pool(), person_mention_id, Some(person_id))
|
PersonMentionView::read(&mut context.pool(), person_mention_id, Some(person_id)).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPersonMention)?;
|
|
||||||
|
|
||||||
Ok(Json(PersonMentionResponse {
|
Ok(Json(PersonMentionResponse {
|
||||||
person_mention_view,
|
person_mention_view,
|
||||||
|
@ -18,9 +18,7 @@ pub async fn mark_reply_as_read(
|
|||||||
local_user_view: LocalUserView,
|
local_user_view: LocalUserView,
|
||||||
) -> LemmyResult<Json<CommentReplyResponse>> {
|
) -> LemmyResult<Json<CommentReplyResponse>> {
|
||||||
let comment_reply_id = data.comment_reply_id;
|
let comment_reply_id = data.comment_reply_id;
|
||||||
let read_comment_reply = CommentReply::read(&mut context.pool(), comment_reply_id)
|
let read_comment_reply = CommentReply::read(&mut context.pool(), comment_reply_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommentReply)?;
|
|
||||||
|
|
||||||
if local_user_view.person.id != read_comment_reply.recipient_id {
|
if local_user_view.person.id != read_comment_reply.recipient_id {
|
||||||
Err(LemmyErrorType::CouldntUpdateComment)?
|
Err(LemmyErrorType::CouldntUpdateComment)?
|
||||||
@ -40,9 +38,7 @@ pub async fn mark_reply_as_read(
|
|||||||
let comment_reply_id = read_comment_reply.id;
|
let comment_reply_id = read_comment_reply.id;
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let comment_reply_view =
|
let comment_reply_view =
|
||||||
CommentReplyView::read(&mut context.pool(), comment_reply_id, Some(person_id))
|
CommentReplyView::read(&mut context.pool(), comment_reply_id, Some(person_id)).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommentReply)?;
|
|
||||||
|
|
||||||
Ok(Json(CommentReplyResponse { comment_reply_view }))
|
Ok(Json(CommentReplyResponse { comment_reply_view }))
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,8 @@ pub async fn reset_password(
|
|||||||
// Fetch that email
|
// Fetch that email
|
||||||
let email = data.email.to_lowercase();
|
let email = data.email.to_lowercase();
|
||||||
let local_user_view = LocalUserView::find_by_email(&mut context.pool(), &email)
|
let local_user_view = LocalUserView::find_by_email(&mut context.pool(), &email)
|
||||||
.await?
|
.await
|
||||||
.ok_or(LemmyErrorType::IncorrectLogin)?;
|
.map_err(|_| LemmyErrorType::IncorrectLogin)?;
|
||||||
|
|
||||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||||
check_email_verified(&local_user_view, &site_view)?;
|
check_email_verified(&local_user_view, &site_view)?;
|
||||||
|
@ -63,9 +63,7 @@ pub async fn save_user_settings(
|
|||||||
let previous_email = local_user_view.local_user.email.clone().unwrap_or_default();
|
let previous_email = local_user_view.local_user.email.clone().unwrap_or_default();
|
||||||
// if email was changed, check that it is not taken and send verification mail
|
// if email was changed, check that it is not taken and send verification mail
|
||||||
if previous_email.deref() != email {
|
if previous_email.deref() != email {
|
||||||
if LocalUser::is_email_taken(&mut context.pool(), email).await? {
|
LocalUser::check_is_email_taken(&mut context.pool(), email).await?;
|
||||||
return Err(LemmyErrorType::EmailAlreadyExists)?;
|
|
||||||
}
|
|
||||||
send_verification_email(
|
send_verification_email(
|
||||||
&local_user_view,
|
&local_user_view,
|
||||||
email,
|
email,
|
||||||
@ -132,7 +130,6 @@ pub async fn save_user_settings(
|
|||||||
send_notifications_to_email: data.send_notifications_to_email,
|
send_notifications_to_email: data.send_notifications_to_email,
|
||||||
show_nsfw: data.show_nsfw,
|
show_nsfw: data.show_nsfw,
|
||||||
blur_nsfw: data.blur_nsfw,
|
blur_nsfw: data.blur_nsfw,
|
||||||
auto_expand: data.auto_expand,
|
|
||||||
show_bot_accounts: data.show_bot_accounts,
|
show_bot_accounts: data.show_bot_accounts,
|
||||||
default_post_sort_type,
|
default_post_sort_type,
|
||||||
default_comment_sort_type,
|
default_comment_sort_type,
|
||||||
|
@ -10,7 +10,7 @@ use lemmy_db_schema::source::{
|
|||||||
local_user::{LocalUser, LocalUserUpdateForm},
|
local_user::{LocalUser, LocalUserUpdateForm},
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
||||||
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
pub async fn verify_email(
|
pub async fn verify_email(
|
||||||
data: Json<VerifyEmail>,
|
data: Json<VerifyEmail>,
|
||||||
@ -18,9 +18,7 @@ pub async fn verify_email(
|
|||||||
) -> LemmyResult<Json<SuccessResponse>> {
|
) -> LemmyResult<Json<SuccessResponse>> {
|
||||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||||
let token = data.token.clone();
|
let token = data.token.clone();
|
||||||
let verification = EmailVerification::read_for_token(&mut context.pool(), &token)
|
let verification = EmailVerification::read_for_token(&mut context.pool(), &token).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::TokenNotFound)?;
|
|
||||||
|
|
||||||
let form = LocalUserUpdateForm {
|
let form = LocalUserUpdateForm {
|
||||||
// necessary in case this is a new signup
|
// necessary in case this is a new signup
|
||||||
@ -37,9 +35,7 @@ pub async fn verify_email(
|
|||||||
|
|
||||||
// send out notification about registration application to admins if enabled
|
// send out notification about registration application to admins if enabled
|
||||||
if site_view.local_site.application_email_admins {
|
if site_view.local_site.application_email_admins {
|
||||||
let local_user = LocalUserView::read(&mut context.pool(), local_user_id)
|
let local_user = LocalUserView::read(&mut context.pool(), local_user_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?;
|
|
||||||
|
|
||||||
send_new_applicant_email_to_admins(
|
send_new_applicant_email_to_admins(
|
||||||
&local_user.person.name,
|
&local_user.person.name,
|
||||||
|
@ -16,7 +16,7 @@ use lemmy_db_schema::{
|
|||||||
PostFeatureType,
|
PostFeatureType,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn feature_post(
|
pub async fn feature_post(
|
||||||
@ -25,9 +25,7 @@ pub async fn feature_post(
|
|||||||
local_user_view: LocalUserView,
|
local_user_view: LocalUserView,
|
||||||
) -> LemmyResult<Json<PostResponse>> {
|
) -> LemmyResult<Json<PostResponse>> {
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let orig_post = Post::read(&mut context.pool(), post_id)
|
let orig_post = Post::read(&mut context.pool(), post_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
check_community_mod_action(
|
check_community_mod_action(
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
|
@ -38,9 +38,7 @@ pub async fn like_post(
|
|||||||
|
|
||||||
// Check for a community ban
|
// Check for a community ban
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let post = Post::read(&mut context.pool(), post_id)
|
let post = Post::read(&mut context.pool(), post_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
check_community_user_action(
|
check_community_user_action(
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
@ -70,9 +68,7 @@ pub async fn like_post(
|
|||||||
|
|
||||||
mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
||||||
|
|
||||||
let community = Community::read(&mut context.pool(), post.community_id)
|
let community = Community::read(&mut context.pool(), post.community_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
ActivityChannel::submit_activity(
|
ActivityChannel::submit_activity(
|
||||||
SendActivityData::LikePostOrComment {
|
SendActivityData::LikePostOrComment {
|
||||||
|
@ -6,7 +6,7 @@ use lemmy_api_common::{
|
|||||||
};
|
};
|
||||||
use lemmy_db_schema::{source::post::Post, traits::Crud};
|
use lemmy_db_schema::{source::post::Post, traits::Crud};
|
||||||
use lemmy_db_views::structs::{LocalUserView, VoteView};
|
use lemmy_db_views::structs::{LocalUserView, VoteView};
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
/// Lists likes for a post
|
/// Lists likes for a post
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
@ -15,9 +15,7 @@ pub async fn list_post_likes(
|
|||||||
context: Data<LemmyContext>,
|
context: Data<LemmyContext>,
|
||||||
local_user_view: LocalUserView,
|
local_user_view: LocalUserView,
|
||||||
) -> LemmyResult<Json<ListPostLikesResponse>> {
|
) -> LemmyResult<Json<ListPostLikesResponse>> {
|
||||||
let post = Post::read(&mut context.pool(), data.post_id)
|
let post = Post::read(&mut context.pool(), data.post_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
is_mod_or_admin(
|
is_mod_or_admin(
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
|
@ -15,7 +15,7 @@ use lemmy_db_schema::{
|
|||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn lock_post(
|
pub async fn lock_post(
|
||||||
@ -24,9 +24,7 @@ pub async fn lock_post(
|
|||||||
local_user_view: LocalUserView,
|
local_user_view: LocalUserView,
|
||||||
) -> LemmyResult<Json<PostResponse>> {
|
) -> LemmyResult<Json<PostResponse>> {
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let orig_post = Post::read(&mut context.pool(), post_id)
|
let orig_post = Post::read(&mut context.pool(), post_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
check_community_mod_action(
|
check_community_mod_action(
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
|
@ -40,8 +40,7 @@ pub async fn save_post(
|
|||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
||||||
|
|
||||||
|
@ -35,9 +35,7 @@ pub async fn create_post_report(
|
|||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let post_view = PostView::read(&mut context.pool(), post_id, None, false)
|
let post_view = PostView::read(&mut context.pool(), post_id, None, false).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
check_community_user_action(
|
check_community_user_action(
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
@ -61,9 +59,7 @@ pub async fn create_post_report(
|
|||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntCreateReport)?;
|
.with_lemmy_type(LemmyErrorType::CouldntCreateReport)?;
|
||||||
|
|
||||||
let post_report_view = PostReportView::read(&mut context.pool(), report.id, person_id)
|
let post_report_view = PostReportView::read(&mut context.pool(), report.id, person_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPostReport)?;
|
|
||||||
|
|
||||||
// Email the admins
|
// Email the admins
|
||||||
if local_site.reports_email_admins {
|
if local_site.reports_email_admins {
|
||||||
|
@ -17,9 +17,7 @@ pub async fn resolve_post_report(
|
|||||||
) -> LemmyResult<Json<PostReportResponse>> {
|
) -> LemmyResult<Json<PostReportResponse>> {
|
||||||
let report_id = data.report_id;
|
let report_id = data.report_id;
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let report = PostReportView::read(&mut context.pool(), report_id, person_id)
|
let report = PostReportView::read(&mut context.pool(), report_id, person_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPostReport)?;
|
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
check_community_mod_action(
|
check_community_mod_action(
|
||||||
@ -40,9 +38,7 @@ pub async fn resolve_post_report(
|
|||||||
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let post_report_view = PostReportView::read(&mut context.pool(), report_id, person_id)
|
let post_report_view = PostReportView::read(&mut context.pool(), report_id, person_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPostReport)?;
|
|
||||||
|
|
||||||
Ok(Json(PostReportResponse { post_report_view }))
|
Ok(Json(PostReportResponse { post_report_view }))
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,7 @@ pub async fn mark_pm_as_read(
|
|||||||
) -> LemmyResult<Json<PrivateMessageResponse>> {
|
) -> LemmyResult<Json<PrivateMessageResponse>> {
|
||||||
// Checking permissions
|
// Checking permissions
|
||||||
let private_message_id = data.private_message_id;
|
let private_message_id = data.private_message_id;
|
||||||
let orig_private_message = PrivateMessage::read(&mut context.pool(), private_message_id)
|
let orig_private_message = PrivateMessage::read(&mut context.pool(), private_message_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPrivateMessage)?;
|
|
||||||
if local_user_view.person.id != orig_private_message.recipient_id {
|
if local_user_view.person.id != orig_private_message.recipient_id {
|
||||||
Err(LemmyErrorType::CouldntUpdatePrivateMessage)?
|
Err(LemmyErrorType::CouldntUpdatePrivateMessage)?
|
||||||
}
|
}
|
||||||
@ -39,9 +37,7 @@ pub async fn mark_pm_as_read(
|
|||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdatePrivateMessage)?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdatePrivateMessage)?;
|
||||||
|
|
||||||
let view = PrivateMessageView::read(&mut context.pool(), private_message_id)
|
let view = PrivateMessageView::read(&mut context.pool(), private_message_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPrivateMessage)?;
|
|
||||||
Ok(Json(PrivateMessageResponse {
|
Ok(Json(PrivateMessageResponse {
|
||||||
private_message_view: view,
|
private_message_view: view,
|
||||||
}))
|
}))
|
||||||
|
@ -29,9 +29,7 @@ pub async fn create_pm_report(
|
|||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let private_message_id = data.private_message_id;
|
let private_message_id = data.private_message_id;
|
||||||
let private_message = PrivateMessage::read(&mut context.pool(), private_message_id)
|
let private_message = PrivateMessage::read(&mut context.pool(), private_message_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPrivateMessage)?;
|
|
||||||
|
|
||||||
// Make sure that only the recipient of the private message can create a report
|
// Make sure that only the recipient of the private message can create a report
|
||||||
if person_id != private_message.recipient_id {
|
if person_id != private_message.recipient_id {
|
||||||
@ -49,9 +47,8 @@ pub async fn create_pm_report(
|
|||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntCreateReport)?;
|
.with_lemmy_type(LemmyErrorType::CouldntCreateReport)?;
|
||||||
|
|
||||||
let private_message_report_view = PrivateMessageReportView::read(&mut context.pool(), report.id)
|
let private_message_report_view =
|
||||||
.await?
|
PrivateMessageReportView::read(&mut context.pool(), report.id).await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindPrivateMessageReport)?;
|
|
||||||
|
|
||||||
// Email the admins
|
// Email the admins
|
||||||
if local_site.reports_email_admins {
|
if local_site.reports_email_admins {
|
||||||
|
@ -28,9 +28,8 @@ pub async fn resolve_pm_report(
|
|||||||
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let private_message_report_view = PrivateMessageReportView::read(&mut context.pool(), report_id)
|
let private_message_report_view =
|
||||||
.await?
|
PrivateMessageReportView::read(&mut context.pool(), report_id).await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindPrivateMessageReport)?;
|
|
||||||
|
|
||||||
Ok(Json(PrivateMessageReportResponse {
|
Ok(Json(PrivateMessageReportResponse {
|
||||||
private_message_report_view,
|
private_message_report_view,
|
||||||
|
@ -16,7 +16,7 @@ use lemmy_db_schema::{
|
|||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{CommentView, LocalUserView};
|
use lemmy_db_views::structs::{CommentView, LocalUserView};
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn purge_comment(
|
pub async fn purge_comment(
|
||||||
@ -35,8 +35,7 @@ pub async fn purge_comment(
|
|||||||
comment_id,
|
comment_id,
|
||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
|
|
||||||
// Also check that you're a higher admin
|
// Also check that you're a higher admin
|
||||||
LocalUser::is_higher_admin_check(
|
LocalUser::is_higher_admin_check(
|
||||||
|
@ -19,7 +19,7 @@ use lemmy_db_schema::{
|
|||||||
};
|
};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_db_views_actor::structs::CommunityModeratorView;
|
use lemmy_db_views_actor::structs::CommunityModeratorView;
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn purge_community(
|
pub async fn purge_community(
|
||||||
@ -31,9 +31,7 @@ pub async fn purge_community(
|
|||||||
is_admin(&local_user_view)?;
|
is_admin(&local_user_view)?;
|
||||||
|
|
||||||
// Read the community to get its images
|
// Read the community to get its images
|
||||||
let community = Community::read(&mut context.pool(), data.community_id)
|
let community = Community::read(&mut context.pool(), data.community_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
// Also check that you're a higher admin than all the mods
|
// Also check that you're a higher admin than all the mods
|
||||||
let community_mod_person_ids =
|
let community_mod_person_ids =
|
||||||
|
@ -17,7 +17,7 @@ use lemmy_db_schema::{
|
|||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn purge_person(
|
pub async fn purge_person(
|
||||||
@ -36,9 +36,7 @@ pub async fn purge_person(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let person = Person::read(&mut context.pool(), data.person_id)
|
let person = Person::read(&mut context.pool(), data.person_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?;
|
|
||||||
|
|
||||||
ban_nonlocal_user_from_local_communities(
|
ban_nonlocal_user_from_local_communities(
|
||||||
&local_user_view,
|
&local_user_view,
|
||||||
|
@ -17,7 +17,7 @@ use lemmy_db_schema::{
|
|||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn purge_post(
|
pub async fn purge_post(
|
||||||
@ -29,9 +29,7 @@ pub async fn purge_post(
|
|||||||
is_admin(&local_user_view)?;
|
is_admin(&local_user_view)?;
|
||||||
|
|
||||||
// Read the post to get the community_id
|
// Read the post to get the community_id
|
||||||
let post = Post::read(&mut context.pool(), data.post_id)
|
let post = Post::read(&mut context.pool(), data.post_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
// Also check that you're a higher admin
|
// Also check that you're a higher admin
|
||||||
LocalUser::is_higher_admin_check(
|
LocalUser::is_higher_admin_check(
|
||||||
|
@ -14,10 +14,7 @@ use lemmy_db_schema::{
|
|||||||
utils::{diesel_string_update, get_conn},
|
utils::{diesel_string_update, get_conn},
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{LocalUserView, RegistrationApplicationView};
|
use lemmy_db_views::structs::{LocalUserView, RegistrationApplicationView};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||||
error::{LemmyError, LemmyResult},
|
|
||||||
LemmyErrorType,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub async fn approve_registration_application(
|
pub async fn approve_registration_application(
|
||||||
data: Json<ApproveRegistrationApplication>,
|
data: Json<ApproveRegistrationApplication>,
|
||||||
@ -61,9 +58,8 @@ pub async fn approve_registration_application(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if data.approve {
|
if data.approve {
|
||||||
let approved_local_user_view = LocalUserView::read(&mut context.pool(), approved_user_id)
|
let approved_local_user_view =
|
||||||
.await?
|
LocalUserView::read(&mut context.pool(), approved_user_id).await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindLocalUser)?;
|
|
||||||
if approved_local_user_view.local_user.email.is_some() {
|
if approved_local_user_view.local_user.email.is_some() {
|
||||||
// Email sending may fail, but this won't revert the application approval
|
// Email sending may fail, but this won't revert the application approval
|
||||||
send_application_approved_email(&approved_local_user_view, context.settings()).await?;
|
send_application_approved_email(&approved_local_user_view, context.settings()).await?;
|
||||||
@ -71,9 +67,8 @@ pub async fn approve_registration_application(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Read the view
|
// Read the view
|
||||||
let registration_application = RegistrationApplicationView::read(&mut context.pool(), app_id)
|
let registration_application =
|
||||||
.await?
|
RegistrationApplicationView::read(&mut context.pool(), app_id).await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindRegistrationApplication)?;
|
|
||||||
|
|
||||||
Ok(Json(RegistrationApplicationResponse {
|
Ok(Json(RegistrationApplicationResponse {
|
||||||
registration_application,
|
registration_application,
|
||||||
|
@ -5,7 +5,7 @@ use lemmy_api_common::{
|
|||||||
utils::is_admin,
|
utils::is_admin,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{LocalUserView, RegistrationApplicationView};
|
use lemmy_db_views::structs::{LocalUserView, RegistrationApplicationView};
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
/// Lists registration applications, filterable by undenied only.
|
/// Lists registration applications, filterable by undenied only.
|
||||||
pub async fn get_registration_application(
|
pub async fn get_registration_application(
|
||||||
@ -18,9 +18,7 @@ pub async fn get_registration_application(
|
|||||||
|
|
||||||
// Read the view
|
// Read the view
|
||||||
let registration_application =
|
let registration_application =
|
||||||
RegistrationApplicationView::read_by_person(&mut context.pool(), data.person_id)
|
RegistrationApplicationView::read_by_person(&mut context.pool(), data.person_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindRegistrationApplication)?;
|
|
||||||
|
|
||||||
Ok(Json(RegistrationApplicationResponse {
|
Ok(Json(RegistrationApplicationResponse {
|
||||||
registration_application,
|
registration_application,
|
||||||
|
@ -34,7 +34,7 @@ use lemmy_db_views::structs::LocalUserView;
|
|||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType, CACHE_DURATION_API};
|
use lemmy_utils::{error::LemmyResult, LemmyErrorType, CACHE_DURATION_API};
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
#[allow(clippy::unwrap_used)]
|
#[expect(clippy::unwrap_used)]
|
||||||
async fn create_test_site(context: &Data<LemmyContext>) -> LemmyResult<(Instance, LocalUserView)> {
|
async fn create_test_site(context: &Data<LemmyContext>) -> LemmyResult<(Instance, LocalUserView)> {
|
||||||
let pool = &mut context.pool();
|
let pool = &mut context.pool();
|
||||||
|
|
||||||
@ -54,20 +54,20 @@ async fn create_test_site(context: &Data<LemmyContext>) -> LemmyResult<(Instance
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let admin_local_user_view = LocalUserView::read_person(pool, admin_person.id)
|
let admin_local_user_view = LocalUserView::read_person(pool, admin_person.id).await?;
|
||||||
.await?
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let site_form = SiteInsertForm::new("test site".to_string(), inserted_instance.id);
|
let site_form = SiteInsertForm::new("test site".to_string(), inserted_instance.id);
|
||||||
let site = Site::create(pool, &site_form).await.unwrap();
|
let site = Site::create(pool, &site_form).await.unwrap();
|
||||||
|
|
||||||
// Create a local site, since this is necessary for determining if email verification is
|
// Create a local site, since this is necessary for determining if email verification is
|
||||||
// required
|
// required
|
||||||
let mut local_site_form = LocalSiteInsertForm::new(site.id);
|
let local_site_form = LocalSiteInsertForm {
|
||||||
local_site_form.require_email_verification = Some(true);
|
require_email_verification: Some(true),
|
||||||
local_site_form.application_question = Some(".".to_string());
|
application_question: Some(".".to_string()),
|
||||||
local_site_form.registration_mode = Some(RegistrationMode::RequireApplication);
|
registration_mode: Some(RegistrationMode::RequireApplication),
|
||||||
local_site_form.site_setup = Some(true);
|
site_setup: Some(true),
|
||||||
|
..LocalSiteInsertForm::new(site.id)
|
||||||
|
};
|
||||||
let local_site = LocalSite::create(pool, &local_site_form).await.unwrap();
|
let local_site = LocalSite::create(pool, &local_site_form).await.unwrap();
|
||||||
|
|
||||||
// Required to have a working local SiteView when updating the site to change email verification
|
// Required to have a working local SiteView when updating the site to change email verification
|
||||||
@ -109,7 +109,7 @@ async fn signup(
|
|||||||
Ok((local_user, application))
|
Ok((local_user, application))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::unwrap_used)]
|
#[expect(clippy::unwrap_used)]
|
||||||
async fn get_application_statuses(
|
async fn get_application_statuses(
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
admin: LocalUserView,
|
admin: LocalUserView,
|
||||||
@ -138,10 +138,9 @@ async fn get_application_statuses(
|
|||||||
Ok((application_count, unread_applications, all_applications))
|
Ok((application_count, unread_applications, all_applications))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::indexing_slicing)]
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
#[tokio::test]
|
|
||||||
#[serial]
|
#[serial]
|
||||||
|
#[tokio::test]
|
||||||
|
#[expect(clippy::indexing_slicing)]
|
||||||
async fn test_application_approval() -> LemmyResult<()> {
|
async fn test_application_approval() -> LemmyResult<()> {
|
||||||
let context = LemmyContext::init_test_context().await;
|
let context = LemmyContext::init_test_context().await;
|
||||||
let pool = &mut context.pool();
|
let pool = &mut context.pool();
|
||||||
|
@ -42,7 +42,7 @@ pub async fn get_sitemap(context: Data<LemmyContext>) -> LemmyResult<HttpRespons
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::unwrap_used)]
|
#[expect(clippy::unwrap_used)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
|
|
||||||
use crate::sitemap::generate_urlset;
|
use crate::sitemap::generate_urlset;
|
||||||
|
@ -27,7 +27,6 @@ use lemmy_db_views_actor::structs::CommunityView;
|
|||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
error::LemmyResult,
|
error::LemmyResult,
|
||||||
utils::{markdown::markdown_to_html, mention::MentionData},
|
utils::{markdown::markdown_to_html, mention::MentionData},
|
||||||
LemmyErrorType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub async fn build_comment_response(
|
pub async fn build_comment_response(
|
||||||
@ -37,9 +36,8 @@ pub async fn build_comment_response(
|
|||||||
recipient_ids: Vec<LocalUserId>,
|
recipient_ids: Vec<LocalUserId>,
|
||||||
) -> LemmyResult<CommentResponse> {
|
) -> LemmyResult<CommentResponse> {
|
||||||
let local_user = local_user_view.map(|l| l.local_user);
|
let local_user = local_user_view.map(|l| l.local_user);
|
||||||
let comment_view = CommentView::read(&mut context.pool(), comment_id, local_user.as_ref())
|
let comment_view =
|
||||||
.await?
|
CommentView::read(&mut context.pool(), comment_id, local_user.as_ref()).await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
Ok(CommentResponse {
|
Ok(CommentResponse {
|
||||||
comment_view,
|
comment_view,
|
||||||
recipient_ids,
|
recipient_ids,
|
||||||
@ -61,8 +59,7 @@ pub async fn build_community_response(
|
|||||||
Some(&local_user),
|
Some(&local_user),
|
||||||
is_mod_or_admin,
|
is_mod_or_admin,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
let discussion_languages = CommunityLanguage::read(&mut context.pool(), community_id).await?;
|
let discussion_languages = CommunityLanguage::read(&mut context.pool(), community_id).await?;
|
||||||
|
|
||||||
Ok(Json(CommunityResponse {
|
Ok(Json(CommunityResponse {
|
||||||
@ -87,8 +84,7 @@ pub async fn build_post_response(
|
|||||||
Some(&local_user),
|
Some(&local_user),
|
||||||
is_mod_or_admin,
|
is_mod_or_admin,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
Ok(Json(PostResponse { post_view }))
|
Ok(Json(PostResponse { post_view }))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,8 +108,7 @@ pub async fn send_local_notifs(
|
|||||||
comment_id,
|
comment_id,
|
||||||
local_user_view.map(|view| &view.local_user),
|
local_user_view.map(|view| &view.local_user),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
let comment = comment_view.comment;
|
let comment = comment_view.comment;
|
||||||
let post = comment_view.post;
|
let post = comment_view.post;
|
||||||
let community = comment_view.community;
|
let community = comment_view.community;
|
||||||
@ -125,7 +120,7 @@ pub async fn send_local_notifs(
|
|||||||
{
|
{
|
||||||
let mention_name = mention.name.clone();
|
let mention_name = mention.name.clone();
|
||||||
let user_view = LocalUserView::read_from_name(&mut context.pool(), &mention_name).await;
|
let user_view = LocalUserView::read_from_name(&mut context.pool(), &mention_name).await;
|
||||||
if let Ok(Some(mention_user_view)) = user_view {
|
if let Ok(mention_user_view) = user_view {
|
||||||
// TODO
|
// TODO
|
||||||
// At some point, make it so you can't tag the parent creator either
|
// At some point, make it so you can't tag the parent creator either
|
||||||
// Potential duplication of notifications, one for reply and the other for mention, is handled
|
// Potential duplication of notifications, one for reply and the other for mention, is handled
|
||||||
@ -161,9 +156,7 @@ pub async fn send_local_notifs(
|
|||||||
|
|
||||||
// Send comment_reply to the parent commenter / poster
|
// Send comment_reply to the parent commenter / poster
|
||||||
if let Some(parent_comment_id) = comment.parent_comment_id() {
|
if let Some(parent_comment_id) = comment.parent_comment_id() {
|
||||||
let parent_comment = Comment::read(&mut context.pool(), parent_comment_id)
|
let parent_comment = Comment::read(&mut context.pool(), parent_comment_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
|
|
||||||
// Get the parent commenter local_user
|
// Get the parent commenter local_user
|
||||||
let parent_creator_id = parent_comment.creator_id;
|
let parent_creator_id = parent_comment.creator_id;
|
||||||
@ -182,7 +175,7 @@ pub async fn send_local_notifs(
|
|||||||
// Don't send a notif to yourself
|
// Don't send a notif to yourself
|
||||||
if parent_comment.creator_id != person.id && !check_blocks {
|
if parent_comment.creator_id != person.id && !check_blocks {
|
||||||
let user_view = LocalUserView::read_person(&mut context.pool(), parent_creator_id).await;
|
let user_view = LocalUserView::read_person(&mut context.pool(), parent_creator_id).await;
|
||||||
if let Ok(Some(parent_user_view)) = user_view {
|
if let Ok(parent_user_view) = user_view {
|
||||||
// Don't duplicate notif if already mentioned by checking recipient ids
|
// Don't duplicate notif if already mentioned by checking recipient ids
|
||||||
if !recipient_ids.contains(&parent_user_view.local_user.id) {
|
if !recipient_ids.contains(&parent_user_view.local_user.id) {
|
||||||
recipient_ids.push(parent_user_view.local_user.id);
|
recipient_ids.push(parent_user_view.local_user.id);
|
||||||
@ -229,7 +222,7 @@ pub async fn send_local_notifs(
|
|||||||
if post.creator_id != person.id && !check_blocks {
|
if post.creator_id != person.id && !check_blocks {
|
||||||
let creator_id = post.creator_id;
|
let creator_id = post.creator_id;
|
||||||
let parent_user = LocalUserView::read_person(&mut context.pool(), creator_id).await;
|
let parent_user = LocalUserView::read_person(&mut context.pool(), creator_id).await;
|
||||||
if let Ok(Some(parent_user_view)) = parent_user {
|
if let Ok(parent_user_view) = parent_user {
|
||||||
if !recipient_ids.contains(&parent_user_view.local_user.id) {
|
if !recipient_ids.contains(&parent_user_view.local_user.id) {
|
||||||
recipient_ids.push(parent_user_view.local_user.id);
|
recipient_ids.push(parent_user_view.local_user.id);
|
||||||
|
|
||||||
|
@ -29,13 +29,9 @@ impl Claims {
|
|||||||
let claims =
|
let claims =
|
||||||
decode::<Claims>(jwt, &key, &validation).with_lemmy_type(LemmyErrorType::NotLoggedIn)?;
|
decode::<Claims>(jwt, &key, &validation).with_lemmy_type(LemmyErrorType::NotLoggedIn)?;
|
||||||
let user_id = LocalUserId(claims.claims.sub.parse()?);
|
let user_id = LocalUserId(claims.claims.sub.parse()?);
|
||||||
let is_valid = LoginToken::validate(&mut context.pool(), user_id, jwt).await?;
|
LoginToken::validate(&mut context.pool(), user_id, jwt).await?;
|
||||||
if !is_valid {
|
|
||||||
Err(LemmyErrorType::NotLoggedIn)?
|
|
||||||
} else {
|
|
||||||
Ok(user_id)
|
Ok(user_id)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn generate(
|
pub async fn generate(
|
||||||
user_id: LocalUserId,
|
user_id: LocalUserId,
|
||||||
@ -73,8 +69,7 @@ impl Claims {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::unwrap_used)]
|
#[expect(clippy::unwrap_used)]
|
||||||
#[allow(clippy::indexing_slicing)]
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use crate::{claims::Claims, context::LemmyContext};
|
use crate::{claims::Claims, context::LemmyContext};
|
||||||
|
@ -84,8 +84,8 @@ pub struct CaptchaResponse {
|
|||||||
pub struct SaveUserSettings {
|
pub struct SaveUserSettings {
|
||||||
/// Show nsfw posts.
|
/// Show nsfw posts.
|
||||||
pub show_nsfw: Option<bool>,
|
pub show_nsfw: Option<bool>,
|
||||||
|
/// Blur nsfw posts.
|
||||||
pub blur_nsfw: Option<bool>,
|
pub blur_nsfw: Option<bool>,
|
||||||
pub auto_expand: Option<bool>,
|
|
||||||
/// Your user's theme.
|
/// Your user's theme.
|
||||||
pub theme: Option<String>,
|
pub theme: Option<String>,
|
||||||
/// The default post listing type, usually "local"
|
/// The default post listing type, usually "local"
|
||||||
|
@ -30,6 +30,8 @@ pub struct CreatePost {
|
|||||||
pub language_id: Option<LanguageId>,
|
pub language_id: Option<LanguageId>,
|
||||||
/// Instead of fetching a thumbnail, use a custom one.
|
/// Instead of fetching a thumbnail, use a custom one.
|
||||||
pub custom_thumbnail: Option<String>,
|
pub custom_thumbnail: Option<String>,
|
||||||
|
/// Time when this post should be scheduled. Null means publish immediately.
|
||||||
|
pub scheduled_publish_time: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
@ -124,6 +126,8 @@ pub struct EditPost {
|
|||||||
pub language_id: Option<LanguageId>,
|
pub language_id: Option<LanguageId>,
|
||||||
/// Instead of fetching a thumbnail, use a custom one.
|
/// Instead of fetching a thumbnail, use a custom one.
|
||||||
pub custom_thumbnail: Option<String>,
|
pub custom_thumbnail: Option<String>,
|
||||||
|
/// Time when this post should be scheduled. Null means publish immediately.
|
||||||
|
pub scheduled_publish_time: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||||
|
@ -471,8 +471,7 @@ pub async fn replace_image(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::unwrap_used)]
|
#[expect(clippy::unwrap_used)]
|
||||||
#[allow(clippy::indexing_slicing)]
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -78,7 +78,11 @@ pub struct Search {
|
|||||||
pub listing_type: Option<ListingType>,
|
pub listing_type: Option<ListingType>,
|
||||||
pub page: Option<i64>,
|
pub page: Option<i64>,
|
||||||
pub limit: Option<i64>,
|
pub limit: Option<i64>,
|
||||||
pub post_title_only: Option<bool>,
|
pub title_only: Option<bool>,
|
||||||
|
pub post_url_only: Option<bool>,
|
||||||
|
pub saved_only: Option<bool>,
|
||||||
|
pub liked_only: Option<bool>,
|
||||||
|
pub disliked_only: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
@ -17,7 +17,7 @@ use lemmy_db_schema::{
|
|||||||
community::{Community, CommunityModerator, CommunityUpdateForm},
|
community::{Community, CommunityModerator, CommunityUpdateForm},
|
||||||
community_block::CommunityBlock,
|
community_block::CommunityBlock,
|
||||||
email_verification::{EmailVerification, EmailVerificationForm},
|
email_verification::{EmailVerification, EmailVerificationForm},
|
||||||
images::RemoteImage,
|
images::{ImageDetails, RemoteImage},
|
||||||
instance::Instance,
|
instance::Instance,
|
||||||
instance_block::InstanceBlock,
|
instance_block::InstanceBlock,
|
||||||
local_site::LocalSite,
|
local_site::LocalSite,
|
||||||
@ -73,13 +73,7 @@ pub async fn is_mod_or_admin(
|
|||||||
community_id: CommunityId,
|
community_id: CommunityId,
|
||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
check_user_valid(person)?;
|
check_user_valid(person)?;
|
||||||
|
CommunityView::check_is_mod_or_admin(pool, person.id, community_id).await
|
||||||
let is_mod_or_admin = CommunityView::is_mod_or_admin(pool, person.id, community_id).await?;
|
|
||||||
if !is_mod_or_admin {
|
|
||||||
Err(LemmyErrorType::NotAModOrAdmin)?
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
@ -110,13 +104,7 @@ pub async fn check_community_mod_of_any_or_admin_action(
|
|||||||
let person = &local_user_view.person;
|
let person = &local_user_view.person;
|
||||||
|
|
||||||
check_user_valid(person)?;
|
check_user_valid(person)?;
|
||||||
|
CommunityView::check_is_mod_of_any_or_admin(pool, person.id).await
|
||||||
let is_mod_of_any_or_admin = CommunityView::is_mod_of_any_or_admin(pool, person.id).await?;
|
|
||||||
if !is_mod_of_any_or_admin {
|
|
||||||
Err(LemmyErrorType::NotAModOrAdmin)?
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_admin(local_user_view: &LocalUserView) -> LemmyResult<()> {
|
pub fn is_admin(local_user_view: &LocalUserView) -> LemmyResult<()> {
|
||||||
@ -175,9 +163,7 @@ pub async fn update_read_comments(
|
|||||||
..PersonPostAggregatesForm::default()
|
..PersonPostAggregatesForm::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
PersonPostAggregates::upsert(pool, &person_post_agg_form)
|
PersonPostAggregates::upsert(pool, &person_post_agg_form).await?;
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -223,9 +209,7 @@ pub async fn check_registration_application(
|
|||||||
// Fetch the registration application. If no admin id is present its still pending. Otherwise it
|
// Fetch the registration application. If no admin id is present its still pending. Otherwise it
|
||||||
// was processed (either accepted or denied).
|
// was processed (either accepted or denied).
|
||||||
let local_user_id = local_user_view.local_user.id;
|
let local_user_id = local_user_view.local_user.id;
|
||||||
let registration = RegistrationApplication::find_by_local_user_id(pool, local_user_id)
|
let registration = RegistrationApplication::find_by_local_user_id(pool, local_user_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindRegistrationApplication)?;
|
|
||||||
if registration.admin_id.is_some() {
|
if registration.admin_id.is_some() {
|
||||||
Err(LemmyErrorType::RegistrationDenied(registration.deny_reason))?
|
Err(LemmyErrorType::RegistrationDenied(registration.deny_reason))?
|
||||||
} else {
|
} else {
|
||||||
@ -246,7 +230,7 @@ pub async fn check_community_user_action(
|
|||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
check_user_valid(person)?;
|
check_user_valid(person)?;
|
||||||
check_community_deleted_removed(community_id, pool).await?;
|
check_community_deleted_removed(community_id, pool).await?;
|
||||||
check_community_ban(person, community_id, pool).await?;
|
CommunityPersonBanView::check(pool, person.id, community_id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,28 +238,13 @@ async fn check_community_deleted_removed(
|
|||||||
community_id: CommunityId,
|
community_id: CommunityId,
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
let community = Community::read(pool, community_id)
|
let community = Community::read(pool, community_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
if community.deleted || community.removed {
|
if community.deleted || community.removed {
|
||||||
Err(LemmyErrorType::Deleted)?
|
Err(LemmyErrorType::Deleted)?
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn check_community_ban(
|
|
||||||
person: &Person,
|
|
||||||
community_id: CommunityId,
|
|
||||||
pool: &mut DbPool<'_>,
|
|
||||||
) -> LemmyResult<()> {
|
|
||||||
// check if user was banned from site or community
|
|
||||||
let is_banned = CommunityPersonBanView::get(pool, person.id, community_id).await?;
|
|
||||||
if is_banned {
|
|
||||||
Err(LemmyErrorType::BannedFromCommunity)?
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that the given user can perform a mod action in the community.
|
/// Check that the given user can perform a mod action in the community.
|
||||||
///
|
///
|
||||||
/// In particular it checks that he is an admin or mod, wasn't banned and the community isn't
|
/// In particular it checks that he is an admin or mod, wasn't banned and the community isn't
|
||||||
@ -287,7 +256,7 @@ pub async fn check_community_mod_action(
|
|||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
is_mod_or_admin(pool, person, community_id).await?;
|
is_mod_or_admin(pool, person, community_id).await?;
|
||||||
check_community_ban(person, community_id, pool).await?;
|
CommunityPersonBanView::check(pool, person.id, community_id).await?;
|
||||||
|
|
||||||
// it must be possible to restore deleted community
|
// it must be possible to restore deleted community
|
||||||
if !allow_deleted {
|
if !allow_deleted {
|
||||||
@ -313,51 +282,6 @@ pub fn check_comment_deleted_or_removed(comment: &Comment) -> LemmyResult<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Throws an error if a recipient has blocked a person.
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
pub async fn check_person_block(
|
|
||||||
my_id: PersonId,
|
|
||||||
potential_blocker_id: PersonId,
|
|
||||||
pool: &mut DbPool<'_>,
|
|
||||||
) -> LemmyResult<()> {
|
|
||||||
let is_blocked = PersonBlock::read(pool, potential_blocker_id, my_id).await?;
|
|
||||||
if is_blocked {
|
|
||||||
Err(LemmyErrorType::PersonIsBlocked)?
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Throws an error if a recipient has blocked a community.
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
async fn check_community_block(
|
|
||||||
community_id: CommunityId,
|
|
||||||
person_id: PersonId,
|
|
||||||
pool: &mut DbPool<'_>,
|
|
||||||
) -> LemmyResult<()> {
|
|
||||||
let is_blocked = CommunityBlock::read(pool, person_id, community_id).await?;
|
|
||||||
if is_blocked {
|
|
||||||
Err(LemmyErrorType::CommunityIsBlocked)?
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Throws an error if a recipient has blocked an instance.
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
async fn check_instance_block(
|
|
||||||
instance_id: InstanceId,
|
|
||||||
person_id: PersonId,
|
|
||||||
pool: &mut DbPool<'_>,
|
|
||||||
) -> LemmyResult<()> {
|
|
||||||
let is_blocked = InstanceBlock::read(pool, person_id, instance_id).await?;
|
|
||||||
if is_blocked {
|
|
||||||
Err(LemmyErrorType::InstanceIsBlocked)?
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn check_person_instance_community_block(
|
pub async fn check_person_instance_community_block(
|
||||||
my_id: PersonId,
|
my_id: PersonId,
|
||||||
@ -366,9 +290,9 @@ pub async fn check_person_instance_community_block(
|
|||||||
community_id: CommunityId,
|
community_id: CommunityId,
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
check_person_block(my_id, potential_blocker_id, pool).await?;
|
PersonBlock::read(pool, potential_blocker_id, my_id).await?;
|
||||||
check_instance_block(community_instance_id, potential_blocker_id, pool).await?;
|
InstanceBlock::read(pool, potential_blocker_id, community_instance_id).await?;
|
||||||
check_community_block(community_id, potential_blocker_id, pool).await?;
|
CommunityBlock::read(pool, potential_blocker_id, community_id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,7 +628,7 @@ pub async fn purge_image_posts_for_person(
|
|||||||
|
|
||||||
/// Delete a local_user's images
|
/// Delete a local_user's images
|
||||||
async fn delete_local_user_images(person_id: PersonId, context: &LemmyContext) -> LemmyResult<()> {
|
async fn delete_local_user_images(person_id: PersonId, context: &LemmyContext) -> LemmyResult<()> {
|
||||||
if let Ok(Some(local_user)) = LocalUserView::read_person(&mut context.pool(), person_id).await {
|
if let Ok(local_user) = LocalUserView::read_person(&mut context.pool(), person_id).await {
|
||||||
let pictrs_uploads =
|
let pictrs_uploads =
|
||||||
LocalImageView::get_all_by_local_user_id(&mut context.pool(), local_user.local_user.id)
|
LocalImageView::get_all_by_local_user_id(&mut context.pool(), local_user.local_user.id)
|
||||||
.await?;
|
.await?;
|
||||||
@ -749,9 +673,7 @@ pub async fn remove_user_data(
|
|||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
let pool = &mut context.pool();
|
let pool = &mut context.pool();
|
||||||
// Purge user images
|
// Purge user images
|
||||||
let person = Person::read(pool, banned_person_id)
|
let person = Person::read(pool, banned_person_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?;
|
|
||||||
if let Some(avatar) = person.avatar {
|
if let Some(avatar) = person.avatar {
|
||||||
purge_image_from_pictrs(&avatar, context).await.ok();
|
purge_image_from_pictrs(&avatar, context).await.ok();
|
||||||
}
|
}
|
||||||
@ -854,12 +776,13 @@ pub async fn remove_or_restore_user_data_in_community(
|
|||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
// TODO Diesel doesn't allow updates with joins, so this has to be a loop
|
// TODO Diesel doesn't allow updates with joins, so this has to be a loop
|
||||||
|
let site = Site::read_local(pool).await?;
|
||||||
let comments = CommentQuery {
|
let comments = CommentQuery {
|
||||||
creator_id: Some(banned_person_id),
|
creator_id: Some(banned_person_id),
|
||||||
community_id: Some(community_id),
|
community_id: Some(community_id),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(pool)
|
.list(&site, pool)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
for comment_view in &comments {
|
for comment_view in &comments {
|
||||||
@ -881,9 +804,7 @@ pub async fn remove_or_restore_user_data_in_community(
|
|||||||
pub async fn purge_user_account(person_id: PersonId, context: &LemmyContext) -> LemmyResult<()> {
|
pub async fn purge_user_account(person_id: PersonId, context: &LemmyContext) -> LemmyResult<()> {
|
||||||
let pool = &mut context.pool();
|
let pool = &mut context.pool();
|
||||||
|
|
||||||
let person = Person::read(pool, person_id)
|
let person = Person::read(pool, person_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?;
|
|
||||||
|
|
||||||
// Delete their local images, if they're a local user
|
// Delete their local images, if they're a local user
|
||||||
delete_local_user_images(person_id, context).await.ok();
|
delete_local_user_images(person_id, context).await.ok();
|
||||||
@ -913,7 +834,7 @@ pub async fn purge_user_account(person_id: PersonId, context: &LemmyContext) ->
|
|||||||
CommunityModerator::leave_all_communities(pool, person_id).await?;
|
CommunityModerator::leave_all_communities(pool, person_id).await?;
|
||||||
|
|
||||||
// Delete the oauth accounts linked to the local user
|
// Delete the oauth accounts linked to the local user
|
||||||
if let Ok(Some(local_user)) = LocalUserView::read_person(pool, person_id).await {
|
if let Ok(local_user) = LocalUserView::read_person(pool, person_id).await {
|
||||||
OAuthAccount::delete_user_accounts(pool, local_user.local_user.id).await?;
|
OAuthAccount::delete_user_accounts(pool, local_user.local_user.id).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -999,6 +920,18 @@ fn limit_expire_time(expires: DateTime<Utc>) -> LemmyResult<Option<DateTime<Utc>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
|
pub fn check_conflicting_like_filters(
|
||||||
|
liked_only: Option<bool>,
|
||||||
|
disliked_only: Option<bool>,
|
||||||
|
) -> LemmyResult<()> {
|
||||||
|
if liked_only.unwrap_or_default() && disliked_only.unwrap_or_default() {
|
||||||
|
Err(LemmyErrorType::ContradictingFilters)?
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn process_markdown(
|
pub async fn process_markdown(
|
||||||
text: &str,
|
text: &str,
|
||||||
slur_regex: &Option<Regex>,
|
slur_regex: &Option<Regex>,
|
||||||
@ -1012,6 +945,7 @@ pub async fn process_markdown(
|
|||||||
|
|
||||||
if context.settings().pictrs_config()?.image_mode() == PictrsImageMode::ProxyAllImages {
|
if context.settings().pictrs_config()?.image_mode() == PictrsImageMode::ProxyAllImages {
|
||||||
let (text, links) = markdown_rewrite_image_links(text);
|
let (text, links) = markdown_rewrite_image_links(text);
|
||||||
|
RemoteImage::create(&mut context.pool(), links.clone()).await?;
|
||||||
|
|
||||||
// Create images and image detail rows
|
// Create images and image detail rows
|
||||||
for link in links {
|
for link in links {
|
||||||
@ -1021,7 +955,7 @@ pub async fn process_markdown(
|
|||||||
let proxied =
|
let proxied =
|
||||||
build_proxied_image_url(&link, &context.settings().get_protocol_and_hostname())?;
|
build_proxied_image_url(&link, &context.settings().get_protocol_and_hostname())?;
|
||||||
let details_form = details.build_image_details_form(&proxied);
|
let details_form = details.build_image_details_form(&proxied);
|
||||||
RemoteImage::create(&mut context.pool(), &details_form).await?;
|
ImageDetails::create(&mut context.pool(), &details_form).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(text)
|
Ok(text)
|
||||||
@ -1057,13 +991,15 @@ async fn proxy_image_link_internal(
|
|||||||
if link.domain() == Some(&context.settings().hostname) {
|
if link.domain() == Some(&context.settings().hostname) {
|
||||||
Ok(link.into())
|
Ok(link.into())
|
||||||
} else if image_mode == PictrsImageMode::ProxyAllImages {
|
} else if image_mode == PictrsImageMode::ProxyAllImages {
|
||||||
|
RemoteImage::create(&mut context.pool(), vec![link.clone()]).await?;
|
||||||
|
|
||||||
let proxied = build_proxied_image_url(&link, &context.settings().get_protocol_and_hostname())?;
|
let proxied = build_proxied_image_url(&link, &context.settings().get_protocol_and_hostname())?;
|
||||||
// This should fail softly, since pictrs might not even be running
|
// This should fail softly, since pictrs might not even be running
|
||||||
let details_res = fetch_pictrs_proxied_image_details(&link, context).await;
|
let details_res = fetch_pictrs_proxied_image_details(&link, context).await;
|
||||||
|
|
||||||
if let Ok(details) = details_res {
|
if let Ok(details) = details_res {
|
||||||
let details_form = details.build_image_details_form(&proxied);
|
let details_form = details.build_image_details_form(&proxied);
|
||||||
RemoteImage::create(&mut context.pool(), &details_form).await?;
|
ImageDetails::create(&mut context.pool(), &details_form).await?;
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(proxied.into())
|
Ok(proxied.into())
|
||||||
@ -1131,8 +1067,7 @@ fn build_proxied_image_url(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::unwrap_used)]
|
#[expect(clippy::unwrap_used)]
|
||||||
#[allow(clippy::indexing_slicing)]
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -1209,7 +1144,7 @@ mod tests {
|
|||||||
assert!(
|
assert!(
|
||||||
RemoteImage::validate(&mut context.pool(), remote_image.into())
|
RemoteImage::validate(&mut context.pool(), remote_image.into())
|
||||||
.await
|
.await
|
||||||
.is_err()
|
.is_ok()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ futures.workspace = true
|
|||||||
uuid = { workspace = true }
|
uuid = { workspace = true }
|
||||||
moka.workspace = true
|
moka.workspace = true
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
|
chrono.workspace = true
|
||||||
webmention = "0.6.0"
|
webmention = "0.6.0"
|
||||||
accept-language = "3.1.0"
|
accept-language = "3.1.0"
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
|
@ -57,8 +57,7 @@ pub async fn create_comment(
|
|||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
let post = post_view.post;
|
let post = post_view.post;
|
||||||
let community_id = post_view.community.id;
|
let community_id = post_view.community.id;
|
||||||
@ -79,8 +78,7 @@ pub async fn create_comment(
|
|||||||
Comment::read(&mut context.pool(), parent_id).await.ok()
|
Comment::read(&mut context.pool(), parent_id).await.ok()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
};
|
||||||
.flatten();
|
|
||||||
|
|
||||||
// If there's a parent_id, check to make sure that comment is in that post
|
// If there's a parent_id, check to make sure that comment is in that post
|
||||||
// Strange issue where sometimes the post ID of the parent comment is incorrect
|
// Strange issue where sometimes the post ID of the parent comment is incorrect
|
||||||
@ -111,9 +109,10 @@ pub async fn create_comment(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut comment_form =
|
let comment_form = CommentInsertForm {
|
||||||
CommentInsertForm::new(local_user_view.person.id, data.post_id, content.clone());
|
language_id,
|
||||||
comment_form.language_id = language_id;
|
..CommentInsertForm::new(local_user_view.person.id, data.post_id, content.clone())
|
||||||
|
};
|
||||||
|
|
||||||
// Create the comment
|
// Create the comment
|
||||||
let parent_path = parent_opt.clone().map(|t| t.path);
|
let parent_path = parent_opt.clone().map(|t| t.path);
|
||||||
|
@ -26,8 +26,7 @@ pub async fn delete_comment(
|
|||||||
comment_id,
|
comment_id,
|
||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
|
|
||||||
// Dont delete it if its already been deleted.
|
// Dont delete it if its already been deleted.
|
||||||
if orig_comment.comment.deleted == data.deleted {
|
if orig_comment.comment.deleted == data.deleted {
|
||||||
|
@ -31,8 +31,7 @@ pub async fn remove_comment(
|
|||||||
comment_id,
|
comment_id,
|
||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
|
|
||||||
check_community_mod_action(
|
check_community_mod_action(
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
|
@ -41,8 +41,7 @@ pub async fn update_comment(
|
|||||||
comment_id,
|
comment_id,
|
||||||
Some(&local_user_view.local_user),
|
Some(&local_user_view.local_user),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?;
|
|
||||||
|
|
||||||
check_community_user_action(
|
check_community_user_action(
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
|
@ -88,23 +88,25 @@ pub async fn create_community(
|
|||||||
// When you create a community, make sure the user becomes a moderator and a follower
|
// When you create a community, make sure the user becomes a moderator and a follower
|
||||||
let keypair = generate_actor_keypair()?;
|
let keypair = generate_actor_keypair()?;
|
||||||
|
|
||||||
let mut community_form = CommunityInsertForm::new(
|
let community_form = CommunityInsertForm {
|
||||||
|
description,
|
||||||
|
icon,
|
||||||
|
banner,
|
||||||
|
nsfw: data.nsfw,
|
||||||
|
actor_id: Some(community_actor_id.clone()),
|
||||||
|
private_key: Some(keypair.private_key),
|
||||||
|
followers_url: Some(generate_followers_url(&community_actor_id)?),
|
||||||
|
inbox_url: Some(generate_inbox_url(&community_actor_id)?),
|
||||||
|
shared_inbox_url: Some(generate_shared_inbox_url(context.settings())?),
|
||||||
|
posting_restricted_to_mods: data.posting_restricted_to_mods,
|
||||||
|
visibility: data.visibility,
|
||||||
|
..CommunityInsertForm::new(
|
||||||
site_view.site.instance_id,
|
site_view.site.instance_id,
|
||||||
data.name.clone(),
|
data.name.clone(),
|
||||||
data.title.clone(),
|
data.title.clone(),
|
||||||
keypair.public_key,
|
keypair.public_key,
|
||||||
);
|
)
|
||||||
community_form.description = description;
|
};
|
||||||
community_form.icon = icon;
|
|
||||||
community_form.banner = banner;
|
|
||||||
community_form.nsfw = data.nsfw;
|
|
||||||
community_form.actor_id = Some(community_actor_id.clone());
|
|
||||||
community_form.private_key = Some(keypair.private_key);
|
|
||||||
community_form.followers_url = Some(generate_followers_url(&community_actor_id)?);
|
|
||||||
community_form.inbox_url = Some(generate_inbox_url(&community_actor_id)?);
|
|
||||||
community_form.shared_inbox_url = Some(generate_shared_inbox_url(context.settings())?);
|
|
||||||
community_form.posting_restricted_to_mods = data.posting_restricted_to_mods;
|
|
||||||
community_form.visibility = data.visibility;
|
|
||||||
|
|
||||||
let inserted_community = Community::create(&mut context.pool(), &community_form)
|
let inserted_community = Community::create(&mut context.pool(), &community_form)
|
||||||
.await
|
.await
|
||||||
|
@ -51,9 +51,7 @@ pub async fn update_community(
|
|||||||
is_valid_body_field(desc, false)?;
|
is_valid_body_field(desc, false)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let old_community = Community::read(&mut context.pool(), data.community_id)
|
let old_community = Community::read(&mut context.pool(), data.community_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
let icon = diesel_url_update(data.icon.as_deref())?;
|
let icon = diesel_url_update(data.icon.as_deref())?;
|
||||||
replace_image(&icon, &old_community.icon, &context).await?;
|
replace_image(&icon, &old_community.icon, &context).await?;
|
||||||
|
@ -7,7 +7,7 @@ use lemmy_db_schema::{
|
|||||||
utils::{diesel_required_string_update, diesel_required_url_update, naive_now},
|
utils::{diesel_required_string_update, diesel_required_url_update, naive_now},
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_utils::{error::LemmyError, LemmyErrorType};
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn update_oauth_provider(
|
pub async fn update_oauth_provider(
|
||||||
@ -37,8 +37,6 @@ pub async fn update_oauth_provider(
|
|||||||
|
|
||||||
let update_result =
|
let update_result =
|
||||||
OAuthProvider::update(&mut context.pool(), data.id, &oauth_provider_form).await?;
|
OAuthProvider::update(&mut context.pool(), data.id, &oauth_provider_form).await?;
|
||||||
let oauth_provider = OAuthProvider::read(&mut context.pool(), update_result.id)
|
let oauth_provider = OAuthProvider::read(&mut context.pool(), update_result.id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindOauthProvider)?;
|
|
||||||
Ok(Json(oauth_provider))
|
Ok(Json(oauth_provider))
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::convert_published_time;
|
||||||
use activitypub_federation::config::Data;
|
use activitypub_federation::config::Data;
|
||||||
use actix_web::web::Json;
|
use actix_web::web::Json;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
@ -92,20 +93,15 @@ pub async fn create_post(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let community = Community::read(&mut context.pool(), community_id)
|
let community = Community::read(&mut context.pool(), community_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
if community.posting_restricted_to_mods {
|
if community.posting_restricted_to_mods {
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let is_mod = CommunityModeratorView::is_community_moderator(
|
CommunityModeratorView::check_is_community_moderator(
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
community_id,
|
community_id,
|
||||||
local_user_view.local_user.person_id,
|
local_user_view.local_user.person_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
if !is_mod {
|
|
||||||
Err(LemmyErrorType::OnlyModsCanPostInCommunity)?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only need to check if language is allowed in case user set it explicitly. When using default
|
// Only need to check if language is allowed in case user set it explicitly. When using default
|
||||||
@ -130,25 +126,36 @@ pub async fn create_post(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut post_form = PostInsertForm::new(
|
let scheduled_publish_time =
|
||||||
|
convert_published_time(data.scheduled_publish_time, &local_user_view, &context).await?;
|
||||||
|
let post_form = PostInsertForm {
|
||||||
|
url: url.map(Into::into),
|
||||||
|
body,
|
||||||
|
alt_text: data.alt_text.clone(),
|
||||||
|
nsfw: data.nsfw,
|
||||||
|
language_id,
|
||||||
|
scheduled_publish_time,
|
||||||
|
..PostInsertForm::new(
|
||||||
data.name.trim().to_string(),
|
data.name.trim().to_string(),
|
||||||
local_user_view.person.id,
|
local_user_view.person.id,
|
||||||
data.community_id,
|
data.community_id,
|
||||||
);
|
)
|
||||||
post_form.url = url.map(Into::into);
|
};
|
||||||
post_form.body = body;
|
|
||||||
post_form.alt_text = data.alt_text.clone();
|
|
||||||
post_form.nsfw = data.nsfw;
|
|
||||||
post_form.language_id = language_id;
|
|
||||||
|
|
||||||
let inserted_post = Post::create(&mut context.pool(), &post_form)
|
let inserted_post = Post::create(&mut context.pool(), &post_form)
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntCreatePost)?;
|
.with_lemmy_type(LemmyErrorType::CouldntCreatePost)?;
|
||||||
|
|
||||||
|
let federate_post = if scheduled_publish_time.is_none() {
|
||||||
|
send_webmention(inserted_post.clone(), community);
|
||||||
|
|post| Some(SendActivityData::CreatePost(post))
|
||||||
|
} else {
|
||||||
|
|_| None
|
||||||
|
};
|
||||||
generate_post_link_metadata(
|
generate_post_link_metadata(
|
||||||
inserted_post.clone(),
|
inserted_post.clone(),
|
||||||
custom_thumbnail.map(Into::into),
|
custom_thumbnail.map(Into::into),
|
||||||
|post| Some(SendActivityData::CreatePost(post)),
|
federate_post,
|
||||||
context.reset_request_count(),
|
context.reset_request_count(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -168,11 +175,14 @@ pub async fn create_post(
|
|||||||
|
|
||||||
mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
||||||
|
|
||||||
if let Some(url) = inserted_post.url.clone() {
|
build_post_response(&context, community_id, local_user_view, post_id).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_webmention(post: Post, community: Community) {
|
||||||
|
if let Some(url) = post.url.clone() {
|
||||||
if community.visibility == CommunityVisibility::Public {
|
if community.visibility == CommunityVisibility::Public {
|
||||||
spawn_try_task(async move {
|
spawn_try_task(async move {
|
||||||
let mut webmention =
|
let mut webmention = Webmention::new::<Url>(post.ap_id.clone().into(), url.clone().into())?;
|
||||||
Webmention::new::<Url>(inserted_post.ap_id.clone().into(), url.clone().into())?;
|
|
||||||
webmention.set_checked(true);
|
webmention.set_checked(true);
|
||||||
match webmention
|
match webmention
|
||||||
.send()
|
.send()
|
||||||
@ -186,6 +196,4 @@ pub async fn create_post(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
build_post_response(&context, community_id, local_user_view, post_id).await
|
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,7 @@ pub async fn delete_post(
|
|||||||
local_user_view: LocalUserView,
|
local_user_view: LocalUserView,
|
||||||
) -> LemmyResult<Json<PostResponse>> {
|
) -> LemmyResult<Json<PostResponse>> {
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let orig_post = Post::read(&mut context.pool(), post_id)
|
let orig_post = Post::read(&mut context.pool(), post_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
// Dont delete it if its already been deleted.
|
// Dont delete it if its already been deleted.
|
||||||
if orig_post.deleted == data.deleted {
|
if orig_post.deleted == data.deleted {
|
||||||
|
@ -1,5 +1,38 @@
|
|||||||
|
use chrono::{DateTime, TimeZone, Utc};
|
||||||
|
use lemmy_api_common::context::LemmyContext;
|
||||||
|
use lemmy_db_schema::source::post::Post;
|
||||||
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
|
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
||||||
|
|
||||||
pub mod create;
|
pub mod create;
|
||||||
pub mod delete;
|
pub mod delete;
|
||||||
pub mod read;
|
pub mod read;
|
||||||
pub mod remove;
|
pub mod remove;
|
||||||
pub mod update;
|
pub mod update;
|
||||||
|
|
||||||
|
async fn convert_published_time(
|
||||||
|
scheduled_publish_time: Option<i64>,
|
||||||
|
local_user_view: &LocalUserView,
|
||||||
|
context: &LemmyContext,
|
||||||
|
) -> LemmyResult<Option<DateTime<Utc>>> {
|
||||||
|
const MAX_SCHEDULED_POSTS: i64 = 10;
|
||||||
|
if let Some(scheduled_publish_time) = scheduled_publish_time {
|
||||||
|
let converted = Utc
|
||||||
|
.timestamp_opt(scheduled_publish_time, 0)
|
||||||
|
.single()
|
||||||
|
.ok_or(LemmyErrorType::InvalidUnixTime)?;
|
||||||
|
if converted < Utc::now() {
|
||||||
|
Err(LemmyErrorType::PostScheduleTimeMustBeInFuture)?;
|
||||||
|
}
|
||||||
|
if !local_user_view.local_user.admin {
|
||||||
|
let count =
|
||||||
|
Post::user_scheduled_post_count(local_user_view.person.id, &mut context.pool()).await?;
|
||||||
|
if count >= MAX_SCHEDULED_POSTS {
|
||||||
|
Err(LemmyErrorType::TooManyScheduledPosts)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Some(converted))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -33,16 +33,14 @@ pub async fn get_post(
|
|||||||
} else if let Some(comment_id) = data.comment_id {
|
} else if let Some(comment_id) = data.comment_id {
|
||||||
Comment::read(&mut context.pool(), comment_id)
|
Comment::read(&mut context.pool(), comment_id)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?
|
|
||||||
.post_id
|
.post_id
|
||||||
} else {
|
} else {
|
||||||
Err(LemmyErrorType::CouldntFindPost)?
|
Err(LemmyErrorType::NotFound)?
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check to see if the person is a mod or admin, to show deleted / removed
|
// Check to see if the person is a mod or admin, to show deleted / removed
|
||||||
let community_id = Post::read(&mut context.pool(), post_id)
|
let community_id = Post::read_xx(&mut context.pool(), post_id)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?
|
|
||||||
.community_id;
|
.community_id;
|
||||||
|
|
||||||
let is_mod_or_admin = is_mod_or_admin_opt(
|
let is_mod_or_admin = is_mod_or_admin_opt(
|
||||||
@ -60,8 +58,7 @@ pub async fn get_post(
|
|||||||
local_user.as_ref(),
|
local_user.as_ref(),
|
||||||
is_mod_or_admin,
|
is_mod_or_admin,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
let post_id = post_view.post.id;
|
let post_id = post_view.post.id;
|
||||||
if let Some(person_id) = person_id {
|
if let Some(person_id) = person_id {
|
||||||
@ -83,15 +80,15 @@ pub async fn get_post(
|
|||||||
local_user.as_ref(),
|
local_user.as_ref(),
|
||||||
is_mod_or_admin,
|
is_mod_or_admin,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
|
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
|
||||||
|
|
||||||
// Fetch the cross_posts
|
// Fetch the cross_posts
|
||||||
let cross_posts = if let Some(url) = &post_view.post.url {
|
let cross_posts = if let Some(url) = &post_view.post.url {
|
||||||
let mut x_posts = PostQuery {
|
let mut x_posts = PostQuery {
|
||||||
url_search: Some(url.inner().as_str().into()),
|
url_only: Some(true),
|
||||||
|
search_term: Some(url.inner().as_str().into()),
|
||||||
local_user: local_user.as_ref(),
|
local_user: local_user.as_ref(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ use lemmy_db_schema::{
|
|||||||
traits::{Crud, Reportable},
|
traits::{Crud, Reportable},
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn remove_post(
|
pub async fn remove_post(
|
||||||
@ -26,9 +26,7 @@ pub async fn remove_post(
|
|||||||
local_user_view: LocalUserView,
|
local_user_view: LocalUserView,
|
||||||
) -> LemmyResult<Json<PostResponse>> {
|
) -> LemmyResult<Json<PostResponse>> {
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let orig_post = Post::read(&mut context.pool(), post_id)
|
let orig_post = Post::read(&mut context.pool(), post_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
check_community_mod_action(
|
check_community_mod_action(
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::{convert_published_time, create::send_webmention};
|
||||||
use activitypub_federation::config::Data;
|
use activitypub_federation::config::Data;
|
||||||
use actix_web::web::Json;
|
use actix_web::web::Json;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
@ -16,6 +17,7 @@ use lemmy_api_common::{
|
|||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
actor_language::CommunityLanguage,
|
actor_language::CommunityLanguage,
|
||||||
|
community::Community,
|
||||||
local_site::LocalSite,
|
local_site::LocalSite,
|
||||||
post::{Post, PostUpdateForm},
|
post::{Post, PostUpdateForm},
|
||||||
},
|
},
|
||||||
@ -85,9 +87,7 @@ pub async fn update_post(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let orig_post = Post::read(&mut context.pool(), post_id)
|
let orig_post = Post::read(&mut context.pool(), post_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
check_community_user_action(
|
check_community_user_action(
|
||||||
&local_user_view.person,
|
&local_user_view.person,
|
||||||
@ -109,6 +109,21 @@ pub async fn update_post(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// handle changes to scheduled_publish_time
|
||||||
|
let scheduled_publish_time = match (
|
||||||
|
orig_post.scheduled_publish_time,
|
||||||
|
data.scheduled_publish_time,
|
||||||
|
) {
|
||||||
|
// schedule time can be changed if post is still scheduled (and not published yet)
|
||||||
|
(Some(_), Some(_)) => {
|
||||||
|
Some(convert_published_time(data.scheduled_publish_time, &local_user_view, &context).await?)
|
||||||
|
}
|
||||||
|
// post was scheduled, gets changed to publish immediately
|
||||||
|
(Some(_), None) => Some(None),
|
||||||
|
// unchanged
|
||||||
|
(_, _) => None,
|
||||||
|
};
|
||||||
|
|
||||||
let post_form = PostUpdateForm {
|
let post_form = PostUpdateForm {
|
||||||
name: data.name.clone(),
|
name: data.name.clone(),
|
||||||
url,
|
url,
|
||||||
@ -117,6 +132,7 @@ pub async fn update_post(
|
|||||||
nsfw: data.nsfw,
|
nsfw: data.nsfw,
|
||||||
language_id: data.language_id,
|
language_id: data.language_id,
|
||||||
updated: Some(Some(naive_now())),
|
updated: Some(Some(naive_now())),
|
||||||
|
scheduled_publish_time,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,13 +141,36 @@ pub async fn update_post(
|
|||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdatePost)?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdatePost)?;
|
||||||
|
|
||||||
|
// send out federation/webmention if necessary
|
||||||
|
match (
|
||||||
|
orig_post.scheduled_publish_time,
|
||||||
|
data.scheduled_publish_time,
|
||||||
|
) {
|
||||||
|
// schedule was removed, send create activity and webmention
|
||||||
|
(Some(_), None) => {
|
||||||
|
let community = Community::read(&mut context.pool(), orig_post.community_id).await?;
|
||||||
|
send_webmention(updated_post.clone(), community);
|
||||||
|
generate_post_link_metadata(
|
||||||
|
updated_post.clone(),
|
||||||
|
custom_thumbnail.flatten().map(Into::into),
|
||||||
|
|post| Some(SendActivityData::CreatePost(post)),
|
||||||
|
context.reset_request_count(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
// post was already public, send update
|
||||||
|
(None, _) => {
|
||||||
generate_post_link_metadata(
|
generate_post_link_metadata(
|
||||||
updated_post.clone(),
|
updated_post.clone(),
|
||||||
custom_thumbnail.flatten().map(Into::into),
|
custom_thumbnail.flatten().map(Into::into),
|
||||||
|post| Some(SendActivityData::UpdatePost(post)),
|
|post| Some(SendActivityData::UpdatePost(post)),
|
||||||
context.reset_request_count(),
|
context.reset_request_count(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?
|
||||||
|
}
|
||||||
|
// schedule was changed, do nothing
|
||||||
|
(Some(_), Some(_)) => {}
|
||||||
|
};
|
||||||
|
|
||||||
build_post_response(
|
build_post_response(
|
||||||
context.deref(),
|
context.deref(),
|
||||||
|
@ -5,7 +5,6 @@ use lemmy_api_common::{
|
|||||||
private_message::{CreatePrivateMessage, PrivateMessageResponse},
|
private_message::{CreatePrivateMessage, PrivateMessageResponse},
|
||||||
send_activity::{ActivityChannel, SendActivityData},
|
send_activity::{ActivityChannel, SendActivityData},
|
||||||
utils::{
|
utils::{
|
||||||
check_person_block,
|
|
||||||
get_interface_language,
|
get_interface_language,
|
||||||
get_url_blocklist,
|
get_url_blocklist,
|
||||||
local_site_to_slur_regex,
|
local_site_to_slur_regex,
|
||||||
@ -16,6 +15,7 @@ use lemmy_api_common::{
|
|||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
local_site::LocalSite,
|
local_site::LocalSite,
|
||||||
|
person_block::PersonBlock,
|
||||||
private_message::{PrivateMessage, PrivateMessageInsertForm},
|
private_message::{PrivateMessage, PrivateMessageInsertForm},
|
||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
@ -39,10 +39,10 @@ pub async fn create_private_message(
|
|||||||
let content = process_markdown(&data.content, &slur_regex, &url_blocklist, &context).await?;
|
let content = process_markdown(&data.content, &slur_regex, &url_blocklist, &context).await?;
|
||||||
is_valid_body_field(&content, false)?;
|
is_valid_body_field(&content, false)?;
|
||||||
|
|
||||||
check_person_block(
|
PersonBlock::read(
|
||||||
local_user_view.person.id,
|
|
||||||
data.recipient_id,
|
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
|
data.recipient_id,
|
||||||
|
local_user_view.person.id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@ -56,16 +56,12 @@ pub async fn create_private_message(
|
|||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntCreatePrivateMessage)?;
|
.with_lemmy_type(LemmyErrorType::CouldntCreatePrivateMessage)?;
|
||||||
|
|
||||||
let view = PrivateMessageView::read(&mut context.pool(), inserted_private_message.id)
|
let view = PrivateMessageView::read(&mut context.pool(), inserted_private_message.id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPrivateMessage)?;
|
|
||||||
|
|
||||||
// Send email to the local recipient, if one exists
|
// Send email to the local recipient, if one exists
|
||||||
if view.recipient.local {
|
if view.recipient.local {
|
||||||
let recipient_id = data.recipient_id;
|
let recipient_id = data.recipient_id;
|
||||||
let local_recipient = LocalUserView::read_person(&mut context.pool(), recipient_id)
|
let local_recipient = LocalUserView::read_person(&mut context.pool(), recipient_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?;
|
|
||||||
let lang = get_interface_language(&local_recipient);
|
let lang = get_interface_language(&local_recipient);
|
||||||
let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname());
|
let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname());
|
||||||
let sender_name = &local_user_view.person.name;
|
let sender_name = &local_user_view.person.name;
|
||||||
|
@ -20,9 +20,7 @@ pub async fn delete_private_message(
|
|||||||
) -> LemmyResult<Json<PrivateMessageResponse>> {
|
) -> LemmyResult<Json<PrivateMessageResponse>> {
|
||||||
// Checking permissions
|
// Checking permissions
|
||||||
let private_message_id = data.private_message_id;
|
let private_message_id = data.private_message_id;
|
||||||
let orig_private_message = PrivateMessage::read(&mut context.pool(), private_message_id)
|
let orig_private_message = PrivateMessage::read(&mut context.pool(), private_message_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPrivateMessage)?;
|
|
||||||
if local_user_view.person.id != orig_private_message.creator_id {
|
if local_user_view.person.id != orig_private_message.creator_id {
|
||||||
Err(LemmyErrorType::EditPrivateMessageNotAllowed)?
|
Err(LemmyErrorType::EditPrivateMessageNotAllowed)?
|
||||||
}
|
}
|
||||||
@ -47,9 +45,7 @@ pub async fn delete_private_message(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let view = PrivateMessageView::read(&mut context.pool(), private_message_id)
|
let view = PrivateMessageView::read(&mut context.pool(), private_message_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPrivateMessage)?;
|
|
||||||
Ok(Json(PrivateMessageResponse {
|
Ok(Json(PrivateMessageResponse {
|
||||||
private_message_view: view,
|
private_message_view: view,
|
||||||
}))
|
}))
|
||||||
|
@ -30,9 +30,7 @@ pub async fn update_private_message(
|
|||||||
|
|
||||||
// Checking permissions
|
// Checking permissions
|
||||||
let private_message_id = data.private_message_id;
|
let private_message_id = data.private_message_id;
|
||||||
let orig_private_message = PrivateMessage::read(&mut context.pool(), private_message_id)
|
let orig_private_message = PrivateMessage::read(&mut context.pool(), private_message_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPrivateMessage)?;
|
|
||||||
if local_user_view.person.id != orig_private_message.creator_id {
|
if local_user_view.person.id != orig_private_message.creator_id {
|
||||||
Err(LemmyErrorType::EditPrivateMessageNotAllowed)?
|
Err(LemmyErrorType::EditPrivateMessageNotAllowed)?
|
||||||
}
|
}
|
||||||
@ -56,9 +54,7 @@ pub async fn update_private_message(
|
|||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdatePrivateMessage)?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdatePrivateMessage)?;
|
||||||
|
|
||||||
let view = PrivateMessageView::read(&mut context.pool(), private_message_id)
|
let view = PrivateMessageView::read(&mut context.pool(), private_message_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPrivateMessage)?;
|
|
||||||
|
|
||||||
ActivityChannel::submit_activity(
|
ActivityChannel::submit_activity(
|
||||||
SendActivityData::UpdatePrivateMessage(view.clone()),
|
SendActivityData::UpdatePrivateMessage(view.clone()),
|
||||||
|
@ -191,8 +191,6 @@ fn validate_create_payload(local_site: &LocalSite, create_site: &CreateSite) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
#[allow(clippy::indexing_slicing)]
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use crate::site::create::validate_create_payload;
|
use crate::site::create::validate_create_payload;
|
||||||
|
@ -48,8 +48,6 @@ fn not_zero(val: Option<i32>) -> Option<i32> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
#[allow(clippy::indexing_slicing)]
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use crate::site::{application_question_check, not_zero, site_default_post_listing_type_check};
|
use crate::site::{application_question_check, not_zero, site_default_post_listing_type_check};
|
||||||
|
@ -243,8 +243,6 @@ fn validate_update_payload(local_site: &LocalSite, edit_site: &EditSite) -> Lemm
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
#[allow(clippy::indexing_slicing)]
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use crate::site::update::validate_update_payload;
|
use crate::site::update::validate_update_payload;
|
||||||
|
@ -92,9 +92,8 @@ pub async fn register(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if local_site.site_setup && local_site.captcha_enabled {
|
if local_site.site_setup && local_site.captcha_enabled {
|
||||||
if let Some(captcha_uuid) = &data.captcha_uuid {
|
let uuid = uuid::Uuid::parse_str(&data.captcha_uuid.clone().unwrap_or_default())?;
|
||||||
let uuid = uuid::Uuid::parse_str(captcha_uuid)?;
|
CaptchaAnswer::check_captcha(
|
||||||
let check = CaptchaAnswer::check_captcha(
|
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
CheckCaptchaAnswer {
|
CheckCaptchaAnswer {
|
||||||
uuid,
|
uuid,
|
||||||
@ -102,26 +101,16 @@ pub async fn register(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
if !check {
|
|
||||||
Err(LemmyErrorType::CaptchaIncorrect)?
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(LemmyErrorType::CaptchaIncorrect)?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let slur_regex = local_site_to_slur_regex(&local_site);
|
let slur_regex = local_site_to_slur_regex(&local_site);
|
||||||
check_slurs(&data.username, &slur_regex)?;
|
check_slurs(&data.username, &slur_regex)?;
|
||||||
check_slurs_opt(&data.answer, &slur_regex)?;
|
check_slurs_opt(&data.answer, &slur_regex)?;
|
||||||
|
|
||||||
if Person::is_username_taken(&mut context.pool(), &data.username).await? {
|
Person::check_username_taken(&mut context.pool(), &data.username).await?;
|
||||||
return Err(LemmyErrorType::UsernameAlreadyExists)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(email) = &data.email {
|
if let Some(email) = &data.email {
|
||||||
if LocalUser::is_email_taken(&mut context.pool(), email).await? {
|
LocalUser::check_is_email_taken(&mut context.pool(), email).await?;
|
||||||
Err(LemmyErrorType::EmailAlreadyExists)?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to create both a person, and local_user
|
// We have to create both a person, and local_user
|
||||||
@ -234,7 +223,6 @@ pub async fn authenticate_with_oauth(
|
|||||||
let oauth_provider = OAuthProvider::read(&mut context.pool(), oauth_provider_id)
|
let oauth_provider = OAuthProvider::read(&mut context.pool(), oauth_provider_id)
|
||||||
.await
|
.await
|
||||||
.ok()
|
.ok()
|
||||||
.flatten()
|
|
||||||
.ok_or(LemmyErrorType::OauthAuthorizationInvalid)?;
|
.ok_or(LemmyErrorType::OauthAuthorizationInvalid)?;
|
||||||
|
|
||||||
if !oauth_provider.enabled {
|
if !oauth_provider.enabled {
|
||||||
@ -262,10 +250,10 @@ pub async fn authenticate_with_oauth(
|
|||||||
|
|
||||||
// Lookup user by oauth_user_id
|
// Lookup user by oauth_user_id
|
||||||
let mut local_user_view =
|
let mut local_user_view =
|
||||||
LocalUserView::find_by_oauth_id(&mut context.pool(), oauth_provider.id, &oauth_user_id).await?;
|
LocalUserView::find_by_oauth_id(&mut context.pool(), oauth_provider.id, &oauth_user_id).await;
|
||||||
|
|
||||||
let local_user: LocalUser;
|
let local_user: LocalUser;
|
||||||
if let Some(user_view) = local_user_view {
|
if let Ok(user_view) = local_user_view {
|
||||||
// user found by oauth_user_id => Login user
|
// user found by oauth_user_id => Login user
|
||||||
local_user = user_view.clone().local_user;
|
local_user = user_view.clone().local_user;
|
||||||
|
|
||||||
@ -292,10 +280,10 @@ pub async fn authenticate_with_oauth(
|
|||||||
local_site.registration_mode == RegistrationMode::RequireApplication;
|
local_site.registration_mode == RegistrationMode::RequireApplication;
|
||||||
|
|
||||||
// Lookup user by OAUTH email and link accounts
|
// Lookup user by OAUTH email and link accounts
|
||||||
local_user_view = LocalUserView::find_by_email(&mut context.pool(), &email).await?;
|
local_user_view = LocalUserView::find_by_email(&mut context.pool(), &email).await;
|
||||||
|
|
||||||
let person;
|
let person;
|
||||||
if let Some(user_view) = local_user_view {
|
if let Ok(user_view) = local_user_view {
|
||||||
// user found by email => link and login if linking is allowed
|
// user found by email => link and login if linking is allowed
|
||||||
|
|
||||||
// we only allow linking by email when email_verification is required otherwise emails cannot
|
// we only allow linking by email when email_verification is required otherwise emails cannot
|
||||||
@ -339,9 +327,7 @@ pub async fn authenticate_with_oauth(
|
|||||||
check_slurs(username, &slur_regex)?;
|
check_slurs(username, &slur_regex)?;
|
||||||
check_slurs_opt(&data.answer, &slur_regex)?;
|
check_slurs_opt(&data.answer, &slur_regex)?;
|
||||||
|
|
||||||
if Person::is_username_taken(&mut context.pool(), username).await? {
|
Person::check_username_taken(&mut context.pool(), username).await?;
|
||||||
return Err(LemmyErrorType::UsernameAlreadyExists)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have to create a person, a local_user, and an oauth_account
|
// We have to create a person, a local_user, and an oauth_account
|
||||||
person = create_person(
|
person = create_person(
|
||||||
|
@ -22,10 +22,7 @@ use lemmy_db_schema::{
|
|||||||
traits::Crud,
|
traits::Crud,
|
||||||
utils::DbPool,
|
utils::DbPool,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||||
error::{LemmyError, LemmyResult},
|
|
||||||
LemmyErrorType,
|
|
||||||
};
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
@ -182,7 +179,6 @@ pub(crate) async fn send_ban_from_community(
|
|||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
let community: ApubCommunity = Community::read(&mut context.pool(), community_id)
|
let community: ApubCommunity = Community::read(&mut context.pool(), community_id)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?
|
|
||||||
.into();
|
.into();
|
||||||
let expires = check_expire_time(data.expires)?;
|
let expires = check_expire_time(data.expires)?;
|
||||||
|
|
||||||
|
@ -213,14 +213,12 @@ async fn can_accept_activity_in_community(
|
|||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
if let Some(community) = community {
|
if let Some(community) = community {
|
||||||
if !community.local
|
|
||||||
&& !CommunityFollower::has_local_followers(&mut context.pool(), community.id).await?
|
|
||||||
{
|
|
||||||
Err(LemmyErrorType::CommunityHasNoFollowers)?
|
|
||||||
}
|
|
||||||
// Local only community can't federate
|
// Local only community can't federate
|
||||||
if community.visibility != CommunityVisibility::Public {
|
if community.visibility != CommunityVisibility::Public {
|
||||||
return Err(LemmyErrorType::CouldntFindCommunity.into());
|
return Err(LemmyErrorType::NotFound.into());
|
||||||
|
}
|
||||||
|
if !community.local {
|
||||||
|
CommunityFollower::check_has_local_followers(&mut context.pool(), community.id).await?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -36,10 +36,7 @@ use lemmy_db_schema::{
|
|||||||
},
|
},
|
||||||
traits::{Crud, Joinable},
|
traits::{Crud, Joinable},
|
||||||
};
|
};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||||
error::{LemmyError, LemmyResult},
|
|
||||||
LemmyErrorType,
|
|
||||||
};
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
impl CollectionAdd {
|
impl CollectionAdd {
|
||||||
@ -129,9 +126,7 @@ impl ActivityHandler for CollectionAdd {
|
|||||||
async fn receive(self, context: &Data<Self::DataType>) -> LemmyResult<()> {
|
async fn receive(self, context: &Data<Self::DataType>) -> LemmyResult<()> {
|
||||||
insert_received_activity(&self.id, context).await?;
|
insert_received_activity(&self.id, context).await?;
|
||||||
let (community, collection_type) =
|
let (community, collection_type) =
|
||||||
Community::get_by_collection_url(&mut context.pool(), &self.target.into())
|
Community::get_by_collection_url(&mut context.pool(), &self.target.into()).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
match collection_type {
|
match collection_type {
|
||||||
CollectionType::Moderators => {
|
CollectionType::Moderators => {
|
||||||
let new_mod = ObjectId::<ApubPerson>::from(self.object)
|
let new_mod = ObjectId::<ApubPerson>::from(self.object)
|
||||||
@ -188,11 +183,9 @@ pub(crate) async fn send_add_mod_to_community(
|
|||||||
let actor: ApubPerson = actor.into();
|
let actor: ApubPerson = actor.into();
|
||||||
let community: ApubCommunity = Community::read(&mut context.pool(), community_id)
|
let community: ApubCommunity = Community::read(&mut context.pool(), community_id)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?
|
|
||||||
.into();
|
.into();
|
||||||
let updated_mod: ApubPerson = Person::read(&mut context.pool(), updated_mod_id)
|
let updated_mod: ApubPerson = Person::read(&mut context.pool(), updated_mod_id)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?
|
|
||||||
.into();
|
.into();
|
||||||
if added {
|
if added {
|
||||||
CollectionAdd::send_add_mod(&community, &updated_mod, &actor, &context).await
|
CollectionAdd::send_add_mod(&community, &updated_mod, &actor, &context).await
|
||||||
@ -211,7 +204,6 @@ pub(crate) async fn send_feature_post(
|
|||||||
let post: ApubPost = post.into();
|
let post: ApubPost = post.into();
|
||||||
let community = Community::read(&mut context.pool(), post.community_id)
|
let community = Community::read(&mut context.pool(), post.community_id)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?
|
|
||||||
.into();
|
.into();
|
||||||
if featured {
|
if featured {
|
||||||
CollectionAdd::send_add_featured_post(&community, &post, &actor, &context).await
|
CollectionAdd::send_add_featured_post(&community, &post, &actor, &context).await
|
||||||
|
@ -31,10 +31,7 @@ use lemmy_db_schema::{
|
|||||||
},
|
},
|
||||||
traits::{Crud, Joinable},
|
traits::{Crud, Joinable},
|
||||||
};
|
};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||||
error::{LemmyError, LemmyResult},
|
|
||||||
LemmyErrorType,
|
|
||||||
};
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
impl CollectionRemove {
|
impl CollectionRemove {
|
||||||
@ -124,9 +121,7 @@ impl ActivityHandler for CollectionRemove {
|
|||||||
async fn receive(self, context: &Data<Self::DataType>) -> LemmyResult<()> {
|
async fn receive(self, context: &Data<Self::DataType>) -> LemmyResult<()> {
|
||||||
insert_received_activity(&self.id, context).await?;
|
insert_received_activity(&self.id, context).await?;
|
||||||
let (community, collection_type) =
|
let (community, collection_type) =
|
||||||
Community::get_by_collection_url(&mut context.pool(), &self.target.into())
|
Community::get_by_collection_url(&mut context.pool(), &self.target.into()).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
match collection_type {
|
match collection_type {
|
||||||
CollectionType::Moderators => {
|
CollectionType::Moderators => {
|
||||||
let remove_mod = ObjectId::<ApubPerson>::from(self.object)
|
let remove_mod = ObjectId::<ApubPerson>::from(self.object)
|
||||||
|
@ -32,10 +32,7 @@ use lemmy_db_schema::{
|
|||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||||
error::{LemmyError, LemmyResult},
|
|
||||||
LemmyErrorType,
|
|
||||||
};
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
@ -132,7 +129,6 @@ pub(crate) async fn send_lock_post(
|
|||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
let community: ApubCommunity = Community::read(&mut context.pool(), post.community_id)
|
let community: ApubCommunity = Community::read(&mut context.pool(), post.community_id)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?
|
|
||||||
.into();
|
.into();
|
||||||
let id = generate_activity_id(
|
let id = generate_activity_id(
|
||||||
LockType::Lock,
|
LockType::Lock,
|
||||||
|
@ -29,10 +29,7 @@ use lemmy_db_schema::{
|
|||||||
},
|
},
|
||||||
traits::{Crud, Reportable},
|
traits::{Crud, Reportable},
|
||||||
};
|
};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||||
error::{LemmyError, LemmyResult},
|
|
||||||
LemmyErrorType,
|
|
||||||
};
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
impl Report {
|
impl Report {
|
||||||
@ -70,9 +67,7 @@ impl Report {
|
|||||||
PostOrComment::Post(p) => p.creator_id,
|
PostOrComment::Post(p) => p.creator_id,
|
||||||
PostOrComment::Comment(c) => c.creator_id,
|
PostOrComment::Comment(c) => c.creator_id,
|
||||||
};
|
};
|
||||||
let object_creator = Person::read(&mut context.pool(), object_creator_id)
|
let object_creator = Person::read(&mut context.pool(), object_creator_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?;
|
|
||||||
let object_creator_site: Option<ApubSite> =
|
let object_creator_site: Option<ApubSite> =
|
||||||
Site::read_from_instance_id(&mut context.pool(), object_creator.instance_id)
|
Site::read_from_instance_id(&mut context.pool(), object_creator.instance_id)
|
||||||
.await?
|
.await?
|
||||||
|
@ -42,7 +42,6 @@ use lemmy_db_schema::{
|
|||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
error::{LemmyError, LemmyResult},
|
error::{LemmyError, LemmyResult},
|
||||||
utils::mention::scrape_text_for_mentions,
|
utils::mention::scrape_text_for_mentions,
|
||||||
LemmyErrorType,
|
|
||||||
};
|
};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
@ -56,17 +55,11 @@ impl CreateOrUpdateNote {
|
|||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
// TODO: might be helpful to add a comment method to retrieve community directly
|
// TODO: might be helpful to add a comment method to retrieve community directly
|
||||||
let post_id = comment.post_id;
|
let post_id = comment.post_id;
|
||||||
let post = Post::read(&mut context.pool(), post_id)
|
let post = Post::read(&mut context.pool(), post_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
let person: ApubPerson = Person::read(&mut context.pool(), person_id)
|
let person: ApubPerson = Person::read(&mut context.pool(), person_id).await?.into();
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?
|
|
||||||
.into();
|
|
||||||
let community: ApubCommunity = Community::read(&mut context.pool(), community_id)
|
let community: ApubCommunity = Community::read(&mut context.pool(), community_id)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?
|
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
let id = generate_activity_id(
|
let id = generate_activity_id(
|
||||||
|
@ -32,7 +32,7 @@ use lemmy_db_schema::{
|
|||||||
},
|
},
|
||||||
traits::{Crud, Likeable},
|
traits::{Crud, Likeable},
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorType, LemmyResult};
|
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
impl CreateOrUpdatePage {
|
impl CreateOrUpdatePage {
|
||||||
@ -66,13 +66,9 @@ impl CreateOrUpdatePage {
|
|||||||
context: Data<LemmyContext>,
|
context: Data<LemmyContext>,
|
||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
let person: ApubPerson = Person::read(&mut context.pool(), person_id)
|
let person: ApubPerson = Person::read(&mut context.pool(), person_id).await?.into();
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?
|
|
||||||
.into();
|
|
||||||
let community: ApubCommunity = Community::read(&mut context.pool(), community_id)
|
let community: ApubCommunity = Community::read(&mut context.pool(), community_id)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?
|
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
let create_or_update =
|
let create_or_update =
|
||||||
|
@ -176,8 +176,8 @@ pub(in crate::activities) async fn receive_remove_action(
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
// TODO these need to be implemented yet, for now, return errors
|
// TODO these need to be implemented yet, for now, return errors
|
||||||
DeletableObjects::PrivateMessage(_) => Err(LemmyErrorType::CouldntFindPrivateMessage)?,
|
DeletableObjects::PrivateMessage(_) => Err(LemmyErrorType::NotFound)?,
|
||||||
DeletableObjects::Person(_) => Err(LemmyErrorType::CouldntFindPerson)?,
|
DeletableObjects::Person(_) => Err(LemmyErrorType::NotFound)?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ use lemmy_db_schema::{
|
|||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
@ -87,7 +87,6 @@ pub(crate) async fn send_apub_delete_private_message(
|
|||||||
let recipient_id = pm.recipient_id;
|
let recipient_id = pm.recipient_id;
|
||||||
let recipient: ApubPerson = Person::read(&mut context.pool(), recipient_id)
|
let recipient: ApubPerson = Person::read(&mut context.pool(), recipient_id)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?
|
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
let deletable = DeletableObjects::PrivateMessage(pm.into());
|
let deletable = DeletableObjects::PrivateMessage(pm.into());
|
||||||
|
@ -156,8 +156,8 @@ impl UndoDelete {
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
// TODO these need to be implemented yet, for now, return errors
|
// TODO these need to be implemented yet, for now, return errors
|
||||||
DeletableObjects::PrivateMessage(_) => Err(LemmyErrorType::CouldntFindPrivateMessage)?,
|
DeletableObjects::PrivateMessage(_) => Err(LemmyErrorType::NotFound)?,
|
||||||
DeletableObjects::Person(_) => Err(LemmyErrorType::CouldntFindPerson)?,
|
DeletableObjects::Person(_) => Err(LemmyErrorType::NotFound)?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ impl ActivityHandler for Follow {
|
|||||||
UserOrCommunity::Community(c) => {
|
UserOrCommunity::Community(c) => {
|
||||||
// Dont allow following local-only community via federation.
|
// Dont allow following local-only community via federation.
|
||||||
if c.visibility != CommunityVisibility::Public {
|
if c.visibility != CommunityVisibility::Public {
|
||||||
return Err(LemmyErrorType::CouldntFindCommunity.into());
|
return Err(LemmyErrorType::NotFound.into());
|
||||||
}
|
}
|
||||||
let form = CommunityFollowerForm {
|
let form = CommunityFollowerForm {
|
||||||
community_id: c.id,
|
community_id: c.id,
|
||||||
|
@ -87,12 +87,7 @@ pub(crate) async fn verify_person_in_community(
|
|||||||
}
|
}
|
||||||
let person_id = person.id;
|
let person_id = person.id;
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
let is_banned = CommunityPersonBanView::get(&mut context.pool(), person_id, community_id).await?;
|
CommunityPersonBanView::check(&mut context.pool(), person_id, community_id).await
|
||||||
if is_banned {
|
|
||||||
Err(LemmyErrorType::PersonIsBannedFromCommunity)?
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify that mod action in community was performed by a moderator.
|
/// Verify that mod action in community was performed by a moderator.
|
||||||
@ -106,14 +101,6 @@ pub(crate) async fn verify_mod_action(
|
|||||||
community: &Community,
|
community: &Community,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
let mod_ = mod_id.dereference(context).await?;
|
|
||||||
|
|
||||||
let is_mod_or_admin =
|
|
||||||
CommunityView::is_mod_or_admin(&mut context.pool(), mod_.id, community.id).await?;
|
|
||||||
if is_mod_or_admin {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
// mod action comes from the same instance as the community, so it was presumably done
|
// mod action comes from the same instance as the community, so it was presumably done
|
||||||
// by an instance admin.
|
// by an instance admin.
|
||||||
// TODO: federate instance admin status and check it here
|
// TODO: federate instance admin status and check it here
|
||||||
@ -121,7 +108,8 @@ pub(crate) async fn verify_mod_action(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(LemmyErrorType::NotAModerator)?
|
let mod_ = mod_id.dereference(context).await?;
|
||||||
|
CommunityView::check_is_mod_or_admin(&mut context.pool(), mod_.id, community.id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn verify_is_public(to: &[Url], cc: &[Url]) -> LemmyResult<()> {
|
pub(crate) fn verify_is_public(to: &[Url], cc: &[Url]) -> LemmyResult<()> {
|
||||||
@ -245,9 +233,7 @@ pub async fn match_outgoing_activities(
|
|||||||
CreateOrUpdatePage::send(post, creator_id, CreateOrUpdateType::Update, context).await
|
CreateOrUpdatePage::send(post, creator_id, CreateOrUpdateType::Update, context).await
|
||||||
}
|
}
|
||||||
DeletePost(post, person, data) => {
|
DeletePost(post, person, data) => {
|
||||||
let community = Community::read(&mut context.pool(), post.community_id)
|
let community = Community::read(&mut context.pool(), post.community_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
send_apub_delete_in_community(
|
send_apub_delete_in_community(
|
||||||
person,
|
person,
|
||||||
community,
|
community,
|
||||||
@ -264,9 +250,7 @@ pub async fn match_outgoing_activities(
|
|||||||
reason,
|
reason,
|
||||||
removed,
|
removed,
|
||||||
} => {
|
} => {
|
||||||
let community = Community::read(&mut context.pool(), post.community_id)
|
let community = Community::read(&mut context.pool(), post.community_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
send_apub_delete_in_community(
|
send_apub_delete_in_community(
|
||||||
moderator,
|
moderator,
|
||||||
community,
|
community,
|
||||||
|
@ -117,13 +117,12 @@ impl InCommunity for AnnouncableActivities {
|
|||||||
CollectionRemove(a) => a.community(context).await,
|
CollectionRemove(a) => a.community(context).await,
|
||||||
LockPost(a) => a.community(context).await,
|
LockPost(a) => a.community(context).await,
|
||||||
UndoLockPost(a) => a.community(context).await,
|
UndoLockPost(a) => a.community(context).await,
|
||||||
Page(_) => Err(LemmyErrorType::CouldntFindPost.into()),
|
Page(_) => Err(LemmyErrorType::NotFound.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::indexing_slicing)]
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -12,10 +12,13 @@ use lemmy_api_common::{
|
|||||||
utils::check_private_instance,
|
utils::check_private_instance,
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{comment::Comment, community::Community, local_site::LocalSite},
|
source::{comment::Comment, community::Community},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::{comment_view::CommentQuery, structs::LocalUserView};
|
use lemmy_db_views::{
|
||||||
|
comment_view::CommentQuery,
|
||||||
|
structs::{LocalUserView, SiteView},
|
||||||
|
};
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult};
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
@ -24,8 +27,8 @@ pub async fn list_comments(
|
|||||||
context: Data<LemmyContext>,
|
context: Data<LemmyContext>,
|
||||||
local_user_view: Option<LocalUserView>,
|
local_user_view: Option<LocalUserView>,
|
||||||
) -> LemmyResult<Json<GetCommentsResponse>> {
|
) -> LemmyResult<Json<GetCommentsResponse>> {
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||||
check_private_instance(&local_user_view, &local_site)?;
|
check_private_instance(&local_user_view, &site_view.local_site)?;
|
||||||
|
|
||||||
let community_id = if let Some(name) = &data.community_name {
|
let community_id = if let Some(name) = &data.community_name {
|
||||||
Some(
|
Some(
|
||||||
@ -40,7 +43,7 @@ pub async fn list_comments(
|
|||||||
let sort = Some(comment_sort_type_with_default(
|
let sort = Some(comment_sort_type_with_default(
|
||||||
data.sort,
|
data.sort,
|
||||||
local_user_ref,
|
local_user_ref,
|
||||||
&local_site,
|
&site_view.local_site,
|
||||||
));
|
));
|
||||||
let max_depth = data.max_depth;
|
let max_depth = data.max_depth;
|
||||||
let saved_only = data.saved_only;
|
let saved_only = data.saved_only;
|
||||||
@ -58,18 +61,13 @@ pub async fn list_comments(
|
|||||||
let listing_type = Some(listing_type_with_default(
|
let listing_type = Some(listing_type_with_default(
|
||||||
data.type_,
|
data.type_,
|
||||||
local_user_view.as_ref().map(|u| &u.local_user),
|
local_user_view.as_ref().map(|u| &u.local_user),
|
||||||
&local_site,
|
&site_view.local_site,
|
||||||
community_id,
|
community_id,
|
||||||
));
|
));
|
||||||
|
|
||||||
// If a parent_id is given, fetch the comment to get the path
|
// If a parent_id is given, fetch the comment to get the path
|
||||||
let parent_path = if let Some(parent_id) = parent_id {
|
let parent_path = if let Some(parent_id) = parent_id {
|
||||||
Some(
|
Some(Comment::read(&mut context.pool(), parent_id).await?.path)
|
||||||
Comment::read(&mut context.pool(), parent_id)
|
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?
|
|
||||||
.path,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@ -93,7 +91,7 @@ pub async fn list_comments(
|
|||||||
limit,
|
limit,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(&mut context.pool())
|
.list(&site_view.site, &mut context.pool())
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntGetComments)?;
|
.with_lemmy_type(LemmyErrorType::CouldntGetComments)?;
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@ use actix_web::web::{Json, Query};
|
|||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
post::{GetPosts, GetPostsResponse},
|
post::{GetPosts, GetPostsResponse},
|
||||||
utils::check_private_instance,
|
utils::{check_conflicting_like_filters, check_private_instance},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::source::community::Community;
|
use lemmy_db_schema::source::community::Community;
|
||||||
use lemmy_db_views::{
|
use lemmy_db_views::{
|
||||||
post_view::PostQuery,
|
post_view::PostQuery,
|
||||||
structs::{LocalUserView, PaginationCursor, SiteView},
|
structs::{LocalUserView, PaginationCursor, SiteView},
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult};
|
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn list_posts(
|
pub async fn list_posts(
|
||||||
@ -45,9 +45,7 @@ pub async fn list_posts(
|
|||||||
|
|
||||||
let liked_only = data.liked_only;
|
let liked_only = data.liked_only;
|
||||||
let disliked_only = data.disliked_only;
|
let disliked_only = data.disliked_only;
|
||||||
if liked_only.unwrap_or_default() && disliked_only.unwrap_or_default() {
|
check_conflicting_like_filters(liked_only, disliked_only)?;
|
||||||
return Err(LemmyError::from(LemmyErrorType::ContradictingFilters));
|
|
||||||
}
|
|
||||||
|
|
||||||
let local_user = local_user_view.as_ref().map(|u| &u.local_user);
|
let local_user = local_user_view.as_ref().map(|u| &u.local_user);
|
||||||
let listing_type = Some(listing_type_with_default(
|
let listing_type = Some(listing_type_with_default(
|
||||||
|
@ -13,7 +13,7 @@ use lemmy_db_schema::source::{
|
|||||||
};
|
};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
|
use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
|
||||||
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorExt2, LemmyErrorType, LemmyResult};
|
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn get_community(
|
pub async fn get_community(
|
||||||
@ -36,8 +36,7 @@ pub async fn get_community(
|
|||||||
None => {
|
None => {
|
||||||
let name = data.name.clone().unwrap_or_else(|| "main".to_string());
|
let name = data.name.clone().unwrap_or_else(|| "main".to_string());
|
||||||
resolve_actor_identifier::<ApubCommunity, Community>(&name, &context, &local_user_view, true)
|
resolve_actor_identifier::<ApubCommunity, Community>(&name, &context, &local_user_view, true)
|
||||||
.await
|
.await?
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?
|
|
||||||
.id
|
.id
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -56,12 +55,9 @@ pub async fn get_community(
|
|||||||
local_user,
|
local_user,
|
||||||
is_mod_or_admin,
|
is_mod_or_admin,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id)
|
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
let site = read_site_for_actor(community_view.community.actor_id.clone(), &context).await?;
|
let site = read_site_for_actor(community_view.community.actor_id.clone(), &context).await?;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ use lemmy_db_views::{
|
|||||||
structs::{LocalUserView, SiteView},
|
structs::{LocalUserView, SiteView},
|
||||||
};
|
};
|
||||||
use lemmy_db_views_actor::structs::{CommunityModeratorView, PersonView};
|
use lemmy_db_views_actor::structs::{CommunityModeratorView, PersonView};
|
||||||
use lemmy_utils::error::{LemmyErrorExt2, LemmyErrorType, LemmyResult};
|
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn read_person(
|
pub async fn read_person(
|
||||||
@ -35,20 +35,17 @@ pub async fn read_person(
|
|||||||
None => {
|
None => {
|
||||||
if let Some(username) = &data.username {
|
if let Some(username) = &data.username {
|
||||||
resolve_actor_identifier::<ApubPerson, Person>(username, &context, &local_user_view, true)
|
resolve_actor_identifier::<ApubPerson, Person>(username, &context, &local_user_view, true)
|
||||||
.await
|
.await?
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindPerson)?
|
|
||||||
.id
|
.id
|
||||||
} else {
|
} else {
|
||||||
Err(LemmyErrorType::CouldntFindPerson)?
|
Err(LemmyErrorType::NotFound)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// You don't need to return settings for the user, since this comes back with GetSite
|
// You don't need to return settings for the user, since this comes back with GetSite
|
||||||
// `my_user`
|
// `my_user`
|
||||||
let person_view = PersonView::read(&mut context.pool(), person_details_id)
|
let person_view = PersonView::read(&mut context.pool(), person_details_id).await?;
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?;
|
|
||||||
|
|
||||||
let sort = data.sort;
|
let sort = data.sort;
|
||||||
let page = data.page;
|
let page = data.page;
|
||||||
@ -88,7 +85,7 @@ pub async fn read_person(
|
|||||||
creator_id,
|
creator_id,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(&mut context.pool())
|
.list(&local_site.site, &mut context.pool())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let moderates = CommunityModeratorView::for_person(
|
let moderates = CommunityModeratorView::for_person(
|
||||||
|
@ -34,11 +34,11 @@ pub async fn resolve_object(
|
|||||||
// user isn't authenticated only allow a local search.
|
// user isn't authenticated only allow a local search.
|
||||||
search_query_to_object_id_local(&data.q, &context).await
|
search_query_to_object_id_local(&data.q, &context).await
|
||||||
}
|
}
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindObject)?;
|
.with_lemmy_type(LemmyErrorType::NotFound)?;
|
||||||
|
|
||||||
convert_response(res, local_user_view, &mut context.pool())
|
convert_response(res, local_user_view, &mut context.pool())
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindObject)
|
.with_lemmy_type(LemmyErrorType::NotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn convert_response(
|
async fn convert_response(
|
||||||
@ -54,36 +54,20 @@ async fn convert_response(
|
|||||||
match object {
|
match object {
|
||||||
Post(p) => {
|
Post(p) => {
|
||||||
removed_or_deleted = p.deleted || p.removed;
|
removed_or_deleted = p.deleted || p.removed;
|
||||||
res.post = Some(
|
res.post = Some(PostView::read(pool, p.id, local_user.as_ref(), false).await?)
|
||||||
PostView::read(pool, p.id, local_user.as_ref(), false)
|
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Comment(c) => {
|
Comment(c) => {
|
||||||
removed_or_deleted = c.deleted || c.removed;
|
removed_or_deleted = c.deleted || c.removed;
|
||||||
res.comment = Some(
|
res.comment = Some(CommentView::read(pool, c.id, local_user.as_ref()).await?)
|
||||||
CommentView::read(pool, c.id, local_user.as_ref())
|
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
PersonOrCommunity(p) => match *p {
|
PersonOrCommunity(p) => match *p {
|
||||||
UserOrCommunity::User(u) => {
|
UserOrCommunity::User(u) => {
|
||||||
removed_or_deleted = u.deleted;
|
removed_or_deleted = u.deleted;
|
||||||
res.person = Some(
|
res.person = Some(PersonView::read(pool, u.id).await?)
|
||||||
PersonView::read(pool, u.id)
|
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPerson)?,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
UserOrCommunity::Community(c) => {
|
UserOrCommunity::Community(c) => {
|
||||||
removed_or_deleted = c.deleted || c.removed;
|
removed_or_deleted = c.deleted || c.removed;
|
||||||
res.community = Some(
|
res.community = Some(CommunityView::read(pool, c.id, local_user.as_ref(), false).await?)
|
||||||
CommunityView::read(pool, c.id, local_user.as_ref(), false)
|
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,7 @@ use actix_web::web::{Json, Query};
|
|||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
site::{Search, SearchResponse},
|
site::{Search, SearchResponse},
|
||||||
utils::{check_private_instance, is_admin},
|
utils::{check_conflicting_like_filters, check_private_instance, is_admin},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{source::community::Community, utils::post_to_comment_sort_type, SearchType};
|
use lemmy_db_schema::{source::community::Community, utils::post_to_comment_sort_type, SearchType};
|
||||||
use lemmy_db_views::{
|
use lemmy_db_views::{
|
||||||
@ -37,67 +37,88 @@ pub async fn search(
|
|||||||
|
|
||||||
// TODO no clean / non-nsfw searching rn
|
// TODO no clean / non-nsfw searching rn
|
||||||
|
|
||||||
let q = data.q.clone();
|
let Query(Search {
|
||||||
let page = data.page;
|
q,
|
||||||
let limit = data.limit;
|
community_id,
|
||||||
let sort = data.sort;
|
community_name,
|
||||||
let listing_type = data.listing_type;
|
creator_id,
|
||||||
let search_type = data.type_.unwrap_or(SearchType::All);
|
type_,
|
||||||
let community_id = if let Some(name) = &data.community_name {
|
sort,
|
||||||
|
listing_type,
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
title_only,
|
||||||
|
post_url_only,
|
||||||
|
saved_only,
|
||||||
|
liked_only,
|
||||||
|
disliked_only,
|
||||||
|
}) = data;
|
||||||
|
|
||||||
|
let q = q.clone();
|
||||||
|
let search_type = type_.unwrap_or(SearchType::All);
|
||||||
|
let community_id = if let Some(name) = &community_name {
|
||||||
Some(
|
Some(
|
||||||
resolve_actor_identifier::<ApubCommunity, Community>(name, &context, &local_user_view, false)
|
resolve_actor_identifier::<ApubCommunity, Community>(name, &context, &local_user_view, false)
|
||||||
.await?,
|
.await?,
|
||||||
)
|
)
|
||||||
.map(|c| c.id)
|
.map(|c| c.id)
|
||||||
} else {
|
} else {
|
||||||
data.community_id
|
community_id
|
||||||
};
|
};
|
||||||
let creator_id = data.creator_id;
|
|
||||||
let local_user = local_user_view.as_ref().map(|l| &l.local_user);
|
let local_user = local_user_view.as_ref().map(|l| &l.local_user);
|
||||||
let post_title_only = data.post_title_only;
|
|
||||||
|
check_conflicting_like_filters(liked_only, disliked_only)?;
|
||||||
|
|
||||||
let posts_query = PostQuery {
|
let posts_query = PostQuery {
|
||||||
sort: (sort),
|
sort,
|
||||||
listing_type: (listing_type),
|
listing_type,
|
||||||
community_id: (community_id),
|
community_id,
|
||||||
creator_id: (creator_id),
|
creator_id,
|
||||||
local_user,
|
local_user,
|
||||||
search_term: (Some(q.clone())),
|
search_term: Some(q.clone()),
|
||||||
page: (page),
|
page,
|
||||||
limit: (limit),
|
limit,
|
||||||
title_only: (post_title_only),
|
title_only,
|
||||||
|
url_only: post_url_only,
|
||||||
|
liked_only,
|
||||||
|
disliked_only,
|
||||||
|
saved_only,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let comment_query = CommentQuery {
|
let comment_query = CommentQuery {
|
||||||
sort: (sort.map(post_to_comment_sort_type)),
|
sort: sort.map(post_to_comment_sort_type),
|
||||||
listing_type: (listing_type),
|
listing_type,
|
||||||
search_term: (Some(q.clone())),
|
search_term: Some(q.clone()),
|
||||||
community_id: (community_id),
|
community_id,
|
||||||
creator_id: (creator_id),
|
creator_id,
|
||||||
local_user,
|
local_user,
|
||||||
page: (page),
|
page,
|
||||||
limit: (limit),
|
limit,
|
||||||
|
liked_only,
|
||||||
|
disliked_only,
|
||||||
|
saved_only,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let community_query = CommunityQuery {
|
let community_query = CommunityQuery {
|
||||||
sort: (sort),
|
sort,
|
||||||
listing_type: (listing_type),
|
listing_type,
|
||||||
search_term: (Some(q.clone())),
|
search_term: Some(q.clone()),
|
||||||
|
title_only,
|
||||||
local_user,
|
local_user,
|
||||||
is_mod_or_admin: (is_admin),
|
is_mod_or_admin: is_admin,
|
||||||
page: (page),
|
page,
|
||||||
limit: (limit),
|
limit,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let person_query = PersonQuery {
|
let person_query = PersonQuery {
|
||||||
sort,
|
sort,
|
||||||
search_term: (Some(q.clone())),
|
search_term: Some(q.clone()),
|
||||||
listing_type: (listing_type),
|
listing_type,
|
||||||
page: (page),
|
page,
|
||||||
limit: (limit),
|
limit,
|
||||||
};
|
};
|
||||||
|
|
||||||
match search_type {
|
match search_type {
|
||||||
@ -107,7 +128,9 @@ pub async fn search(
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
SearchType::Comments => {
|
SearchType::Comments => {
|
||||||
comments = comment_query.list(&mut context.pool()).await?;
|
comments = comment_query
|
||||||
|
.list(&local_site.site, &mut context.pool())
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
SearchType::Communities => {
|
SearchType::Communities => {
|
||||||
communities = community_query
|
communities = community_query
|
||||||
@ -120,13 +143,15 @@ pub async fn search(
|
|||||||
SearchType::All => {
|
SearchType::All => {
|
||||||
// If the community or creator is included, dont search communities or users
|
// If the community or creator is included, dont search communities or users
|
||||||
let community_or_creator_included =
|
let community_or_creator_included =
|
||||||
data.community_id.is_some() || data.community_name.is_some() || data.creator_id.is_some();
|
community_id.is_some() || community_name.is_some() || creator_id.is_some();
|
||||||
|
|
||||||
posts = posts_query
|
posts = posts_query
|
||||||
.list(&local_site.site, &mut context.pool())
|
.list(&local_site.site, &mut context.pool())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
comments = comment_query.list(&mut context.pool()).await?;
|
comments = comment_query
|
||||||
|
.list(&local_site.site, &mut context.pool())
|
||||||
|
.await?;
|
||||||
|
|
||||||
communities = if community_or_creator_included {
|
communities = if community_or_creator_included {
|
||||||
vec![]
|
vec![]
|
||||||
@ -142,21 +167,6 @@ pub async fn search(
|
|||||||
person_query.list(&mut context.pool()).await?
|
person_query.list(&mut context.pool()).await?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
SearchType::Url => {
|
|
||||||
posts = PostQuery {
|
|
||||||
sort: (sort),
|
|
||||||
listing_type: (listing_type),
|
|
||||||
community_id: (community_id),
|
|
||||||
creator_id: (creator_id),
|
|
||||||
url_search: (Some(q)),
|
|
||||||
local_user,
|
|
||||||
page: (page),
|
|
||||||
limit: (limit),
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
.list(&local_site.site, &mut context.pool())
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
|
@ -127,7 +127,6 @@ pub async fn import_settings(
|
|||||||
show_read_posts: data.settings.as_ref().map(|s| s.show_read_posts),
|
show_read_posts: data.settings.as_ref().map(|s| s.show_read_posts),
|
||||||
open_links_in_new_tab: data.settings.as_ref().map(|s| s.open_links_in_new_tab),
|
open_links_in_new_tab: data.settings.as_ref().map(|s| s.open_links_in_new_tab),
|
||||||
blur_nsfw: data.settings.as_ref().map(|s| s.blur_nsfw),
|
blur_nsfw: data.settings.as_ref().map(|s| s.blur_nsfw),
|
||||||
auto_expand: data.settings.as_ref().map(|s| s.auto_expand),
|
|
||||||
infinite_scroll_enabled: data.settings.as_ref().map(|s| s.infinite_scroll_enabled),
|
infinite_scroll_enabled: data.settings.as_ref().map(|s| s.infinite_scroll_enabled),
|
||||||
post_listing_mode: data.settings.as_ref().map(|s| s.post_listing_mode),
|
post_listing_mode: data.settings.as_ref().map(|s| s.post_listing_mode),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -308,8 +307,9 @@ where
|
|||||||
});
|
});
|
||||||
Ok(failed_items.into_iter().join(","))
|
Ok(failed_items.into_iter().join(","))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::indexing_slicing)]
|
#[expect(clippy::indexing_slicing)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use crate::api::user_settings_backup::{export_settings, import_settings, UserSettingsBackup};
|
use crate::api::user_settings_backup::{export_settings, import_settings, UserSettingsBackup};
|
||||||
@ -348,11 +348,7 @@ mod tests {
|
|||||||
let user_form = LocalUserInsertForm::test_form(person.id);
|
let user_form = LocalUserInsertForm::test_form(person.id);
|
||||||
let local_user = LocalUser::create(&mut context.pool(), &user_form, vec![]).await?;
|
let local_user = LocalUser::create(&mut context.pool(), &user_form, vec![]).await?;
|
||||||
|
|
||||||
Ok(
|
Ok(LocalUserView::read(&mut context.pool(), local_user.id).await?)
|
||||||
LocalUserView::read(&mut context.pool(), local_user.id)
|
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindLocalUser)?,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@ -386,9 +382,8 @@ mod tests {
|
|||||||
// wait for background task to finish
|
// wait for background task to finish
|
||||||
sleep(Duration::from_millis(1000)).await;
|
sleep(Duration::from_millis(1000)).await;
|
||||||
|
|
||||||
let import_user_updated = LocalUserView::read(&mut context.pool(), import_user.local_user.id)
|
let import_user_updated =
|
||||||
.await?
|
LocalUserView::read(&mut context.pool(), import_user.local_user.id).await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindLocalUser)?;
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
export_user.person.display_name,
|
export_user.person.display_name,
|
||||||
|
@ -98,7 +98,7 @@ impl Collection for ApubCommunityModerators {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::indexing_slicing)]
|
#[expect(clippy::indexing_slicing)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -12,10 +12,7 @@ use lemmy_db_schema::{
|
|||||||
source::{community::Community, post::Post},
|
source::{community::Community, post::Post},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||||
error::{LemmyError, LemmyResult},
|
|
||||||
LemmyErrorType,
|
|
||||||
};
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
@ -97,15 +94,9 @@ impl InCommunity for PostOrComment {
|
|||||||
PostOrComment::Comment(c) => {
|
PostOrComment::Comment(c) => {
|
||||||
Post::read(&mut context.pool(), c.post_id)
|
Post::read(&mut context.pool(), c.post_id)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?
|
|
||||||
.community_id
|
.community_id
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(
|
Ok(Community::read(&mut context.pool(), cid).await?.into())
|
||||||
Community::read(&mut context.pool(), cid)
|
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use lemmy_db_schema::{
|
|||||||
source::{comment::Comment, community::Community, post::Post},
|
source::{comment::Comment, community::Community, post::Post},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
use lemmy_utils::error::LemmyResult;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@ -31,16 +31,9 @@ pub(crate) async fn get_apub_comment(
|
|||||||
) -> LemmyResult<HttpResponse> {
|
) -> LemmyResult<HttpResponse> {
|
||||||
let id = CommentId(info.comment_id.parse::<i32>()?);
|
let id = CommentId(info.comment_id.parse::<i32>()?);
|
||||||
// Can't use CommentView here because it excludes deleted/removed/local-only items
|
// Can't use CommentView here because it excludes deleted/removed/local-only items
|
||||||
let comment: ApubComment = Comment::read(&mut context.pool(), id)
|
let comment: ApubComment = Comment::read(&mut context.pool(), id).await?.into();
|
||||||
.await?
|
let post = Post::read(&mut context.pool(), comment.post_id).await?;
|
||||||
.ok_or(LemmyErrorType::CouldntFindComment)?
|
let community = Community::read(&mut context.pool(), post.community_id).await?;
|
||||||
.into();
|
|
||||||
let post = Post::read(&mut context.pool(), comment.post_id)
|
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
let community = Community::read(&mut context.pool(), post.community_id)
|
|
||||||
.await?
|
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
check_community_public(&community)?;
|
check_community_public(&community)?;
|
||||||
|
|
||||||
if !comment.local {
|
if !comment.local {
|
||||||
|
@ -35,7 +35,7 @@ pub(crate) async fn get_apub_community_http(
|
|||||||
let community: ApubCommunity =
|
let community: ApubCommunity =
|
||||||
Community::read_from_name(&mut context.pool(), &info.community_name, true)
|
Community::read_from_name(&mut context.pool(), &info.community_name, true)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?
|
.ok_or(LemmyErrorType::NotFound)?
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
if community.deleted || community.removed {
|
if community.deleted || community.removed {
|
||||||
@ -67,7 +67,7 @@ pub(crate) async fn get_apub_community_followers(
|
|||||||
) -> LemmyResult<HttpResponse> {
|
) -> LemmyResult<HttpResponse> {
|
||||||
let community = Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
let community = Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
.ok_or(LemmyErrorType::NotFound)?;
|
||||||
check_community_public(&community)?;
|
check_community_public(&community)?;
|
||||||
let followers = ApubCommunityFollower::read_local(&community.into(), &context).await?;
|
let followers = ApubCommunityFollower::read_local(&community.into(), &context).await?;
|
||||||
create_apub_response(&followers)
|
create_apub_response(&followers)
|
||||||
@ -82,7 +82,7 @@ pub(crate) async fn get_apub_community_outbox(
|
|||||||
let community: ApubCommunity =
|
let community: ApubCommunity =
|
||||||
Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?
|
.ok_or(LemmyErrorType::NotFound)?
|
||||||
.into();
|
.into();
|
||||||
check_community_public(&community)?;
|
check_community_public(&community)?;
|
||||||
let outbox = ApubCommunityOutbox::read_local(&community, &context).await?;
|
let outbox = ApubCommunityOutbox::read_local(&community, &context).await?;
|
||||||
@ -97,7 +97,7 @@ pub(crate) async fn get_apub_community_moderators(
|
|||||||
let community: ApubCommunity =
|
let community: ApubCommunity =
|
||||||
Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?
|
.ok_or(LemmyErrorType::NotFound)?
|
||||||
.into();
|
.into();
|
||||||
check_community_public(&community)?;
|
check_community_public(&community)?;
|
||||||
let moderators = ApubCommunityModerators::read_local(&community, &context).await?;
|
let moderators = ApubCommunityModerators::read_local(&community, &context).await?;
|
||||||
@ -112,7 +112,7 @@ pub(crate) async fn get_apub_community_featured(
|
|||||||
let community: ApubCommunity =
|
let community: ApubCommunity =
|
||||||
Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?
|
.ok_or(LemmyErrorType::NotFound)?
|
||||||
.into();
|
.into();
|
||||||
check_community_public(&community)?;
|
check_community_public(&community)?;
|
||||||
let featured = ApubCommunityFeatured::read_local(&community, &context).await?;
|
let featured = ApubCommunityFeatured::read_local(&community, &context).await?;
|
||||||
@ -120,8 +120,7 @@ pub(crate) async fn get_apub_community_featured(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::unwrap_used)]
|
#[expect(clippy::unwrap_used)]
|
||||||
#[allow(clippy::indexing_slicing)]
|
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -151,14 +150,16 @@ pub(crate) mod tests {
|
|||||||
Instance::read_or_create(&mut context.pool(), "my_domain.tld".to_string()).await?;
|
Instance::read_or_create(&mut context.pool(), "my_domain.tld".to_string()).await?;
|
||||||
create_local_site(context, instance.id).await?;
|
create_local_site(context, instance.id).await?;
|
||||||
|
|
||||||
let mut community_form = CommunityInsertForm::new(
|
let community_form = CommunityInsertForm {
|
||||||
|
deleted: Some(deleted),
|
||||||
|
visibility: Some(visibility),
|
||||||
|
..CommunityInsertForm::new(
|
||||||
instance.id,
|
instance.id,
|
||||||
"testcom6".to_string(),
|
"testcom6".to_string(),
|
||||||
"nada".to_owned(),
|
"nada".to_owned(),
|
||||||
"pubkey".to_string(),
|
"pubkey".to_string(),
|
||||||
);
|
)
|
||||||
community_form.deleted = Some(deleted);
|
};
|
||||||
community_form.visibility = Some(visibility);
|
|
||||||
let community = Community::create(&mut context.pool(), &community_form).await?;
|
let community = Community::create(&mut context.pool(), &community_form).await?;
|
||||||
Ok((instance, community))
|
Ok((instance, community))
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user