mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-10-01 01:36:12 -04:00
Compare commits
10 Commits
dd52d68e1b
...
dff5feb486
Author | SHA1 | Date | |
---|---|---|---|
|
dff5feb486 | ||
|
777992e829 | ||
|
0fcbd25ad5 | ||
|
c4e0c24408 | ||
|
f583041d5f | ||
|
44dda08b13 | ||
|
5115ed4c09 | ||
|
4ad1fffee8 | ||
|
a3b7a46e93 | ||
|
f0adbaab72 |
40
Cargo.lock
generated
40
Cargo.lock
generated
@ -42,7 +42,7 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rand",
|
"rand",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest 0.12.7",
|
"reqwest 0.12.8",
|
||||||
"reqwest-middleware",
|
"reqwest-middleware",
|
||||||
"rsa",
|
"rsa",
|
||||||
"serde",
|
"serde",
|
||||||
@ -839,9 +839,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.17"
|
version = "4.5.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac"
|
checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
@ -849,9 +849,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.17"
|
version = "4.5.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73"
|
checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
@ -861,9 +861,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.5.13"
|
version = "4.5.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
|
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@ -1989,7 +1989,7 @@ dependencies = [
|
|||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"http-signature-normalization",
|
"http-signature-normalization",
|
||||||
"httpdate",
|
"httpdate",
|
||||||
"reqwest 0.12.7",
|
"reqwest 0.12.8",
|
||||||
"reqwest-middleware",
|
"reqwest-middleware",
|
||||||
"sha2",
|
"sha2",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@ -2514,7 +2514,7 @@ dependencies = [
|
|||||||
"moka",
|
"moka",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest 0.12.7",
|
"reqwest 0.12.8",
|
||||||
"reqwest-middleware",
|
"reqwest-middleware",
|
||||||
"rosetta-i18n",
|
"rosetta-i18n",
|
||||||
"serde",
|
"serde",
|
||||||
@ -2579,7 +2579,7 @@ dependencies = [
|
|||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"moka",
|
"moka",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"reqwest 0.12.7",
|
"reqwest 0.12.8",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
@ -2718,7 +2718,7 @@ dependencies = [
|
|||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"mockall",
|
"mockall",
|
||||||
"moka",
|
"moka",
|
||||||
"reqwest 0.12.7",
|
"reqwest 0.12.8",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"test-context",
|
"test-context",
|
||||||
@ -2745,7 +2745,7 @@ dependencies = [
|
|||||||
"lemmy_db_views",
|
"lemmy_db_views",
|
||||||
"lemmy_db_views_actor",
|
"lemmy_db_views_actor",
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"reqwest 0.12.7",
|
"reqwest 0.12.8",
|
||||||
"reqwest-middleware",
|
"reqwest-middleware",
|
||||||
"rss",
|
"rss",
|
||||||
"serde",
|
"serde",
|
||||||
@ -2778,7 +2778,7 @@ dependencies = [
|
|||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"prometheus",
|
"prometheus",
|
||||||
"reqwest 0.12.7",
|
"reqwest 0.12.8",
|
||||||
"reqwest-middleware",
|
"reqwest-middleware",
|
||||||
"reqwest-tracing",
|
"reqwest-tracing",
|
||||||
"rustls 0.23.13",
|
"rustls 0.23.13",
|
||||||
@ -2811,7 +2811,7 @@ dependencies = [
|
|||||||
"markdown-it",
|
"markdown-it",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest 0.12.7",
|
"reqwest 0.12.8",
|
||||||
"reqwest-middleware",
|
"reqwest-middleware",
|
||||||
"rosetta-build",
|
"rosetta-build",
|
||||||
"rosetta-i18n",
|
"rosetta-i18n",
|
||||||
@ -2870,7 +2870,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.48.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3966,9 +3966,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.12.7"
|
version = "0.12.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63"
|
checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-compression",
|
"async-compression",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
@ -4019,7 +4019,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"reqwest 0.12.7",
|
"reqwest 0.12.8",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
@ -4036,7 +4036,7 @@ dependencies = [
|
|||||||
"getrandom",
|
"getrandom",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"matchit",
|
"matchit",
|
||||||
"reqwest 0.12.7",
|
"reqwest 0.12.8",
|
||||||
"reqwest-middleware",
|
"reqwest-middleware",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
@ -5579,7 +5579,7 @@ version = "0.1.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -90,7 +90,7 @@ lemmy_db_views = { version = "=0.19.6-beta.7", path = "./crates/db_views" }
|
|||||||
lemmy_db_views_actor = { version = "=0.19.6-beta.7", path = "./crates/db_views_actor" }
|
lemmy_db_views_actor = { version = "=0.19.6-beta.7", path = "./crates/db_views_actor" }
|
||||||
lemmy_db_views_moderator = { version = "=0.19.6-beta.7", path = "./crates/db_views_moderator" }
|
lemmy_db_views_moderator = { version = "=0.19.6-beta.7", path = "./crates/db_views_moderator" }
|
||||||
lemmy_federate = { version = "=0.19.6-beta.7", path = "./crates/federate" }
|
lemmy_federate = { version = "=0.19.6-beta.7", path = "./crates/federate" }
|
||||||
activitypub_federation = { version = "0.6.0-alpha1", default-features = false, features = [
|
activitypub_federation = { version = "0.6.0-alpha2", default-features = false, features = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
] }
|
] }
|
||||||
diesel = "2.1.6"
|
diesel = "2.1.6"
|
||||||
|
@ -858,3 +858,26 @@ test("Dont send a comment reply to a blocked community", async () => {
|
|||||||
blockRes = await blockCommunity(beta, newCommunityId, false);
|
blockRes = await blockCommunity(beta, newCommunityId, false);
|
||||||
expect(blockRes.blocked).toBe(false);
|
expect(blockRes.blocked).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// Fetching a deeply nested comment can lead to stack overflow as all parent comments are also
|
||||||
|
/// fetched recursively. Ensure that it works properly.
|
||||||
|
test("Fetch a deeply nested comment", async () => {
|
||||||
|
let lastComment;
|
||||||
|
for (let i = 0; i < 50; i++) {
|
||||||
|
let commentRes = await createComment(
|
||||||
|
alpha,
|
||||||
|
postOnAlphaRes.post_view.post.id,
|
||||||
|
lastComment?.comment_view.comment.id,
|
||||||
|
);
|
||||||
|
expect(commentRes.comment_view.comment).toBeDefined();
|
||||||
|
lastComment = commentRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
let betaComment = await resolveComment(
|
||||||
|
beta,
|
||||||
|
lastComment!.comment_view.comment,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(betaComment!.comment!.comment).toBeDefined();
|
||||||
|
expect(betaComment?.comment?.post).toBeDefined();
|
||||||
|
});
|
||||||
|
@ -5,7 +5,7 @@ use lemmy_api_common::{
|
|||||||
comment::{CommentResponse, CreateCommentLike},
|
comment::{CommentResponse, CreateCommentLike},
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
send_activity::{ActivityChannel, SendActivityData},
|
send_activity::{ActivityChannel, SendActivityData},
|
||||||
utils::{check_bot_account, check_community_user_action, check_downvotes_enabled},
|
utils::{check_bot_account, check_community_user_action, check_local_vote_mode, VoteItem},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::LocalUserId,
|
newtypes::LocalUserId,
|
||||||
@ -30,8 +30,7 @@ pub async fn like_comment(
|
|||||||
|
|
||||||
let mut recipient_ids = Vec::<LocalUserId>::new();
|
let mut recipient_ids = Vec::<LocalUserId>::new();
|
||||||
|
|
||||||
// Don't do a downvote if site has downvotes disabled
|
check_local_vote_mode(data.score, VoteItem::Comment, &local_site)?;
|
||||||
check_downvotes_enabled(data.score, &local_site)?;
|
|
||||||
check_bot_account(&local_user_view.person)?;
|
check_bot_account(&local_user_view.person)?;
|
||||||
|
|
||||||
let comment_id = data.comment_id;
|
let comment_id = data.comment_id;
|
||||||
|
@ -8,8 +8,9 @@ use lemmy_api_common::{
|
|||||||
utils::{
|
utils::{
|
||||||
check_bot_account,
|
check_bot_account,
|
||||||
check_community_user_action,
|
check_community_user_action,
|
||||||
check_downvotes_enabled,
|
check_local_vote_mode,
|
||||||
mark_post_as_read,
|
mark_post_as_read,
|
||||||
|
VoteItem,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
@ -32,8 +33,7 @@ pub async fn like_post(
|
|||||||
) -> LemmyResult<Json<PostResponse>> {
|
) -> LemmyResult<Json<PostResponse>> {
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||||
|
|
||||||
// Don't do a downvote if site has downvotes disabled
|
check_local_vote_mode(data.score, VoteItem::Post, &local_site)?;
|
||||||
check_downvotes_enabled(data.score, &local_site)?;
|
|
||||||
check_bot_account(&local_user_view.person)?;
|
check_bot_account(&local_user_view.person)?;
|
||||||
|
|
||||||
// Check for a community ban
|
// Check for a community ban
|
||||||
|
@ -21,6 +21,7 @@ use lemmy_db_schema::{
|
|||||||
tagline::Tagline,
|
tagline::Tagline,
|
||||||
},
|
},
|
||||||
CommentSortType,
|
CommentSortType,
|
||||||
|
FederationMode,
|
||||||
ListingType,
|
ListingType,
|
||||||
ModlogActionType,
|
ModlogActionType,
|
||||||
PostListingMode,
|
PostListingMode,
|
||||||
@ -170,7 +171,6 @@ pub struct CreateSite {
|
|||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<String>,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<String>,
|
||||||
pub enable_downvotes: Option<bool>,
|
|
||||||
pub enable_nsfw: Option<bool>,
|
pub enable_nsfw: Option<bool>,
|
||||||
pub community_creation_admin_only: Option<bool>,
|
pub community_creation_admin_only: Option<bool>,
|
||||||
pub require_email_verification: Option<bool>,
|
pub require_email_verification: Option<bool>,
|
||||||
@ -208,6 +208,10 @@ pub struct CreateSite {
|
|||||||
pub registration_mode: Option<RegistrationMode>,
|
pub registration_mode: Option<RegistrationMode>,
|
||||||
pub oauth_registration: Option<bool>,
|
pub oauth_registration: Option<bool>,
|
||||||
pub content_warning: Option<String>,
|
pub content_warning: Option<String>,
|
||||||
|
pub post_upvotes: Option<FederationMode>,
|
||||||
|
pub post_downvotes: Option<FederationMode>,
|
||||||
|
pub comment_upvotes: Option<FederationMode>,
|
||||||
|
pub comment_downvotes: Option<FederationMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
@ -224,8 +228,6 @@ pub struct EditSite {
|
|||||||
pub icon: Option<String>,
|
pub icon: Option<String>,
|
||||||
/// A url for your site's banner.
|
/// A url for your site's banner.
|
||||||
pub banner: Option<String>,
|
pub banner: Option<String>,
|
||||||
/// Whether to enable downvotes.
|
|
||||||
pub enable_downvotes: Option<bool>,
|
|
||||||
/// Whether to enable NSFW.
|
/// Whether to enable NSFW.
|
||||||
pub enable_nsfw: Option<bool>,
|
pub enable_nsfw: Option<bool>,
|
||||||
/// Limits community creation to admins only.
|
/// Limits community creation to admins only.
|
||||||
@ -291,13 +293,21 @@ pub struct EditSite {
|
|||||||
/// A list of blocked URLs
|
/// A list of blocked URLs
|
||||||
pub blocked_urls: Option<Vec<String>>,
|
pub blocked_urls: Option<Vec<String>>,
|
||||||
pub registration_mode: Option<RegistrationMode>,
|
pub registration_mode: Option<RegistrationMode>,
|
||||||
/// Whether or not external auth methods can auto-register users.
|
|
||||||
pub oauth_registration: Option<bool>,
|
|
||||||
/// Whether to email admins for new reports.
|
/// Whether to email admins for new reports.
|
||||||
pub reports_email_admins: Option<bool>,
|
pub reports_email_admins: Option<bool>,
|
||||||
/// If present, nsfw content is visible by default. Should be displayed by frontends/clients
|
/// If present, nsfw content is visible by default. Should be displayed by frontends/clients
|
||||||
/// when the site is first opened by a user.
|
/// when the site is first opened by a user.
|
||||||
pub content_warning: Option<String>,
|
pub content_warning: Option<String>,
|
||||||
|
/// Whether or not external auth methods can auto-register users.
|
||||||
|
pub oauth_registration: Option<bool>,
|
||||||
|
/// What kind of post upvotes your site allows.
|
||||||
|
pub post_upvotes: Option<FederationMode>,
|
||||||
|
/// What kind of post downvotes your site allows.
|
||||||
|
pub post_downvotes: Option<FederationMode>,
|
||||||
|
/// What kind of comment upvotes your site allows.
|
||||||
|
pub comment_upvotes: Option<FederationMode>,
|
||||||
|
/// What kind of comment downvotes your site allows.
|
||||||
|
pub comment_downvotes: Option<FederationMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
@ -33,6 +33,7 @@ use lemmy_db_schema::{
|
|||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
utils::DbPool,
|
utils::DbPool,
|
||||||
|
FederationMode,
|
||||||
RegistrationMode,
|
RegistrationMode,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::{
|
use lemmy_db_views::{
|
||||||
@ -296,10 +297,28 @@ pub async fn check_person_instance_community_block(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A vote item type used to check the vote mode.
|
||||||
|
pub enum VoteItem {
|
||||||
|
Post,
|
||||||
|
Comment,
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn check_downvotes_enabled(score: i16, local_site: &LocalSite) -> LemmyResult<()> {
|
pub fn check_local_vote_mode(
|
||||||
if score == -1 && !local_site.enable_downvotes {
|
score: i16,
|
||||||
Err(LemmyErrorType::DownvotesAreDisabled)?
|
vote_item: VoteItem,
|
||||||
|
local_site: &LocalSite,
|
||||||
|
) -> LemmyResult<()> {
|
||||||
|
let (downvote_setting, upvote_setting) = match vote_item {
|
||||||
|
VoteItem::Post => (local_site.post_downvotes, local_site.post_upvotes),
|
||||||
|
VoteItem::Comment => (local_site.comment_downvotes, local_site.comment_upvotes),
|
||||||
|
};
|
||||||
|
|
||||||
|
let downvote_fail = score == -1 && downvote_setting == FederationMode::Disable;
|
||||||
|
let upvote_fail = score == 1 && upvote_setting == FederationMode::Disable;
|
||||||
|
|
||||||
|
if downvote_fail || upvote_fail {
|
||||||
|
Err(LemmyErrorType::VoteNotAllowed)?
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,9 @@ use lemmy_db_views::structs::{LocalUserView, PostView};
|
|||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
error::{LemmyErrorExt, LemmyErrorType, LemmyResult},
|
error::{LemmyErrorExt, LemmyErrorType, LemmyResult},
|
||||||
utils::{mention::scrape_text_for_mentions, validation::is_valid_body_field},
|
utils::{mention::scrape_text_for_mentions, validation::is_valid_body_field},
|
||||||
|
MAX_COMMENT_DEPTH_LIMIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
const MAX_COMMENT_DEPTH_LIMIT: usize = 100;
|
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn create_comment(
|
pub async fn create_comment(
|
||||||
data: Json<CreateComment>,
|
data: Json<CreateComment>,
|
||||||
|
@ -90,7 +90,6 @@ pub async fn create_site(
|
|||||||
let local_site_form = LocalSiteUpdateForm {
|
let local_site_form = LocalSiteUpdateForm {
|
||||||
// Set the site setup to true
|
// Set the site setup to true
|
||||||
site_setup: Some(true),
|
site_setup: Some(true),
|
||||||
enable_downvotes: data.enable_downvotes,
|
|
||||||
registration_mode: data.registration_mode,
|
registration_mode: data.registration_mode,
|
||||||
community_creation_admin_only: data.community_creation_admin_only,
|
community_creation_admin_only: data.community_creation_admin_only,
|
||||||
require_email_verification: data.require_email_verification,
|
require_email_verification: data.require_email_verification,
|
||||||
@ -110,6 +109,10 @@ pub async fn create_site(
|
|||||||
captcha_enabled: data.captcha_enabled,
|
captcha_enabled: data.captcha_enabled,
|
||||||
captcha_difficulty: data.captcha_difficulty.clone(),
|
captcha_difficulty: data.captcha_difficulty.clone(),
|
||||||
default_post_listing_mode: data.default_post_listing_mode,
|
default_post_listing_mode: data.default_post_listing_mode,
|
||||||
|
post_upvotes: data.post_upvotes,
|
||||||
|
post_downvotes: data.post_downvotes,
|
||||||
|
comment_upvotes: data.comment_upvotes,
|
||||||
|
comment_downvotes: data.comment_downvotes,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,7 +99,6 @@ pub async fn update_site(
|
|||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
let local_site_form = LocalSiteUpdateForm {
|
let local_site_form = LocalSiteUpdateForm {
|
||||||
enable_downvotes: data.enable_downvotes,
|
|
||||||
registration_mode: data.registration_mode,
|
registration_mode: data.registration_mode,
|
||||||
community_creation_admin_only: data.community_creation_admin_only,
|
community_creation_admin_only: data.community_creation_admin_only,
|
||||||
require_email_verification: data.require_email_verification,
|
require_email_verification: data.require_email_verification,
|
||||||
@ -121,6 +120,10 @@ pub async fn update_site(
|
|||||||
reports_email_admins: data.reports_email_admins,
|
reports_email_admins: data.reports_email_admins,
|
||||||
default_post_listing_mode: data.default_post_listing_mode,
|
default_post_listing_mode: data.default_post_listing_mode,
|
||||||
oauth_registration: data.oauth_registration,
|
oauth_registration: data.oauth_registration,
|
||||||
|
post_upvotes: data.post_upvotes,
|
||||||
|
post_downvotes: data.post_downvotes,
|
||||||
|
comment_upvotes: data.comment_upvotes,
|
||||||
|
comment_downvotes: data.comment_downvotes,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use activitypub_federation::{
|
|||||||
traits::{ActivityHandler, Actor},
|
traits::{ActivityHandler, Actor},
|
||||||
};
|
};
|
||||||
use lemmy_api_common::{context::LemmyContext, utils::check_bot_account};
|
use lemmy_api_common::{context::LemmyContext, utils::check_bot_account};
|
||||||
use lemmy_db_schema::source::local_site::LocalSite;
|
use lemmy_db_schema::{source::local_site::LocalSite, FederationMode};
|
||||||
use lemmy_utils::error::{LemmyError, LemmyResult};
|
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
@ -68,12 +68,22 @@ impl ActivityHandler for Vote {
|
|||||||
|
|
||||||
check_bot_account(&actor.0)?;
|
check_bot_account(&actor.0)?;
|
||||||
|
|
||||||
let enable_downvotes = LocalSite::read(&mut context.pool())
|
// Check for enabled federation votes
|
||||||
|
let local_site = LocalSite::read(&mut context.pool())
|
||||||
.await
|
.await
|
||||||
.map(|l| l.enable_downvotes)
|
.unwrap_or_default();
|
||||||
.unwrap_or(true);
|
|
||||||
if self.kind == VoteType::Dislike && !enable_downvotes {
|
let (downvote_setting, upvote_setting) = match object {
|
||||||
// If this is a downvote but downvotes are ignored, only undo any existing vote
|
PostOrComment::Post(_) => (local_site.post_downvotes, local_site.post_upvotes),
|
||||||
|
PostOrComment::Comment(_) => (local_site.comment_downvotes, local_site.comment_upvotes),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Don't allow dislikes for either disabled, or local only votes
|
||||||
|
let downvote_fail = self.kind == VoteType::Dislike && downvote_setting != FederationMode::All;
|
||||||
|
let upvote_fail = self.kind == VoteType::Like && upvote_setting != FederationMode::All;
|
||||||
|
|
||||||
|
if downvote_fail || upvote_fail {
|
||||||
|
// If this is a rejection, undo the vote
|
||||||
match object {
|
match object {
|
||||||
PostOrComment::Post(p) => undo_vote_post(actor, &p, context).await,
|
PostOrComment::Post(p) => undo_vote_post(actor, &p, context).await,
|
||||||
PostOrComment::Comment(c) => undo_vote_comment(actor, &c, context).await,
|
PostOrComment::Comment(c) => undo_vote_comment(actor, &c, context).await,
|
||||||
|
@ -103,13 +103,16 @@ pub async fn import_settings(
|
|||||||
context: Data<LemmyContext>,
|
context: Data<LemmyContext>,
|
||||||
) -> LemmyResult<Json<SuccessResponse>> {
|
) -> LemmyResult<Json<SuccessResponse>> {
|
||||||
let person_form = PersonUpdateForm {
|
let person_form = PersonUpdateForm {
|
||||||
display_name: Some(data.display_name.clone()),
|
display_name: data.display_name.clone().map(Some),
|
||||||
bio: Some(data.bio.clone()),
|
bio: data.bio.clone().map(Some),
|
||||||
matrix_user_id: Some(data.matrix_id.clone()),
|
matrix_user_id: data.bio.clone().map(Some),
|
||||||
bot_account: data.bot_account,
|
bot_account: data.bot_account,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
Person::update(&mut context.pool(), local_user_view.person.id, &person_form).await?;
|
// ignore error in case form is empty
|
||||||
|
Person::update(&mut context.pool(), local_user_view.person.id, &person_form)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
|
||||||
let local_user_form = LocalUserUpdateForm {
|
let local_user_form = LocalUserUpdateForm {
|
||||||
show_nsfw: data.settings.as_ref().map(|s| s.show_nsfw),
|
show_nsfw: data.settings.as_ref().map(|s| s.show_nsfw),
|
||||||
@ -312,8 +315,9 @@ where
|
|||||||
#[expect(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};
|
||||||
use activitypub_federation::config::Data;
|
use activitypub_federation::config::Data;
|
||||||
|
use actix_web::web::Json;
|
||||||
use lemmy_api_common::context::LemmyContext;
|
use lemmy_api_common::context::LemmyContext;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
@ -401,45 +405,6 @@ mod tests {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
#[serial]
|
|
||||||
async fn test_settings_partial_import() -> LemmyResult<()> {
|
|
||||||
let context = LemmyContext::init_test_context().await;
|
|
||||||
|
|
||||||
let export_user =
|
|
||||||
create_user("hanna".to_string(), Some("my bio".to_string()), &context).await?;
|
|
||||||
|
|
||||||
let community_form = CommunityInsertForm::new(
|
|
||||||
export_user.person.instance_id,
|
|
||||||
"testcom".to_string(),
|
|
||||||
"testcom".to_string(),
|
|
||||||
"pubkey".to_string(),
|
|
||||||
);
|
|
||||||
let community = Community::create(&mut context.pool(), &community_form).await?;
|
|
||||||
let follower_form = CommunityFollowerForm {
|
|
||||||
community_id: community.id,
|
|
||||||
person_id: export_user.person.id,
|
|
||||||
pending: false,
|
|
||||||
};
|
|
||||||
CommunityFollower::follow(&mut context.pool(), &follower_form).await?;
|
|
||||||
|
|
||||||
let backup = export_settings(export_user.clone(), context.reset_request_count()).await?;
|
|
||||||
|
|
||||||
let import_user = create_user("charles".to_string(), None, &context).await?;
|
|
||||||
|
|
||||||
let backup2 = UserSettingsBackup {
|
|
||||||
followed_communities: backup.followed_communities.clone(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
import_settings(
|
|
||||||
actix_web::web::Json(backup2),
|
|
||||||
import_user.clone(),
|
|
||||||
context.reset_request_count(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn disallow_large_backup() -> LemmyResult<()> {
|
async fn disallow_large_backup() -> LemmyResult<()> {
|
||||||
@ -475,4 +440,33 @@ mod tests {
|
|||||||
LocalUser::delete(&mut context.pool(), import_user.local_user.id).await?;
|
LocalUser::delete(&mut context.pool(), import_user.local_user.id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[serial]
|
||||||
|
async fn import_partial_backup() -> LemmyResult<()> {
|
||||||
|
let context = LemmyContext::init_test_context().await;
|
||||||
|
|
||||||
|
let import_user =
|
||||||
|
create_user("hanna".to_string(), Some("my bio".to_string()), &context).await?;
|
||||||
|
|
||||||
|
let backup =
|
||||||
|
serde_json::from_str("{\"bot_account\": true, \"settings\": {\"theme\": \"my_theme\"}}")?;
|
||||||
|
import_settings(
|
||||||
|
Json(backup),
|
||||||
|
import_user.clone(),
|
||||||
|
context.reset_request_count(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let import_user_updated =
|
||||||
|
LocalUserView::read(&mut context.pool(), import_user.local_user.id).await?;
|
||||||
|
// mark as bot account
|
||||||
|
assert!(import_user_updated.person.bot_account);
|
||||||
|
// dont remove existing bio
|
||||||
|
assert_eq!(import_user.person.bio, import_user_updated.person.bio);
|
||||||
|
// local_user can be deserialized without id/person_id fields
|
||||||
|
assert_eq!("my_theme", import_user_updated.local_user.theme);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,9 @@ use lemmy_db_schema::{
|
|||||||
source::{community::Community, post::Post},
|
source::{community::Community, post::Post},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::LemmyResult;
|
use lemmy_utils::{error::LemmyResult, LemmyErrorType, MAX_COMMENT_DEPTH_LIMIT};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_with::skip_serializing_none;
|
use serde_with::skip_serializing_none;
|
||||||
use std::ops::Deref;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
@ -58,9 +57,19 @@ impl Note {
|
|||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
) -> LemmyResult<(ApubPost, Option<ApubComment>)> {
|
) -> LemmyResult<(ApubPost, Option<ApubComment>)> {
|
||||||
// Fetch parent comment chain in a box, otherwise it can cause a stack overflow.
|
// We use recursion here to fetch the entire comment chain up to the top-level parent. This is
|
||||||
let parent = Box::pin(self.in_reply_to.dereference(context).await?);
|
// necessary because we need to know the post and parent comment in order to insert a new
|
||||||
match parent.deref() {
|
// comment. However it can also lead to stack overflow when fetching many comments recursively.
|
||||||
|
// To avoid this we check the request count against max comment depth, which based on testing
|
||||||
|
// can be handled without risking stack overflow. This is not a perfect solution, because in
|
||||||
|
// some cases we have to fetch user profiles too, and reach the limit after only 25 comments
|
||||||
|
// or so.
|
||||||
|
// A cleaner solution would be converting the recursion into a loop, but that is tricky.
|
||||||
|
if context.request_count() > MAX_COMMENT_DEPTH_LIMIT as u32 {
|
||||||
|
Err(LemmyErrorType::MaxCommentDepthReached)?;
|
||||||
|
}
|
||||||
|
let parent = self.in_reply_to.dereference(context).await?;
|
||||||
|
match parent {
|
||||||
PostOrComment::Post(p) => Ok((p.clone(), None)),
|
PostOrComment::Post(p) => Ok((p.clone(), None)),
|
||||||
PostOrComment::Comment(c) => {
|
PostOrComment::Comment(c) => {
|
||||||
let post_id = c.post_id;
|
let post_id = c.post_id;
|
||||||
|
@ -251,6 +251,27 @@ pub enum CommunityVisibility {
|
|||||||
LocalOnly,
|
LocalOnly,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default, Hash,
|
||||||
|
)]
|
||||||
|
#[cfg_attr(feature = "full", derive(DbEnum, TS))]
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "full",
|
||||||
|
ExistingTypePath = "crate::schema::sql_types::FederationModeEnum"
|
||||||
|
)]
|
||||||
|
#[cfg_attr(feature = "full", DbValueStyle = "verbatim")]
|
||||||
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
|
/// The federation mode for an item
|
||||||
|
pub enum FederationMode {
|
||||||
|
#[default]
|
||||||
|
/// Allows all
|
||||||
|
All,
|
||||||
|
/// Allows only local
|
||||||
|
Local,
|
||||||
|
/// Disables
|
||||||
|
Disable,
|
||||||
|
}
|
||||||
|
|
||||||
/// Wrapper for assert_eq! macro. Checks that vec matches the given length, and prints the
|
/// Wrapper for assert_eq! macro. Checks that vec matches the given length, and prints the
|
||||||
/// vec on failure.
|
/// vec on failure.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
@ -13,6 +13,10 @@ pub mod sql_types {
|
|||||||
#[diesel(postgres_type(name = "community_visibility"))]
|
#[diesel(postgres_type(name = "community_visibility"))]
|
||||||
pub struct CommunityVisibility;
|
pub struct CommunityVisibility;
|
||||||
|
|
||||||
|
#[derive(diesel::sql_types::SqlType)]
|
||||||
|
#[diesel(postgres_type(name = "federation_mode_enum"))]
|
||||||
|
pub struct FederationModeEnum;
|
||||||
|
|
||||||
#[derive(diesel::sql_types::SqlType)]
|
#[derive(diesel::sql_types::SqlType)]
|
||||||
#[diesel(postgres_type(name = "listing_type_enum"))]
|
#[diesel(postgres_type(name = "listing_type_enum"))]
|
||||||
pub struct ListingTypeEnum;
|
pub struct ListingTypeEnum;
|
||||||
@ -368,12 +372,12 @@ diesel::table! {
|
|||||||
use super::sql_types::PostListingModeEnum;
|
use super::sql_types::PostListingModeEnum;
|
||||||
use super::sql_types::PostSortTypeEnum;
|
use super::sql_types::PostSortTypeEnum;
|
||||||
use super::sql_types::CommentSortTypeEnum;
|
use super::sql_types::CommentSortTypeEnum;
|
||||||
|
use super::sql_types::FederationModeEnum;
|
||||||
|
|
||||||
local_site (id) {
|
local_site (id) {
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
site_id -> Int4,
|
site_id -> Int4,
|
||||||
site_setup -> Bool,
|
site_setup -> Bool,
|
||||||
enable_downvotes -> Bool,
|
|
||||||
community_creation_admin_only -> Bool,
|
community_creation_admin_only -> Bool,
|
||||||
require_email_verification -> Bool,
|
require_email_verification -> Bool,
|
||||||
application_question -> Nullable<Text>,
|
application_question -> Nullable<Text>,
|
||||||
@ -398,6 +402,10 @@ diesel::table! {
|
|||||||
default_post_sort_type -> PostSortTypeEnum,
|
default_post_sort_type -> PostSortTypeEnum,
|
||||||
default_comment_sort_type -> CommentSortTypeEnum,
|
default_comment_sort_type -> CommentSortTypeEnum,
|
||||||
oauth_registration -> Bool,
|
oauth_registration -> Bool,
|
||||||
|
post_upvotes -> FederationModeEnum,
|
||||||
|
post_downvotes -> FederationModeEnum,
|
||||||
|
comment_upvotes -> FederationModeEnum,
|
||||||
|
comment_downvotes -> FederationModeEnum,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ use crate::schema::local_site;
|
|||||||
use crate::{
|
use crate::{
|
||||||
newtypes::{LocalSiteId, SiteId},
|
newtypes::{LocalSiteId, SiteId},
|
||||||
CommentSortType,
|
CommentSortType,
|
||||||
|
FederationMode,
|
||||||
ListingType,
|
ListingType,
|
||||||
PostListingMode,
|
PostListingMode,
|
||||||
PostSortType,
|
PostSortType,
|
||||||
@ -27,8 +28,6 @@ pub struct LocalSite {
|
|||||||
pub site_id: SiteId,
|
pub site_id: SiteId,
|
||||||
/// True if the site is set up.
|
/// True if the site is set up.
|
||||||
pub site_setup: bool,
|
pub site_setup: bool,
|
||||||
/// Whether downvotes are enabled.
|
|
||||||
pub enable_downvotes: bool,
|
|
||||||
/// Whether only admins can create communities.
|
/// Whether only admins can create communities.
|
||||||
pub community_creation_admin_only: bool,
|
pub community_creation_admin_only: bool,
|
||||||
/// Whether emails are required.
|
/// Whether emails are required.
|
||||||
@ -72,6 +71,14 @@ pub struct LocalSite {
|
|||||||
pub default_comment_sort_type: CommentSortType,
|
pub default_comment_sort_type: CommentSortType,
|
||||||
/// Whether or not external auth methods can auto-register users.
|
/// Whether or not external auth methods can auto-register users.
|
||||||
pub oauth_registration: bool,
|
pub oauth_registration: bool,
|
||||||
|
/// What kind of post upvotes your site allows.
|
||||||
|
pub post_upvotes: FederationMode,
|
||||||
|
/// What kind of post downvotes your site allows.
|
||||||
|
pub post_downvotes: FederationMode,
|
||||||
|
/// What kind of comment upvotes your site allows.
|
||||||
|
pub comment_upvotes: FederationMode,
|
||||||
|
/// What kind of comment downvotes your site allows.
|
||||||
|
pub comment_downvotes: FederationMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, derive_new::new)]
|
#[derive(Clone, derive_new::new)]
|
||||||
@ -82,8 +89,6 @@ pub struct LocalSiteInsertForm {
|
|||||||
#[new(default)]
|
#[new(default)]
|
||||||
pub site_setup: Option<bool>,
|
pub site_setup: Option<bool>,
|
||||||
#[new(default)]
|
#[new(default)]
|
||||||
pub enable_downvotes: Option<bool>,
|
|
||||||
#[new(default)]
|
|
||||||
pub community_creation_admin_only: Option<bool>,
|
pub community_creation_admin_only: Option<bool>,
|
||||||
#[new(default)]
|
#[new(default)]
|
||||||
pub require_email_verification: Option<bool>,
|
pub require_email_verification: Option<bool>,
|
||||||
@ -114,8 +119,6 @@ pub struct LocalSiteInsertForm {
|
|||||||
#[new(default)]
|
#[new(default)]
|
||||||
pub registration_mode: Option<RegistrationMode>,
|
pub registration_mode: Option<RegistrationMode>,
|
||||||
#[new(default)]
|
#[new(default)]
|
||||||
pub oauth_registration: Option<bool>,
|
|
||||||
#[new(default)]
|
|
||||||
pub reports_email_admins: Option<bool>,
|
pub reports_email_admins: Option<bool>,
|
||||||
#[new(default)]
|
#[new(default)]
|
||||||
pub federation_signed_fetch: Option<bool>,
|
pub federation_signed_fetch: Option<bool>,
|
||||||
@ -125,6 +128,16 @@ pub struct LocalSiteInsertForm {
|
|||||||
pub default_post_sort_type: Option<PostSortType>,
|
pub default_post_sort_type: Option<PostSortType>,
|
||||||
#[new(default)]
|
#[new(default)]
|
||||||
pub default_comment_sort_type: Option<CommentSortType>,
|
pub default_comment_sort_type: Option<CommentSortType>,
|
||||||
|
#[new(default)]
|
||||||
|
pub oauth_registration: Option<bool>,
|
||||||
|
#[new(default)]
|
||||||
|
pub post_upvotes: Option<FederationMode>,
|
||||||
|
#[new(default)]
|
||||||
|
pub post_downvotes: Option<FederationMode>,
|
||||||
|
#[new(default)]
|
||||||
|
pub comment_upvotes: Option<FederationMode>,
|
||||||
|
#[new(default)]
|
||||||
|
pub comment_downvotes: Option<FederationMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
@ -132,7 +145,6 @@ pub struct LocalSiteInsertForm {
|
|||||||
#[cfg_attr(feature = "full", diesel(table_name = local_site))]
|
#[cfg_attr(feature = "full", diesel(table_name = local_site))]
|
||||||
pub struct LocalSiteUpdateForm {
|
pub struct LocalSiteUpdateForm {
|
||||||
pub site_setup: Option<bool>,
|
pub site_setup: Option<bool>,
|
||||||
pub enable_downvotes: Option<bool>,
|
|
||||||
pub community_creation_admin_only: Option<bool>,
|
pub community_creation_admin_only: Option<bool>,
|
||||||
pub require_email_verification: Option<bool>,
|
pub require_email_verification: Option<bool>,
|
||||||
pub application_question: Option<Option<String>>,
|
pub application_question: Option<Option<String>>,
|
||||||
@ -148,11 +160,15 @@ pub struct LocalSiteUpdateForm {
|
|||||||
pub captcha_enabled: Option<bool>,
|
pub captcha_enabled: Option<bool>,
|
||||||
pub captcha_difficulty: Option<String>,
|
pub captcha_difficulty: Option<String>,
|
||||||
pub registration_mode: Option<RegistrationMode>,
|
pub registration_mode: Option<RegistrationMode>,
|
||||||
pub oauth_registration: Option<bool>,
|
|
||||||
pub reports_email_admins: Option<bool>,
|
pub reports_email_admins: Option<bool>,
|
||||||
pub updated: Option<Option<DateTime<Utc>>>,
|
pub updated: Option<Option<DateTime<Utc>>>,
|
||||||
pub federation_signed_fetch: Option<bool>,
|
pub federation_signed_fetch: Option<bool>,
|
||||||
pub default_post_listing_mode: Option<PostListingMode>,
|
pub default_post_listing_mode: Option<PostListingMode>,
|
||||||
pub default_post_sort_type: Option<PostSortType>,
|
pub default_post_sort_type: Option<PostSortType>,
|
||||||
pub default_comment_sort_type: Option<CommentSortType>,
|
pub default_comment_sort_type: Option<CommentSortType>,
|
||||||
|
pub oauth_registration: Option<bool>,
|
||||||
|
pub post_upvotes: Option<FederationMode>,
|
||||||
|
pub post_downvotes: Option<FederationMode>,
|
||||||
|
pub comment_upvotes: Option<FederationMode>,
|
||||||
|
pub comment_downvotes: Option<FederationMode>,
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,12 @@ use serde_with::skip_serializing_none;
|
|||||||
use ts_rs::TS;
|
use ts_rs::TS;
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
|
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Default)]
|
||||||
#[cfg_attr(feature = "full", derive(Queryable, Selectable, Identifiable, TS))]
|
#[cfg_attr(feature = "full", derive(Queryable, Selectable, Identifiable, TS))]
|
||||||
#[cfg_attr(feature = "full", diesel(table_name = local_user))]
|
#[cfg_attr(feature = "full", diesel(table_name = local_user))]
|
||||||
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||||
#[cfg_attr(feature = "full", ts(export))]
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
|
#[serde(default)]
|
||||||
/// A local user.
|
/// A local user.
|
||||||
pub struct LocalUser {
|
pub struct LocalUser {
|
||||||
pub id: LocalUserId,
|
pub id: LocalUserId,
|
||||||
|
@ -46,7 +46,7 @@ pub enum LemmyErrorType {
|
|||||||
PersonIsBlocked,
|
PersonIsBlocked,
|
||||||
CommunityIsBlocked,
|
CommunityIsBlocked,
|
||||||
InstanceIsBlocked,
|
InstanceIsBlocked,
|
||||||
DownvotesAreDisabled,
|
VoteNotAllowed,
|
||||||
InstanceIsPrivate,
|
InstanceIsPrivate,
|
||||||
/// Password must be between 10 and 60 characters
|
/// Password must be between 10 and 60 characters
|
||||||
InvalidPassword,
|
InvalidPassword,
|
||||||
|
@ -29,6 +29,8 @@ pub const CACHE_DURATION_FEDERATION: Duration = Duration::from_secs(60);
|
|||||||
|
|
||||||
pub const CACHE_DURATION_API: Duration = Duration::from_secs(1);
|
pub const CACHE_DURATION_API: Duration = Duration::from_secs(1);
|
||||||
|
|
||||||
|
pub const MAX_COMMENT_DEPTH_LIMIT: usize = 50;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! location_info {
|
macro_rules! location_info {
|
||||||
() => {
|
() => {
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
-- Add back the enable_downvotes column
|
||||||
|
ALTER TABLE local_site
|
||||||
|
ADD COLUMN enable_downvotes boolean DEFAULT TRUE NOT NULL;
|
||||||
|
|
||||||
|
-- regenerate their values (from post_downvotes alone)
|
||||||
|
WITH subquery AS (
|
||||||
|
SELECT
|
||||||
|
post_downvotes,
|
||||||
|
CASE WHEN post_downvotes = 'Disable'::federation_mode_enum THEN
|
||||||
|
FALSE
|
||||||
|
ELSE
|
||||||
|
TRUE
|
||||||
|
END
|
||||||
|
FROM
|
||||||
|
local_site)
|
||||||
|
UPDATE
|
||||||
|
local_site
|
||||||
|
SET
|
||||||
|
enable_downvotes = subquery.case
|
||||||
|
FROM
|
||||||
|
subquery;
|
||||||
|
|
||||||
|
-- Drop the new columns
|
||||||
|
ALTER TABLE local_site
|
||||||
|
DROP COLUMN post_upvotes,
|
||||||
|
DROP COLUMN post_downvotes,
|
||||||
|
DROP COLUMN comment_upvotes,
|
||||||
|
DROP COLUMN comment_downvotes;
|
||||||
|
|
||||||
|
DROP TYPE federation_mode_enum;
|
||||||
|
|
@ -0,0 +1,39 @@
|
|||||||
|
-- This removes the simple enable_downvotes setting, in favor of an
|
||||||
|
-- expanded federation mode type for post/comment up/downvotes.
|
||||||
|
-- Create the federation mode enum
|
||||||
|
CREATE TYPE federation_mode_enum AS ENUM (
|
||||||
|
'All',
|
||||||
|
'Local',
|
||||||
|
'Disable'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Add the new columns
|
||||||
|
ALTER TABLE local_site
|
||||||
|
ADD COLUMN post_upvotes federation_mode_enum DEFAULT 'All'::federation_mode_enum NOT NULL,
|
||||||
|
ADD COLUMN post_downvotes federation_mode_enum DEFAULT 'All'::federation_mode_enum NOT NULL,
|
||||||
|
ADD COLUMN comment_upvotes federation_mode_enum DEFAULT 'All'::federation_mode_enum NOT NULL,
|
||||||
|
ADD COLUMN comment_downvotes federation_mode_enum DEFAULT 'All'::federation_mode_enum NOT NULL;
|
||||||
|
|
||||||
|
-- Copy over the enable_downvotes into the post and comment downvote settings
|
||||||
|
WITH subquery AS (
|
||||||
|
SELECT
|
||||||
|
enable_downvotes,
|
||||||
|
CASE WHEN enable_downvotes = TRUE THEN
|
||||||
|
'All'::federation_mode_enum
|
||||||
|
ELSE
|
||||||
|
'Disable'::federation_mode_enum
|
||||||
|
END
|
||||||
|
FROM
|
||||||
|
local_site)
|
||||||
|
UPDATE
|
||||||
|
local_site
|
||||||
|
SET
|
||||||
|
post_downvotes = subquery.case,
|
||||||
|
comment_downvotes = subquery.case
|
||||||
|
FROM
|
||||||
|
subquery;
|
||||||
|
|
||||||
|
-- Drop the enable_downvotes column
|
||||||
|
ALTER TABLE local_site
|
||||||
|
DROP COLUMN enable_downvotes;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user