mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-10-02 08:11:55 +00:00
Some fixes from suggestions.
This commit is contained in:
parent
c969675b9b
commit
8b4996c10c
41 changed files with 484 additions and 564 deletions
|
@ -44,7 +44,7 @@ lemmy_api_common = { version = "=0.16.5", path = "crates/api_common" }
|
|||
lemmy_websocket = { version = "=0.16.5", path = "./crates/websocket" }
|
||||
lemmy_routes = { version = "=0.16.5", path = "./crates/routes" }
|
||||
activitypub_federation = "0.2.0"
|
||||
diesel = { version = "2.0.0", features = ["64-column-tables"] }
|
||||
diesel = "2.0.0"
|
||||
diesel_migrations = "2.0.0"
|
||||
serde = { version = "1.0.145", features = ["derive"] }
|
||||
actix = "0.13.0"
|
||||
|
|
|
@ -23,6 +23,18 @@
|
|||
api_key: "string"
|
||||
}
|
||||
# Email sending configuration. All options except login/password are mandatory
|
||||
email: {
|
||||
# Hostname and port of the smtp server
|
||||
smtp_server: "localhost:25"
|
||||
# Login name for smtp server
|
||||
smtp_login: "string"
|
||||
# Password to login to the smtp server
|
||||
smtp_password: "string"
|
||||
# Address to send emails from, eg noreply@your-instance.com
|
||||
smtp_from_address: "noreply@example.com"
|
||||
# Whether or not smtp connections should use tls. Can be none, tls, or starttls
|
||||
tls_type: "none"
|
||||
}
|
||||
# Parameters for automatic configuration of new instance (only used at first start)
|
||||
setup: {
|
||||
# Username for the admin user
|
||||
|
|
|
@ -2,9 +2,8 @@ use crate::Perform;
|
|||
use actix_web::web::Data;
|
||||
use lemmy_api_common::{
|
||||
person::{PasswordReset, PasswordResetResponse},
|
||||
utils::{blocking, local_site_to_email_config, send_password_reset_email},
|
||||
utils::{blocking, send_password_reset_email},
|
||||
};
|
||||
use lemmy_db_schema::source::local_site::LocalSite;
|
||||
use lemmy_db_views::structs::LocalUserView;
|
||||
use lemmy_utils::{error::LemmyError, ConnectionId};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
@ -21,8 +20,6 @@ impl Perform for PasswordReset {
|
|||
) -> Result<PasswordResetResponse, LemmyError> {
|
||||
let data: &PasswordReset = self;
|
||||
|
||||
let local_site = blocking(context.pool(), LocalSite::read).await??;
|
||||
|
||||
// Fetch that email
|
||||
let email = data.email.to_lowercase();
|
||||
let local_user_view = blocking(context.pool(), move |conn| {
|
||||
|
@ -32,14 +29,7 @@ impl Perform for PasswordReset {
|
|||
.map_err(|e| LemmyError::from_error_message(e, "couldnt_find_that_username_or_email"))?;
|
||||
|
||||
// Email the pure token to the user.
|
||||
let email_config = local_site_to_email_config(&local_site)?;
|
||||
send_password_reset_email(
|
||||
&local_user_view,
|
||||
context.pool(),
|
||||
context.settings(),
|
||||
&email_config,
|
||||
)
|
||||
.await?;
|
||||
send_password_reset_email(&local_user_view, context.pool(), context.settings()).await?;
|
||||
Ok(PasswordResetResponse {})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,7 @@ use crate::Perform;
|
|||
use actix_web::web::Data;
|
||||
use lemmy_api_common::{
|
||||
person::{LoginResponse, SaveUserSettings},
|
||||
utils::{
|
||||
blocking,
|
||||
get_local_user_view_from_jwt,
|
||||
local_site_to_email_config,
|
||||
send_verification_email,
|
||||
},
|
||||
utils::{blocking, get_local_user_view_from_jwt, send_verification_email},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
|
@ -55,14 +50,7 @@ impl Perform for SaveUserSettings {
|
|||
let previous_email = local_user_view.local_user.email.clone().unwrap_or_default();
|
||||
// Only send the verification email if there was an email change
|
||||
if previous_email.ne(email) {
|
||||
let email_config = local_site_to_email_config(&local_site)?;
|
||||
send_verification_email(
|
||||
&local_user_view,
|
||||
email,
|
||||
context.pool(),
|
||||
context.settings(),
|
||||
&email_config,
|
||||
)
|
||||
send_verification_email(&local_user_view, email, context.pool(), context.settings())
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,11 @@ use crate::Perform;
|
|||
use actix_web::web::Data;
|
||||
use lemmy_api_common::{
|
||||
person::{VerifyEmail, VerifyEmailResponse},
|
||||
utils::{blocking, local_site_to_email_config, send_email_verification_success},
|
||||
utils::{blocking, send_email_verification_success},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
email_verification::EmailVerification,
|
||||
local_site::LocalSite,
|
||||
local_user::{LocalUser, LocalUserUpdateForm},
|
||||
},
|
||||
traits::Crud,
|
||||
|
@ -49,9 +48,7 @@ impl Perform for VerifyEmail {
|
|||
})
|
||||
.await??;
|
||||
|
||||
let local_site = blocking(context.pool(), LocalSite::read).await??;
|
||||
let email_config = local_site_to_email_config(&local_site)?;
|
||||
send_email_verification_success(&local_user_view, context.settings(), &email_config)?;
|
||||
send_email_verification_success(&local_user_view, context.settings())?;
|
||||
|
||||
blocking(context.pool(), move |conn| {
|
||||
EmailVerification::delete_old_tokens_for_local_user(conn, local_user_id)
|
||||
|
|
|
@ -2,17 +2,10 @@ use crate::Perform;
|
|||
use actix_web::web::Data;
|
||||
use lemmy_api_common::{
|
||||
site::{ApproveRegistrationApplication, RegistrationApplicationResponse},
|
||||
utils::{
|
||||
blocking,
|
||||
get_local_user_view_from_jwt,
|
||||
is_admin,
|
||||
local_site_to_email_config,
|
||||
send_application_approved_email,
|
||||
},
|
||||
utils::{blocking, get_local_user_view_from_jwt, is_admin, send_application_approved_email},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
local_site::LocalSite,
|
||||
local_user::{LocalUser, LocalUserUpdateForm},
|
||||
registration_application::{RegistrationApplication, RegistrationApplicationUpdateForm},
|
||||
},
|
||||
|
@ -71,13 +64,7 @@ impl Perform for ApproveRegistrationApplication {
|
|||
.await??;
|
||||
|
||||
if approved_local_user_view.local_user.email.is_some() {
|
||||
let local_site = blocking(context.pool(), LocalSite::read).await??;
|
||||
let email_config = local_site_to_email_config(&local_site)?;
|
||||
send_application_approved_email(
|
||||
&approved_local_user_view,
|
||||
context.settings(),
|
||||
&email_config,
|
||||
)?;
|
||||
send_application_approved_email(&approved_local_user_view, context.settings())?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,16 +148,10 @@ pub struct CreateSite {
|
|||
pub federation_strict_allowlist: Option<bool>,
|
||||
pub federation_http_fetch_retry_limit: Option<i32>,
|
||||
pub federation_worker_count: Option<i32>,
|
||||
pub email_enabled: Option<bool>,
|
||||
pub email_smtp_server: Option<String>,
|
||||
pub email_smtp_login: Option<String>,
|
||||
pub email_smtp_password: Option<String>,
|
||||
pub email_smtp_from_address: Option<String>,
|
||||
pub email_tls_type: Option<String>,
|
||||
pub captcha_enabled: Option<bool>,
|
||||
pub captcha_difficulty: Option<String>,
|
||||
pub allowed_instances: Option<String>,
|
||||
pub blocked_instances: Option<String>,
|
||||
pub allowed_instances: Option<Vec<String>>,
|
||||
pub blocked_instances: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
|
||||
|
@ -200,16 +194,10 @@ pub struct EditSite {
|
|||
pub federation_strict_allowlist: Option<bool>,
|
||||
pub federation_http_fetch_retry_limit: Option<i32>,
|
||||
pub federation_worker_count: Option<i32>,
|
||||
pub email_enabled: Option<bool>,
|
||||
pub email_smtp_server: Option<String>,
|
||||
pub email_smtp_login: Option<String>,
|
||||
pub email_smtp_password: Option<String>,
|
||||
pub email_smtp_from_address: Option<String>,
|
||||
pub email_tls_type: Option<String>,
|
||||
pub captcha_enabled: Option<bool>,
|
||||
pub captcha_difficulty: Option<String>,
|
||||
pub allowed_instances: Option<String>,
|
||||
pub blocked_instances: Option<String>,
|
||||
pub allowed_instances: Option<Vec<String>>,
|
||||
pub blocked_instances: Option<Vec<String>>,
|
||||
pub auth: Sensitive<String>,
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ use lemmy_db_schema::{
|
|||
email_verification::{EmailVerification, EmailVerificationForm},
|
||||
instance::Instance,
|
||||
local_site::LocalSite,
|
||||
local_site_rate_limit::LocalSiteRateLimit,
|
||||
password_reset_request::PasswordResetRequest,
|
||||
person::{Person, PersonUpdateForm},
|
||||
person_block::PersonBlock,
|
||||
|
@ -31,7 +32,7 @@ use lemmy_db_views_actor::structs::{
|
|||
};
|
||||
use lemmy_utils::{
|
||||
claims::Claims,
|
||||
email::{send_email, translations::Lang, EmailConfig},
|
||||
email::{send_email, translations::Lang},
|
||||
error::LemmyError,
|
||||
rate_limit::RateLimitConfig,
|
||||
settings::structs::Settings,
|
||||
|
@ -342,8 +343,7 @@ pub fn send_email_to_user(
|
|||
local_user_view: &LocalUserView,
|
||||
subject: &str,
|
||||
body: &str,
|
||||
hostname: &str,
|
||||
config: &EmailConfig,
|
||||
settings: &Settings,
|
||||
) {
|
||||
if local_user_view.person.banned || !local_user_view.local_user.send_notifications_to_email {
|
||||
return;
|
||||
|
@ -355,8 +355,7 @@ pub fn send_email_to_user(
|
|||
user_email,
|
||||
&local_user_view.person.name,
|
||||
body,
|
||||
hostname,
|
||||
config,
|
||||
settings,
|
||||
) {
|
||||
Ok(_o) => _o,
|
||||
Err(e) => warn!("{}", e),
|
||||
|
@ -368,7 +367,6 @@ pub async fn send_password_reset_email(
|
|||
user: &LocalUserView,
|
||||
pool: &DbPool,
|
||||
settings: &Settings,
|
||||
config: &EmailConfig,
|
||||
) -> Result<(), LemmyError> {
|
||||
// Generate a random token
|
||||
let token = generate_random_string();
|
||||
|
@ -387,14 +385,7 @@ pub async fn send_password_reset_email(
|
|||
let protocol_and_hostname = settings.get_protocol_and_hostname();
|
||||
let reset_link = format!("{}/password_change/{}", protocol_and_hostname, &token);
|
||||
let body = &lang.password_reset_body(reset_link, &user.person.name);
|
||||
send_email(
|
||||
subject,
|
||||
email,
|
||||
&user.person.name,
|
||||
body,
|
||||
&settings.hostname,
|
||||
config,
|
||||
)
|
||||
send_email(subject, email, &user.person.name, body, settings)
|
||||
}
|
||||
|
||||
/// Send a verification email
|
||||
|
@ -403,7 +394,6 @@ pub async fn send_verification_email(
|
|||
new_email: &str,
|
||||
pool: &DbPool,
|
||||
settings: &Settings,
|
||||
config: &EmailConfig,
|
||||
) -> Result<(), LemmyError> {
|
||||
let form = EmailVerificationForm {
|
||||
local_user_id: user.local_user.id,
|
||||
|
@ -420,14 +410,7 @@ pub async fn send_verification_email(
|
|||
let lang = get_interface_language(user);
|
||||
let subject = lang.verify_email_subject(&settings.hostname);
|
||||
let body = lang.verify_email_body(&settings.hostname, &user.person.name, verify_link);
|
||||
send_email(
|
||||
&subject,
|
||||
new_email,
|
||||
&user.person.name,
|
||||
&body,
|
||||
&settings.hostname,
|
||||
config,
|
||||
)?;
|
||||
send_email(&subject, new_email, &user.person.name, &body, settings)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -435,20 +418,12 @@ pub async fn send_verification_email(
|
|||
pub fn send_email_verification_success(
|
||||
user: &LocalUserView,
|
||||
settings: &Settings,
|
||||
config: &EmailConfig,
|
||||
) -> Result<(), LemmyError> {
|
||||
let email = &user.local_user.email.to_owned().expect("email");
|
||||
let lang = get_interface_language(user);
|
||||
let subject = &lang.email_verified_subject(&user.person.actor_id);
|
||||
let body = &lang.email_verified_body();
|
||||
send_email(
|
||||
subject,
|
||||
email,
|
||||
&user.person.name,
|
||||
body,
|
||||
&settings.hostname,
|
||||
config,
|
||||
)
|
||||
send_email(subject, email, &user.person.name, body, settings)
|
||||
}
|
||||
|
||||
pub fn get_interface_language(user: &LocalUserView) -> Lang {
|
||||
|
@ -467,39 +442,23 @@ fn lang_str_to_lang(lang: &str) -> Lang {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn local_site_to_email_config(local_site: &LocalSite) -> Result<EmailConfig, LemmyError> {
|
||||
let ls = local_site.to_owned();
|
||||
|
||||
let err_msg = LemmyError::from_message("no_email_setup");
|
||||
|
||||
if ls.email_enabled {
|
||||
Ok(EmailConfig {
|
||||
smtp_server: ls.email_smtp_server.as_ref().ok_or(err_msg)?.to_string(),
|
||||
smtp_login: ls.email_smtp_login,
|
||||
smtp_password: ls.email_smtp_password,
|
||||
smtp_from_address: ls.email_smtp_from_address,
|
||||
tls_type: ls.email_tls_type,
|
||||
})
|
||||
} else {
|
||||
Err(err_msg)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn local_site_to_rate_limit_config(local_site: &LocalSite) -> RateLimitConfig {
|
||||
let l = local_site;
|
||||
pub fn local_site_rate_limit_to_rate_limit_config(
|
||||
local_site_rate_limit: &LocalSiteRateLimit,
|
||||
) -> RateLimitConfig {
|
||||
let l = local_site_rate_limit;
|
||||
RateLimitConfig {
|
||||
message: l.rate_limit_message,
|
||||
message_per_second: l.rate_limit_message_per_second,
|
||||
post: l.rate_limit_post,
|
||||
post_per_second: l.rate_limit_post_per_second,
|
||||
register: l.rate_limit_register,
|
||||
register_per_second: l.rate_limit_register_per_second,
|
||||
image: l.rate_limit_image,
|
||||
image_per_second: l.rate_limit_image_per_second,
|
||||
comment: l.rate_limit_comment,
|
||||
comment_per_second: l.rate_limit_comment_per_second,
|
||||
search: l.rate_limit_search,
|
||||
search_per_second: l.rate_limit_search_per_second,
|
||||
message: l.message,
|
||||
message_per_second: l.message_per_second,
|
||||
post: l.post,
|
||||
post_per_second: l.post_per_second,
|
||||
register: l.register,
|
||||
register_per_second: l.register_per_second,
|
||||
image: l.image,
|
||||
image_per_second: l.image_per_second,
|
||||
comment: l.comment,
|
||||
comment_per_second: l.comment_per_second,
|
||||
search: l.search,
|
||||
search_per_second: l.search_per_second,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,20 +469,12 @@ pub fn local_site_to_slur_regex(local_site: &LocalSite) -> Option<Regex> {
|
|||
pub fn send_application_approved_email(
|
||||
user: &LocalUserView,
|
||||
settings: &Settings,
|
||||
config: &EmailConfig,
|
||||
) -> Result<(), LemmyError> {
|
||||
let email = &user.local_user.email.to_owned().expect("email");
|
||||
let lang = get_interface_language(user);
|
||||
let subject = lang.registration_approved_subject(&user.person.actor_id);
|
||||
let body = lang.registration_approved_body(&settings.hostname);
|
||||
send_email(
|
||||
&subject,
|
||||
email,
|
||||
&user.person.name,
|
||||
&body,
|
||||
&settings.hostname,
|
||||
config,
|
||||
)
|
||||
send_email(&subject, email, &user.person.name, &body, settings)
|
||||
}
|
||||
|
||||
/// Send a new applicant email notification to all admins
|
||||
|
@ -531,7 +482,6 @@ pub async fn send_new_applicant_email_to_admins(
|
|||
applicant_username: &str,
|
||||
pool: &DbPool,
|
||||
settings: &Settings,
|
||||
config: &EmailConfig,
|
||||
) -> Result<(), LemmyError> {
|
||||
// Collect the admins with emails
|
||||
let admins = blocking(pool, move |conn| {
|
||||
|
@ -549,14 +499,7 @@ pub async fn send_new_applicant_email_to_admins(
|
|||
let lang = get_interface_language_from_settings(admin);
|
||||
let subject = lang.new_application_subject(applicant_username, &settings.hostname);
|
||||
let body = lang.new_application_body(applications_link);
|
||||
send_email(
|
||||
&subject,
|
||||
email,
|
||||
&admin.person.name,
|
||||
&body,
|
||||
&settings.hostname,
|
||||
config,
|
||||
)?;
|
||||
send_email(&subject, email, &admin.person.name, &body, settings)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -146,7 +146,6 @@ impl PerformCrud for CreateComment {
|
|||
&updated_comment,
|
||||
&local_user_view.person,
|
||||
&post,
|
||||
&local_site,
|
||||
true,
|
||||
context,
|
||||
)
|
||||
|
|
|
@ -9,7 +9,6 @@ use lemmy_db_schema::{
|
|||
source::{
|
||||
comment::{Comment, CommentUpdateForm},
|
||||
community::Community,
|
||||
local_site::LocalSite,
|
||||
post::Post,
|
||||
},
|
||||
traits::Crud,
|
||||
|
@ -35,7 +34,6 @@ impl PerformCrud for DeleteComment {
|
|||
let data: &DeleteComment = self;
|
||||
let local_user_view =
|
||||
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
||||
let local_site = blocking(context.pool(), LocalSite::read).await??;
|
||||
|
||||
let comment_id = data.comment_id;
|
||||
let orig_comment = blocking(context.pool(), move |conn| {
|
||||
|
@ -79,7 +77,6 @@ impl PerformCrud for DeleteComment {
|
|||
&updated_comment,
|
||||
&local_user_view.person,
|
||||
&post,
|
||||
&local_site,
|
||||
false,
|
||||
context,
|
||||
)
|
||||
|
|
|
@ -9,7 +9,6 @@ use lemmy_db_schema::{
|
|||
source::{
|
||||
comment::{Comment, CommentUpdateForm},
|
||||
community::Community,
|
||||
local_site::LocalSite,
|
||||
moderator::{ModRemoveComment, ModRemoveCommentForm},
|
||||
post::Post,
|
||||
},
|
||||
|
@ -36,7 +35,6 @@ impl PerformCrud for RemoveComment {
|
|||
let data: &RemoveComment = self;
|
||||
let local_user_view =
|
||||
get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
|
||||
let local_site = blocking(context.pool(), LocalSite::read).await??;
|
||||
|
||||
let comment_id = data.comment_id;
|
||||
let orig_comment = blocking(context.pool(), move |conn| {
|
||||
|
@ -90,7 +88,6 @@ impl PerformCrud for RemoveComment {
|
|||
&updated_comment,
|
||||
&local_user_view.person.clone(),
|
||||
&post,
|
||||
&local_site,
|
||||
false,
|
||||
context,
|
||||
)
|
||||
|
|
|
@ -114,7 +114,6 @@ impl PerformCrud for EditComment {
|
|||
&updated_comment,
|
||||
&local_user_view.person,
|
||||
&orig_comment.post,
|
||||
&local_site,
|
||||
false,
|
||||
context,
|
||||
)
|
||||
|
|
|
@ -7,7 +7,6 @@ use lemmy_api_common::{
|
|||
check_person_block,
|
||||
get_interface_language,
|
||||
get_local_user_view_from_jwt,
|
||||
local_site_to_email_config,
|
||||
local_site_to_slur_regex,
|
||||
send_email_to_user,
|
||||
},
|
||||
|
@ -128,8 +127,7 @@ impl PerformCrud for CreatePrivateMessage {
|
|||
&content_slurs_removed,
|
||||
&local_recipient.person.name,
|
||||
),
|
||||
&context.settings().hostname,
|
||||
&local_site_to_email_config(&local_site)?,
|
||||
context.settings(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ use lemmy_db_schema::{
|
|||
newtypes::DbUrl,
|
||||
source::{
|
||||
local_site::{LocalSite, LocalSiteUpdateForm},
|
||||
local_site_rate_limit::{LocalSiteRateLimit, LocalSiteRateLimitUpdateForm},
|
||||
site::{Site, SiteUpdateForm},
|
||||
},
|
||||
traits::Crud,
|
||||
|
@ -111,29 +112,11 @@ impl PerformCrud for CreateSite {
|
|||
.updated(Some(Some(naive_now())))
|
||||
.slur_filter_regex(diesel_option_overwrite(&data.slur_filter_regex))
|
||||
.actor_name_max_length(data.actor_name_max_length)
|
||||
.rate_limit_message(data.rate_limit_message)
|
||||
.rate_limit_message_per_second(data.rate_limit_message_per_second)
|
||||
.rate_limit_post(data.rate_limit_post)
|
||||
.rate_limit_post_per_second(data.rate_limit_post_per_second)
|
||||
.rate_limit_register(data.rate_limit_register)
|
||||
.rate_limit_register_per_second(data.rate_limit_register_per_second)
|
||||
.rate_limit_image(data.rate_limit_image)
|
||||
.rate_limit_image_per_second(data.rate_limit_image_per_second)
|
||||
.rate_limit_comment(data.rate_limit_comment)
|
||||
.rate_limit_comment_per_second(data.rate_limit_comment_per_second)
|
||||
.rate_limit_search(data.rate_limit_search)
|
||||
.rate_limit_search_per_second(data.rate_limit_search_per_second)
|
||||
.federation_enabled(data.federation_enabled)
|
||||
.federation_debug(data.federation_debug)
|
||||
.federation_strict_allowlist(data.federation_strict_allowlist)
|
||||
.federation_http_fetch_retry_limit(data.federation_http_fetch_retry_limit)
|
||||
.federation_worker_count(data.federation_worker_count)
|
||||
.email_enabled(data.email_enabled)
|
||||
.email_smtp_server(diesel_option_overwrite(&data.email_smtp_server))
|
||||
.email_smtp_login(diesel_option_overwrite(&data.email_smtp_login))
|
||||
.email_smtp_password(diesel_option_overwrite(&data.email_smtp_password))
|
||||
.email_smtp_from_address(diesel_option_overwrite(&data.email_smtp_from_address))
|
||||
.email_tls_type(data.email_tls_type.to_owned())
|
||||
.captcha_enabled(data.captcha_enabled)
|
||||
.captcha_difficulty(data.captcha_difficulty.to_owned())
|
||||
.build();
|
||||
|
@ -142,6 +125,26 @@ impl PerformCrud for CreateSite {
|
|||
})
|
||||
.await??;
|
||||
|
||||
let local_site_rate_limit_form = LocalSiteRateLimitUpdateForm::builder()
|
||||
.message(data.rate_limit_message)
|
||||
.message_per_second(data.rate_limit_message_per_second)
|
||||
.post(data.rate_limit_post)
|
||||
.post_per_second(data.rate_limit_post_per_second)
|
||||
.register(data.rate_limit_register)
|
||||
.register_per_second(data.rate_limit_register_per_second)
|
||||
.image(data.rate_limit_image)
|
||||
.image_per_second(data.rate_limit_image_per_second)
|
||||
.comment(data.rate_limit_comment)
|
||||
.comment_per_second(data.rate_limit_comment_per_second)
|
||||
.search(data.rate_limit_search)
|
||||
.search_per_second(data.rate_limit_search_per_second)
|
||||
.build();
|
||||
|
||||
blocking(context.pool(), move |conn| {
|
||||
LocalSiteRateLimit::update(conn, &local_site_rate_limit_form)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let site_view = blocking(context.pool(), SiteView::read_local).await??;
|
||||
|
||||
Ok(SiteResponse { site_view })
|
||||
|
|
|
@ -13,9 +13,10 @@ use lemmy_api_common::{
|
|||
use lemmy_db_schema::{
|
||||
source::{
|
||||
actor_language::SiteLanguage,
|
||||
allowlist::AllowList,
|
||||
blocklist::BlockList,
|
||||
federation_allowlist::FederationAllowList,
|
||||
federation_blocklist::FederationBlockList,
|
||||
local_site::{LocalSite, LocalSiteUpdateForm},
|
||||
local_site_rate_limit::{LocalSiteRateLimit, LocalSiteRateLimitUpdateForm},
|
||||
local_user::LocalUser,
|
||||
site::{Site, SiteUpdateForm},
|
||||
},
|
||||
|
@ -113,29 +114,11 @@ impl PerformCrud for EditSite {
|
|||
.updated(Some(Some(naive_now())))
|
||||
.slur_filter_regex(diesel_option_overwrite(&data.slur_filter_regex))
|
||||
.actor_name_max_length(data.actor_name_max_length)
|
||||
.rate_limit_message(data.rate_limit_message)
|
||||
.rate_limit_message_per_second(data.rate_limit_message_per_second)
|
||||
.rate_limit_post(data.rate_limit_post)
|
||||
.rate_limit_post_per_second(data.rate_limit_post_per_second)
|
||||
.rate_limit_register(data.rate_limit_register)
|
||||
.rate_limit_register_per_second(data.rate_limit_register_per_second)
|
||||
.rate_limit_image(data.rate_limit_image)
|
||||
.rate_limit_image_per_second(data.rate_limit_image_per_second)
|
||||
.rate_limit_comment(data.rate_limit_comment)
|
||||
.rate_limit_comment_per_second(data.rate_limit_comment_per_second)
|
||||
.rate_limit_search(data.rate_limit_search)
|
||||
.rate_limit_search_per_second(data.rate_limit_search_per_second)
|
||||
.federation_enabled(data.federation_enabled)
|
||||
.federation_debug(data.federation_debug)
|
||||
.federation_strict_allowlist(data.federation_strict_allowlist)
|
||||
.federation_http_fetch_retry_limit(data.federation_http_fetch_retry_limit)
|
||||
.federation_worker_count(data.federation_worker_count)
|
||||
.email_enabled(data.email_enabled)
|
||||
.email_smtp_server(diesel_option_overwrite(&data.email_smtp_server))
|
||||
.email_smtp_login(diesel_option_overwrite(&data.email_smtp_login))
|
||||
.email_smtp_password(diesel_option_overwrite(&data.email_smtp_password))
|
||||
.email_smtp_from_address(diesel_option_overwrite(&data.email_smtp_from_address))
|
||||
.email_tls_type(data.email_tls_type.to_owned())
|
||||
.captcha_enabled(data.captcha_enabled)
|
||||
.captcha_difficulty(data.captcha_difficulty.to_owned())
|
||||
.build();
|
||||
|
@ -146,15 +129,35 @@ impl PerformCrud for EditSite {
|
|||
.await?
|
||||
.map_err(|e| LemmyError::from_error_message(e, "couldnt_update_site"))?;
|
||||
|
||||
// Replace the blocked and allowed instances
|
||||
let allowed = diesel_option_overwrite(&data.allowed_instances);
|
||||
let local_site_rate_limit_form = LocalSiteRateLimitUpdateForm::builder()
|
||||
.message(data.rate_limit_message)
|
||||
.message_per_second(data.rate_limit_message_per_second)
|
||||
.post(data.rate_limit_post)
|
||||
.post_per_second(data.rate_limit_post_per_second)
|
||||
.register(data.rate_limit_register)
|
||||
.register_per_second(data.rate_limit_register_per_second)
|
||||
.image(data.rate_limit_image)
|
||||
.image_per_second(data.rate_limit_image_per_second)
|
||||
.comment(data.rate_limit_comment)
|
||||
.comment_per_second(data.rate_limit_comment_per_second)
|
||||
.search(data.rate_limit_search)
|
||||
.search_per_second(data.rate_limit_search_per_second)
|
||||
.build();
|
||||
|
||||
blocking(context.pool(), move |conn| {
|
||||
AllowList::replace(conn, allowed)
|
||||
LocalSiteRateLimit::update(conn, &local_site_rate_limit_form)
|
||||
})
|
||||
.await??;
|
||||
let blocked = diesel_option_overwrite(&data.blocked_instances);
|
||||
|
||||
// Replace the blocked and allowed instances
|
||||
let allowed = data.allowed_instances.to_owned();
|
||||
blocking(context.pool(), move |conn| {
|
||||
BlockList::replace(conn, blocked)
|
||||
FederationAllowList::replace(conn, allowed)
|
||||
})
|
||||
.await??;
|
||||
let blocked = data.blocked_instances.to_owned();
|
||||
blocking(context.pool(), move |conn| {
|
||||
FederationBlockList::replace(conn, blocked)
|
||||
})
|
||||
.await??;
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ use lemmy_api_common::{
|
|||
utils::{
|
||||
blocking,
|
||||
honeypot_check,
|
||||
local_site_to_email_config,
|
||||
local_site_to_slur_regex,
|
||||
password_length_check,
|
||||
send_new_applicant_email_to_admins,
|
||||
|
@ -185,13 +184,7 @@ impl PerformCrud for Register {
|
|||
|
||||
// Email the admins
|
||||
if local_site.application_email_admins {
|
||||
let email_config = local_site_to_email_config(&local_site)?;
|
||||
send_new_applicant_email_to_admins(
|
||||
&data.username,
|
||||
context.pool(),
|
||||
context.settings(),
|
||||
&email_config,
|
||||
)
|
||||
send_new_applicant_email_to_admins(&data.username, context.pool(), context.settings())
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -225,14 +218,7 @@ impl PerformCrud for Register {
|
|||
.clone()
|
||||
.expect("email was provided");
|
||||
|
||||
let email_config = local_site_to_email_config(&local_site)?;
|
||||
send_verification_email(
|
||||
&local_user_view,
|
||||
&email,
|
||||
context.pool(),
|
||||
context.settings(),
|
||||
&email_config,
|
||||
)
|
||||
send_verification_email(&local_user_view, &email, context.pool(), context.settings())
|
||||
.await?;
|
||||
login_response.verify_email_sent = true;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use activitypub_federation::core::object_id::ObjectId;
|
|||
use lemmy_api_common::utils::blocking;
|
||||
use lemmy_db_schema::{
|
||||
newtypes::LocalUserId,
|
||||
source::{comment::Comment, local_site::LocalSite, post::Post},
|
||||
source::{comment::Comment, post::Post},
|
||||
traits::Crud,
|
||||
};
|
||||
use lemmy_utils::{error::LemmyError, utils::scrape_text_for_mentions};
|
||||
|
@ -27,22 +27,11 @@ async fn get_comment_notif_recipients(
|
|||
.dereference(context, local_instance(context), request_counter)
|
||||
.await?;
|
||||
|
||||
let local_site = blocking(context.pool(), LocalSite::read).await??;
|
||||
|
||||
// Note:
|
||||
// Although mentions could be gotten from the post tags (they are included there), or the ccs,
|
||||
// Its much easier to scrape them from the comment body, since the API has to do that
|
||||
// anyway.
|
||||
// TODO: for compatibility with other projects, it would be much better to read this from cc or tags
|
||||
let mentions = scrape_text_for_mentions(&comment.content);
|
||||
send_local_notifs(
|
||||
mentions,
|
||||
comment,
|
||||
&*actor,
|
||||
&post,
|
||||
&local_site,
|
||||
do_send_email,
|
||||
context,
|
||||
)
|
||||
.await
|
||||
send_local_notifs(mentions, comment, &*actor, &post, do_send_email, context).await
|
||||
}
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
use crate::{
|
||||
schema::allowlist,
|
||||
source::{
|
||||
allowlist::{AllowList, AllowListForm},
|
||||
instance::{Instance, InstanceForm},
|
||||
},
|
||||
};
|
||||
use diesel::{dsl::*, result::Error, *};
|
||||
|
||||
impl AllowList {
|
||||
pub fn replace(
|
||||
conn: &mut PgConnection,
|
||||
list_opt_str: Option<Option<String>>,
|
||||
) -> Result<(), Error> {
|
||||
conn.build_transaction().read_write().run(|conn| {
|
||||
if let Some(list_str) = list_opt_str {
|
||||
Self::clear(conn)?;
|
||||
|
||||
if let Some(list_replace_str) = list_str {
|
||||
let remove_whitespace = list_replace_str.split_whitespace().collect::<String>();
|
||||
let list = remove_whitespace.split(',').collect::<Vec<&str>>();
|
||||
for domain in list {
|
||||
// Upsert all of these as instances
|
||||
let instance_form = InstanceForm {
|
||||
domain: domain.to_string(),
|
||||
updated: None,
|
||||
};
|
||||
let instance = Instance::create(conn, &instance_form)?;
|
||||
|
||||
let form = AllowListForm {
|
||||
instance_id: instance.id,
|
||||
updated: None,
|
||||
};
|
||||
insert_into(allowlist::table)
|
||||
.values(form)
|
||||
.get_result::<Self>(conn)?;
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn clear(conn: &mut PgConnection) -> Result<usize, Error> {
|
||||
diesel::delete(allowlist::table).execute(conn)
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
source::{allowlist::AllowList, instance::Instance},
|
||||
utils::establish_unpooled_connection,
|
||||
};
|
||||
use serial_test::serial;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_allowlist_insert_and_clear() {
|
||||
let conn = &mut establish_unpooled_connection();
|
||||
let allowed = Some(Some("tld1.xyz, tld2.xyz,tld3.xyz".to_string()));
|
||||
|
||||
AllowList::replace(conn, allowed).unwrap();
|
||||
|
||||
let allows = Instance::allowlist(conn).unwrap();
|
||||
|
||||
assert_eq!(3, allows.len());
|
||||
assert_eq!(
|
||||
vec![
|
||||
"tld1.xyz".to_string(),
|
||||
"tld2.xyz".to_string(),
|
||||
"tld3.xyz".to_string()
|
||||
],
|
||||
allows
|
||||
);
|
||||
|
||||
// Now test clearing them via Some(none)
|
||||
let clear_allows = Some(None);
|
||||
|
||||
AllowList::replace(conn, clear_allows).unwrap();
|
||||
let allows = Instance::allowlist(conn).unwrap();
|
||||
|
||||
assert_eq!(0, allows.len());
|
||||
|
||||
Instance::delete_all(conn).unwrap();
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
use crate::{
|
||||
schema::blocklist,
|
||||
source::{
|
||||
blocklist::{BlockList, BlockListForm},
|
||||
instance::{Instance, InstanceForm},
|
||||
},
|
||||
};
|
||||
use diesel::{dsl::*, result::Error, *};
|
||||
|
||||
impl BlockList {
|
||||
pub fn replace(
|
||||
conn: &mut PgConnection,
|
||||
list_opt_str: Option<Option<String>>,
|
||||
) -> Result<(), Error> {
|
||||
conn.build_transaction().read_write().run(|conn| {
|
||||
if let Some(list_str) = list_opt_str {
|
||||
Self::clear(conn)?;
|
||||
|
||||
if let Some(list_replace_str) = list_str {
|
||||
let remove_whitespace = list_replace_str.split_whitespace().collect::<String>();
|
||||
let list = remove_whitespace.split(',').collect::<Vec<&str>>();
|
||||
for domain in list {
|
||||
// Upsert all of these as instances
|
||||
let instance_form = InstanceForm {
|
||||
domain: domain.to_string(),
|
||||
updated: None,
|
||||
};
|
||||
let instance = Instance::create(conn, &instance_form)?;
|
||||
|
||||
let form = BlockListForm {
|
||||
instance_id: instance.id,
|
||||
updated: None,
|
||||
};
|
||||
insert_into(blocklist::table)
|
||||
.values(form)
|
||||
.get_result::<Self>(conn)?;
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn clear(conn: &mut PgConnection) -> Result<usize, Error> {
|
||||
diesel::delete(blocklist::table).execute(conn)
|
||||
}
|
||||
}
|
85
crates/db_schema/src/impls/federation_allowlist.rs
Normal file
85
crates/db_schema/src/impls/federation_allowlist.rs
Normal file
|
@ -0,0 +1,85 @@
|
|||
use crate::{
|
||||
schema::federation_allowlist,
|
||||
source::{
|
||||
federation_allowlist::{FederationAllowList, FederationAllowListForm},
|
||||
instance::{Instance, InstanceForm},
|
||||
},
|
||||
};
|
||||
use diesel::{dsl::*, result::Error, *};
|
||||
|
||||
impl FederationAllowList {
|
||||
pub fn replace(conn: &mut PgConnection, list_opt: Option<Vec<String>>) -> Result<(), Error> {
|
||||
conn.build_transaction().read_write().run(|conn| {
|
||||
if let Some(list) = list_opt {
|
||||
Self::clear(conn)?;
|
||||
|
||||
for domain in list {
|
||||
// Upsert all of these as instances
|
||||
let instance_form = InstanceForm {
|
||||
domain: domain.to_string(),
|
||||
updated: None,
|
||||
};
|
||||
let instance = Instance::create(conn, &instance_form)?;
|
||||
|
||||
let form = FederationAllowListForm {
|
||||
instance_id: instance.id,
|
||||
updated: None,
|
||||
};
|
||||
insert_into(federation_allowlist::table)
|
||||
.values(form)
|
||||
.get_result::<Self>(conn)?;
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn clear(conn: &mut PgConnection) -> Result<usize, Error> {
|
||||
diesel::delete(federation_allowlist::table).execute(conn)
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
source::{federation_allowlist::FederationAllowList, instance::Instance},
|
||||
utils::establish_unpooled_connection,
|
||||
};
|
||||
use serial_test::serial;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_allowlist_insert_and_clear() {
|
||||
let conn = &mut establish_unpooled_connection();
|
||||
let allowed = Some(vec![
|
||||
"tld1.xyz".to_string(),
|
||||
"tld2.xyz".to_string(),
|
||||
"tld3.xyz".to_string(),
|
||||
]);
|
||||
|
||||
FederationAllowList::replace(conn, allowed).unwrap();
|
||||
|
||||
let allows = Instance::allowlist(conn).unwrap();
|
||||
|
||||
assert_eq!(3, allows.len());
|
||||
assert_eq!(
|
||||
vec![
|
||||
"tld1.xyz".to_string(),
|
||||
"tld2.xyz".to_string(),
|
||||
"tld3.xyz".to_string()
|
||||
],
|
||||
allows
|
||||
);
|
||||
|
||||
// Now test clearing them via Some(empty vec)
|
||||
let clear_allows = Some(Vec::new());
|
||||
|
||||
FederationAllowList::replace(conn, clear_allows).unwrap();
|
||||
let allows = Instance::allowlist(conn).unwrap();
|
||||
|
||||
assert_eq!(0, allows.len());
|
||||
|
||||
Instance::delete_all(conn).unwrap();
|
||||
}
|
||||
}
|
42
crates/db_schema/src/impls/federation_blocklist.rs
Normal file
42
crates/db_schema/src/impls/federation_blocklist.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
use crate::{
|
||||
schema::federation_blocklist,
|
||||
source::{
|
||||
federation_blocklist::{FederationBlockList, FederationBlockListForm},
|
||||
instance::{Instance, InstanceForm},
|
||||
},
|
||||
};
|
||||
use diesel::{dsl::*, result::Error, *};
|
||||
|
||||
impl FederationBlockList {
|
||||
pub fn replace(conn: &mut PgConnection, list_opt: Option<Vec<String>>) -> Result<(), Error> {
|
||||
conn.build_transaction().read_write().run(|conn| {
|
||||
if let Some(list) = list_opt {
|
||||
Self::clear(conn)?;
|
||||
|
||||
for domain in list {
|
||||
// Upsert all of these as instances
|
||||
let instance_form = InstanceForm {
|
||||
domain: domain.to_string(),
|
||||
updated: None,
|
||||
};
|
||||
let instance = Instance::create(conn, &instance_form)?;
|
||||
|
||||
let form = FederationBlockListForm {
|
||||
instance_id: instance.id,
|
||||
updated: None,
|
||||
};
|
||||
insert_into(federation_blocklist::table)
|
||||
.values(form)
|
||||
.get_result::<Self>(conn)?;
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn clear(conn: &mut PgConnection) -> Result<usize, Error> {
|
||||
diesel::delete(federation_blocklist::table).execute(conn)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
newtypes::InstanceId,
|
||||
schema::{allowlist, blocklist, instance},
|
||||
schema::{federation_allowlist, federation_blocklist, instance},
|
||||
source::instance::{Instance, InstanceForm},
|
||||
};
|
||||
use diesel::{dsl::*, result::Error, *};
|
||||
|
@ -23,22 +23,22 @@ impl Instance {
|
|||
}
|
||||
pub fn allowlist(conn: &mut PgConnection) -> Result<Vec<String>, Error> {
|
||||
instance::table
|
||||
.inner_join(allowlist::table)
|
||||
.inner_join(federation_allowlist::table)
|
||||
.select(instance::domain)
|
||||
.load::<String>(conn)
|
||||
}
|
||||
|
||||
pub fn blocklist(conn: &mut PgConnection) -> Result<Vec<String>, Error> {
|
||||
instance::table
|
||||
.inner_join(blocklist::table)
|
||||
.inner_join(federation_blocklist::table)
|
||||
.select(instance::domain)
|
||||
.load::<String>(conn)
|
||||
}
|
||||
|
||||
pub fn linked(conn: &mut PgConnection) -> Result<Vec<String>, Error> {
|
||||
instance::table
|
||||
.left_join(blocklist::table)
|
||||
.filter(blocklist::id.is_null())
|
||||
.left_join(federation_blocklist::table)
|
||||
.filter(federation_blocklist::id.is_null())
|
||||
.select(instance::domain)
|
||||
.load::<String>(conn)
|
||||
}
|
||||
|
|
25
crates/db_schema/src/impls/local_site_rate_limit.rs
Normal file
25
crates/db_schema/src/impls/local_site_rate_limit.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use crate::{schema::local_site_rate_limit, source::local_site_rate_limit::*};
|
||||
use diesel::{dsl::*, result::Error, *};
|
||||
|
||||
impl LocalSiteRateLimit {
|
||||
pub fn read(conn: &mut PgConnection) -> Result<Self, Error> {
|
||||
local_site_rate_limit::table.first::<Self>(conn)
|
||||
}
|
||||
|
||||
pub fn create(
|
||||
conn: &mut PgConnection,
|
||||
form: &LocalSiteRateLimitInsertForm,
|
||||
) -> Result<Self, Error> {
|
||||
insert_into(local_site_rate_limit::table)
|
||||
.values(form)
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
pub fn update(
|
||||
conn: &mut PgConnection,
|
||||
form: &LocalSiteRateLimitUpdateForm,
|
||||
) -> Result<Self, Error> {
|
||||
diesel::update(local_site_rate_limit::table)
|
||||
.set(form)
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
}
|
|
@ -1,16 +1,17 @@
|
|||
pub mod activity;
|
||||
pub mod actor_language;
|
||||
pub mod allowlist;
|
||||
pub mod blocklist;
|
||||
pub mod comment;
|
||||
pub mod comment_reply;
|
||||
pub mod comment_report;
|
||||
pub mod community;
|
||||
pub mod community_block;
|
||||
pub mod email_verification;
|
||||
pub mod federation_allowlist;
|
||||
pub mod federation_blocklist;
|
||||
pub mod instance;
|
||||
pub mod language;
|
||||
pub mod local_site;
|
||||
pub mod local_site_rate_limit;
|
||||
pub mod local_user;
|
||||
pub mod moderator;
|
||||
pub mod password_reset_request;
|
||||
|
|
|
@ -651,7 +651,7 @@ table! {
|
|||
}
|
||||
|
||||
table! {
|
||||
allowlist(id) {
|
||||
federation_allowlist(id) {
|
||||
id -> Int4,
|
||||
instance_id -> Int4,
|
||||
published -> Timestamp,
|
||||
|
@ -660,7 +660,7 @@ table! {
|
|||
}
|
||||
|
||||
table! {
|
||||
blocklist(id) {
|
||||
federation_blocklist(id) {
|
||||
id -> Int4,
|
||||
instance_id -> Int4,
|
||||
published -> Timestamp,
|
||||
|
@ -688,29 +688,11 @@ table! {
|
|||
application_email_admins -> Bool,
|
||||
slur_filter_regex -> Nullable<Text>,
|
||||
actor_name_max_length -> Int4,
|
||||
rate_limit_message -> Int4,
|
||||
rate_limit_message_per_second-> Int4,
|
||||
rate_limit_post -> Int4,
|
||||
rate_limit_post_per_second -> Int4,
|
||||
rate_limit_register -> Int4,
|
||||
rate_limit_register_per_second -> Int4,
|
||||
rate_limit_image -> Int4,
|
||||
rate_limit_image_per_second -> Int4,
|
||||
rate_limit_comment -> Int4,
|
||||
rate_limit_comment_per_second -> Int4,
|
||||
rate_limit_search -> Int4,
|
||||
rate_limit_search_per_second -> Int4,
|
||||
federation_enabled -> Bool,
|
||||
federation_debug -> Bool,
|
||||
federation_strict_allowlist -> Bool,
|
||||
federation_http_fetch_retry_limit -> Int4,
|
||||
federation_worker_count -> Int4,
|
||||
email_enabled -> Bool,
|
||||
email_smtp_server -> Nullable<Text>,
|
||||
email_smtp_login -> Nullable<Text>,
|
||||
email_smtp_password -> Nullable<Text>,
|
||||
email_smtp_from_address -> Nullable<Text>,
|
||||
email_tls_type -> Text,
|
||||
captcha_enabled -> Bool,
|
||||
captcha_difficulty -> Text,
|
||||
published -> Timestamp,
|
||||
|
@ -718,6 +700,27 @@ table! {
|
|||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
local_site_rate_limit(id) {
|
||||
id -> Int4,
|
||||
local_site_id -> Int4,
|
||||
message -> Int4,
|
||||
message_per_second-> Int4,
|
||||
post -> Int4,
|
||||
post_per_second -> Int4,
|
||||
register -> Int4,
|
||||
register_per_second -> Int4,
|
||||
image -> Int4,
|
||||
image_per_second -> Int4,
|
||||
comment -> Int4,
|
||||
comment_per_second -> Int4,
|
||||
search -> Int4,
|
||||
search_per_second -> Int4,
|
||||
published -> Timestamp,
|
||||
updated -> Nullable<Timestamp>,
|
||||
}
|
||||
}
|
||||
|
||||
joinable!(person_block -> person (person_id));
|
||||
|
||||
joinable!(comment -> person (creator_id));
|
||||
|
@ -797,9 +800,10 @@ joinable!(admin_purge_post -> person (admin_person_id));
|
|||
joinable!(site -> instance (instance_id));
|
||||
joinable!(person -> instance (instance_id));
|
||||
joinable!(community -> instance (instance_id));
|
||||
joinable!(allowlist -> instance (instance_id));
|
||||
joinable!(blocklist -> instance (instance_id));
|
||||
joinable!(federation_allowlist -> instance (instance_id));
|
||||
joinable!(federation_blocklist -> instance (instance_id));
|
||||
joinable!(local_site -> site (site_id));
|
||||
joinable!(local_site_rate_limit -> local_site (local_site_id));
|
||||
|
||||
allow_tables_to_appear_in_same_query!(
|
||||
activity,
|
||||
|
@ -855,7 +859,8 @@ allow_tables_to_appear_in_same_query!(
|
|||
site_language,
|
||||
community_language,
|
||||
instance,
|
||||
allowlist,
|
||||
blocklist,
|
||||
federation_allowlist,
|
||||
federation_blocklist,
|
||||
local_site,
|
||||
local_site_rate_limit,
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{newtypes::InstanceId, schema::allowlist};
|
||||
use crate::{newtypes::InstanceId, schema::federation_allowlist};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
|
||||
|
@ -8,8 +8,8 @@ use std::fmt::Debug;
|
|||
feature = "full",
|
||||
diesel(belongs_to(crate::source::instance::Instance))
|
||||
)]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = allowlist))]
|
||||
pub struct AllowList {
|
||||
#[cfg_attr(feature = "full", diesel(table_name = federation_allowlist))]
|
||||
pub struct FederationAllowList {
|
||||
pub id: i32,
|
||||
pub instance_id: InstanceId,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
|
@ -18,8 +18,8 @@ pub struct AllowList {
|
|||
|
||||
#[derive(Clone, Default)]
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = allowlist))]
|
||||
pub struct AllowListForm {
|
||||
#[cfg_attr(feature = "full", diesel(table_name = federation_allowlist))]
|
||||
pub struct FederationAllowListForm {
|
||||
pub instance_id: InstanceId,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{newtypes::InstanceId, schema::blocklist};
|
||||
use crate::{newtypes::InstanceId, schema::federation_blocklist};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
|
||||
|
@ -8,8 +8,8 @@ use std::fmt::Debug;
|
|||
feature = "full",
|
||||
diesel(belongs_to(crate::source::instance::Instance))
|
||||
)]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = blocklist))]
|
||||
pub struct BlockList {
|
||||
#[cfg_attr(feature = "full", diesel(table_name = federation_blocklist))]
|
||||
pub struct FederationBlockList {
|
||||
pub id: i32,
|
||||
pub instance_id: InstanceId,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
|
@ -18,8 +18,8 @@ pub struct BlockList {
|
|||
|
||||
#[derive(Clone, Default)]
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = blocklist))]
|
||||
pub struct BlockListForm {
|
||||
#[cfg_attr(feature = "full", diesel(table_name = federation_blocklist))]
|
||||
pub struct FederationBlockListForm {
|
||||
pub instance_id: InstanceId,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
}
|
|
@ -28,29 +28,11 @@ pub struct LocalSite {
|
|||
pub application_email_admins: bool,
|
||||
pub slur_filter_regex: Option<String>,
|
||||
pub actor_name_max_length: i32,
|
||||
pub rate_limit_message: i32,
|
||||
pub rate_limit_message_per_second: i32,
|
||||
pub rate_limit_post: i32,
|
||||
pub rate_limit_post_per_second: i32,
|
||||
pub rate_limit_register: i32,
|
||||
pub rate_limit_register_per_second: i32,
|
||||
pub rate_limit_image: i32,
|
||||
pub rate_limit_image_per_second: i32,
|
||||
pub rate_limit_comment: i32,
|
||||
pub rate_limit_comment_per_second: i32,
|
||||
pub rate_limit_search: i32,
|
||||
pub rate_limit_search_per_second: i32,
|
||||
pub federation_enabled: bool,
|
||||
pub federation_debug: bool,
|
||||
pub federation_strict_allowlist: bool,
|
||||
pub federation_http_fetch_retry_limit: i32,
|
||||
pub federation_worker_count: i32,
|
||||
pub email_enabled: bool,
|
||||
pub email_smtp_server: Option<String>,
|
||||
pub email_smtp_login: Option<String>,
|
||||
pub email_smtp_password: Option<String>,
|
||||
pub email_smtp_from_address: Option<String>,
|
||||
pub email_tls_type: String,
|
||||
pub captcha_enabled: bool,
|
||||
pub captcha_difficulty: String,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
|
@ -80,29 +62,11 @@ pub struct LocalSiteInsertForm {
|
|||
pub application_email_admins: Option<bool>,
|
||||
pub slur_filter_regex: Option<String>,
|
||||
pub actor_name_max_length: Option<i32>,
|
||||
pub rate_limit_message: Option<i32>,
|
||||
pub rate_limit_message_per_second: Option<i32>,
|
||||
pub rate_limit_post: Option<i32>,
|
||||
pub rate_limit_post_per_second: Option<i32>,
|
||||
pub rate_limit_register: Option<i32>,
|
||||
pub rate_limit_register_per_second: Option<i32>,
|
||||
pub rate_limit_image: Option<i32>,
|
||||
pub rate_limit_image_per_second: Option<i32>,
|
||||
pub rate_limit_comment: Option<i32>,
|
||||
pub rate_limit_comment_per_second: Option<i32>,
|
||||
pub rate_limit_search: Option<i32>,
|
||||
pub rate_limit_search_per_second: Option<i32>,
|
||||
pub federation_enabled: Option<bool>,
|
||||
pub federation_debug: Option<bool>,
|
||||
pub federation_strict_allowlist: Option<bool>,
|
||||
pub federation_http_fetch_retry_limit: Option<i32>,
|
||||
pub federation_worker_count: Option<i32>,
|
||||
pub email_enabled: Option<bool>,
|
||||
pub email_smtp_server: Option<String>,
|
||||
pub email_smtp_login: Option<String>,
|
||||
pub email_smtp_password: Option<String>,
|
||||
pub email_smtp_from_address: Option<String>,
|
||||
pub email_tls_type: Option<String>,
|
||||
pub captcha_enabled: Option<bool>,
|
||||
pub captcha_difficulty: Option<String>,
|
||||
}
|
||||
|
@ -128,29 +92,11 @@ pub struct LocalSiteUpdateForm {
|
|||
pub application_email_admins: Option<bool>,
|
||||
pub slur_filter_regex: Option<Option<String>>,
|
||||
pub actor_name_max_length: Option<i32>,
|
||||
pub rate_limit_message: Option<i32>,
|
||||
pub rate_limit_message_per_second: Option<i32>,
|
||||
pub rate_limit_post: Option<i32>,
|
||||
pub rate_limit_post_per_second: Option<i32>,
|
||||
pub rate_limit_register: Option<i32>,
|
||||
pub rate_limit_register_per_second: Option<i32>,
|
||||
pub rate_limit_image: Option<i32>,
|
||||
pub rate_limit_image_per_second: Option<i32>,
|
||||
pub rate_limit_comment: Option<i32>,
|
||||
pub rate_limit_comment_per_second: Option<i32>,
|
||||
pub rate_limit_search: Option<i32>,
|
||||
pub rate_limit_search_per_second: Option<i32>,
|
||||
pub federation_enabled: Option<bool>,
|
||||
pub federation_debug: Option<bool>,
|
||||
pub federation_strict_allowlist: Option<bool>,
|
||||
pub federation_http_fetch_retry_limit: Option<i32>,
|
||||
pub federation_worker_count: Option<i32>,
|
||||
pub email_enabled: Option<bool>,
|
||||
pub email_smtp_server: Option<Option<String>>,
|
||||
pub email_smtp_login: Option<Option<String>>,
|
||||
pub email_smtp_password: Option<Option<String>>,
|
||||
pub email_smtp_from_address: Option<Option<String>>,
|
||||
pub email_tls_type: Option<String>,
|
||||
pub captcha_enabled: Option<bool>,
|
||||
pub captcha_difficulty: Option<String>,
|
||||
pub updated: Option<Option<chrono::NaiveDateTime>>,
|
||||
|
|
73
crates/db_schema/src/source/local_site_rate_limit.rs
Normal file
73
crates/db_schema/src/source/local_site_rate_limit.rs
Normal file
|
@ -0,0 +1,73 @@
|
|||
use crate::newtypes::LocalSiteId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typed_builder::TypedBuilder;
|
||||
|
||||
#[cfg(feature = "full")]
|
||||
use crate::schema::local_site_rate_limit;
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = local_site_rate_limit))]
|
||||
#[cfg_attr(
|
||||
feature = "full",
|
||||
diesel(belongs_to(crate::source::local_site::LocalSite))
|
||||
)]
|
||||
pub struct LocalSiteRateLimit {
|
||||
pub id: i32,
|
||||
pub local_site_id: LocalSiteId,
|
||||
pub message: i32,
|
||||
pub message_per_second: i32,
|
||||
pub post: i32,
|
||||
pub post_per_second: i32,
|
||||
pub register: i32,
|
||||
pub register_per_second: i32,
|
||||
pub image: i32,
|
||||
pub image_per_second: i32,
|
||||
pub comment: i32,
|
||||
pub comment_per_second: i32,
|
||||
pub search: i32,
|
||||
pub search_per_second: i32,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
}
|
||||
|
||||
#[derive(Clone, TypedBuilder)]
|
||||
#[builder(field_defaults(default))]
|
||||
#[cfg_attr(feature = "full", derive(Insertable))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = local_site_rate_limit))]
|
||||
pub struct LocalSiteRateLimitInsertForm {
|
||||
#[builder(!default)]
|
||||
pub local_site_id: LocalSiteId,
|
||||
pub message: Option<i32>,
|
||||
pub message_per_second: Option<i32>,
|
||||
pub post: Option<i32>,
|
||||
pub post_per_second: Option<i32>,
|
||||
pub register: Option<i32>,
|
||||
pub register_per_second: Option<i32>,
|
||||
pub image: Option<i32>,
|
||||
pub image_per_second: Option<i32>,
|
||||
pub comment: Option<i32>,
|
||||
pub comment_per_second: Option<i32>,
|
||||
pub search: Option<i32>,
|
||||
pub search_per_second: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Clone, TypedBuilder)]
|
||||
#[builder(field_defaults(default))]
|
||||
#[cfg_attr(feature = "full", derive(AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = local_site_rate_limit))]
|
||||
pub struct LocalSiteRateLimitUpdateForm {
|
||||
pub message: Option<i32>,
|
||||
pub message_per_second: Option<i32>,
|
||||
pub post: Option<i32>,
|
||||
pub post_per_second: Option<i32>,
|
||||
pub register: Option<i32>,
|
||||
pub register_per_second: Option<i32>,
|
||||
pub image: Option<i32>,
|
||||
pub image_per_second: Option<i32>,
|
||||
pub comment: Option<i32>,
|
||||
pub comment_per_second: Option<i32>,
|
||||
pub search: Option<i32>,
|
||||
pub search_per_second: Option<i32>,
|
||||
pub updated: Option<Option<chrono::NaiveDateTime>>,
|
||||
}
|
|
@ -1,17 +1,18 @@
|
|||
#[cfg(feature = "full")]
|
||||
pub mod activity;
|
||||
pub mod actor_language;
|
||||
pub mod allowlist;
|
||||
pub mod blocklist;
|
||||
pub mod comment;
|
||||
pub mod comment_reply;
|
||||
pub mod comment_report;
|
||||
pub mod community;
|
||||
pub mod community_block;
|
||||
pub mod email_verification;
|
||||
pub mod federation_allowlist;
|
||||
pub mod federation_blocklist;
|
||||
pub mod instance;
|
||||
pub mod language;
|
||||
pub mod local_site;
|
||||
pub mod local_site_rate_limit;
|
||||
pub mod local_user;
|
||||
pub mod moderator;
|
||||
pub mod password_reset_request;
|
||||
|
|
|
@ -34,7 +34,6 @@ pub struct SiteInsertForm {
|
|||
pub name: String,
|
||||
pub sidebar: Option<String>,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
// when you want to null out a column, you have to send Some(None)), since sending None means you just don't want to update that column.
|
||||
pub icon: Option<DbUrl>,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub description: Option<String>,
|
||||
|
|
|
@ -11,6 +11,7 @@ pub trait Crud {
|
|||
fn read(conn: &mut PgConnection, id: Self::IdType) -> Result<Self, Error>
|
||||
where
|
||||
Self: Sized;
|
||||
/// when you want to null out a column, you have to send Some(None)), since sending None means you just don't want to update that column.
|
||||
fn update(
|
||||
conn: &mut PgConnection,
|
||||
id: Self::IdType,
|
||||
|
|
|
@ -2,26 +2,31 @@ use crate::structs::SiteView;
|
|||
use diesel::{result::Error, *};
|
||||
use lemmy_db_schema::{
|
||||
aggregates::structs::SiteAggregates,
|
||||
schema::{local_site, site, site_aggregates},
|
||||
source::{local_site::LocalSite, site::Site},
|
||||
schema::{local_site, local_site_rate_limit, site, site_aggregates},
|
||||
source::{local_site::LocalSite, local_site_rate_limit::LocalSiteRateLimit, site::Site},
|
||||
};
|
||||
|
||||
impl SiteView {
|
||||
pub fn read_local(conn: &mut PgConnection) -> Result<Self, Error> {
|
||||
let (mut site, local_site, counts) = site::table
|
||||
let (mut site, local_site, local_site_rate_limit, counts) = site::table
|
||||
.inner_join(local_site::table)
|
||||
.inner_join(
|
||||
local_site_rate_limit::table.on(local_site::id.eq(local_site_rate_limit::local_site_id)),
|
||||
)
|
||||
.inner_join(site_aggregates::table)
|
||||
.select((
|
||||
site::all_columns,
|
||||
local_site::all_columns,
|
||||
local_site_rate_limit::all_columns,
|
||||
site_aggregates::all_columns,
|
||||
))
|
||||
.first::<(Site, LocalSite, SiteAggregates)>(conn)?;
|
||||
.first::<(Site, LocalSite, LocalSiteRateLimit, SiteAggregates)>(conn)?;
|
||||
|
||||
site.private_key = None;
|
||||
Ok(SiteView {
|
||||
site,
|
||||
local_site,
|
||||
local_site_rate_limit,
|
||||
counts,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use lemmy_db_schema::{
|
|||
community::CommunitySafe,
|
||||
language::Language,
|
||||
local_site::LocalSite,
|
||||
local_site_rate_limit::LocalSiteRateLimit,
|
||||
local_user::{LocalUser, LocalUserSettings},
|
||||
person::{Person, PersonSafe},
|
||||
post::Post,
|
||||
|
@ -117,6 +118,7 @@ pub struct RegistrationApplicationView {
|
|||
pub struct SiteView {
|
||||
pub site: Site,
|
||||
pub local_site: LocalSite,
|
||||
pub local_site_rate_limit: LocalSiteRateLimit,
|
||||
pub counts: SiteAggregates,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::error::LemmyError;
|
||||
use crate::{error::LemmyError, settings::structs::Settings};
|
||||
use html2text;
|
||||
use lettre::{
|
||||
message::{Mailbox, MultiPart},
|
||||
|
@ -8,7 +8,6 @@ use lettre::{
|
|||
SmtpTransport,
|
||||
Transport,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -16,33 +15,21 @@ pub mod translations {
|
|||
rosetta_i18n::include_translations!();
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct EmailConfig {
|
||||
/// Hostname and port of the smtp server
|
||||
/// example = "localhost:25"
|
||||
pub smtp_server: String,
|
||||
/// Login name for smtp server
|
||||
pub smtp_login: Option<String>,
|
||||
/// Password to login to the smtp server
|
||||
pub smtp_password: Option<String>,
|
||||
/// example = "noreply@example.com"
|
||||
/// Address to send emails from, eg "noreply@your-instance.com"
|
||||
pub smtp_from_address: Option<String>,
|
||||
/// Whether or not smtp connections should use tls. Can be none, tls, or starttls
|
||||
/// example = "none"
|
||||
pub tls_type: String,
|
||||
}
|
||||
|
||||
pub fn send_email(
|
||||
subject: &str,
|
||||
to_email: &str,
|
||||
to_username: &str,
|
||||
html: &str,
|
||||
hostname: &str,
|
||||
config: &EmailConfig,
|
||||
settings: &Settings,
|
||||
) -> Result<(), LemmyError> {
|
||||
let email_config = settings
|
||||
.email
|
||||
.to_owned()
|
||||
.ok_or_else(|| LemmyError::from_message("no_email_setup"))?;
|
||||
let domain = settings.hostname.to_owned();
|
||||
|
||||
let (smtp_server, smtp_port) = {
|
||||
let email_and_port = config.smtp_server.split(':').collect::<Vec<&str>>();
|
||||
let email_and_port = email_config.smtp_server.split(':').collect::<Vec<&str>>();
|
||||
if email_and_port.len() == 1 {
|
||||
return Err(LemmyError::from_message(
|
||||
"email.smtp_server needs a port, IE smtp.xxx.com:465",
|
||||
|
@ -62,10 +49,8 @@ pub fn send_email(
|
|||
|
||||
let email = Message::builder()
|
||||
.from(
|
||||
config
|
||||
email_config
|
||||
.smtp_from_address
|
||||
.as_ref()
|
||||
.expect("email from address isn't valid")
|
||||
.parse()
|
||||
.expect("email from address isn't valid"),
|
||||
)
|
||||
|
@ -73,7 +58,7 @@ pub fn send_email(
|
|||
Some(to_username.to_string()),
|
||||
Address::from_str(to_email).expect("email to address isn't valid"),
|
||||
))
|
||||
.message_id(Some(format!("{}@{}", Uuid::new_v4(), hostname)))
|
||||
.message_id(Some(format!("{}@{}", Uuid::new_v4(), settings.hostname)))
|
||||
.subject(subject)
|
||||
.multipart(MultiPart::alternative_plain_html(
|
||||
plain_text,
|
||||
|
@ -87,23 +72,18 @@ pub fn send_email(
|
|||
// Set the TLS
|
||||
let builder_dangerous = SmtpTransport::builder_dangerous(smtp_server).port(smtp_port);
|
||||
|
||||
let mut builder = match config.tls_type.as_str() {
|
||||
let mut builder = match email_config.tls_type.as_str() {
|
||||
"starttls" => SmtpTransport::starttls_relay(smtp_server)?,
|
||||
"tls" => SmtpTransport::relay(smtp_server)?,
|
||||
_ => builder_dangerous,
|
||||
};
|
||||
|
||||
// Set the creds if they exist
|
||||
if let (Some(username), Some(password)) = (
|
||||
config.smtp_login.to_owned(),
|
||||
config.smtp_password.to_owned(),
|
||||
) {
|
||||
if let (Some(username), Some(password)) = (email_config.smtp_login, email_config.smtp_password) {
|
||||
builder = builder.credentials(Credentials::new(username, password));
|
||||
}
|
||||
|
||||
let mailer = builder
|
||||
.hello_name(ClientId::Domain(hostname.to_owned()))
|
||||
.build();
|
||||
let mailer = builder.hello_name(ClientId::Domain(domain)).build();
|
||||
|
||||
let result = mailer.send(&email);
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@ pub struct Settings {
|
|||
#[default(Some(Default::default()))]
|
||||
pub(crate) pictrs: Option<PictrsConfig>,
|
||||
/// Email sending configuration. All options except login/password are mandatory
|
||||
#[default(None)]
|
||||
#[doku(example = "Some(Default::default())")]
|
||||
pub email: Option<EmailConfig>,
|
||||
/// Parameters for automatic configuration of new instance (only used at first start)
|
||||
#[default(None)]
|
||||
#[doku(example = "Some(Default::default())")]
|
||||
|
@ -21,7 +24,7 @@ pub struct Settings {
|
|||
/// the domain name of your instance (mandatory)
|
||||
#[default("unset")]
|
||||
#[doku(example = "example.com")]
|
||||
pub hostname: String, // TODO this is duplicated in the instance / local_site table now tho?
|
||||
pub hostname: String,
|
||||
/// Address where lemmy should listen for incoming requests
|
||||
#[default(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)))]
|
||||
#[doku(as = "String")]
|
||||
|
@ -74,6 +77,24 @@ pub struct DatabaseConfig {
|
|||
pub pool_size: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, Document, SmartDefault)]
|
||||
pub struct EmailConfig {
|
||||
/// Hostname and port of the smtp server
|
||||
#[doku(example = "localhost:25")]
|
||||
pub smtp_server: String,
|
||||
/// Login name for smtp server
|
||||
pub smtp_login: Option<String>,
|
||||
/// Password to login to the smtp server
|
||||
pub smtp_password: Option<String>,
|
||||
#[doku(example = "noreply@example.com")]
|
||||
/// Address to send emails from, eg "noreply@your-instance.com"
|
||||
pub smtp_from_address: String,
|
||||
/// Whether or not smtp connections should use tls. Can be none, tls, or starttls
|
||||
#[default("none")]
|
||||
#[doku(example = "none")]
|
||||
pub tls_type: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)]
|
||||
pub struct SetupConfig {
|
||||
/// Username for the admin user
|
||||
|
|
|
@ -8,20 +8,13 @@ use lemmy_api_common::{
|
|||
community::CommunityResponse,
|
||||
post::PostResponse,
|
||||
private_message::PrivateMessageResponse,
|
||||
utils::{
|
||||
blocking,
|
||||
check_person_block,
|
||||
get_interface_language,
|
||||
local_site_to_email_config,
|
||||
send_email_to_user,
|
||||
},
|
||||
utils::{blocking, check_person_block, get_interface_language, send_email_to_user},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId, PrivateMessageId},
|
||||
source::{
|
||||
comment::Comment,
|
||||
comment_reply::{CommentReply, CommentReplyInsertForm},
|
||||
local_site::LocalSite,
|
||||
person::Person,
|
||||
person_mention::{PersonMention, PersonMentionInsertForm},
|
||||
post::Post,
|
||||
|
@ -181,19 +174,16 @@ pub async fn send_local_notifs(
|
|||
comment: &Comment,
|
||||
person: &Person,
|
||||
post: &Post,
|
||||
local_site: &LocalSite,
|
||||
do_send_email: bool,
|
||||
context: &LemmyContext,
|
||||
) -> Result<Vec<LocalUserId>, LemmyError> {
|
||||
let mut recipient_ids = Vec::new();
|
||||
let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname());
|
||||
|
||||
let hostname = &context.settings().hostname;
|
||||
|
||||
// Send the local mentions
|
||||
for mention in mentions
|
||||
.iter()
|
||||
.filter(|m| m.is_local(hostname) && m.name.ne(&person.name))
|
||||
.filter(|m| m.is_local(&context.settings().hostname) && m.name.ne(&person.name))
|
||||
.collect::<Vec<&MentionData>>()
|
||||
{
|
||||
let mention_name = mention.name.clone();
|
||||
|
@ -201,7 +191,6 @@ pub async fn send_local_notifs(
|
|||
LocalUserView::read_from_name(conn, &mention_name)
|
||||
})
|
||||
.await?;
|
||||
let hostname = &context.settings().hostname;
|
||||
if let Ok(mention_user_view) = user_view {
|
||||
// TODO
|
||||
// At some point, make it so you can't tag the parent creator either
|
||||
|
@ -229,8 +218,7 @@ pub async fn send_local_notifs(
|
|||
&mention_user_view,
|
||||
&lang.notification_mentioned_by_subject(&person.name),
|
||||
&lang.notification_mentioned_by_body(&comment.content, &inbox_link, &person.name),
|
||||
hostname,
|
||||
&local_site_to_email_config(local_site)?,
|
||||
context.settings(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -280,8 +268,7 @@ pub async fn send_local_notifs(
|
|||
&parent_user_view,
|
||||
&lang.notification_comment_reply_subject(&person.name),
|
||||
&lang.notification_comment_reply_body(&comment.content, &inbox_link, &person.name),
|
||||
hostname,
|
||||
&local_site_to_email_config(local_site)?,
|
||||
context.settings(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -322,8 +309,7 @@ pub async fn send_local_notifs(
|
|||
&parent_user_view,
|
||||
&lang.notification_post_reply_subject(&person.name),
|
||||
&lang.notification_post_reply_body(&comment.content, &inbox_link, &person.name),
|
||||
hostname,
|
||||
&local_site_to_email_config(local_site)?,
|
||||
context.settings(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,8 @@ alter table site drop column instance_id;
|
|||
alter table person drop column instance_id;
|
||||
alter table community drop column instance_id;
|
||||
|
||||
drop table local_site_rate_limit;
|
||||
drop table local_site;
|
||||
drop table allowlist;
|
||||
drop table blocklist;
|
||||
drop table federation_allowlist;
|
||||
drop table federation_blocklist;
|
||||
drop table instance;
|
||||
|
|
|
@ -48,14 +48,14 @@ alter table person alter column instance_id set not null;
|
|||
alter table community alter column instance_id set not null;
|
||||
|
||||
-- Create allowlist and blocklist tables
|
||||
create table allowlist (
|
||||
create table federation_allowlist (
|
||||
id serial primary key,
|
||||
instance_id int references instance on update cascade on delete cascade not null unique,
|
||||
published timestamp not null default now(),
|
||||
updated timestamp null
|
||||
);
|
||||
|
||||
create table blocklist (
|
||||
create table federation_blocklist (
|
||||
id serial primary key,
|
||||
instance_id int references instance on update cascade on delete cascade not null unique,
|
||||
published timestamp not null default now(),
|
||||
|
@ -87,29 +87,11 @@ create table local_site (
|
|||
-- Fields from lemmy.hjson
|
||||
slur_filter_regex text,
|
||||
actor_name_max_length int default 20 not null,
|
||||
rate_limit_message int default 180 not null,
|
||||
rate_limit_message_per_second int default 60 not null,
|
||||
rate_limit_post int default 6 not null,
|
||||
rate_limit_post_per_second int default 600 not null,
|
||||
rate_limit_register int default 3 not null,
|
||||
rate_limit_register_per_second int default 3600 not null,
|
||||
rate_limit_image int default 6 not null,
|
||||
rate_limit_image_per_second int default 3600 not null,
|
||||
rate_limit_comment int default 6 not null,
|
||||
rate_limit_comment_per_second int default 600 not null,
|
||||
rate_limit_search int default 60 not null,
|
||||
rate_limit_search_per_second int default 600 not null,
|
||||
federation_enabled boolean default true not null,
|
||||
federation_debug boolean default false not null,
|
||||
federation_strict_allowlist boolean default true not null,
|
||||
federation_http_fetch_retry_limit int default 25 not null,
|
||||
federation_worker_count int default 64 not null,
|
||||
email_enabled boolean default false not null,
|
||||
email_smtp_server varchar(255),
|
||||
email_smtp_login varchar(255),
|
||||
email_smtp_password varchar(255),
|
||||
email_smtp_from_address varchar(255),
|
||||
email_tls_type varchar(255) default 'none' not null,
|
||||
captcha_enabled boolean default false not null,
|
||||
captcha_difficulty varchar(255) default 'medium' not null,
|
||||
|
||||
|
@ -118,6 +100,26 @@ create table local_site (
|
|||
updated timestamp without time zone
|
||||
);
|
||||
|
||||
-- local_site_rate_limit is its own table, so as to not go over 32 columns, and force diesel to use the 64-column-tables feature
|
||||
create table local_site_rate_limit (
|
||||
id serial primary key,
|
||||
local_site_id int references local_site on update cascade on delete cascade not null unique,
|
||||
message int default 180 not null,
|
||||
message_per_second int default 60 not null,
|
||||
post int default 6 not null,
|
||||
post_per_second int default 600 not null,
|
||||
register int default 3 not null,
|
||||
register_per_second int default 3600 not null,
|
||||
image int default 6 not null,
|
||||
image_per_second int default 3600 not null,
|
||||
comment int default 6 not null,
|
||||
comment_per_second int default 600 not null,
|
||||
search int default 60 not null,
|
||||
search_per_second int default 600 not null,
|
||||
published timestamp without time zone default now() not null,
|
||||
updated timestamp without time zone
|
||||
);
|
||||
|
||||
-- Insert the data into local_site
|
||||
insert into local_site (
|
||||
site_id,
|
||||
|
@ -159,6 +161,13 @@ select
|
|||
from site
|
||||
order by id limit 1;
|
||||
|
||||
-- Default here
|
||||
insert into local_site_rate_limit (
|
||||
local_site_id
|
||||
)
|
||||
select id from local_site
|
||||
order by id limit 1;
|
||||
|
||||
-- Drop all those columns from site
|
||||
alter table site
|
||||
drop column enable_downvotes,
|
||||
|
|
|
@ -19,6 +19,7 @@ use lemmy_db_schema::{
|
|||
community::{Community, CommunityUpdateForm},
|
||||
instance::{Instance, InstanceForm},
|
||||
local_site::{LocalSite, LocalSiteInsertForm},
|
||||
local_site_rate_limit::{LocalSiteRateLimit, LocalSiteRateLimitInsertForm},
|
||||
local_user::{LocalUser, LocalUserInsertForm},
|
||||
person::{Person, PersonInsertForm, PersonUpdateForm},
|
||||
post::{Post, PostUpdateForm},
|
||||
|
@ -458,7 +459,13 @@ fn initialize_local_site_2022_10_10(
|
|||
.site_id(site.id)
|
||||
.site_setup(Some(settings.setup.is_some()))
|
||||
.build();
|
||||
LocalSite::create(conn, &local_site_form)?;
|
||||
let local_site = LocalSite::create(conn, &local_site_form)?;
|
||||
|
||||
// Create the rate limit table
|
||||
let local_site_rate_limit_form = LocalSiteRateLimitInsertForm::builder()
|
||||
.local_site_id(local_site.id)
|
||||
.build();
|
||||
LocalSiteRateLimit::create(conn, &local_site_rate_limit_form)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
22
src/main.rs
22
src/main.rs
|
@ -12,18 +12,16 @@ use diesel_migrations::EmbeddedMigrations;
|
|||
use doku::json::{AutoComments, Formatting};
|
||||
use lemmy_api::match_websocket_operation;
|
||||
use lemmy_api_common::{
|
||||
lemmy_db_views::structs::SiteView,
|
||||
request::build_user_agent,
|
||||
utils::{
|
||||
blocking,
|
||||
check_private_instance_and_federation_enabled,
|
||||
local_site_to_rate_limit_config,
|
||||
local_site_rate_limit_to_rate_limit_config,
|
||||
},
|
||||
};
|
||||
use lemmy_api_crud::match_websocket_operation_crud;
|
||||
use lemmy_db_schema::{
|
||||
source::{local_site::LocalSite, secret::Secret},
|
||||
utils::get_database_url_from_env,
|
||||
};
|
||||
use lemmy_db_schema::{source::secret::Secret, utils::get_database_url_from_env};
|
||||
use lemmy_routes::{feeds, images, nodeinfo, webfinger};
|
||||
use lemmy_server::{
|
||||
api_routes,
|
||||
|
@ -105,7 +103,8 @@ async fn main() -> Result<(), LemmyError> {
|
|||
let secret = Secret::init(conn).expect("Couldn't initialize secrets.");
|
||||
|
||||
// Make sure the local site is set up.
|
||||
let local_site = LocalSite::read(conn).expect("local site not set up");
|
||||
let site_view = SiteView::read_local(conn).expect("local site not set up");
|
||||
let local_site = site_view.local_site;
|
||||
let federation_enabled = local_site.federation_enabled;
|
||||
|
||||
if federation_enabled {
|
||||
|
@ -115,7 +114,8 @@ async fn main() -> Result<(), LemmyError> {
|
|||
check_private_instance_and_federation_enabled(&local_site)?;
|
||||
|
||||
// Set up the rate limiter
|
||||
let rate_limit_config = local_site_to_rate_limit_config(&local_site);
|
||||
let rate_limit_config =
|
||||
local_site_rate_limit_to_rate_limit_config(&site_view.local_site_rate_limit);
|
||||
let rate_limiter = RateLimit {
|
||||
rate_limiter: Arc::new(Mutex::new(RateLimiter::default())),
|
||||
rate_limit_config,
|
||||
|
@ -179,17 +179,13 @@ async fn main() -> Result<(), LemmyError> {
|
|||
.configure(|cfg| api_routes::config(cfg, &rate_limiter))
|
||||
.configure(|cfg| {
|
||||
if federation_enabled {
|
||||
lemmy_apub::http::routes::config(cfg)
|
||||
lemmy_apub::http::routes::config(cfg);
|
||||
webfinger::config(cfg);
|
||||
}
|
||||
})
|
||||
.configure(feeds::config)
|
||||
.configure(|cfg| images::config(cfg, pictrs_client.clone(), &rate_limiter))
|
||||
.configure(nodeinfo::config)
|
||||
.configure(|cfg| {
|
||||
if federation_enabled {
|
||||
webfinger::config(cfg)
|
||||
}
|
||||
})
|
||||
})
|
||||
.bind((settings_bind.bind, settings_bind.port))?
|
||||
.run()
|
||||
|
|
Loading…
Reference in a new issue