mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-30 09:02:24 +00:00
Merge remote-tracking branch 'origin/main' into content_removal_remote_users
This commit is contained in:
commit
8cc80703d8
|
@ -18,7 +18,7 @@ doctest = false
|
|||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
lemmy_utils = { workspace = true, features = ["default"] }
|
||||
lemmy_utils = { workspace = true }
|
||||
lemmy_db_schema = { workspace = true, features = ["full"] }
|
||||
lemmy_db_views = { workspace = true, features = ["full"] }
|
||||
lemmy_db_views_moderator = { workspace = true, features = ["full"] }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::check_totp_2fa_valid;
|
||||
use crate::{check_totp_2fa_valid, local_user::check_email_verified};
|
||||
use actix_web::{
|
||||
web::{Data, Json},
|
||||
HttpRequest,
|
||||
|
@ -43,15 +43,7 @@ pub async fn login(
|
|||
Err(LemmyErrorType::IncorrectLogin)?
|
||||
}
|
||||
check_user_valid(&local_user_view.person)?;
|
||||
|
||||
// Check if the user's email is verified if email verification is turned on
|
||||
// However, skip checking verification if the user is an admin
|
||||
if !local_user_view.local_user.admin
|
||||
&& site_view.local_site.require_email_verification
|
||||
&& !local_user_view.local_user.email_verified
|
||||
{
|
||||
Err(LemmyErrorType::EmailNotVerified)?
|
||||
}
|
||||
check_email_verified(&local_user_view, &site_view)?;
|
||||
|
||||
check_registration_application(&local_user_view, &site_view.local_site, &mut context.pool())
|
||||
.await?;
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
||||
|
||||
pub mod add_admin;
|
||||
pub mod ban_person;
|
||||
pub mod block;
|
||||
|
@ -16,3 +19,15 @@ pub mod save_settings;
|
|||
pub mod update_totp;
|
||||
pub mod validate_auth;
|
||||
pub mod verify_email;
|
||||
|
||||
/// Check if the user's email is verified if email verification is turned on
|
||||
/// However, skip checking verification if the user is an admin
|
||||
fn check_email_verified(local_user_view: &LocalUserView, site_view: &SiteView) -> LemmyResult<()> {
|
||||
if !local_user_view.local_user.admin
|
||||
&& site_view.local_site.require_email_verification
|
||||
&& !local_user_view.local_user.email_verified
|
||||
{
|
||||
Err(LemmyErrorType::EmailNotVerified)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::local_user::check_email_verified;
|
||||
use actix_web::web::{Data, Json};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
|
@ -6,7 +7,7 @@ use lemmy_api_common::{
|
|||
SuccessResponse,
|
||||
};
|
||||
use lemmy_db_schema::source::password_reset_request::PasswordResetRequest;
|
||||
use lemmy_db_views::structs::LocalUserView;
|
||||
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
||||
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
|
||||
|
||||
#[tracing::instrument(skip(context))]
|
||||
|
@ -29,6 +30,8 @@ pub async fn reset_password(
|
|||
if recent_resets_count >= 3 {
|
||||
Err(LemmyErrorType::PasswordResetLimitReached)?
|
||||
}
|
||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||
check_email_verified(&local_user_view, &site_view)?;
|
||||
|
||||
// Email the pure token to the user.
|
||||
send_password_reset_email(&local_user_view, &mut context.pool(), context.settings()).await?;
|
||||
|
|
|
@ -23,7 +23,7 @@ full = [
|
|||
"lemmy_db_views/full",
|
||||
"lemmy_db_views_actor/full",
|
||||
"lemmy_db_views_moderator/full",
|
||||
"lemmy_utils/default",
|
||||
"lemmy_utils/full",
|
||||
"activitypub_federation",
|
||||
"encoding",
|
||||
"reqwest-middleware",
|
||||
|
@ -44,7 +44,7 @@ lemmy_db_views = { workspace = true }
|
|||
lemmy_db_views_moderator = { workspace = true }
|
||||
lemmy_db_views_actor = { workspace = true }
|
||||
lemmy_db_schema = { workspace = true }
|
||||
lemmy_utils = { workspace = true, features = ["error-type"] }
|
||||
lemmy_utils = { workspace = true }
|
||||
activitypub_federation = { workspace = true, optional = true }
|
||||
serde = { workspace = true }
|
||||
serde_with = { workspace = true }
|
||||
|
|
|
@ -13,7 +13,7 @@ repository.workspace = true
|
|||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
lemmy_utils = { workspace = true, features = ["default"] }
|
||||
lemmy_utils = { workspace = true, features = ["full"] }
|
||||
lemmy_db_schema = { workspace = true, features = ["full"] }
|
||||
lemmy_db_views = { workspace = true, features = ["full"] }
|
||||
lemmy_db_views_actor = { workspace = true, features = ["full"] }
|
||||
|
|
|
@ -18,7 +18,7 @@ doctest = false
|
|||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
lemmy_utils = { workspace = true, features = ["default"] }
|
||||
lemmy_utils = { workspace = true, features = ["full"] }
|
||||
lemmy_db_schema = { workspace = true, features = ["full"] }
|
||||
lemmy_db_views = { workspace = true, features = ["full"] }
|
||||
lemmy_db_views_actor = { workspace = true, features = ["full"] }
|
||||
|
|
|
@ -19,6 +19,6 @@ diesel = { workspace = true }
|
|||
diesel-async = { workspace = true }
|
||||
lemmy_db_schema = { workspace = true }
|
||||
lemmy_db_views = { workspace = true, features = ["full"] }
|
||||
lemmy_utils = { workspace = true, features = ["default"] }
|
||||
lemmy_utils = { workspace = true, features = ["full"] }
|
||||
tokio = { workspace = true }
|
||||
url = { workspace = true }
|
||||
|
|
|
@ -18,6 +18,7 @@ workspace = true
|
|||
|
||||
[features]
|
||||
full = [
|
||||
"lemmy_utils/full",
|
||||
"diesel",
|
||||
"diesel-derive-newtype",
|
||||
"diesel-derive-enum",
|
||||
|
@ -48,7 +49,7 @@ strum = { workspace = true }
|
|||
strum_macros = { workspace = true }
|
||||
serde_json = { workspace = true, optional = true }
|
||||
activitypub_federation = { workspace = true, optional = true }
|
||||
lemmy_utils = { workspace = true, optional = true, features = ["default"] }
|
||||
lemmy_utils = { workspace = true, optional = true }
|
||||
bcrypt = { workspace = true, optional = true }
|
||||
diesel = { workspace = true, features = [
|
||||
"postgres",
|
||||
|
|
|
@ -29,7 +29,7 @@ full = [
|
|||
|
||||
[dependencies]
|
||||
lemmy_db_schema = { workspace = true }
|
||||
lemmy_utils = { workspace = true, optional = true, features = ["default"] }
|
||||
lemmy_utils = { workspace = true, optional = true }
|
||||
diesel = { workspace = true, optional = true }
|
||||
diesel-async = { workspace = true, optional = true }
|
||||
diesel_ltree = { workspace = true, optional = true }
|
||||
|
|
|
@ -16,7 +16,7 @@ doctest = false
|
|||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
lemmy_utils = { workspace = true, features = ["default"] }
|
||||
lemmy_utils = { workspace = true, features = ["full"] }
|
||||
lemmy_db_views = { workspace = true }
|
||||
lemmy_db_views_actor = { workspace = true }
|
||||
lemmy_db_schema = { workspace = true }
|
||||
|
|
|
@ -16,23 +16,24 @@ doctest = false
|
|||
[[bin]]
|
||||
name = "lemmy_util_bin"
|
||||
path = "src/main.rs"
|
||||
required-features = ["default"]
|
||||
required-features = ["full"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[features]
|
||||
default = [
|
||||
"error-type",
|
||||
"dep:serde_json",
|
||||
"dep:anyhow",
|
||||
"dep:tracing-error",
|
||||
full = [
|
||||
"dep:ts-rs",
|
||||
"dep:diesel",
|
||||
"dep:http",
|
||||
"dep:rosetta-i18n",
|
||||
"dep:actix-web",
|
||||
"dep:reqwest-middleware",
|
||||
"dep:tracing",
|
||||
"dep:actix-web",
|
||||
"dep:serde_json",
|
||||
"dep:anyhow",
|
||||
"dep:tracing-error",
|
||||
"dep:http",
|
||||
"dep:deser-hjson",
|
||||
"dep:regex",
|
||||
"dep:urlencoding",
|
||||
|
@ -47,27 +48,23 @@ default = [
|
|||
"dep:html2text",
|
||||
"dep:lettre",
|
||||
"dep:uuid",
|
||||
"dep:rosetta-i18n",
|
||||
"dep:itertools",
|
||||
"dep:markdown-it",
|
||||
|
||||
]
|
||||
full = ["default", "dep:ts-rs"]
|
||||
error-type = ["dep:serde", "dep:strum"]
|
||||
|
||||
[dependencies]
|
||||
regex = { workspace = true, optional = true }
|
||||
tracing = { workspace = true, optional = true }
|
||||
tracing-error = { workspace = true, optional = true }
|
||||
itertools = { workspace = true, optional = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true, optional = true }
|
||||
once_cell = { workspace = true, optional = true }
|
||||
url = { workspace = true, optional = true }
|
||||
actix-web = { workspace = true, optional = true }
|
||||
anyhow = { workspace = true, optional = true }
|
||||
reqwest-middleware = { workspace = true, optional = true }
|
||||
strum = { workspace = true, optional = true }
|
||||
strum = { workspace = true }
|
||||
strum_macros = { workspace = true }
|
||||
futures = { workspace = true, optional = true }
|
||||
diesel = { workspace = true, features = ["chrono"], optional = true }
|
||||
|
|
|
@ -2,12 +2,10 @@ use cfg_if::cfg_if;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
use strum_macros::{Display, EnumIter};
|
||||
#[cfg(feature = "ts-rs")]
|
||||
use ts_rs::TS;
|
||||
|
||||
#[derive(Display, Debug, Serialize, Deserialize, Clone, PartialEq, Eq, EnumIter, Hash)]
|
||||
#[cfg_attr(feature = "ts-rs", derive(TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(export))]
|
||||
#[cfg_attr(feature = "full", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "full", ts(export))]
|
||||
#[serde(tag = "error", content = "message", rename_all = "snake_case")]
|
||||
#[non_exhaustive]
|
||||
// TODO: order these based on the crate they belong to (utils, federation, db, api)
|
||||
|
@ -168,7 +166,7 @@ pub enum LemmyErrorType {
|
|||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "default")] {
|
||||
if #[cfg(feature = "full")] {
|
||||
|
||||
use tracing_error::SpanTrace;
|
||||
use std::fmt;
|
||||
|
@ -276,52 +274,52 @@ cfg_if! {
|
|||
self.map_err(|e| e.inner)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#![allow(clippy::unwrap_used)]
|
||||
#![allow(clippy::indexing_slicing)]
|
||||
use super::*;
|
||||
use actix_web::{body::MessageBody, ResponseError};
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::fs::read_to_string;
|
||||
use strum::IntoEnumIterator;
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#![allow(clippy::unwrap_used)]
|
||||
#![allow(clippy::indexing_slicing)]
|
||||
use super::*;
|
||||
use actix_web::{body::MessageBody, ResponseError};
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::fs::read_to_string;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
#[test]
|
||||
fn deserializes_no_message() {
|
||||
let err = LemmyError::from(LemmyErrorType::Banned).error_response();
|
||||
let json = String::from_utf8(err.into_body().try_into_bytes().unwrap().to_vec()).unwrap();
|
||||
assert_eq!(&json, "{\"error\":\"banned\"}")
|
||||
}
|
||||
#[test]
|
||||
fn deserializes_no_message() {
|
||||
let err = LemmyError::from(LemmyErrorType::Banned).error_response();
|
||||
let json = String::from_utf8(err.into_body().try_into_bytes().unwrap().to_vec()).unwrap();
|
||||
assert_eq!(&json, "{\"error\":\"banned\"}")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserializes_with_message() {
|
||||
let reg_banned = LemmyErrorType::PersonIsBannedFromSite(String::from("reason"));
|
||||
let err = LemmyError::from(reg_banned).error_response();
|
||||
let json = String::from_utf8(err.into_body().try_into_bytes().unwrap().to_vec()).unwrap();
|
||||
assert_eq!(
|
||||
&json,
|
||||
"{\"error\":\"person_is_banned_from_site\",\"message\":\"reason\"}"
|
||||
)
|
||||
}
|
||||
#[test]
|
||||
fn deserializes_with_message() {
|
||||
let reg_banned = LemmyErrorType::PersonIsBannedFromSite(String::from("reason"));
|
||||
let err = LemmyError::from(reg_banned).error_response();
|
||||
let json = String::from_utf8(err.into_body().try_into_bytes().unwrap().to_vec()).unwrap();
|
||||
assert_eq!(
|
||||
&json,
|
||||
"{\"error\":\"person_is_banned_from_site\",\"message\":\"reason\"}"
|
||||
)
|
||||
}
|
||||
|
||||
/// Check if errors match translations. Disabled because many are not translated at all.
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_translations_match() {
|
||||
#[derive(Deserialize)]
|
||||
struct Err {
|
||||
error: String,
|
||||
/// Check if errors match translations. Disabled because many are not translated at all.
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_translations_match() {
|
||||
#[derive(Deserialize)]
|
||||
struct Err {
|
||||
error: String,
|
||||
}
|
||||
|
||||
let translations = read_to_string("translations/translations/en.json").unwrap();
|
||||
LemmyErrorType::iter().for_each(|e| {
|
||||
let msg = serde_json::to_string(&e).unwrap();
|
||||
let msg: Err = serde_json::from_str(&msg).unwrap();
|
||||
let msg = msg.error;
|
||||
assert!(translations.contains(&format!("\"{msg}\"")), "{msg}");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let translations = read_to_string("translations/translations/en.json").unwrap();
|
||||
LemmyErrorType::iter().for_each(|e| {
|
||||
let msg = serde_json::to_string(&e).unwrap();
|
||||
let msg: Err = serde_json::from_str(&msg).unwrap();
|
||||
let msg = msg.error;
|
||||
assert!(translations.contains(&format!("\"{msg}\"")), "{msg}");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,21 @@
|
|||
use cfg_if::cfg_if;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "default")] {
|
||||
if #[cfg(feature = "full")] {
|
||||
pub mod apub;
|
||||
pub mod cache_header;
|
||||
pub mod email;
|
||||
pub mod error;
|
||||
pub mod rate_limit;
|
||||
pub mod request;
|
||||
pub mod response;
|
||||
pub mod settings;
|
||||
pub mod utils;
|
||||
pub mod version;
|
||||
} else {
|
||||
mod error;
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "error-type")] {
|
||||
pub use error::LemmyErrorType;
|
||||
}
|
||||
}
|
||||
|
||||
pub mod error;
|
||||
pub use error::LemmyErrorType;
|
||||
use std::time::Duration;
|
||||
|
||||
pub type ConnectionId = usize;
|
||||
|
@ -41,7 +34,7 @@ macro_rules! location_info {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "default")]
|
||||
#[cfg(feature = "full")]
|
||||
/// tokio::spawn, but accepts a future that may fail and also
|
||||
/// * logs errors
|
||||
/// * attaches the spawned task to the tracing span of the caller for better logging
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
use doku::json::{AutoComments, CommentsStyle, Formatting, ObjectsStyle};
|
||||
use lemmy_utils::settings::structs::Settings;
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
fn main() {
|
||||
let fmt = Formatting {
|
||||
auto_comments: AutoComments::none(),
|
||||
comments_style: CommentsStyle {
|
||||
separator: "#".to_owned(),
|
||||
},
|
||||
objects_style: ObjectsStyle {
|
||||
surround_keys_with_quotes: false,
|
||||
use_comma_as_separator: false,
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
println!("{}", doku::to_json_fmt_val(&fmt, &Settings::default()));
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "full")] {
|
||||
use doku::json::{AutoComments, CommentsStyle, Formatting, ObjectsStyle};
|
||||
use lemmy_utils::settings::structs::Settings;
|
||||
let fmt = Formatting {
|
||||
auto_comments: AutoComments::none(),
|
||||
comments_style: CommentsStyle {
|
||||
separator: "#".to_owned(),
|
||||
},
|
||||
objects_style: ObjectsStyle {
|
||||
surround_keys_with_quotes: false,
|
||||
use_comma_as_separator: false,
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
println!("{}", doku::to_json_fmt_val(&fmt, &Settings::default()));
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,4 +3,4 @@ set -e
|
|||
|
||||
dest=${1-config/defaults.hjson}
|
||||
|
||||
cargo run --manifest-path crates/utils/Cargo.toml > "$dest"
|
||||
cargo run --manifest-path crates/utils/Cargo.toml --features full > "$dest"
|
||||
|
|
Loading…
Reference in a new issue