mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-26 21:01:34 +00:00
A first pass.
This commit is contained in:
parent
ddf4a667b1
commit
9cb4dad4b4
73 changed files with 1010 additions and 1394 deletions
|
@ -2,9 +2,9 @@ use crate::{
|
|||
check_community_ban,
|
||||
check_downvotes_enabled,
|
||||
collect_moderated_communities,
|
||||
get_post,
|
||||
get_local_user_view_from_jwt,
|
||||
get_local_user_view_from_jwt_opt,
|
||||
get_post,
|
||||
is_mod_or_admin,
|
||||
Perform,
|
||||
};
|
||||
|
@ -115,7 +115,9 @@ impl Perform for CreateComment {
|
|||
Err(_e) => return Err(ApiError::err("couldnt_create_comment").into()),
|
||||
};
|
||||
|
||||
updated_comment.send_create(&local_user_view.person, context).await?;
|
||||
updated_comment
|
||||
.send_create(&local_user_view.person, context)
|
||||
.await?;
|
||||
|
||||
// Scan the comment for user mentions, add those rows
|
||||
let post_id = post.id;
|
||||
|
@ -143,7 +145,9 @@ impl Perform for CreateComment {
|
|||
return Err(ApiError::err("couldnt_like_comment").into());
|
||||
}
|
||||
|
||||
updated_comment.send_like(&local_user_view.person, context).await?;
|
||||
updated_comment
|
||||
.send_like(&local_user_view.person, context)
|
||||
.await?;
|
||||
|
||||
let person_id = local_user_view.person.id;
|
||||
let mut comment_view = blocking(context.pool(), move |conn| {
|
||||
|
@ -201,7 +205,12 @@ impl Perform for EditComment {
|
|||
})
|
||||
.await??;
|
||||
|
||||
check_community_ban(local_user_view.person.id, orig_comment.community.id, context.pool()).await?;
|
||||
check_community_ban(
|
||||
local_user_view.person.id,
|
||||
orig_comment.community.id,
|
||||
context.pool(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Verify that only the creator can edit
|
||||
if local_user_view.person.id != orig_comment.creator.id {
|
||||
|
@ -221,7 +230,9 @@ impl Perform for EditComment {
|
|||
};
|
||||
|
||||
// Send the apub update
|
||||
updated_comment.send_update(&local_user_view.person, context).await?;
|
||||
updated_comment
|
||||
.send_update(&local_user_view.person, context)
|
||||
.await?;
|
||||
|
||||
// Do the mentions / recipients
|
||||
let updated_comment_content = updated_comment.content.to_owned();
|
||||
|
@ -277,7 +288,12 @@ impl Perform for DeleteComment {
|
|||
})
|
||||
.await??;
|
||||
|
||||
check_community_ban(local_user_view.person.id, orig_comment.community.id, context.pool()).await?;
|
||||
check_community_ban(
|
||||
local_user_view.person.id,
|
||||
orig_comment.community.id,
|
||||
context.pool(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Verify that only the creator can delete
|
||||
if local_user_view.person.id != orig_comment.creator.id {
|
||||
|
@ -297,9 +313,13 @@ impl Perform for DeleteComment {
|
|||
|
||||
// Send the apub message
|
||||
if deleted {
|
||||
updated_comment.send_delete(&local_user_view.person, context).await?;
|
||||
updated_comment
|
||||
.send_delete(&local_user_view.person, context)
|
||||
.await?;
|
||||
} else {
|
||||
updated_comment.send_undo_delete(&local_user_view.person, context).await?;
|
||||
updated_comment
|
||||
.send_undo_delete(&local_user_view.person, context)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Refetch it
|
||||
|
@ -357,10 +377,20 @@ impl Perform for RemoveComment {
|
|||
})
|
||||
.await??;
|
||||
|
||||
check_community_ban(local_user_view.person.id, orig_comment.community.id, context.pool()).await?;
|
||||
check_community_ban(
|
||||
local_user_view.person.id,
|
||||
orig_comment.community.id,
|
||||
context.pool(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Verify that only a mod or admin can remove
|
||||
is_mod_or_admin(context.pool(), local_user_view.person.id, orig_comment.community.id).await?;
|
||||
is_mod_or_admin(
|
||||
context.pool(),
|
||||
local_user_view.person.id,
|
||||
orig_comment.community.id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Do the remove
|
||||
let removed = data.removed;
|
||||
|
@ -387,9 +417,13 @@ impl Perform for RemoveComment {
|
|||
|
||||
// Send the apub message
|
||||
if removed {
|
||||
updated_comment.send_remove(&local_user_view.person, context).await?;
|
||||
updated_comment
|
||||
.send_remove(&local_user_view.person, context)
|
||||
.await?;
|
||||
} else {
|
||||
updated_comment.send_undo_remove(&local_user_view.person, context).await?;
|
||||
updated_comment
|
||||
.send_undo_remove(&local_user_view.person, context)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Refetch it
|
||||
|
@ -448,7 +482,12 @@ impl Perform for MarkCommentAsRead {
|
|||
})
|
||||
.await??;
|
||||
|
||||
check_community_ban(local_user_view.person.id, orig_comment.community.id, context.pool()).await?;
|
||||
check_community_ban(
|
||||
local_user_view.person.id,
|
||||
orig_comment.community.id,
|
||||
context.pool(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Verify that only the recipient can mark as read
|
||||
if local_user_view.person.id != orig_comment.get_recipient_id() {
|
||||
|
@ -551,7 +590,12 @@ impl Perform for CreateCommentLike {
|
|||
})
|
||||
.await??;
|
||||
|
||||
check_community_ban(local_user_view.person.id, orig_comment.community.id, context.pool()).await?;
|
||||
check_community_ban(
|
||||
local_user_view.person.id,
|
||||
orig_comment.community.id,
|
||||
context.pool(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Add parent user to recipients
|
||||
recipient_ids.push(orig_comment.get_recipient_id());
|
||||
|
@ -583,10 +627,14 @@ impl Perform for CreateCommentLike {
|
|||
if like_form.score == 1 {
|
||||
comment.send_like(&local_user_view.person, context).await?;
|
||||
} else if like_form.score == -1 {
|
||||
comment.send_dislike(&local_user_view.person, context).await?;
|
||||
comment
|
||||
.send_dislike(&local_user_view.person, context)
|
||||
.await?;
|
||||
}
|
||||
} else {
|
||||
comment.send_undo_like(&local_user_view.person, context).await?;
|
||||
comment
|
||||
.send_undo_like(&local_user_view.person, context)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Have to refetch the comment to get the current state
|
||||
|
|
|
@ -517,9 +517,15 @@ impl Perform for FollowCommunity {
|
|||
} else if data.follow {
|
||||
// Dont actually add to the community followers here, because you need
|
||||
// to wait for the accept
|
||||
local_user_view.person.send_follow(&community.actor_id(), context).await?;
|
||||
local_user_view
|
||||
.person
|
||||
.send_follow(&community.actor_id(), context)
|
||||
.await?;
|
||||
} else {
|
||||
local_user_view.person.send_unfollow(&community.actor_id(), context).await?;
|
||||
local_user_view
|
||||
.person
|
||||
.send_unfollow(&community.actor_id(), context)
|
||||
.await?;
|
||||
let unfollow = move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form);
|
||||
if blocking(context.pool(), unfollow).await?.is_err() {
|
||||
return Err(ApiError::err("community_follower_already_exists").into());
|
||||
|
@ -788,7 +794,10 @@ impl Perform for TransferCommunity {
|
|||
|
||||
// Make sure user is the creator, or an admin
|
||||
if local_user_view.person.id != read_community.creator_id
|
||||
&& !admins.iter().map(|a| a.person.id).any(|x| x == local_user_view.person.id)
|
||||
&& !admins
|
||||
.iter()
|
||||
.map(|a| a.person.id)
|
||||
.any(|x| x == local_user_view.person.id)
|
||||
{
|
||||
return Err(ApiError::err("not_an_admin").into());
|
||||
}
|
||||
|
|
|
@ -3,17 +3,15 @@ use lemmy_api_structs::{
|
|||
blocking,
|
||||
comment::*,
|
||||
community::*,
|
||||
person::*,
|
||||
post::*,
|
||||
site::*,
|
||||
person::*,
|
||||
websocket::*,
|
||||
};
|
||||
use lemmy_db_queries::{
|
||||
source::{
|
||||
community::{CommunityModerator_, Community_},
|
||||
site::Site_,
|
||||
local_user::LocalUserSettings_,
|
||||
local_user::LocalUser_,
|
||||
},
|
||||
Crud,
|
||||
DbPool,
|
||||
|
@ -22,15 +20,12 @@ use lemmy_db_schema::source::{
|
|||
community::{Community, CommunityModerator},
|
||||
post::Post,
|
||||
site::Site,
|
||||
person::{Person, PersonSafe},
|
||||
local_user::LocalUserSettings,
|
||||
local_user::LocalUser,
|
||||
};
|
||||
use lemmy_db_views::local_user_view::{LocalUserSettingsView, LocalUserView};
|
||||
use lemmy_db_views_actor::{
|
||||
community_person_ban_view::CommunityPersonBanView,
|
||||
community_view::CommunityView,
|
||||
};
|
||||
use lemmy_db_views::local_user_view::{LocalUserView, LocalUserSettingsView};
|
||||
use lemmy_utils::{
|
||||
claims::Claims,
|
||||
settings::structs::Settings,
|
||||
|
@ -45,10 +40,10 @@ use url::Url;
|
|||
|
||||
pub mod comment;
|
||||
pub mod community;
|
||||
pub mod local_user;
|
||||
pub mod post;
|
||||
pub mod routes;
|
||||
pub mod site;
|
||||
pub mod user;
|
||||
pub mod websocket;
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
|
@ -100,13 +95,19 @@ pub(crate) async fn get_post(post_id: i32, pool: &DbPool) -> Result<Post, LemmyE
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn get_local_user_view_from_jwt(jwt: &str, pool: &DbPool) -> Result<LocalUserView, LemmyError> {
|
||||
pub(crate) async fn get_local_user_view_from_jwt(
|
||||
jwt: &str,
|
||||
pool: &DbPool,
|
||||
) -> Result<LocalUserView, LemmyError> {
|
||||
let claims = match Claims::decode(&jwt) {
|
||||
Ok(claims) => claims.claims,
|
||||
Err(_e) => return Err(ApiError::err("not_logged_in").into()),
|
||||
};
|
||||
let person_id = claims.id;
|
||||
let local_user_view = blocking(pool, move |conn| LocalUserView::read(conn, person_id)).await??;
|
||||
let local_user_view = blocking(pool, move |conn| {
|
||||
LocalUserView::read_person(conn, person_id)
|
||||
})
|
||||
.await??;
|
||||
// Check for a site ban
|
||||
if local_user_view.person.banned {
|
||||
return Err(ApiError::err("site_ban").into());
|
||||
|
@ -124,13 +125,19 @@ pub(crate) async fn get_local_user_view_from_jwt_opt(
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn get_local_user_settings_view_from_jwt(jwt: &str, pool: &DbPool) -> Result<LocalUserSettingsView, LemmyError> {
|
||||
pub(crate) async fn get_local_user_settings_view_from_jwt(
|
||||
jwt: &str,
|
||||
pool: &DbPool,
|
||||
) -> Result<LocalUserSettingsView, LemmyError> {
|
||||
let claims = match Claims::decode(&jwt) {
|
||||
Ok(claims) => claims.claims,
|
||||
Err(_e) => return Err(ApiError::err("not_logged_in").into()),
|
||||
};
|
||||
let person_id = claims.id;
|
||||
let local_user_view = blocking(pool, move |conn| LocalUserSettingsView::read(conn, person_id)).await??;
|
||||
let local_user_view = blocking(pool, move |conn| {
|
||||
LocalUserSettingsView::read(conn, person_id)
|
||||
})
|
||||
.await??;
|
||||
// Check for a site ban
|
||||
if local_user_view.person.banned {
|
||||
return Err(ApiError::err("site_ban").into());
|
||||
|
@ -143,7 +150,9 @@ pub(crate) async fn get_local_user_settings_view_from_jwt_opt(
|
|||
pool: &DbPool,
|
||||
) -> Result<Option<LocalUserSettingsView>, LemmyError> {
|
||||
match jwt {
|
||||
Some(jwt) => Ok(Some(get_local_user_settings_view_from_jwt(jwt, pool).await?)),
|
||||
Some(jwt) => Ok(Some(
|
||||
get_local_user_settings_view_from_jwt(jwt, pool).await?,
|
||||
)),
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +162,8 @@ pub(crate) async fn check_community_ban(
|
|||
community_id: i32,
|
||||
pool: &DbPool,
|
||||
) -> Result<(), LemmyError> {
|
||||
let is_banned = move |conn: &'_ _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok();
|
||||
let is_banned =
|
||||
move |conn: &'_ _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok();
|
||||
if blocking(pool, is_banned).await? {
|
||||
Err(ApiError::err("community_ban").into())
|
||||
} else {
|
||||
|
|
|
@ -12,7 +12,7 @@ use anyhow::Context;
|
|||
use bcrypt::verify;
|
||||
use captcha::{gen, Difficulty};
|
||||
use chrono::Duration;
|
||||
use lemmy_api_structs::{blocking, send_email_to_user, person::*};
|
||||
use lemmy_api_structs::{blocking, person::*, send_email_to_user};
|
||||
use lemmy_apub::{
|
||||
generate_apub_endpoint,
|
||||
generate_followers_url,
|
||||
|
@ -27,12 +27,13 @@ use lemmy_db_queries::{
|
|||
source::{
|
||||
comment::Comment_,
|
||||
community::Community_,
|
||||
local_user::LocalUser_,
|
||||
password_reset_request::PasswordResetRequest_,
|
||||
person::Person_,
|
||||
person_mention::PersonMention_,
|
||||
post::Post_,
|
||||
private_message::PrivateMessage_,
|
||||
site::Site_,
|
||||
person::Person_,
|
||||
person_mention::PersonMention_,
|
||||
},
|
||||
Crud,
|
||||
Followable,
|
||||
|
@ -40,14 +41,28 @@ use lemmy_db_queries::{
|
|||
ListingType,
|
||||
SortType,
|
||||
};
|
||||
use lemmy_db_schema::{naive_now, source::{comment::Comment, community::*, local_user::LocalUserForm, moderator::*, password_reset_request::*, person::*, person_mention::*, post::Post, private_message::*, site::*}};
|
||||
use lemmy_db_schema::{
|
||||
naive_now,
|
||||
source::{
|
||||
comment::Comment,
|
||||
community::*,
|
||||
local_user::{LocalUser, LocalUserForm},
|
||||
moderator::*,
|
||||
password_reset_request::*,
|
||||
person::*,
|
||||
person_mention::*,
|
||||
post::Post,
|
||||
private_message::*,
|
||||
site::*,
|
||||
},
|
||||
};
|
||||
use lemmy_db_views::{
|
||||
comment_report_view::CommentReportView,
|
||||
comment_view::CommentQueryBuilder,
|
||||
local_user_view::LocalUserView,
|
||||
post_report_view::PostReportView,
|
||||
post_view::PostQueryBuilder,
|
||||
private_message_view::{PrivateMessageQueryBuilder, PrivateMessageView},
|
||||
local_user_view::LocalUserView,
|
||||
};
|
||||
use lemmy_db_views_actor::{
|
||||
community_follower_view::CommunityFollowerView,
|
||||
|
@ -103,7 +118,11 @@ impl Perform for Login {
|
|||
};
|
||||
|
||||
// Verify the password
|
||||
let valid: bool = verify(&data.password, &local_user_view.local_user.password_encrypted).unwrap_or(false);
|
||||
let valid: bool = verify(
|
||||
&data.password,
|
||||
&local_user_view.local_user.password_encrypted,
|
||||
)
|
||||
.unwrap_or(false);
|
||||
if !valid {
|
||||
return Err(ApiError::err("password_incorrect").into());
|
||||
}
|
||||
|
@ -175,7 +194,7 @@ impl Perform for Register {
|
|||
let actor_id = generate_apub_endpoint(EndpointType::Person, &data.username)?;
|
||||
|
||||
// We have to create both a person, and local_user
|
||||
|
||||
|
||||
// Register the new person
|
||||
let person_form = PersonForm {
|
||||
name: data.username.to_owned(),
|
||||
|
@ -186,18 +205,11 @@ impl Perform for Register {
|
|||
updated: None,
|
||||
banned: None,
|
||||
deleted: None,
|
||||
show_nsfw: data.show_nsfw,
|
||||
theme: "browser".into(),
|
||||
default_sort_type: SortType::Active as i16,
|
||||
default_listing_type: ListingType::Subscribed as i16,
|
||||
lang: "browser".into(),
|
||||
show_avatars: true,
|
||||
send_notifications_to_email: false,
|
||||
actor_id: Some(actor_id.clone()),
|
||||
bio: None,
|
||||
local: true,
|
||||
private_key: Some(actor_keypair.private_key),
|
||||
public_key: Some(actor_keypair.public_key),
|
||||
local: Some(true),
|
||||
private_key: Some(Some(actor_keypair.private_key)),
|
||||
public_key: Some(Some(actor_keypair.public_key)),
|
||||
last_refreshed_at: None,
|
||||
inbox_url: Some(generate_inbox_url(&actor_id)?),
|
||||
shared_inbox_url: Some(Some(generate_shared_inbox_url(&actor_id)?)),
|
||||
|
@ -209,8 +221,8 @@ impl Perform for Register {
|
|||
})
|
||||
.await?
|
||||
{
|
||||
Ok(user) => user,
|
||||
Err(e) => {
|
||||
Ok(u) => u,
|
||||
Err(_) => {
|
||||
return Err(ApiError::err("user_already_exists").into());
|
||||
}
|
||||
};
|
||||
|
@ -221,11 +233,17 @@ impl Perform for Register {
|
|||
email: Some(data.email.to_owned()),
|
||||
matrix_user_id: None,
|
||||
password_encrypted: data.password.to_owned(),
|
||||
admin: no_admins,
|
||||
|
||||
admin: Some(no_admins),
|
||||
show_nsfw: Some(data.show_nsfw),
|
||||
theme: Some("browser".into()),
|
||||
default_sort_type: Some(SortType::Active as i16),
|
||||
default_listing_type: Some(ListingType::Subscribed as i16),
|
||||
lang: Some("browser".into()),
|
||||
show_avatars: Some(true),
|
||||
send_notifications_to_email: Some(false),
|
||||
};
|
||||
|
||||
let inserted_local_user = match blocking(context.pool(), move |conn| {
|
||||
match blocking(context.pool(), move |conn| {
|
||||
LocalUser::register(conn, &local_user_form)
|
||||
})
|
||||
.await?
|
||||
|
@ -241,12 +259,14 @@ impl Perform for Register {
|
|||
};
|
||||
|
||||
// If the local user creation errored, then delete that person
|
||||
blocking(context.pool(), move |conn| Person::delete(&conn, inserted_person.id)).await??;
|
||||
blocking(context.pool(), move |conn| {
|
||||
Person::delete(&conn, inserted_person.id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
return Err(ApiError::err(err_type).into());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let main_community_keypair = generate_actor_keypair()?;
|
||||
|
||||
|
@ -374,7 +394,7 @@ impl Perform for SaveUserSettings {
|
|||
_websocket_id: Option<ConnectionId>,
|
||||
) -> Result<LoginResponse, LemmyError> {
|
||||
let data: &SaveUserSettings = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
let avatar = diesel_option_overwrite_to_url(&data.avatar)?;
|
||||
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||
|
@ -395,7 +415,8 @@ impl Perform for SaveUserSettings {
|
|||
}
|
||||
}
|
||||
|
||||
let user_id = user.id;
|
||||
let local_user_id = local_user_view.local_user.id;
|
||||
let person_id = local_user_view.person.id;
|
||||
let password_encrypted = match &data.new_password {
|
||||
Some(new_password) => {
|
||||
match &data.new_password_verify {
|
||||
|
@ -410,13 +431,15 @@ impl Perform for SaveUserSettings {
|
|||
// Check the old password
|
||||
match &data.old_password {
|
||||
Some(old_password) => {
|
||||
let valid: bool = verify(old_password, &user.password_encrypted).unwrap_or(false);
|
||||
let valid: bool =
|
||||
verify(old_password, &local_user_view.local_user.password_encrypted)
|
||||
.unwrap_or(false);
|
||||
if !valid {
|
||||
return Err(ApiError::err("password_incorrect").into());
|
||||
}
|
||||
let new_password = new_password.to_owned();
|
||||
let user = blocking(context.pool(), move |conn| {
|
||||
User_::update_password(conn, user_id, &new_password)
|
||||
LocalUser::update_password(conn, local_user_id, &new_password)
|
||||
})
|
||||
.await??;
|
||||
user.password_encrypted
|
||||
|
@ -427,25 +450,48 @@ impl Perform for SaveUserSettings {
|
|||
None => return Err(ApiError::err("passwords_dont_match").into()),
|
||||
}
|
||||
}
|
||||
None => user.password_encrypted,
|
||||
None => local_user_view.local_user.password_encrypted,
|
||||
};
|
||||
|
||||
let default_listing_type = data.default_listing_type;
|
||||
let default_sort_type = data.default_sort_type;
|
||||
|
||||
let user_form = UserForm {
|
||||
name: user.name,
|
||||
email,
|
||||
matrix_user_id,
|
||||
let person_form = PersonForm {
|
||||
name: local_user_view.person.name,
|
||||
avatar,
|
||||
banner,
|
||||
inbox_url: None,
|
||||
password_encrypted,
|
||||
preferred_username,
|
||||
published: Some(user.published),
|
||||
published: None,
|
||||
updated: Some(naive_now()),
|
||||
admin: user.admin,
|
||||
banned: Some(user.banned),
|
||||
banned: None,
|
||||
deleted: None,
|
||||
actor_id: None,
|
||||
bio,
|
||||
local: None,
|
||||
private_key: None,
|
||||
public_key: None,
|
||||
last_refreshed_at: None,
|
||||
shared_inbox_url: None,
|
||||
};
|
||||
|
||||
let person_res = blocking(context.pool(), move |conn| {
|
||||
Person::update(conn, person_id, &person_form)
|
||||
})
|
||||
.await?;
|
||||
let updated_person: Person = match person_res {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return Err(ApiError::err("user_already_exists").into());
|
||||
}
|
||||
};
|
||||
|
||||
let local_user_form = LocalUserForm {
|
||||
person_id,
|
||||
email,
|
||||
matrix_user_id,
|
||||
password_encrypted,
|
||||
admin: None,
|
||||
show_nsfw: data.show_nsfw,
|
||||
theme: data.theme.to_owned(),
|
||||
default_sort_type,
|
||||
|
@ -453,24 +499,17 @@ impl Perform for SaveUserSettings {
|
|||
lang: data.lang.to_owned(),
|
||||
show_avatars: data.show_avatars,
|
||||
send_notifications_to_email: data.send_notifications_to_email,
|
||||
actor_id: Some(user.actor_id),
|
||||
bio,
|
||||
local: user.local,
|
||||
private_key: user.private_key,
|
||||
public_key: user.public_key,
|
||||
last_refreshed_at: None,
|
||||
shared_inbox_url: None,
|
||||
};
|
||||
|
||||
let res = blocking(context.pool(), move |conn| {
|
||||
User_::update(conn, user_id, &user_form)
|
||||
let local_user_res = blocking(context.pool(), move |conn| {
|
||||
LocalUser::update(conn, local_user_id, &local_user_form)
|
||||
})
|
||||
.await?;
|
||||
let updated_user: User_ = match res {
|
||||
match local_user_res {
|
||||
Ok(user) => user,
|
||||
Err(e) => {
|
||||
let err_type = if e.to_string()
|
||||
== "duplicate key value violates unique constraint \"user__email_key\""
|
||||
== "duplicate key value violates unique constraint \"local_user_email_key\""
|
||||
{
|
||||
"email_already_exists"
|
||||
} else {
|
||||
|
@ -483,25 +522,25 @@ impl Perform for SaveUserSettings {
|
|||
|
||||
// Return the jwt
|
||||
Ok(LoginResponse {
|
||||
jwt: Claims::jwt(updated_user.id, Settings::get().hostname())?,
|
||||
jwt: Claims::jwt(updated_person.id, Settings::get().hostname())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl Perform for GetUserDetails {
|
||||
type Response = GetUserDetailsResponse;
|
||||
impl Perform for GetPersonDetails {
|
||||
type Response = GetPersonDetailsResponse;
|
||||
|
||||
async fn perform(
|
||||
&self,
|
||||
context: &Data<LemmyContext>,
|
||||
_websocket_id: Option<ConnectionId>,
|
||||
) -> Result<GetUserDetailsResponse, LemmyError> {
|
||||
let data: &GetUserDetails = &self;
|
||||
let user = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
|
||||
) -> Result<GetPersonDetailsResponse, LemmyError> {
|
||||
let data: &GetPersonDetails = &self;
|
||||
let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
|
||||
|
||||
let show_nsfw = match &user {
|
||||
Some(user) => user.show_nsfw,
|
||||
let show_nsfw = match &local_user_view {
|
||||
Some(uv) => uv.local_user.show_nsfw,
|
||||
None => false,
|
||||
};
|
||||
|
||||
|
@ -511,26 +550,26 @@ impl Perform for GetUserDetails {
|
|||
.username
|
||||
.to_owned()
|
||||
.unwrap_or_else(|| "admin".to_string());
|
||||
let user_details_id = match data.user_id {
|
||||
let person_details_id = match data.person_id {
|
||||
Some(id) => id,
|
||||
None => {
|
||||
let user = blocking(context.pool(), move |conn| {
|
||||
User_::read_from_name(conn, &username)
|
||||
let person = blocking(context.pool(), move |conn| {
|
||||
Person::find_by_name(conn, &username)
|
||||
})
|
||||
.await?;
|
||||
match user {
|
||||
Ok(user) => user.id,
|
||||
match person {
|
||||
Ok(p) => p.id,
|
||||
Err(_e) => return Err(ApiError::err("couldnt_find_that_username_or_email").into()),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let user_id = user.map(|u| u.id);
|
||||
let person_id = local_user_view.map(|uv| uv.person.id);
|
||||
|
||||
// You don't need to return settings for the user, since this comes back with GetSite
|
||||
// `my_user`
|
||||
let user_view = blocking(context.pool(), move |conn| {
|
||||
UserViewSafe::read(conn, user_details_id)
|
||||
let person_view = blocking(context.pool(), move |conn| {
|
||||
PersonViewSafe::read(conn, person_details_id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
|
@ -545,12 +584,12 @@ impl Perform for GetUserDetails {
|
|||
.show_nsfw(show_nsfw)
|
||||
.saved_only(saved_only)
|
||||
.community_id(community_id)
|
||||
.my_user_id(user_id)
|
||||
.my_person_id(person_id)
|
||||
.page(page)
|
||||
.limit(limit);
|
||||
|
||||
let mut comments_query = CommentQueryBuilder::create(conn)
|
||||
.my_person_id(user_id)
|
||||
.my_person_id(person_id)
|
||||
.sort(&sort)
|
||||
.saved_only(saved_only)
|
||||
.page(page)
|
||||
|
@ -559,8 +598,8 @@ impl Perform for GetUserDetails {
|
|||
// If its saved only, you don't care what creator it was
|
||||
// Or, if its not saved, then you only want it for that specific creator
|
||||
if !saved_only {
|
||||
posts_query = posts_query.creator_id(user_details_id);
|
||||
comments_query = comments_query.creator_id(user_details_id);
|
||||
posts_query = posts_query.creator_id(person_details_id);
|
||||
comments_query = comments_query.creator_id(person_details_id);
|
||||
}
|
||||
|
||||
let posts = posts_query.list()?;
|
||||
|
@ -571,22 +610,22 @@ impl Perform for GetUserDetails {
|
|||
.await??;
|
||||
|
||||
let mut follows = vec![];
|
||||
if let Some(uid) = user_id {
|
||||
if uid == user_details_id {
|
||||
if let Some(pid) = person_id {
|
||||
if pid == person_details_id {
|
||||
follows = blocking(context.pool(), move |conn| {
|
||||
CommunityFollowerView::for_user(conn, user_details_id)
|
||||
CommunityFollowerView::for_person(conn, person_details_id)
|
||||
})
|
||||
.await??;
|
||||
}
|
||||
};
|
||||
let moderates = blocking(context.pool(), move |conn| {
|
||||
CommunityModeratorView::for_person(conn, user_details_id)
|
||||
CommunityModeratorView::for_person(conn, person_details_id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// Return the jwt
|
||||
Ok(GetUserDetailsResponse {
|
||||
user_view,
|
||||
Ok(GetPersonDetailsResponse {
|
||||
person_view,
|
||||
follows,
|
||||
moderates,
|
||||
comments,
|
||||
|
@ -605,22 +644,28 @@ impl Perform for AddAdmin {
|
|||
websocket_id: Option<ConnectionId>,
|
||||
) -> Result<AddAdminResponse, LemmyError> {
|
||||
let data: &AddAdmin = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
// Make sure user is an admin
|
||||
is_admin(context.pool(), user.id).await?;
|
||||
is_admin(&local_user_view)?;
|
||||
|
||||
let added = data.added;
|
||||
let added_user_id = data.user_id;
|
||||
let add_admin = move |conn: &'_ _| User_::add_admin(conn, added_user_id, added);
|
||||
if blocking(context.pool(), add_admin).await?.is_err() {
|
||||
return Err(ApiError::err("couldnt_update_user").into());
|
||||
}
|
||||
let added_local_user_id = data.local_user_id;
|
||||
let added_admin = match blocking(context.pool(), move |conn| {
|
||||
LocalUser::add_admin(conn, added_local_user_id, added)
|
||||
})
|
||||
.await?
|
||||
{
|
||||
Ok(a) => a,
|
||||
Err(_) => {
|
||||
return Err(ApiError::err("couldnt_update_user").into());
|
||||
}
|
||||
};
|
||||
|
||||
// Mod tables
|
||||
let form = ModAddForm {
|
||||
mod_person_id: user.id,
|
||||
other_person_id: data.user_id,
|
||||
mod_person_id: local_user_view.person.id,
|
||||
other_person_id: added_admin.person_id,
|
||||
removed: Some(!data.added),
|
||||
};
|
||||
|
||||
|
@ -631,13 +676,13 @@ impl Perform for AddAdmin {
|
|||
})
|
||||
.await??;
|
||||
|
||||
let mut admins = blocking(context.pool(), move |conn| UserViewSafe::admins(conn)).await??;
|
||||
let mut admins = blocking(context.pool(), move |conn| PersonViewSafe::admins(conn)).await??;
|
||||
let creator_index = admins
|
||||
.iter()
|
||||
.position(|r| r.user.id == site_creator_id)
|
||||
.position(|r| r.person.id == site_creator_id)
|
||||
.context(location_info!())?;
|
||||
let creator_user = admins.remove(creator_index);
|
||||
admins.insert(0, creator_user);
|
||||
let creator_person = admins.remove(creator_index);
|
||||
admins.insert(0, creator_person);
|
||||
|
||||
let res = AddAdminResponse { admins };
|
||||
|
||||
|
@ -652,24 +697,24 @@ impl Perform for AddAdmin {
|
|||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl Perform for BanUser {
|
||||
type Response = BanUserResponse;
|
||||
impl Perform for BanPerson {
|
||||
type Response = BanPersonResponse;
|
||||
|
||||
async fn perform(
|
||||
&self,
|
||||
context: &Data<LemmyContext>,
|
||||
websocket_id: Option<ConnectionId>,
|
||||
) -> Result<BanUserResponse, LemmyError> {
|
||||
let data: &BanUser = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
) -> Result<BanPersonResponse, LemmyError> {
|
||||
let data: &BanPerson = &self;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
// Make sure user is an admin
|
||||
is_admin(context.pool(), user.id).await?;
|
||||
is_admin(&local_user_view)?;
|
||||
|
||||
let ban = data.ban;
|
||||
let banned_user_id = data.user_id;
|
||||
let ban_user = move |conn: &'_ _| User_::ban_user(conn, banned_user_id, ban);
|
||||
if blocking(context.pool(), ban_user).await?.is_err() {
|
||||
let banned_person_id = data.person_id;
|
||||
let ban_person = move |conn: &'_ _| Person::ban_person(conn, banned_person_id, ban);
|
||||
if blocking(context.pool(), ban_person).await?.is_err() {
|
||||
return Err(ApiError::err("couldnt_update_user").into());
|
||||
}
|
||||
|
||||
|
@ -677,19 +722,19 @@ impl Perform for BanUser {
|
|||
if data.remove_data {
|
||||
// Posts
|
||||
blocking(context.pool(), move |conn: &'_ _| {
|
||||
Post::update_removed_for_creator(conn, banned_user_id, None, true)
|
||||
Post::update_removed_for_creator(conn, banned_person_id, None, true)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// Communities
|
||||
blocking(context.pool(), move |conn: &'_ _| {
|
||||
Community::update_removed_for_creator(conn, banned_user_id, true)
|
||||
Community::update_removed_for_creator(conn, banned_person_id, true)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// Comments
|
||||
blocking(context.pool(), move |conn: &'_ _| {
|
||||
Comment::update_removed_for_creator(conn, banned_user_id, true)
|
||||
Comment::update_removed_for_creator(conn, banned_person_id, true)
|
||||
})
|
||||
.await??;
|
||||
}
|
||||
|
@ -701,8 +746,8 @@ impl Perform for BanUser {
|
|||
};
|
||||
|
||||
let form = ModBanForm {
|
||||
mod_person_id: user.id,
|
||||
other_person_id: data.user_id,
|
||||
mod_person_id: local_user_view.person.id,
|
||||
other_person_id: data.person_id,
|
||||
reason: data.reason.to_owned(),
|
||||
banned: Some(data.ban),
|
||||
expires,
|
||||
|
@ -710,14 +755,14 @@ impl Perform for BanUser {
|
|||
|
||||
blocking(context.pool(), move |conn| ModBan::create(conn, &form)).await??;
|
||||
|
||||
let user_id = data.user_id;
|
||||
let user_view = blocking(context.pool(), move |conn| {
|
||||
UserViewSafe::read(conn, user_id)
|
||||
let person_id = data.person_id;
|
||||
let person_view = blocking(context.pool(), move |conn| {
|
||||
PersonViewSafe::read(conn, person_id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = BanUserResponse {
|
||||
user_view,
|
||||
let res = BanPersonResponse {
|
||||
person_view,
|
||||
banned: data.ban,
|
||||
};
|
||||
|
||||
|
@ -741,20 +786,20 @@ impl Perform for GetReplies {
|
|||
_websocket_id: Option<ConnectionId>,
|
||||
) -> Result<GetRepliesResponse, LemmyError> {
|
||||
let data: &GetReplies = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
let sort = SortType::from_str(&data.sort)?;
|
||||
|
||||
let page = data.page;
|
||||
let limit = data.limit;
|
||||
let unread_only = data.unread_only;
|
||||
let user_id = user.id;
|
||||
let person_id = local_user_view.person.id;
|
||||
let replies = blocking(context.pool(), move |conn| {
|
||||
CommentQueryBuilder::create(conn)
|
||||
.sort(&sort)
|
||||
.unread_only(unread_only)
|
||||
.recipient_id(user_id)
|
||||
.my_person_id(user_id)
|
||||
.recipient_id(person_id)
|
||||
.my_person_id(person_id)
|
||||
.page(page)
|
||||
.limit(limit)
|
||||
.list()
|
||||
|
@ -766,27 +811,27 @@ impl Perform for GetReplies {
|
|||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl Perform for GetUserMentions {
|
||||
type Response = GetUserMentionsResponse;
|
||||
impl Perform for GetPersonMentions {
|
||||
type Response = GetPersonMentionsResponse;
|
||||
|
||||
async fn perform(
|
||||
&self,
|
||||
context: &Data<LemmyContext>,
|
||||
_websocket_id: Option<ConnectionId>,
|
||||
) -> Result<GetUserMentionsResponse, LemmyError> {
|
||||
let data: &GetUserMentions = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
) -> Result<GetPersonMentionsResponse, LemmyError> {
|
||||
let data: &GetPersonMentions = &self;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
let sort = SortType::from_str(&data.sort)?;
|
||||
|
||||
let page = data.page;
|
||||
let limit = data.limit;
|
||||
let unread_only = data.unread_only;
|
||||
let user_id = user.id;
|
||||
let person_id = local_user_view.person.id;
|
||||
let mentions = blocking(context.pool(), move |conn| {
|
||||
UserMentionQueryBuilder::create(conn)
|
||||
.recipient_id(user_id)
|
||||
.my_user_id(user_id)
|
||||
PersonMentionQueryBuilder::create(conn)
|
||||
.recipient_id(person_id)
|
||||
.my_person_id(person_id)
|
||||
.sort(&sort)
|
||||
.unread_only(unread_only)
|
||||
.page(page)
|
||||
|
@ -795,47 +840,50 @@ impl Perform for GetUserMentions {
|
|||
})
|
||||
.await??;
|
||||
|
||||
Ok(GetUserMentionsResponse { mentions })
|
||||
Ok(GetPersonMentionsResponse { mentions })
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl Perform for MarkUserMentionAsRead {
|
||||
type Response = UserMentionResponse;
|
||||
impl Perform for MarkPersonMentionAsRead {
|
||||
type Response = PersonMentionResponse;
|
||||
|
||||
async fn perform(
|
||||
&self,
|
||||
context: &Data<LemmyContext>,
|
||||
_websocket_id: Option<ConnectionId>,
|
||||
) -> Result<UserMentionResponse, LemmyError> {
|
||||
let data: &MarkUserMentionAsRead = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
) -> Result<PersonMentionResponse, LemmyError> {
|
||||
let data: &MarkPersonMentionAsRead = &self;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
let user_mention_id = data.user_mention_id;
|
||||
let read_user_mention = blocking(context.pool(), move |conn| {
|
||||
UserMention::read(conn, user_mention_id)
|
||||
let person_mention_id = data.person_mention_id;
|
||||
let read_person_mention = blocking(context.pool(), move |conn| {
|
||||
PersonMention::read(conn, person_mention_id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
if user.id != read_user_mention.recipient_id {
|
||||
if local_user_view.person.id != read_person_mention.recipient_id {
|
||||
return Err(ApiError::err("couldnt_update_comment").into());
|
||||
}
|
||||
|
||||
let user_mention_id = read_user_mention.id;
|
||||
let person_mention_id = read_person_mention.id;
|
||||
let read = data.read;
|
||||
let update_mention = move |conn: &'_ _| UserMention::update_read(conn, user_mention_id, read);
|
||||
let update_mention =
|
||||
move |conn: &'_ _| PersonMention::update_read(conn, person_mention_id, read);
|
||||
if blocking(context.pool(), update_mention).await?.is_err() {
|
||||
return Err(ApiError::err("couldnt_update_comment").into());
|
||||
};
|
||||
|
||||
let user_mention_id = read_user_mention.id;
|
||||
let user_id = user.id;
|
||||
let user_mention_view = blocking(context.pool(), move |conn| {
|
||||
UserMentionView::read(conn, user_mention_id, Some(user_id))
|
||||
let person_mention_id = read_person_mention.id;
|
||||
let person_id = local_user_view.person.id;
|
||||
let person_mention_view = blocking(context.pool(), move |conn| {
|
||||
PersonMentionView::read(conn, person_mention_id, Some(person_id))
|
||||
})
|
||||
.await??;
|
||||
|
||||
Ok(UserMentionResponse { user_mention_view })
|
||||
Ok(PersonMentionResponse {
|
||||
person_mention_view,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -849,13 +897,13 @@ impl Perform for MarkAllAsRead {
|
|||
_websocket_id: Option<ConnectionId>,
|
||||
) -> Result<GetRepliesResponse, LemmyError> {
|
||||
let data: &MarkAllAsRead = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
let user_id = user.id;
|
||||
let person_id = local_user_view.person.id;
|
||||
let replies = blocking(context.pool(), move |conn| {
|
||||
CommentQueryBuilder::create(conn)
|
||||
.my_person_id(user_id)
|
||||
.recipient_id(user_id)
|
||||
.my_person_id(person_id)
|
||||
.recipient_id(person_id)
|
||||
.unread_only(true)
|
||||
.page(1)
|
||||
.limit(999)
|
||||
|
@ -875,8 +923,9 @@ impl Perform for MarkAllAsRead {
|
|||
}
|
||||
|
||||
// Mark all user mentions as read
|
||||
let update_user_mentions = move |conn: &'_ _| UserMention::mark_all_as_read(conn, user_id);
|
||||
if blocking(context.pool(), update_user_mentions)
|
||||
let update_person_mentions =
|
||||
move |conn: &'_ _| PersonMention::mark_all_as_read(conn, person_id);
|
||||
if blocking(context.pool(), update_person_mentions)
|
||||
.await?
|
||||
.is_err()
|
||||
{
|
||||
|
@ -884,7 +933,7 @@ impl Perform for MarkAllAsRead {
|
|||
}
|
||||
|
||||
// Mark all private_messages as read
|
||||
let update_pm = move |conn: &'_ _| PrivateMessage::mark_all_as_read(conn, user_id);
|
||||
let update_pm = move |conn: &'_ _| PrivateMessage::mark_all_as_read(conn, person_id);
|
||||
if blocking(context.pool(), update_pm).await?.is_err() {
|
||||
return Err(ApiError::err("couldnt_update_private_message").into());
|
||||
}
|
||||
|
@ -903,29 +952,33 @@ impl Perform for DeleteAccount {
|
|||
_websocket_id: Option<ConnectionId>,
|
||||
) -> Result<LoginResponse, LemmyError> {
|
||||
let data: &DeleteAccount = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
// Verify the password
|
||||
let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
|
||||
let valid: bool = verify(
|
||||
&data.password,
|
||||
&local_user_view.local_user.password_encrypted,
|
||||
)
|
||||
.unwrap_or(false);
|
||||
if !valid {
|
||||
return Err(ApiError::err("password_incorrect").into());
|
||||
}
|
||||
|
||||
// Comments
|
||||
let user_id = user.id;
|
||||
let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, user_id);
|
||||
let person_id = local_user_view.person.id;
|
||||
let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, person_id);
|
||||
if blocking(context.pool(), permadelete).await?.is_err() {
|
||||
return Err(ApiError::err("couldnt_update_comment").into());
|
||||
}
|
||||
|
||||
// Posts
|
||||
let permadelete = move |conn: &'_ _| Post::permadelete_for_creator(conn, user_id);
|
||||
let permadelete = move |conn: &'_ _| Post::permadelete_for_creator(conn, person_id);
|
||||
if blocking(context.pool(), permadelete).await?.is_err() {
|
||||
return Err(ApiError::err("couldnt_update_post").into());
|
||||
}
|
||||
|
||||
blocking(context.pool(), move |conn| {
|
||||
User_::delete_account(conn, user_id)
|
||||
Person::delete_account(conn, person_id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
|
@ -948,12 +1001,12 @@ impl Perform for PasswordReset {
|
|||
|
||||
// Fetch that email
|
||||
let email = data.email.clone();
|
||||
let user = match blocking(context.pool(), move |conn| {
|
||||
User_::find_by_email(conn, &email)
|
||||
let local_user_view = match blocking(context.pool(), move |conn| {
|
||||
LocalUserView::find_by_email(conn, &email)
|
||||
})
|
||||
.await?
|
||||
{
|
||||
Ok(user) => user,
|
||||
Ok(lu) => lu,
|
||||
Err(_e) => return Err(ApiError::err("couldnt_find_that_username_or_email").into()),
|
||||
};
|
||||
|
||||
|
@ -962,19 +1015,19 @@ impl Perform for PasswordReset {
|
|||
|
||||
// Insert the row
|
||||
let token2 = token.clone();
|
||||
let user_id = user.id;
|
||||
let local_user_id = local_user_view.local_user.id;
|
||||
blocking(context.pool(), move |conn| {
|
||||
PasswordResetRequest::create_token(conn, user_id, &token2)
|
||||
PasswordResetRequest::create_token(conn, local_user_id, &token2)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// Email the pure token to the user.
|
||||
// TODO no i18n support here.
|
||||
let user_email = &user.email.expect("email");
|
||||
let subject = &format!("Password reset for {}", user.name);
|
||||
let email = &local_user_view.local_user.email.expect("email");
|
||||
let subject = &format!("Password reset for {}", local_user_view.person.name);
|
||||
let hostname = &Settings::get().get_protocol_and_hostname();
|
||||
let html = &format!("<h1>Password Reset Request for {}</h1><br><a href={}/password_change/{}>Click here to reset your password</a>", user.name, hostname, &token);
|
||||
match send_email(subject, user_email, &user.name, html) {
|
||||
let html = &format!("<h1>Password Reset Request for {}</h1><br><a href={}/password_change/{}>Click here to reset your password</a>", local_user_view.person.name, hostname, &token);
|
||||
match send_email(subject, email, &local_user_view.person.name, html) {
|
||||
Ok(_o) => _o,
|
||||
Err(_e) => return Err(ApiError::err(&_e).into()),
|
||||
};
|
||||
|
@ -996,7 +1049,7 @@ impl Perform for PasswordChange {
|
|||
|
||||
// Fetch the user_id from the token
|
||||
let token = data.token.clone();
|
||||
let user_id = blocking(context.pool(), move |conn| {
|
||||
let local_user_id = blocking(context.pool(), move |conn| {
|
||||
PasswordResetRequest::read_from_token(conn, &token).map(|p| p.local_user_id)
|
||||
})
|
||||
.await??;
|
||||
|
@ -1010,18 +1063,18 @@ impl Perform for PasswordChange {
|
|||
|
||||
// Update the user with the new password
|
||||
let password = data.password.clone();
|
||||
let updated_user = match blocking(context.pool(), move |conn| {
|
||||
User_::update_password(conn, user_id, &password)
|
||||
let updated_local_user = match blocking(context.pool(), move |conn| {
|
||||
LocalUser::update_password(conn, local_user_id, &password)
|
||||
})
|
||||
.await?
|
||||
{
|
||||
Ok(user) => user,
|
||||
Ok(u) => u,
|
||||
Err(_e) => return Err(ApiError::err("couldnt_update_user").into()),
|
||||
};
|
||||
|
||||
// Return the jwt
|
||||
Ok(LoginResponse {
|
||||
jwt: Claims::jwt(updated_user.id, Settings::get().hostname())?,
|
||||
jwt: Claims::jwt(updated_local_user.id, Settings::get().hostname())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1036,13 +1089,13 @@ impl Perform for CreatePrivateMessage {
|
|||
websocket_id: Option<ConnectionId>,
|
||||
) -> Result<PrivateMessageResponse, LemmyError> {
|
||||
let data: &CreatePrivateMessage = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
let content_slurs_removed = remove_slurs(&data.content.to_owned());
|
||||
|
||||
let private_message_form = PrivateMessageForm {
|
||||
content: content_slurs_removed.to_owned(),
|
||||
creator_id: user.id,
|
||||
creator_id: local_user_view.person.id,
|
||||
recipient_id: data.recipient_id,
|
||||
deleted: None,
|
||||
read: None,
|
||||
|
@ -1084,28 +1137,32 @@ impl Perform for CreatePrivateMessage {
|
|||
Err(_e) => return Err(ApiError::err("couldnt_create_private_message").into()),
|
||||
};
|
||||
|
||||
updated_private_message.send_create(&user, context).await?;
|
||||
updated_private_message
|
||||
.send_create(&local_user_view.person, context)
|
||||
.await?;
|
||||
|
||||
// Send notifications to the recipient
|
||||
let recipient_id = data.recipient_id;
|
||||
let recipient_user =
|
||||
blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
|
||||
if recipient_user.send_notifications_to_email {
|
||||
let recipient = blocking(context.pool(), move |conn| {
|
||||
LocalUserView::read_person(conn, recipient_id)
|
||||
})
|
||||
.await??;
|
||||
if recipient.local_user.send_notifications_to_email {
|
||||
send_email_to_user(
|
||||
recipient_user,
|
||||
recipient,
|
||||
"Private Message from",
|
||||
"Private Message",
|
||||
&content_slurs_removed,
|
||||
);
|
||||
}
|
||||
|
||||
let message = blocking(context.pool(), move |conn| {
|
||||
let private_message_view = blocking(context.pool(), move |conn| {
|
||||
PrivateMessageView::read(conn, inserted_private_message.id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = PrivateMessageResponse {
|
||||
private_message_view: message,
|
||||
private_message_view,
|
||||
};
|
||||
|
||||
context.chat_server().do_send(SendUserRoomMessage {
|
||||
|
@ -1129,7 +1186,7 @@ impl Perform for EditPrivateMessage {
|
|||
websocket_id: Option<ConnectionId>,
|
||||
) -> Result<PrivateMessageResponse, LemmyError> {
|
||||
let data: &EditPrivateMessage = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
// Checking permissions
|
||||
let private_message_id = data.private_message_id;
|
||||
|
@ -1137,7 +1194,7 @@ impl Perform for EditPrivateMessage {
|
|||
PrivateMessage::read(conn, private_message_id)
|
||||
})
|
||||
.await??;
|
||||
if user.id != orig_private_message.creator_id {
|
||||
if local_user_view.person.id != orig_private_message.creator_id {
|
||||
return Err(ApiError::err("no_private_message_edit_allowed").into());
|
||||
}
|
||||
|
||||
|
@ -1154,17 +1211,19 @@ impl Perform for EditPrivateMessage {
|
|||
};
|
||||
|
||||
// Send the apub update
|
||||
updated_private_message.send_update(&user, context).await?;
|
||||
updated_private_message
|
||||
.send_update(&local_user_view.person, context)
|
||||
.await?;
|
||||
|
||||
let private_message_id = data.private_message_id;
|
||||
let message = blocking(context.pool(), move |conn| {
|
||||
let private_message_view = blocking(context.pool(), move |conn| {
|
||||
PrivateMessageView::read(conn, private_message_id)
|
||||
})
|
||||
.await??;
|
||||
let recipient_id = message.recipient.id;
|
||||
let recipient_id = private_message_view.recipient.id;
|
||||
|
||||
let res = PrivateMessageResponse {
|
||||
private_message_view: message,
|
||||
private_message_view,
|
||||
};
|
||||
|
||||
context.chat_server().do_send(SendUserRoomMessage {
|
||||
|
@ -1188,7 +1247,7 @@ impl Perform for DeletePrivateMessage {
|
|||
websocket_id: Option<ConnectionId>,
|
||||
) -> Result<PrivateMessageResponse, LemmyError> {
|
||||
let data: &DeletePrivateMessage = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
// Checking permissions
|
||||
let private_message_id = data.private_message_id;
|
||||
|
@ -1196,7 +1255,7 @@ impl Perform for DeletePrivateMessage {
|
|||
PrivateMessage::read(conn, private_message_id)
|
||||
})
|
||||
.await??;
|
||||
if user.id != orig_private_message.creator_id {
|
||||
if local_user_view.person.id != orig_private_message.creator_id {
|
||||
return Err(ApiError::err("no_private_message_edit_allowed").into());
|
||||
}
|
||||
|
||||
|
@ -1214,22 +1273,24 @@ impl Perform for DeletePrivateMessage {
|
|||
|
||||
// Send the apub update
|
||||
if data.deleted {
|
||||
updated_private_message.send_delete(&user, context).await?;
|
||||
updated_private_message
|
||||
.send_delete(&local_user_view.person, context)
|
||||
.await?;
|
||||
} else {
|
||||
updated_private_message
|
||||
.send_undo_delete(&user, context)
|
||||
.send_undo_delete(&local_user_view.person, context)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let private_message_id = data.private_message_id;
|
||||
let message = blocking(context.pool(), move |conn| {
|
||||
let private_message_view = blocking(context.pool(), move |conn| {
|
||||
PrivateMessageView::read(conn, private_message_id)
|
||||
})
|
||||
.await??;
|
||||
let recipient_id = message.recipient.id;
|
||||
let recipient_id = private_message_view.recipient.id;
|
||||
|
||||
let res = PrivateMessageResponse {
|
||||
private_message_view: message,
|
||||
private_message_view,
|
||||
};
|
||||
|
||||
context.chat_server().do_send(SendUserRoomMessage {
|
||||
|
@ -1253,7 +1314,7 @@ impl Perform for MarkPrivateMessageAsRead {
|
|||
websocket_id: Option<ConnectionId>,
|
||||
) -> Result<PrivateMessageResponse, LemmyError> {
|
||||
let data: &MarkPrivateMessageAsRead = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
// Checking permissions
|
||||
let private_message_id = data.private_message_id;
|
||||
|
@ -1261,7 +1322,7 @@ impl Perform for MarkPrivateMessageAsRead {
|
|||
PrivateMessage::read(conn, private_message_id)
|
||||
})
|
||||
.await??;
|
||||
if user.id != orig_private_message.recipient_id {
|
||||
if local_user_view.person.id != orig_private_message.recipient_id {
|
||||
return Err(ApiError::err("couldnt_update_private_message").into());
|
||||
}
|
||||
|
||||
|
@ -1280,14 +1341,14 @@ impl Perform for MarkPrivateMessageAsRead {
|
|||
// No need to send an apub update
|
||||
|
||||
let private_message_id = data.private_message_id;
|
||||
let message = blocking(context.pool(), move |conn| {
|
||||
let private_message_view = blocking(context.pool(), move |conn| {
|
||||
PrivateMessageView::read(conn, private_message_id)
|
||||
})
|
||||
.await??;
|
||||
let recipient_id = message.recipient.id;
|
||||
let recipient_id = private_message_view.recipient.id;
|
||||
|
||||
let res = PrivateMessageResponse {
|
||||
private_message_view: message,
|
||||
private_message_view,
|
||||
};
|
||||
|
||||
context.chat_server().do_send(SendUserRoomMessage {
|
||||
|
@ -1311,14 +1372,14 @@ impl Perform for GetPrivateMessages {
|
|||
_websocket_id: Option<ConnectionId>,
|
||||
) -> Result<PrivateMessagesResponse, LemmyError> {
|
||||
let data: &GetPrivateMessages = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let user_id = user.id;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let person_id = local_user_view.person.id;
|
||||
|
||||
let page = data.page;
|
||||
let limit = data.limit;
|
||||
let unread_only = data.unread_only;
|
||||
let messages = blocking(context.pool(), move |conn| {
|
||||
PrivateMessageQueryBuilder::create(&conn, user_id)
|
||||
PrivateMessageQueryBuilder::create(&conn, person_id)
|
||||
.page(page)
|
||||
.limit(limit)
|
||||
.unread_only(unread_only)
|
||||
|
@ -1342,12 +1403,12 @@ impl Perform for GetReportCount {
|
|||
websocket_id: Option<ConnectionId>,
|
||||
) -> Result<GetReportCountResponse, LemmyError> {
|
||||
let data: &GetReportCount = &self;
|
||||
let user = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
let user_id = user.id;
|
||||
let person_id = local_user_view.person.id;
|
||||
let community_id = data.community;
|
||||
let community_ids =
|
||||
collect_moderated_communities(user_id, community_id, context.pool()).await?;
|
||||
collect_moderated_communities(person_id, community_id, context.pool()).await?;
|
||||
|
||||
let res = {
|
||||
if community_ids.is_empty() {
|
||||
|
@ -1380,7 +1441,7 @@ impl Perform for GetReportCount {
|
|||
context.chat_server().do_send(SendUserRoomMessage {
|
||||
op: UserOperation::GetReportCount,
|
||||
response: res.clone(),
|
||||
recipient_id: user.id,
|
||||
recipient_id: local_user_view.person.id,
|
||||
websocket_id,
|
||||
});
|
||||
|
|
@ -122,7 +122,9 @@ impl Perform for CreatePost {
|
|||
Err(_e) => return Err(ApiError::err("couldnt_create_post").into()),
|
||||
};
|
||||
|
||||
updated_post.send_create(&local_user_view.person, context).await?;
|
||||
updated_post
|
||||
.send_create(&local_user_view.person, context)
|
||||
.await?;
|
||||
|
||||
// They like their own post by default
|
||||
let like_form = PostLikeForm {
|
||||
|
@ -136,7 +138,9 @@ impl Perform for CreatePost {
|
|||
return Err(ApiError::err("couldnt_like_post").into());
|
||||
}
|
||||
|
||||
updated_post.send_like(&local_user_view.person, context).await?;
|
||||
updated_post
|
||||
.send_like(&local_user_view.person, context)
|
||||
.await?;
|
||||
|
||||
// Refetch the view
|
||||
let inserted_post_id = inserted_post.id;
|
||||
|
@ -327,7 +331,9 @@ impl Perform for CreatePostLike {
|
|||
post.send_dislike(&local_user_view.person, context).await?;
|
||||
}
|
||||
} else {
|
||||
post.send_undo_like(&local_user_view.person, context).await?;
|
||||
post
|
||||
.send_undo_like(&local_user_view.person, context)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let post_id = data.post_id;
|
||||
|
@ -375,7 +381,12 @@ impl Perform for EditPost {
|
|||
let post_id = data.post_id;
|
||||
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||
|
||||
check_community_ban(local_user_view.person.id, orig_post.community_id, context.pool()).await?;
|
||||
check_community_ban(
|
||||
local_user_view.person.id,
|
||||
orig_post.community_id,
|
||||
context.pool(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Verify that only the creator can edit
|
||||
if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) {
|
||||
|
@ -427,7 +438,9 @@ impl Perform for EditPost {
|
|||
};
|
||||
|
||||
// Send apub update
|
||||
updated_post.send_update(&local_user_view.person, context).await?;
|
||||
updated_post
|
||||
.send_update(&local_user_view.person, context)
|
||||
.await?;
|
||||
|
||||
let post_id = data.post_id;
|
||||
let post_view = blocking(context.pool(), move |conn| {
|
||||
|
@ -462,7 +475,12 @@ impl Perform for DeletePost {
|
|||
let post_id = data.post_id;
|
||||
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||
|
||||
check_community_ban(local_user_view.person.id, orig_post.community_id, context.pool()).await?;
|
||||
check_community_ban(
|
||||
local_user_view.person.id,
|
||||
orig_post.community_id,
|
||||
context.pool(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Verify that only the creator can delete
|
||||
if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) {
|
||||
|
@ -479,9 +497,13 @@ impl Perform for DeletePost {
|
|||
|
||||
// apub updates
|
||||
if deleted {
|
||||
updated_post.send_delete(&local_user_view.person, context).await?;
|
||||
updated_post
|
||||
.send_delete(&local_user_view.person, context)
|
||||
.await?;
|
||||
} else {
|
||||
updated_post.send_undo_delete(&local_user_view.person, context).await?;
|
||||
updated_post
|
||||
.send_undo_delete(&local_user_view.person, context)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Refetch the post
|
||||
|
@ -518,10 +540,20 @@ impl Perform for RemovePost {
|
|||
let post_id = data.post_id;
|
||||
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||
|
||||
check_community_ban(local_user_view.person.id, orig_post.community_id, context.pool()).await?;
|
||||
check_community_ban(
|
||||
local_user_view.person.id,
|
||||
orig_post.community_id,
|
||||
context.pool(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Verify that only the mods can remove
|
||||
is_mod_or_admin(context.pool(), local_user_view.person.id, orig_post.community_id).await?;
|
||||
is_mod_or_admin(
|
||||
context.pool(),
|
||||
local_user_view.person.id,
|
||||
orig_post.community_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Update the post
|
||||
let post_id = data.post_id;
|
||||
|
@ -545,9 +577,13 @@ impl Perform for RemovePost {
|
|||
|
||||
// apub updates
|
||||
if removed {
|
||||
updated_post.send_remove(&local_user_view.person, context).await?;
|
||||
updated_post
|
||||
.send_remove(&local_user_view.person, context)
|
||||
.await?;
|
||||
} else {
|
||||
updated_post.send_undo_remove(&local_user_view.person, context).await?;
|
||||
updated_post
|
||||
.send_undo_remove(&local_user_view.person, context)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Refetch the post
|
||||
|
@ -585,10 +621,20 @@ impl Perform for LockPost {
|
|||
let post_id = data.post_id;
|
||||
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||
|
||||
check_community_ban(local_user_view.person.id, orig_post.community_id, context.pool()).await?;
|
||||
check_community_ban(
|
||||
local_user_view.person.id,
|
||||
orig_post.community_id,
|
||||
context.pool(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Verify that only the mods can lock
|
||||
is_mod_or_admin(context.pool(), local_user_view.person.id, orig_post.community_id).await?;
|
||||
is_mod_or_admin(
|
||||
context.pool(),
|
||||
local_user_view.person.id,
|
||||
orig_post.community_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Update the post
|
||||
let post_id = data.post_id;
|
||||
|
@ -607,7 +653,9 @@ impl Perform for LockPost {
|
|||
blocking(context.pool(), move |conn| ModLockPost::create(conn, &form)).await??;
|
||||
|
||||
// apub updates
|
||||
updated_post.send_update(&local_user_view.person, context).await?;
|
||||
updated_post
|
||||
.send_update(&local_user_view.person, context)
|
||||
.await?;
|
||||
|
||||
// Refetch the post
|
||||
let post_id = data.post_id;
|
||||
|
@ -643,10 +691,20 @@ impl Perform for StickyPost {
|
|||
let post_id = data.post_id;
|
||||
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||
|
||||
check_community_ban(local_user_view.person.id, orig_post.community_id, context.pool()).await?;
|
||||
check_community_ban(
|
||||
local_user_view.person.id,
|
||||
orig_post.community_id,
|
||||
context.pool(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Verify that only the mods can sticky
|
||||
is_mod_or_admin(context.pool(), local_user_view.person.id, orig_post.community_id).await?;
|
||||
is_mod_or_admin(
|
||||
context.pool(),
|
||||
local_user_view.person.id,
|
||||
orig_post.community_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Update the post
|
||||
let post_id = data.post_id;
|
||||
|
@ -669,7 +727,9 @@ impl Perform for StickyPost {
|
|||
|
||||
// Apub updates
|
||||
// TODO stickied should pry work like locked for ease of use
|
||||
updated_post.send_update(&local_user_view.person, context).await?;
|
||||
updated_post
|
||||
.send_update(&local_user_view.person, context)
|
||||
.await?;
|
||||
|
||||
// Refetch the post
|
||||
let post_id = data.post_id;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::Perform;
|
||||
use actix_web::{error::ErrorBadRequest, *};
|
||||
use lemmy_api_structs::{comment::*, community::*, post::*, site::*, person::*, websocket::*};
|
||||
use lemmy_api_structs::{comment::*, community::*, person::*, post::*, site::*, websocket::*};
|
||||
use lemmy_utils::rate_limit::RateLimit;
|
||||
use lemmy_websocket::{routes::chat_route, LemmyContext};
|
||||
use serde::Deserialize;
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
use crate::{
|
||||
build_federated_instances,
|
||||
get_local_user_settings_view_from_jwt,
|
||||
get_local_user_settings_view_from_jwt_opt,
|
||||
get_local_user_view_from_jwt,
|
||||
get_local_user_view_from_jwt_opt,
|
||||
get_local_user_settings_view_from_jwt_opt,
|
||||
is_admin,
|
||||
Perform,
|
||||
};
|
||||
use actix_web::web::Data;
|
||||
use anyhow::Context;
|
||||
use lemmy_api_structs::{blocking, site::*, person::Register};
|
||||
use lemmy_api_structs::{blocking, person::Register, site::*};
|
||||
use lemmy_apub::fetcher::search::search_by_apub_id;
|
||||
use lemmy_db_queries::{
|
||||
diesel_option_overwrite_to_url,
|
||||
|
@ -536,13 +537,15 @@ impl Perform for TransferSite {
|
|||
let banned = blocking(context.pool(), move |conn| PersonViewSafe::banned(conn)).await??;
|
||||
let federated_instances = build_federated_instances(context.pool()).await?;
|
||||
|
||||
let my_user = Some(get_local_user_settings_view_from_jwt(&data.auth, context.pool()).await?);
|
||||
|
||||
Ok(GetSiteResponse {
|
||||
site_view: Some(site_view),
|
||||
admins,
|
||||
banned,
|
||||
online: 0,
|
||||
version: version::VERSION.to_string(),
|
||||
my_user: Some(local_user_view),
|
||||
my_user,
|
||||
federated_instances,
|
||||
})
|
||||
}
|
||||
|
@ -582,7 +585,6 @@ impl Perform for SaveSiteConfig {
|
|||
let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
// Only let admins read this
|
||||
let person_id = local_user_view.person.id;
|
||||
is_admin(&local_user_view)?;
|
||||
|
||||
// Make sure docker doesn't have :ro at the end of the volume, so its not a read-only filesystem
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
pub mod comment;
|
||||
pub mod community;
|
||||
pub mod person;
|
||||
pub mod post;
|
||||
pub mod site;
|
||||
pub mod person;
|
||||
pub mod websocket;
|
||||
|
||||
use diesel::PgConnection;
|
||||
use lemmy_db_queries::{Crud, DbPool};
|
||||
use lemmy_db_schema::source::{
|
||||
comment::Comment,
|
||||
post::Post,
|
||||
person::Person,
|
||||
person_mention::{PersonMention, PersonMentionForm},
|
||||
post::Post,
|
||||
};
|
||||
use lemmy_db_views::local_user_view::LocalUserView;
|
||||
use lemmy_utils::{email::send_email, settings::structs::Settings, utils::MentionData, LemmyError};
|
||||
|
@ -119,11 +119,17 @@ fn do_send_local_notifs(
|
|||
Some(parent_id) => {
|
||||
if let Ok(parent_comment) = Comment::read(&conn, parent_id) {
|
||||
if parent_comment.creator_id != person.id {
|
||||
if let Ok(parent_user_view) = LocalUserView::read(&conn, parent_comment.creator_id) {
|
||||
if let Ok(parent_user_view) = LocalUserView::read_person(&conn, parent_comment.creator_id)
|
||||
{
|
||||
recipient_ids.push(parent_user_view.person.id);
|
||||
|
||||
if do_send_email && parent_user_view.local_user.send_notifications_to_email {
|
||||
send_email_to_user(parent_user_view, "Reply from", "Comment Reply", &comment.content)
|
||||
send_email_to_user(
|
||||
parent_user_view,
|
||||
"Reply from",
|
||||
"Comment Reply",
|
||||
&comment.content,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,11 +138,16 @@ fn do_send_local_notifs(
|
|||
// Its a post
|
||||
None => {
|
||||
if post.creator_id != person.id {
|
||||
if let Ok(parent_user_view) = LocalUserView::read(&conn, post.creator_id) {
|
||||
if let Ok(parent_user_view) = LocalUserView::read_person(&conn, post.creator_id) {
|
||||
recipient_ids.push(parent_user_view.person.id);
|
||||
|
||||
if do_send_email && parent_user_view.local_user.send_notifications_to_email {
|
||||
send_email_to_user(parent_user_view, "Reply from", "Post Reply", &comment.content)
|
||||
send_email_to_user(
|
||||
parent_user_view,
|
||||
"Reply from",
|
||||
"Post Reply",
|
||||
&comment.content,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +156,12 @@ fn do_send_local_notifs(
|
|||
recipient_ids
|
||||
}
|
||||
|
||||
pub fn send_email_to_user(local_user_view: LocalUserView, subject_text: &str, body_text: &str, comment_content: &str) {
|
||||
pub fn send_email_to_user(
|
||||
local_user_view: LocalUserView,
|
||||
subject_text: &str,
|
||||
body_text: &str,
|
||||
comment_content: &str,
|
||||
) {
|
||||
if local_user_view.person.banned {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -45,11 +45,11 @@ pub struct CaptchaResponse {
|
|||
|
||||
#[derive(Deserialize)]
|
||||
pub struct SaveUserSettings {
|
||||
pub show_nsfw: bool,
|
||||
pub theme: String,
|
||||
pub default_sort_type: i16,
|
||||
pub default_listing_type: i16,
|
||||
pub lang: String,
|
||||
pub show_nsfw: Option<bool>,
|
||||
pub theme: Option<String>,
|
||||
pub default_sort_type: Option<i16>,
|
||||
pub default_listing_type: Option<i16>,
|
||||
pub lang: Option<String>,
|
||||
pub avatar: Option<String>,
|
||||
pub banner: Option<String>,
|
||||
pub preferred_username: Option<String>,
|
||||
|
@ -59,8 +59,8 @@ pub struct SaveUserSettings {
|
|||
pub new_password: Option<String>,
|
||||
pub new_password_verify: Option<String>,
|
||||
pub old_password: Option<String>,
|
||||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub show_avatars: Option<bool>,
|
||||
pub send_notifications_to_email: Option<bool>,
|
||||
pub auth: String,
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ pub struct MarkAllAsRead {
|
|||
|
||||
#[derive(Deserialize)]
|
||||
pub struct AddAdmin {
|
||||
pub person_id: i32,
|
||||
pub local_user_id: i32,
|
||||
pub added: bool,
|
||||
pub auth: String,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
use lemmy_db_views::{comment_view::CommentView, post_view::PostView, site_view::SiteView, local_user_view::LocalUserSettingsView};
|
||||
use lemmy_db_views::{
|
||||
comment_view::CommentView,
|
||||
local_user_view::LocalUserSettingsView,
|
||||
post_view::PostView,
|
||||
site_view::SiteView,
|
||||
};
|
||||
use lemmy_db_views_actor::{community_view::CommunityView, person_view::PersonViewSafe};
|
||||
use lemmy_db_views_moderator::{
|
||||
mod_add_community_view::ModAddCommunityView,
|
||||
|
|
|
@ -33,8 +33,15 @@ pub(crate) async fn receive_create_comment(
|
|||
// Its much easier to scrape them from the comment body, since the API has to do that
|
||||
// anyway.
|
||||
let mentions = scrape_text_for_mentions(&comment.content);
|
||||
let recipient_ids =
|
||||
send_local_notifs(mentions, comment.clone(), person, post, context.pool(), true).await?;
|
||||
let recipient_ids = send_local_notifs(
|
||||
mentions,
|
||||
comment.clone(),
|
||||
person,
|
||||
post,
|
||||
context.pool(),
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Refetch the view
|
||||
let comment_view = blocking(context.pool(), move |conn| {
|
||||
|
|
|
@ -28,7 +28,7 @@ use anyhow::anyhow;
|
|||
use itertools::Itertools;
|
||||
use lemmy_api_structs::{blocking, WebFingerResponse};
|
||||
use lemmy_db_queries::{Crud, DbPool};
|
||||
use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post, person::Person};
|
||||
use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post};
|
||||
use lemmy_utils::{
|
||||
request::{retry, RecvError},
|
||||
settings::structs::Settings,
|
||||
|
@ -197,7 +197,11 @@ impl ApubObjectType for Comment {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn send_undo_remove(&self, mod_: &Person, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
async fn send_undo_remove(
|
||||
&self,
|
||||
mod_: &Person,
|
||||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError> {
|
||||
let post_id = self.post_id;
|
||||
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||
|
||||
|
@ -389,7 +393,10 @@ async fn collect_non_local_mentions(
|
|||
|
||||
/// Returns the apub ID of the person this comment is responding to. Meaning, in case this is a
|
||||
/// top-level comment, the creator of the post, otherwise the creator of the parent comment.
|
||||
async fn get_comment_parent_creator(pool: &DbPool, comment: &Comment) -> Result<Person, LemmyError> {
|
||||
async fn get_comment_parent_creator(
|
||||
pool: &DbPool,
|
||||
comment: &Comment,
|
||||
) -> Result<Person, LemmyError> {
|
||||
let parent_creator_id = if let Some(parent_comment_id) = comment.parent_id {
|
||||
let parent_comment =
|
||||
blocking(pool, move |conn| Comment::read(conn, parent_comment_id)).await??;
|
||||
|
|
|
@ -4,9 +4,9 @@ use uuid::Uuid;
|
|||
|
||||
pub(crate) mod comment;
|
||||
pub(crate) mod community;
|
||||
pub(crate) mod person;
|
||||
pub(crate) mod post;
|
||||
pub(crate) mod private_message;
|
||||
pub(crate) mod person;
|
||||
|
||||
/// Generate a unique ID for an activity, in the format:
|
||||
/// `http(s)://example.com/receive/create/202daf0a-1489-45df-8d2e-c8a3173fed36`
|
||||
|
|
|
@ -23,7 +23,7 @@ use activitystreams::{
|
|||
};
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::Crud;
|
||||
use lemmy_db_schema::source::{community::Community, post::Post, person::Person};
|
||||
use lemmy_db_schema::source::{community::Community, person::Person, post::Post};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
||||
|
@ -155,7 +155,11 @@ impl ApubObjectType for Post {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn send_undo_remove(&self, mod_: &Person, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
async fn send_undo_remove(
|
||||
&self,
|
||||
mod_: &Person,
|
||||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError> {
|
||||
let community_id = self.community_id;
|
||||
let community = blocking(context.pool(), move |conn| {
|
||||
Community::read(conn, community_id)
|
||||
|
|
|
@ -18,7 +18,7 @@ use activitystreams::{
|
|||
};
|
||||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::Crud;
|
||||
use lemmy_db_schema::source::{private_message::PrivateMessage, person::Person};
|
||||
use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
||||
|
@ -29,7 +29,8 @@ impl ApubObjectType for PrivateMessage {
|
|||
let note = self.to_apub(context.pool()).await?;
|
||||
|
||||
let recipient_id = self.recipient_id;
|
||||
let recipient = blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
|
||||
let recipient =
|
||||
blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
|
||||
|
||||
let mut create = Create::new(
|
||||
creator.actor_id.to_owned().into_inner(),
|
||||
|
@ -50,7 +51,8 @@ impl ApubObjectType for PrivateMessage {
|
|||
let note = self.to_apub(context.pool()).await?;
|
||||
|
||||
let recipient_id = self.recipient_id;
|
||||
let recipient = blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
|
||||
let recipient =
|
||||
blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
|
||||
|
||||
let mut update = Update::new(
|
||||
creator.actor_id.to_owned().into_inner(),
|
||||
|
@ -67,7 +69,8 @@ impl ApubObjectType for PrivateMessage {
|
|||
|
||||
async fn send_delete(&self, creator: &Person, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
let recipient_id = self.recipient_id;
|
||||
let recipient = blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
|
||||
let recipient =
|
||||
blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
|
||||
|
||||
let mut delete = Delete::new(
|
||||
creator.actor_id.to_owned().into_inner(),
|
||||
|
@ -88,7 +91,8 @@ impl ApubObjectType for PrivateMessage {
|
|||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError> {
|
||||
let recipient_id = self.recipient_id;
|
||||
let recipient = blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
|
||||
let recipient =
|
||||
blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
|
||||
|
||||
let mut delete = Delete::new(
|
||||
creator.actor_id.to_owned().into_inner(),
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
pub(crate) mod community;
|
||||
mod fetch;
|
||||
pub(crate) mod objects;
|
||||
pub mod search;
|
||||
pub(crate) mod person;
|
||||
pub mod search;
|
||||
|
||||
use crate::{
|
||||
fetcher::{
|
||||
|
|
|
@ -46,7 +46,8 @@ pub(crate) async fn get_or_fetch_and_upsert_person(
|
|||
return Ok(u);
|
||||
}
|
||||
|
||||
let person = Person::from_apub(&person?, context, apub_id.to_owned(), recursion_counter).await?;
|
||||
let person =
|
||||
Person::from_apub(&person?, context, apub_id.to_owned(), recursion_counter).await?;
|
||||
|
||||
let person_id = person.id;
|
||||
blocking(context.pool(), move |conn| {
|
||||
|
@ -62,7 +63,8 @@ pub(crate) async fn get_or_fetch_and_upsert_person(
|
|||
let person =
|
||||
fetch_remote_object::<PersonExt>(context.client(), apub_id, recursion_counter).await?;
|
||||
|
||||
let person = Person::from_apub(&person, context, apub_id.to_owned(), recursion_counter).await?;
|
||||
let person =
|
||||
Person::from_apub(&person, context, apub_id.to_owned(), recursion_counter).await?;
|
||||
|
||||
Ok(person)
|
||||
}
|
||||
|
|
|
@ -20,18 +20,18 @@ use lemmy_db_queries::{
|
|||
source::{
|
||||
comment::Comment_,
|
||||
community::Community_,
|
||||
person::Person_,
|
||||
post::Post_,
|
||||
private_message::PrivateMessage_,
|
||||
person::Person_,
|
||||
},
|
||||
SearchType,
|
||||
};
|
||||
use lemmy_db_schema::source::{
|
||||
comment::Comment,
|
||||
community::Community,
|
||||
person::Person,
|
||||
post::Post,
|
||||
private_message::PrivateMessage,
|
||||
person::Person,
|
||||
};
|
||||
use lemmy_db_views::{comment_view::CommentView, post_view::PostView};
|
||||
use lemmy_db_views_actor::{community_view::CommunityView, person_view::PersonViewSafe};
|
||||
|
|
|
@ -11,8 +11,8 @@ use url::Url;
|
|||
|
||||
pub mod comment;
|
||||
pub mod community;
|
||||
pub mod post;
|
||||
pub mod person;
|
||||
pub mod post;
|
||||
|
||||
/// Convert the data to json and turn it into an HTTP Response with the correct ActivityPub
|
||||
/// headers.
|
||||
|
|
|
@ -268,7 +268,8 @@ pub(crate) async fn check_community_or_site_ban(
|
|||
return Err(anyhow!("Person is banned from site").into());
|
||||
}
|
||||
let person_id = person.id;
|
||||
let is_banned = move |conn: &'_ _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok();
|
||||
let is_banned =
|
||||
move |conn: &'_ _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok();
|
||||
if blocking(pool, is_banned).await? {
|
||||
return Err(anyhow!("Person is banned from community").into());
|
||||
}
|
||||
|
|
|
@ -26,9 +26,9 @@ use std::fmt::Debug;
|
|||
use url::Url;
|
||||
|
||||
pub mod community_inbox;
|
||||
pub mod person_inbox;
|
||||
mod receive_for_community;
|
||||
pub mod shared_inbox;
|
||||
pub mod person_inbox;
|
||||
|
||||
pub(crate) fn get_activity_id<T, Kind>(activity: &T, creator_uri: &Url) -> Result<Url, LemmyError>
|
||||
where
|
||||
|
|
|
@ -52,8 +52,8 @@ use lemmy_api_structs::blocking;
|
|||
use lemmy_db_queries::{source::person::Person_, ApubObject, Followable};
|
||||
use lemmy_db_schema::source::{
|
||||
community::{Community, CommunityFollower},
|
||||
private_message::PrivateMessage,
|
||||
person::Person,
|
||||
private_message::PrivateMessage,
|
||||
};
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
|
|
@ -31,9 +31,9 @@ use lemmy_db_schema::{
|
|||
activity::Activity,
|
||||
comment::Comment,
|
||||
community::Community,
|
||||
person::Person as DbPerson,
|
||||
post::Post,
|
||||
private_message::PrivateMessage,
|
||||
person::Person as DbPerson,
|
||||
},
|
||||
DbUrl,
|
||||
};
|
||||
|
@ -121,24 +121,38 @@ fn check_is_apub_id_valid(apub_id: &Url) -> Result<(), LemmyError> {
|
|||
/// and actors in Lemmy.
|
||||
#[async_trait::async_trait(?Send)]
|
||||
pub trait ApubObjectType {
|
||||
async fn send_create(&self, creator: &DbPerson, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_update(&self, creator: &DbPerson, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_delete(&self, creator: &DbPerson, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_create(&self, creator: &DbPerson, context: &LemmyContext)
|
||||
-> Result<(), LemmyError>;
|
||||
async fn send_update(&self, creator: &DbPerson, context: &LemmyContext)
|
||||
-> Result<(), LemmyError>;
|
||||
async fn send_delete(&self, creator: &DbPerson, context: &LemmyContext)
|
||||
-> Result<(), LemmyError>;
|
||||
async fn send_undo_delete(
|
||||
&self,
|
||||
creator: &DbPerson,
|
||||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError>;
|
||||
async fn send_remove(&self, mod_: &DbPerson, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_undo_remove(&self, mod_: &DbPerson, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_undo_remove(
|
||||
&self,
|
||||
mod_: &DbPerson,
|
||||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError>;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
pub trait ApubLikeableType {
|
||||
async fn send_like(&self, creator: &DbPerson, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_dislike(&self, creator: &DbPerson, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||
async fn send_undo_like(&self, creator: &DbPerson, context: &LemmyContext)
|
||||
-> Result<(), LemmyError>;
|
||||
async fn send_dislike(
|
||||
&self,
|
||||
creator: &DbPerson,
|
||||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError>;
|
||||
async fn send_undo_like(
|
||||
&self,
|
||||
creator: &DbPerson,
|
||||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError>;
|
||||
}
|
||||
|
||||
/// Common methods provided by ActivityPub actors (community and person). Not all methods are
|
||||
|
@ -316,11 +330,11 @@ pub(crate) async fn find_post_or_comment_by_id(
|
|||
}
|
||||
|
||||
pub(crate) enum Object {
|
||||
Comment(Comment),
|
||||
Post(Post),
|
||||
Community(Community),
|
||||
Person(DbPerson),
|
||||
PrivateMessage(PrivateMessage),
|
||||
Comment(Box<Comment>),
|
||||
Post(Box<Post>),
|
||||
Community(Box<Community>),
|
||||
Person(Box<DbPerson>),
|
||||
PrivateMessage(Box<PrivateMessage>),
|
||||
}
|
||||
|
||||
pub(crate) async fn find_object_by_id(
|
||||
|
@ -330,8 +344,8 @@ pub(crate) async fn find_object_by_id(
|
|||
let ap_id = apub_id.clone();
|
||||
if let Ok(pc) = find_post_or_comment_by_id(context, ap_id.to_owned()).await {
|
||||
return Ok(match pc {
|
||||
PostOrComment::Post(p) => Object::Post(*p),
|
||||
PostOrComment::Comment(c) => Object::Comment(*c),
|
||||
PostOrComment::Post(p) => Object::Post(Box::new(*p)),
|
||||
PostOrComment::Comment(c) => Object::Comment(Box::new(*c)),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -341,7 +355,7 @@ pub(crate) async fn find_object_by_id(
|
|||
})
|
||||
.await?;
|
||||
if let Ok(u) = person {
|
||||
return Ok(Object::Person(u));
|
||||
return Ok(Object::Person(Box::new(u)));
|
||||
}
|
||||
|
||||
let ap_id = apub_id.clone();
|
||||
|
@ -350,7 +364,7 @@ pub(crate) async fn find_object_by_id(
|
|||
})
|
||||
.await?;
|
||||
if let Ok(c) = community {
|
||||
return Ok(Object::Community(c));
|
||||
return Ok(Object::Community(Box::new(c)));
|
||||
}
|
||||
|
||||
let private_message = blocking(context.pool(), move |conn| {
|
||||
|
@ -358,7 +372,7 @@ pub(crate) async fn find_object_by_id(
|
|||
})
|
||||
.await?;
|
||||
if let Ok(pm) = private_message {
|
||||
return Ok(Object::PrivateMessage(pm));
|
||||
return Ok(Object::PrivateMessage(Box::new(pm)));
|
||||
}
|
||||
|
||||
Err(NotFound.into())
|
||||
|
|
|
@ -25,8 +25,8 @@ use lemmy_api_structs::blocking;
|
|||
use lemmy_db_queries::{Crud, DbPool};
|
||||
use lemmy_db_schema::source::{
|
||||
comment::{Comment, CommentForm},
|
||||
post::Post,
|
||||
person::Person,
|
||||
post::Post,
|
||||
};
|
||||
use lemmy_utils::{
|
||||
location_info,
|
||||
|
@ -135,7 +135,8 @@ impl FromApubToForm<NoteExt> for CommentForm {
|
|||
.as_single_xsd_any_uri()
|
||||
.context(location_info!())?;
|
||||
|
||||
let creator = get_or_fetch_and_upsert_person(creator_actor_id, context, request_counter).await?;
|
||||
let creator =
|
||||
get_or_fetch_and_upsert_person(creator_actor_id, context, request_counter).await?;
|
||||
|
||||
let mut in_reply_tos = note
|
||||
.in_reply_to()
|
||||
|
|
|
@ -26,9 +26,9 @@ use url::Url;
|
|||
|
||||
pub(crate) mod comment;
|
||||
pub(crate) mod community;
|
||||
pub(crate) mod person;
|
||||
pub(crate) mod post;
|
||||
pub(crate) mod private_message;
|
||||
pub(crate) mod person;
|
||||
|
||||
/// Trait for converting an object or actor into the respective ActivityPub type.
|
||||
#[async_trait::async_trait(?Send)]
|
||||
|
|
|
@ -22,7 +22,7 @@ use lemmy_api_structs::blocking;
|
|||
use lemmy_db_queries::{ApubObject, DbPool};
|
||||
use lemmy_db_schema::{
|
||||
naive_now,
|
||||
source::person::{PersonForm, Person as DbPerson},
|
||||
source::person::{Person as DbPerson, PersonForm},
|
||||
};
|
||||
use lemmy_utils::{
|
||||
location_info,
|
||||
|
@ -105,7 +105,10 @@ impl FromApub for DbPerson {
|
|||
} else {
|
||||
let person_form =
|
||||
PersonForm::from_apub(person, context, expected_domain, request_counter).await?;
|
||||
let person = blocking(context.pool(), move |conn| DbPerson::upsert(conn, &person_form)).await??;
|
||||
let person = blocking(context.pool(), move |conn| {
|
||||
DbPerson::upsert(conn, &person_form)
|
||||
})
|
||||
.await??;
|
||||
Ok(person)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ use lemmy_db_schema::{
|
|||
self,
|
||||
source::{
|
||||
community::Community,
|
||||
post::{Post, PostForm},
|
||||
person::Person,
|
||||
post::{Post, PostForm},
|
||||
},
|
||||
};
|
||||
use lemmy_utils::{
|
||||
|
@ -142,7 +142,8 @@ impl FromApubToForm<PageExt> for PostForm {
|
|||
.as_single_xsd_any_uri()
|
||||
.context(location_info!())?;
|
||||
|
||||
let creator = get_or_fetch_and_upsert_person(creator_actor_id, context, request_counter).await?;
|
||||
let creator =
|
||||
get_or_fetch_and_upsert_person(creator_actor_id, context, request_counter).await?;
|
||||
|
||||
let community = get_to_community(page, context, request_counter).await?;
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ use anyhow::Context;
|
|||
use lemmy_api_structs::blocking;
|
||||
use lemmy_db_queries::{Crud, DbPool};
|
||||
use lemmy_db_schema::source::{
|
||||
private_message::{PrivateMessage, PrivateMessageForm},
|
||||
person::Person,
|
||||
private_message::{PrivateMessage, PrivateMessageForm},
|
||||
};
|
||||
use lemmy_utils::{location_info, utils::convert_datetime, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
@ -97,7 +97,8 @@ impl FromApubToForm<NoteExt> for PrivateMessageForm {
|
|||
.single_xsd_any_uri()
|
||||
.context(location_info!())?;
|
||||
|
||||
let creator = get_or_fetch_and_upsert_person(&creator_actor_id, context, request_counter).await?;
|
||||
let creator =
|
||||
get_or_fetch_and_upsert_person(&creator_actor_id, context, request_counter).await?;
|
||||
let recipient_actor_id = note
|
||||
.to()
|
||||
.context(location_info!())?
|
||||
|
|
|
@ -8,10 +8,14 @@ use crate::{
|
|||
get_apub_community_outbox,
|
||||
},
|
||||
get_activity,
|
||||
post::get_apub_post,
|
||||
person::{get_apub_person_http, get_apub_person_inbox, get_apub_person_outbox},
|
||||
post::get_apub_post,
|
||||
},
|
||||
inbox::{
|
||||
community_inbox::community_inbox,
|
||||
person_inbox::person_inbox,
|
||||
shared_inbox::shared_inbox,
|
||||
},
|
||||
inbox::{community_inbox::community_inbox, shared_inbox::shared_inbox, person_inbox::person_inbox},
|
||||
APUB_JSON_CONTENT_TYPE,
|
||||
};
|
||||
use actix_web::*;
|
||||
|
@ -54,7 +58,10 @@ pub fn config(cfg: &mut web::ServiceConfig) {
|
|||
web::get().to(get_apub_community_inbox),
|
||||
)
|
||||
.route("/u/{user_name}", web::get().to(get_apub_person_http))
|
||||
.route("/u/{user_name}/outbox", web::get().to(get_apub_person_outbox))
|
||||
.route(
|
||||
"/u/{user_name}/outbox",
|
||||
web::get().to(get_apub_person_outbox),
|
||||
)
|
||||
.route("/u/{user_name}/inbox", web::get().to(get_apub_person_inbox))
|
||||
.route("/post/{post_id}", web::get().to(get_apub_post))
|
||||
.route("/comment/{comment_id}", web::get().to(get_apub_comment))
|
||||
|
|
|
@ -32,8 +32,8 @@ mod tests {
|
|||
use lemmy_db_schema::source::{
|
||||
comment::{Comment, CommentForm, CommentLike, CommentLikeForm},
|
||||
community::{Community, CommunityForm},
|
||||
person::{Person, PersonForm},
|
||||
post::{Post, PostForm},
|
||||
person::{PersonForm, Person},
|
||||
};
|
||||
use serial_test::serial;
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ mod tests {
|
|||
use lemmy_db_schema::source::{
|
||||
comment::{Comment, CommentForm},
|
||||
community::{Community, CommunityFollower, CommunityFollowerForm, CommunityForm},
|
||||
person::{Person, PersonForm},
|
||||
post::{Post, PostForm},
|
||||
person::{PersonForm, Person},
|
||||
};
|
||||
use serial_test::serial;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
pub mod comment_aggregates;
|
||||
pub mod community_aggregates;
|
||||
pub mod person_aggregates;
|
||||
pub mod post_aggregates;
|
||||
pub mod site_aggregates;
|
||||
pub mod person_aggregates;
|
||||
|
|
|
@ -32,8 +32,8 @@ mod tests {
|
|||
use lemmy_db_schema::source::{
|
||||
comment::{Comment, CommentForm, CommentLike, CommentLikeForm},
|
||||
community::{Community, CommunityForm},
|
||||
person::{Person, PersonForm},
|
||||
post::{Post, PostForm, PostLike, PostLikeForm},
|
||||
person::{PersonForm, Person},
|
||||
};
|
||||
use serial_test::serial;
|
||||
|
||||
|
@ -189,7 +189,8 @@ mod tests {
|
|||
|
||||
let _inserted_child_comment_like = CommentLike::like(&conn, &child_comment_like).unwrap();
|
||||
|
||||
let person_aggregates_before_delete = PersonAggregates::read(&conn, inserted_person.id).unwrap();
|
||||
let person_aggregates_before_delete =
|
||||
PersonAggregates::read(&conn, inserted_person.id).unwrap();
|
||||
|
||||
assert_eq!(1, person_aggregates_before_delete.post_count);
|
||||
assert_eq!(1, person_aggregates_before_delete.post_score);
|
||||
|
|
|
@ -36,8 +36,8 @@ mod tests {
|
|||
use lemmy_db_schema::source::{
|
||||
comment::{Comment, CommentForm},
|
||||
community::{Community, CommunityForm},
|
||||
person::{Person, PersonForm},
|
||||
post::{Post, PostForm, PostLike, PostLikeForm},
|
||||
person::{PersonForm, Person},
|
||||
};
|
||||
use serial_test::serial;
|
||||
|
||||
|
|
|
@ -25,17 +25,13 @@ impl SiteAggregates {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
aggregates::site_aggregates::SiteAggregates,
|
||||
establish_unpooled_connection,
|
||||
Crud,
|
||||
};
|
||||
use crate::{aggregates::site_aggregates::SiteAggregates, establish_unpooled_connection, Crud};
|
||||
use lemmy_db_schema::source::{
|
||||
comment::{Comment, CommentForm},
|
||||
community::{Community, CommunityForm},
|
||||
person::{Person, PersonForm},
|
||||
post::{Post, PostForm},
|
||||
site::{Site, SiteForm},
|
||||
person::{PersonForm, Person},
|
||||
};
|
||||
use serial_test::serial;
|
||||
|
||||
|
|
|
@ -122,13 +122,10 @@ impl Activity_ for Activity {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
establish_unpooled_connection,
|
||||
source::activity::Activity_,
|
||||
};
|
||||
use crate::{establish_unpooled_connection, source::activity::Activity_};
|
||||
use lemmy_db_schema::source::{
|
||||
activity::{Activity, ActivityForm},
|
||||
person::{PersonForm, Person},
|
||||
person::{Person, PersonForm},
|
||||
};
|
||||
use serde_json::Value;
|
||||
use serial_test::serial;
|
||||
|
|
|
@ -209,8 +209,8 @@ mod tests {
|
|||
use lemmy_db_schema::source::{
|
||||
comment::*,
|
||||
community::{Community, CommunityForm},
|
||||
person::{Person, PersonForm},
|
||||
post::*,
|
||||
person::{PersonForm, Person},
|
||||
};
|
||||
use serial_test::serial;
|
||||
|
||||
|
|
|
@ -295,7 +295,11 @@ impl Followable<CommunityFollowerForm> for CommunityFollower {
|
|||
.set(community_follower_form)
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
fn follow_accepted(conn: &PgConnection, community_id_: i32, person_id_: i32) -> Result<Self, Error>
|
||||
fn follow_accepted(
|
||||
conn: &PgConnection,
|
||||
community_id_: i32,
|
||||
person_id_: i32,
|
||||
) -> Result<Self, Error>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
|
@ -333,13 +337,7 @@ impl Followable<CommunityFollowerForm> for CommunityFollower {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
establish_unpooled_connection,
|
||||
Bannable,
|
||||
Crud,
|
||||
Followable,
|
||||
Joinable,
|
||||
};
|
||||
use crate::{establish_unpooled_connection, Bannable, Crud, Followable, Joinable};
|
||||
use lemmy_db_schema::source::{community::*, person::*};
|
||||
use serial_test::serial;
|
||||
|
||||
|
@ -438,7 +436,8 @@ mod tests {
|
|||
person_id: inserted_person.id,
|
||||
};
|
||||
|
||||
let inserted_community_moderator = CommunityModerator::join(&conn, &community_moderator_form).unwrap();
|
||||
let inserted_community_moderator =
|
||||
CommunityModerator::join(&conn, &community_moderator_form).unwrap();
|
||||
|
||||
let expected_community_moderator = CommunityModerator {
|
||||
id: inserted_community_moderator.id,
|
||||
|
|
|
@ -1,30 +1,21 @@
|
|||
use crate::{is_email_regex, Crud, ToSafeSettings};
|
||||
use diesel::{dsl::*, result::Error, *};
|
||||
use lemmy_db_schema::source::local_user::LocalUserSettings;
|
||||
use lemmy_db_schema::schema::local_user::dsl::*;
|
||||
use lemmy_db_schema::source::local_user::{LocalUser, LocalUserForm};
|
||||
use crate::{Crud, ToSafeSettings};
|
||||
use bcrypt::{hash, DEFAULT_COST};
|
||||
use diesel::{dsl::*, result::Error, *};
|
||||
use lemmy_db_schema::{
|
||||
schema::local_user::dsl::*,
|
||||
source::local_user::{LocalUser, LocalUserForm, LocalUserSettings},
|
||||
};
|
||||
|
||||
mod safe_type {
|
||||
use crate::ToSafe;
|
||||
use lemmy_db_schema::{schema::local_user::columns::*, source::local_user::LocalUser};
|
||||
|
||||
type Columns = (
|
||||
id,
|
||||
person_id,
|
||||
admin,
|
||||
matrix_user_id,
|
||||
);
|
||||
type Columns = (id, person_id, admin, matrix_user_id);
|
||||
|
||||
impl ToSafe for LocalUser {
|
||||
type SafeColumns = Columns;
|
||||
fn safe_columns_tuple() -> Self::SafeColumns {
|
||||
(
|
||||
id,
|
||||
person_id,
|
||||
admin,
|
||||
matrix_user_id,
|
||||
)
|
||||
(id, person_id, admin, matrix_user_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +41,7 @@ mod safe_settings_type {
|
|||
|
||||
impl ToSafeSettings for LocalUser {
|
||||
type SafeSettingsColumns = Columns;
|
||||
|
||||
|
||||
/// Includes everything but the hashed password
|
||||
fn safe_settings_columns_tuple() -> Self::SafeSettingsColumns {
|
||||
(
|
||||
|
@ -73,10 +64,12 @@ mod safe_settings_type {
|
|||
|
||||
pub trait LocalUser_ {
|
||||
fn register(conn: &PgConnection, form: &LocalUserForm) -> Result<LocalUser, Error>;
|
||||
fn update_password(conn: &PgConnection, person_id: i32, new_password: &str)
|
||||
-> Result<LocalUser, Error>;
|
||||
fn update_password(
|
||||
conn: &PgConnection,
|
||||
local_user_id: i32,
|
||||
new_password: &str,
|
||||
) -> Result<LocalUser, Error>;
|
||||
fn add_admin(conn: &PgConnection, local_user_id: i32, added: bool) -> Result<LocalUser, Error>;
|
||||
fn find_by_email(conn: &PgConnection, from_email: &str) -> Result<LocalUser, Error>;
|
||||
fn find_by_person(conn: &PgConnection, from_person_id: i32) -> Result<LocalUser, Error>;
|
||||
}
|
||||
|
||||
|
@ -91,13 +84,15 @@ impl LocalUser_ for LocalUser {
|
|||
}
|
||||
|
||||
// TODO do more individual updates like these
|
||||
fn update_password(conn: &PgConnection, local_user_id: i32, new_password: &str) -> Result<Self, Error> {
|
||||
fn update_password(
|
||||
conn: &PgConnection,
|
||||
local_user_id: i32,
|
||||
new_password: &str,
|
||||
) -> Result<Self, Error> {
|
||||
let password_hash = hash(new_password, DEFAULT_COST).expect("Couldn't hash password");
|
||||
|
||||
diesel::update(local_user.find(local_user_id))
|
||||
.set((
|
||||
password_encrypted.eq(password_hash),
|
||||
))
|
||||
.set((password_encrypted.eq(password_hash),))
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
|
||||
|
@ -108,33 +103,25 @@ impl LocalUser_ for LocalUser {
|
|||
.get_result::<Self>(conn)
|
||||
}
|
||||
|
||||
// TODO is this used?
|
||||
fn find_by_email(conn: &PgConnection, from_email: &str) -> Result<LocalUser, Error> {
|
||||
local_user
|
||||
.filter(email.eq(from_email))
|
||||
.first::<LocalUser>(conn)
|
||||
}
|
||||
|
||||
// TODO is this used?
|
||||
fn find_by_person(conn: &PgConnection, for_person_id: i32) -> Result<LocalUser, Error> {
|
||||
local_user
|
||||
.filter(person_id.eq(for_person_id))
|
||||
.first::<LocalUser>(conn)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Crud<LocalUserForm> for LocalUser {
|
||||
fn read(conn: &PgConnection, local_user_id: i32) -> Result<Self, Error> {
|
||||
local_user
|
||||
.find(local_user_id)
|
||||
.first::<Self>(conn)
|
||||
local_user.find(local_user_id).first::<Self>(conn)
|
||||
}
|
||||
fn delete(conn: &PgConnection, local_user_id: i32) -> Result<usize, Error> {
|
||||
diesel::delete(local_user.find(local_user_id)).execute(conn)
|
||||
}
|
||||
fn create(conn: &PgConnection, form: &LocalUserForm) -> Result<Self, Error> {
|
||||
insert_into(local_user).values(form).get_result::<Self>(conn)
|
||||
insert_into(local_user)
|
||||
.values(form)
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
fn update(conn: &PgConnection, local_user_id: i32, form: &LocalUserForm) -> Result<Self, Error> {
|
||||
diesel::update(local_user.find(local_user_id))
|
||||
|
|
|
@ -2,12 +2,12 @@ pub mod activity;
|
|||
pub mod comment;
|
||||
pub mod comment_report;
|
||||
pub mod community;
|
||||
pub mod local_user;
|
||||
pub mod moderator;
|
||||
pub mod password_reset_request;
|
||||
pub mod person;
|
||||
pub mod person_mention;
|
||||
pub mod post;
|
||||
pub mod post_report;
|
||||
pub mod private_message;
|
||||
pub mod site;
|
||||
pub mod person;
|
||||
pub mod person_mention;
|
||||
pub mod local_user;
|
||||
|
|
|
@ -198,7 +198,7 @@ impl Crud<ModAddForm> for ModAdd {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{establish_unpooled_connection, Crud};
|
||||
use lemmy_db_schema::source::{comment::*, community::*, moderator::*, post::*, person::*};
|
||||
use lemmy_db_schema::source::{comment::*, community::*, moderator::*, person::*, post::*};
|
||||
use serial_test::serial;
|
||||
|
||||
// use Crud;
|
||||
|
|
|
@ -1,32 +1,31 @@
|
|||
use crate::{is_email_regex, ApubObject, Crud};
|
||||
use crate::{ApubObject, Crud};
|
||||
use diesel::{dsl::*, result::Error, *};
|
||||
use lemmy_db_schema::{
|
||||
naive_now,
|
||||
schema::person::dsl::*,
|
||||
source::person::{PersonForm, Person},
|
||||
source::person::{Person, PersonForm},
|
||||
DbUrl,
|
||||
};
|
||||
use lemmy_utils::settings::structs::Settings;
|
||||
|
||||
mod safe_type {
|
||||
use crate::ToSafe;
|
||||
use lemmy_db_schema::{schema::person::columns::*, source::person::Person};
|
||||
|
||||
type Columns = (
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
inbox_url,
|
||||
shared_inbox_url,
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
inbox_url,
|
||||
shared_inbox_url,
|
||||
);
|
||||
|
||||
impl ToSafe for Person {
|
||||
|
@ -57,20 +56,20 @@ mod safe_type_alias_1 {
|
|||
use lemmy_db_schema::{schema::person_alias_1::columns::*, source::person::PersonAlias1};
|
||||
|
||||
type Columns = (
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
inbox_url,
|
||||
shared_inbox_url,
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
inbox_url,
|
||||
shared_inbox_url,
|
||||
);
|
||||
|
||||
impl ToSafe for PersonAlias1 {
|
||||
|
@ -101,20 +100,20 @@ mod safe_type_alias_2 {
|
|||
use lemmy_db_schema::{schema::person_alias_2::columns::*, source::person::PersonAlias2};
|
||||
|
||||
type Columns = (
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
inbox_url,
|
||||
shared_inbox_url,
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
inbox_url,
|
||||
shared_inbox_url,
|
||||
);
|
||||
|
||||
impl ToSafe for PersonAlias2 {
|
||||
|
@ -181,36 +180,19 @@ impl ApubObject<PersonForm> for Person {
|
|||
|
||||
pub trait Person_ {
|
||||
fn ban_person(conn: &PgConnection, person_id: i32, ban: bool) -> Result<Person, Error>;
|
||||
// TODO
|
||||
// fn find_by_email_or_name(
|
||||
// conn: &PgConnection,
|
||||
// name_or_email: &str,
|
||||
// ) -> Result<Person, Error>;
|
||||
fn find_by_name(conn: &PgConnection, name: &str) -> Result<Person, Error>;
|
||||
fn mark_as_updated(conn: &PgConnection, person_id: i32) -> Result<Person, Error>;
|
||||
fn delete_account(conn: &PgConnection, person_id: i32) -> Result<Person, Error>;
|
||||
}
|
||||
|
||||
impl Person_ for Person {
|
||||
|
||||
fn ban_person(conn: &PgConnection, person_id: i32, ban: bool) -> Result<Self, Error> {
|
||||
diesel::update(person.find(person_id))
|
||||
.set(banned.eq(ban))
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
|
||||
// TODO this needs to get moved to aggregates i think
|
||||
// fn find_by_email_or_name(
|
||||
// conn: &PgConnection,
|
||||
// name_or_email: &str,
|
||||
// ) -> Result<Self, Error> {
|
||||
// if is_email_regex(name_or_email) {
|
||||
// Self::find_by_email(conn, name_or_email)
|
||||
// } else {
|
||||
// Self::find_by_name(conn, name_or_email)
|
||||
// }
|
||||
// }
|
||||
|
||||
// TODO is this used?
|
||||
fn find_by_name(conn: &PgConnection, from_name: &str) -> Result<Person, Error> {
|
||||
person
|
||||
.filter(deleted.eq(false))
|
||||
|
|
|
@ -77,9 +77,9 @@ mod tests {
|
|||
use lemmy_db_schema::source::{
|
||||
comment::*,
|
||||
community::{Community, CommunityForm},
|
||||
post::*,
|
||||
person::*,
|
||||
person_mention::*,
|
||||
post::*,
|
||||
};
|
||||
use serial_test::serial;
|
||||
|
||||
|
|
|
@ -139,12 +139,8 @@ impl PrivateMessage_ for PrivateMessage {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
establish_unpooled_connection,
|
||||
source::private_message::PrivateMessage_,
|
||||
Crud,
|
||||
};
|
||||
use lemmy_db_schema::source::{private_message::*, person::*};
|
||||
use crate::{establish_unpooled_connection, source::private_message::PrivateMessage_, Crud};
|
||||
use lemmy_db_schema::source::{person::*, private_message::*};
|
||||
use serial_test::serial;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,459 +0,0 @@
|
|||
use crate::{is_email_regex, ApubObject, Crud, ToSafeSettings};
|
||||
use bcrypt::{hash, DEFAULT_COST};
|
||||
use diesel::{dsl::*, result::Error, *};
|
||||
use lemmy_db_schema::{
|
||||
naive_now,
|
||||
schema::user_::dsl::*,
|
||||
source::user::{UserForm, UserSafeSettings, User_},
|
||||
DbUrl,
|
||||
};
|
||||
use lemmy_utils::settings::structs::Settings;
|
||||
|
||||
mod safe_type {
|
||||
use crate::ToSafe;
|
||||
use lemmy_db_schema::{schema::user_::columns::*, source::user::User_};
|
||||
|
||||
type Columns = (
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
admin,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
matrix_user_id,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
inbox_url,
|
||||
shared_inbox_url,
|
||||
);
|
||||
|
||||
impl ToSafe for User_ {
|
||||
type SafeColumns = Columns;
|
||||
fn safe_columns_tuple() -> Self::SafeColumns {
|
||||
(
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
admin,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
matrix_user_id,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
inbox_url,
|
||||
shared_inbox_url,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod safe_type_alias_1 {
|
||||
use crate::ToSafe;
|
||||
use lemmy_db_schema::{schema::user_alias_1::columns::*, source::user::UserAlias1};
|
||||
|
||||
type Columns = (
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
admin,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
matrix_user_id,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
);
|
||||
|
||||
impl ToSafe for UserAlias1 {
|
||||
type SafeColumns = Columns;
|
||||
fn safe_columns_tuple() -> Self::SafeColumns {
|
||||
(
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
admin,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
matrix_user_id,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod safe_type_alias_2 {
|
||||
use crate::ToSafe;
|
||||
use lemmy_db_schema::{schema::user_alias_2::columns::*, source::user::UserAlias2};
|
||||
|
||||
type Columns = (
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
admin,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
matrix_user_id,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
);
|
||||
|
||||
impl ToSafe for UserAlias2 {
|
||||
type SafeColumns = Columns;
|
||||
fn safe_columns_tuple() -> Self::SafeColumns {
|
||||
(
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
avatar,
|
||||
admin,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
matrix_user_id,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
banner,
|
||||
deleted,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod safe_settings_type {
|
||||
use crate::ToSafeSettings;
|
||||
use lemmy_db_schema::{schema::user_::columns::*, source::user::User_};
|
||||
|
||||
type Columns = (
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
email,
|
||||
avatar,
|
||||
admin,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
show_nsfw,
|
||||
theme,
|
||||
default_sort_type,
|
||||
default_listing_type,
|
||||
lang,
|
||||
show_avatars,
|
||||
send_notifications_to_email,
|
||||
matrix_user_id,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
last_refreshed_at,
|
||||
banner,
|
||||
deleted,
|
||||
);
|
||||
|
||||
impl ToSafeSettings for User_ {
|
||||
type SafeSettingsColumns = Columns;
|
||||
fn safe_settings_columns_tuple() -> Self::SafeSettingsColumns {
|
||||
(
|
||||
id,
|
||||
name,
|
||||
preferred_username,
|
||||
email,
|
||||
avatar,
|
||||
admin,
|
||||
banned,
|
||||
published,
|
||||
updated,
|
||||
show_nsfw,
|
||||
theme,
|
||||
default_sort_type,
|
||||
default_listing_type,
|
||||
lang,
|
||||
show_avatars,
|
||||
send_notifications_to_email,
|
||||
matrix_user_id,
|
||||
actor_id,
|
||||
bio,
|
||||
local,
|
||||
last_refreshed_at,
|
||||
banner,
|
||||
deleted,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait UserSafeSettings_ {
|
||||
fn read(conn: &PgConnection, user_id: i32) -> Result<UserSafeSettings, Error>;
|
||||
}
|
||||
|
||||
impl UserSafeSettings_ for UserSafeSettings {
|
||||
fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
|
||||
user_
|
||||
.select(User_::safe_settings_columns_tuple())
|
||||
.filter(deleted.eq(false))
|
||||
.find(user_id)
|
||||
.first::<Self>(conn)
|
||||
}
|
||||
}
|
||||
|
||||
impl Crud<UserForm> for User_ {
|
||||
fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
|
||||
user_
|
||||
.filter(deleted.eq(false))
|
||||
.find(user_id)
|
||||
.first::<Self>(conn)
|
||||
}
|
||||
fn delete(conn: &PgConnection, user_id: i32) -> Result<usize, Error> {
|
||||
diesel::delete(user_.find(user_id)).execute(conn)
|
||||
}
|
||||
fn create(conn: &PgConnection, form: &UserForm) -> Result<Self, Error> {
|
||||
insert_into(user_).values(form).get_result::<Self>(conn)
|
||||
}
|
||||
fn update(conn: &PgConnection, user_id: i32, form: &UserForm) -> Result<Self, Error> {
|
||||
diesel::update(user_.find(user_id))
|
||||
.set(form)
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApubObject<UserForm> for User_ {
|
||||
fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error> {
|
||||
use lemmy_db_schema::schema::user_::dsl::*;
|
||||
user_
|
||||
.filter(deleted.eq(false))
|
||||
.filter(actor_id.eq(object_id))
|
||||
.first::<Self>(conn)
|
||||
}
|
||||
|
||||
fn upsert(conn: &PgConnection, user_form: &UserForm) -> Result<User_, Error> {
|
||||
insert_into(user_)
|
||||
.values(user_form)
|
||||
.on_conflict(actor_id)
|
||||
.do_update()
|
||||
.set(user_form)
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait User {
|
||||
fn register(conn: &PgConnection, form: &UserForm) -> Result<User_, Error>;
|
||||
fn update_password(conn: &PgConnection, user_id: i32, new_password: &str)
|
||||
-> Result<User_, Error>;
|
||||
fn read_from_name(conn: &PgConnection, from_user_name: &str) -> Result<User_, Error>;
|
||||
fn add_admin(conn: &PgConnection, user_id: i32, added: bool) -> Result<User_, Error>;
|
||||
fn ban_user(conn: &PgConnection, user_id: i32, ban: bool) -> Result<User_, Error>;
|
||||
fn find_by_email_or_username(
|
||||
conn: &PgConnection,
|
||||
username_or_email: &str,
|
||||
) -> Result<User_, Error>;
|
||||
fn find_by_username(conn: &PgConnection, username: &str) -> Result<User_, Error>;
|
||||
fn get_profile_url(&self, hostname: &str) -> String;
|
||||
fn mark_as_updated(conn: &PgConnection, user_id: i32) -> Result<User_, Error>;
|
||||
fn delete_account(conn: &PgConnection, user_id: i32) -> Result<User_, Error>;
|
||||
}
|
||||
|
||||
impl User for User_ {
|
||||
fn register(conn: &PgConnection, form: &UserForm) -> Result<Self, Error> {
|
||||
let mut edited_user = form.clone();
|
||||
let password_hash =
|
||||
hash(&form.password_encrypted, DEFAULT_COST).expect("Couldn't hash password");
|
||||
edited_user.password_encrypted = password_hash;
|
||||
|
||||
Self::create(&conn, &edited_user)
|
||||
}
|
||||
|
||||
// TODO do more individual updates like these
|
||||
fn update_password(conn: &PgConnection, user_id: i32, new_password: &str) -> Result<Self, Error> {
|
||||
let password_hash = hash(new_password, DEFAULT_COST).expect("Couldn't hash password");
|
||||
|
||||
diesel::update(user_.find(user_id))
|
||||
.set((
|
||||
password_encrypted.eq(password_hash),
|
||||
updated.eq(naive_now()),
|
||||
))
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
|
||||
fn read_from_name(conn: &PgConnection, from_user_name: &str) -> Result<Self, Error> {
|
||||
user_
|
||||
.filter(local.eq(true))
|
||||
.filter(deleted.eq(false))
|
||||
.filter(name.eq(from_user_name))
|
||||
.first::<Self>(conn)
|
||||
}
|
||||
|
||||
fn add_admin(conn: &PgConnection, user_id: i32, added: bool) -> Result<Self, Error> {
|
||||
diesel::update(user_.find(user_id))
|
||||
.set(admin.eq(added))
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
|
||||
fn ban_user(conn: &PgConnection, user_id: i32, ban: bool) -> Result<Self, Error> {
|
||||
diesel::update(user_.find(user_id))
|
||||
.set(banned.eq(ban))
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
|
||||
fn find_by_email_or_username(
|
||||
conn: &PgConnection,
|
||||
username_or_email: &str,
|
||||
) -> Result<Self, Error> {
|
||||
if is_email_regex(username_or_email) {
|
||||
Self::find_by_email(conn, username_or_email)
|
||||
} else {
|
||||
Self::find_by_username(conn, username_or_email)
|
||||
}
|
||||
}
|
||||
|
||||
fn find_by_username(conn: &PgConnection, username: &str) -> Result<User_, Error> {
|
||||
user_
|
||||
.filter(deleted.eq(false))
|
||||
.filter(local.eq(true))
|
||||
.filter(name.ilike(username))
|
||||
.first::<User_>(conn)
|
||||
}
|
||||
|
||||
fn find_by_email(conn: &PgConnection, from_email: &str) -> Result<User_, Error> {
|
||||
user_
|
||||
.filter(deleted.eq(false))
|
||||
.filter(local.eq(true))
|
||||
.filter(email.eq(from_email))
|
||||
.first::<User_>(conn)
|
||||
}
|
||||
|
||||
fn get_profile_url(&self, hostname: &str) -> String {
|
||||
format!(
|
||||
"{}://{}/u/{}",
|
||||
Settings::get().get_protocol_string(),
|
||||
hostname,
|
||||
self.name
|
||||
)
|
||||
}
|
||||
|
||||
fn mark_as_updated(conn: &PgConnection, user_id: i32) -> Result<User_, Error> {
|
||||
diesel::update(user_.find(user_id))
|
||||
.set((last_refreshed_at.eq(naive_now()),))
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
|
||||
fn delete_account(conn: &PgConnection, user_id: i32) -> Result<User_, Error> {
|
||||
diesel::update(user_.find(user_id))
|
||||
.set((
|
||||
preferred_username.eq::<Option<String>>(None),
|
||||
email.eq::<Option<String>>(None),
|
||||
matrix_user_id.eq::<Option<String>>(None),
|
||||
bio.eq::<Option<String>>(None),
|
||||
deleted.eq(true),
|
||||
updated.eq(naive_now()),
|
||||
))
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{establish_unpooled_connection, source::user::*, ListingType, SortType};
|
||||
use serial_test::serial;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_crud() {
|
||||
let conn = establish_unpooled_connection();
|
||||
|
||||
let new_user = UserForm {
|
||||
name: "thommy".into(),
|
||||
preferred_username: None,
|
||||
password_encrypted: "nope".into(),
|
||||
email: None,
|
||||
matrix_user_id: None,
|
||||
avatar: None,
|
||||
banner: None,
|
||||
admin: false,
|
||||
banned: Some(false),
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "browser".into(),
|
||||
default_sort_type: SortType::Hot as i16,
|
||||
default_listing_type: ListingType::Subscribed as i16,
|
||||
lang: "browser".into(),
|
||||
show_avatars: true,
|
||||
send_notifications_to_email: false,
|
||||
actor_id: None,
|
||||
bio: None,
|
||||
local: true,
|
||||
private_key: None,
|
||||
public_key: None,
|
||||
last_refreshed_at: None,
|
||||
inbox_url: None,
|
||||
shared_inbox_url: None,
|
||||
};
|
||||
|
||||
let inserted_user = User_::create(&conn, &new_user).unwrap();
|
||||
|
||||
let expected_user = User_ {
|
||||
id: inserted_user.id,
|
||||
name: "thommy".into(),
|
||||
preferred_username: None,
|
||||
password_encrypted: "nope".into(),
|
||||
email: None,
|
||||
matrix_user_id: None,
|
||||
avatar: None,
|
||||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: inserted_user.published,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "browser".into(),
|
||||
default_sort_type: SortType::Hot as i16,
|
||||
default_listing_type: ListingType::Subscribed as i16,
|
||||
lang: "browser".into(),
|
||||
show_avatars: true,
|
||||
send_notifications_to_email: false,
|
||||
actor_id: inserted_user.actor_id.to_owned(),
|
||||
bio: None,
|
||||
local: true,
|
||||
private_key: None,
|
||||
public_key: None,
|
||||
last_refreshed_at: inserted_user.published,
|
||||
deleted: false,
|
||||
inbox_url: inserted_user.inbox_url.to_owned(),
|
||||
shared_inbox_url: None,
|
||||
};
|
||||
|
||||
let read_user = User_::read(&conn, inserted_user.id).unwrap();
|
||||
let updated_user = User_::update(&conn, inserted_user.id, &new_user).unwrap();
|
||||
let num_deleted = User_::delete(&conn, inserted_user.id).unwrap();
|
||||
|
||||
assert_eq!(expected_user, read_user);
|
||||
assert_eq!(expected_user, inserted_user);
|
||||
assert_eq!(expected_user, updated_user);
|
||||
assert_eq!(1, num_deleted);
|
||||
}
|
||||
}
|
|
@ -4,53 +4,53 @@ use serde::Serialize;
|
|||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "local_user"]
|
||||
pub struct LocalUser {
|
||||
pub id: i32,
|
||||
pub person_id: i32,
|
||||
pub password_encrypted: String,
|
||||
pub email: Option<String>,
|
||||
pub admin: bool,
|
||||
pub show_nsfw: bool,
|
||||
pub theme: String,
|
||||
pub default_sort_type: i16,
|
||||
pub default_listing_type: i16,
|
||||
pub lang: String,
|
||||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub id: i32,
|
||||
pub person_id: i32,
|
||||
pub password_encrypted: String,
|
||||
pub email: Option<String>,
|
||||
pub admin: bool,
|
||||
pub show_nsfw: bool,
|
||||
pub theme: String,
|
||||
pub default_sort_type: i16,
|
||||
pub default_listing_type: i16,
|
||||
pub lang: String,
|
||||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
}
|
||||
|
||||
// TODO redo these, check table defaults
|
||||
#[derive(Insertable, AsChangeset, Clone)]
|
||||
#[table_name = "local_user"]
|
||||
pub struct LocalUserForm {
|
||||
pub person_id: i32,
|
||||
pub password_encrypted: String,
|
||||
pub person_id: i32,
|
||||
pub password_encrypted: String,
|
||||
pub email: Option<Option<String>>,
|
||||
pub admin: Option<bool>,
|
||||
pub show_nsfw: Option<bool>,
|
||||
pub theme: Option<String>,
|
||||
pub default_sort_type: Option<i16>,
|
||||
pub default_listing_type: Option<i16>,
|
||||
pub lang: Option<String>,
|
||||
pub show_avatars: Option<bool>,
|
||||
pub send_notifications_to_email: Option<bool>,
|
||||
pub admin: Option<bool>,
|
||||
pub show_nsfw: Option<bool>,
|
||||
pub theme: Option<String>,
|
||||
pub default_sort_type: Option<i16>,
|
||||
pub default_listing_type: Option<i16>,
|
||||
pub lang: Option<String>,
|
||||
pub show_avatars: Option<bool>,
|
||||
pub send_notifications_to_email: Option<bool>,
|
||||
pub matrix_user_id: Option<Option<String>>,
|
||||
}
|
||||
|
||||
/// A local user view that removes password encrypted
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "local_user"]
|
||||
pub struct LocalUserSettings{
|
||||
pub id: i32,
|
||||
pub person_id: i32,
|
||||
pub email: Option<String>,
|
||||
pub admin: bool,
|
||||
pub show_nsfw: bool,
|
||||
pub theme: String,
|
||||
pub default_sort_type: i16,
|
||||
pub default_listing_type: i16,
|
||||
pub lang: String,
|
||||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub struct LocalUserSettings {
|
||||
pub id: i32,
|
||||
pub person_id: i32,
|
||||
pub email: Option<String>,
|
||||
pub admin: bool,
|
||||
pub show_nsfw: bool,
|
||||
pub theme: String,
|
||||
pub default_sort_type: i16,
|
||||
pub default_listing_type: i16,
|
||||
pub lang: String,
|
||||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@ pub mod activity;
|
|||
pub mod comment;
|
||||
pub mod comment_report;
|
||||
pub mod community;
|
||||
pub mod local_user;
|
||||
pub mod moderator;
|
||||
pub mod password_reset_request;
|
||||
pub mod person;
|
||||
pub mod person_mention;
|
||||
pub mod post;
|
||||
pub mod post_report;
|
||||
pub mod private_message;
|
||||
pub mod site;
|
||||
pub mod person;
|
||||
pub mod person_mention;
|
||||
pub mod local_user;
|
||||
|
|
|
@ -7,145 +7,144 @@ use serde::Serialize;
|
|||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "person"]
|
||||
pub struct Person {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
}
|
||||
|
||||
/// A safe representation of user, without the sensitive info
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "person"]
|
||||
pub struct PersonSafe {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "person_alias_1"]
|
||||
pub struct PersonAlias1 {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "person_alias_1"]
|
||||
pub struct PersonSafeAlias1 {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "person_alias_2"]
|
||||
pub struct PersonAlias2 {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "person_alias_1"]
|
||||
pub struct PersonSafeAlias2 {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
}
|
||||
|
||||
#[derive(Insertable, AsChangeset, Clone)]
|
||||
#[table_name = "person"]
|
||||
pub struct PersonForm {
|
||||
pub name: String,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<Option<String>>,
|
||||
pub avatar: Option<Option<DbUrl>>,
|
||||
pub banned: Option<bool>,
|
||||
pub banned: Option<bool>,
|
||||
pub published: Option<chrono::NaiveDateTime>,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub actor_id: Option<DbUrl>,
|
||||
pub bio: Option<Option<String>>,
|
||||
pub local: Option<bool>,
|
||||
pub private_key: Option<Option<String>>,
|
||||
pub public_key: Option<Option<String>>,
|
||||
pub actor_id: Option<DbUrl>,
|
||||
pub bio: Option<Option<String>>,
|
||||
pub local: Option<bool>,
|
||||
pub private_key: Option<Option<String>>,
|
||||
pub public_key: Option<Option<String>>,
|
||||
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
|
||||
pub banner: Option<Option<DbUrl>>,
|
||||
pub deleted: Option<bool>,
|
||||
pub inbox_url: Option<DbUrl>,
|
||||
pub deleted: Option<bool>,
|
||||
pub inbox_url: Option<DbUrl>,
|
||||
pub shared_inbox_url: Option<Option<DbUrl>>,
|
||||
}
|
||||
|
|
|
@ -1,220 +0,0 @@
|
|||
use crate::{
|
||||
schema::{user_, user_alias_1, user_alias_2},
|
||||
DbUrl,
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "user_"]
|
||||
pub struct User_ {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub password_encrypted: String,
|
||||
pub email: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub show_nsfw: bool,
|
||||
pub theme: String,
|
||||
pub default_sort_type: i16,
|
||||
pub default_listing_type: i16,
|
||||
pub lang: String,
|
||||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
}
|
||||
|
||||
/// A safe representation of user, without the sensitive info
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "user_"]
|
||||
pub struct UserSafe {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
pub inbox_url: DbUrl,
|
||||
pub shared_inbox_url: Option<DbUrl>,
|
||||
}
|
||||
|
||||
/// A safe user view with only settings
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "user_"]
|
||||
pub struct UserSafeSettings {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub email: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub show_nsfw: bool,
|
||||
pub theme: String,
|
||||
pub default_sort_type: i16,
|
||||
pub default_listing_type: i16,
|
||||
pub lang: String,
|
||||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "user_alias_1"]
|
||||
pub struct UserAlias1 {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub password_encrypted: String,
|
||||
pub email: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub show_nsfw: bool,
|
||||
pub theme: String,
|
||||
pub default_sort_type: i16,
|
||||
pub default_listing_type: i16,
|
||||
pub lang: String,
|
||||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "user_alias_1"]
|
||||
pub struct UserSafeAlias1 {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "user_alias_2"]
|
||||
pub struct UserAlias2 {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub password_encrypted: String,
|
||||
pub email: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub show_nsfw: bool,
|
||||
pub theme: String,
|
||||
pub default_sort_type: i16,
|
||||
pub default_listing_type: i16,
|
||||
pub lang: String,
|
||||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: chrono::NaiveDateTime,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||
#[table_name = "user_alias_2"]
|
||||
pub struct UserSafeAlias2 {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub preferred_username: Option<String>,
|
||||
pub avatar: Option<DbUrl>,
|
||||
pub admin: bool,
|
||||
pub banned: bool,
|
||||
pub published: chrono::NaiveDateTime,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub matrix_user_id: Option<String>,
|
||||
pub actor_id: DbUrl,
|
||||
pub bio: Option<String>,
|
||||
pub local: bool,
|
||||
pub banner: Option<DbUrl>,
|
||||
pub deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Insertable, AsChangeset, Clone)]
|
||||
#[table_name = "user_"]
|
||||
pub struct UserForm {
|
||||
pub name: String,
|
||||
pub preferred_username: Option<Option<String>>,
|
||||
pub password_encrypted: String,
|
||||
pub admin: bool,
|
||||
pub banned: Option<bool>,
|
||||
pub email: Option<Option<String>>,
|
||||
pub avatar: Option<Option<DbUrl>>,
|
||||
pub published: Option<chrono::NaiveDateTime>,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub show_nsfw: bool,
|
||||
pub theme: String,
|
||||
pub default_sort_type: i16,
|
||||
pub default_listing_type: i16,
|
||||
pub lang: String,
|
||||
pub show_avatars: bool,
|
||||
pub send_notifications_to_email: bool,
|
||||
pub matrix_user_id: Option<Option<String>>,
|
||||
pub actor_id: Option<DbUrl>,
|
||||
pub bio: Option<Option<String>>,
|
||||
pub local: bool,
|
||||
pub private_key: Option<String>,
|
||||
pub public_key: Option<String>,
|
||||
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
|
||||
pub banner: Option<Option<DbUrl>>,
|
||||
pub inbox_url: Option<DbUrl>,
|
||||
pub shared_inbox_url: Option<Option<DbUrl>>,
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
use diesel::{result::Error, *};
|
||||
use lemmy_db_queries::{limit_and_offset, MaybeOptional, ToSafe, ViewToVec};
|
||||
use lemmy_db_schema::{
|
||||
schema::{comment, comment_report, community, post, person, person_alias_1, person_alias_2},
|
||||
schema::{comment, comment_report, community, person, person_alias_1, person_alias_2, post},
|
||||
source::{
|
||||
comment::Comment,
|
||||
comment_report::CommentReport,
|
||||
community::{Community, CommunitySafe},
|
||||
person::{Person, PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2},
|
||||
post::Post,
|
||||
person::{PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2, Person},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
|
|
@ -20,15 +20,15 @@ use lemmy_db_schema::{
|
|||
community,
|
||||
community_follower,
|
||||
community_person_ban,
|
||||
post,
|
||||
person,
|
||||
person_alias_1,
|
||||
post,
|
||||
},
|
||||
source::{
|
||||
comment::{Comment, CommentAlias1, CommentSaved},
|
||||
community::{Community, CommunityFollower, CommunitySafe, CommunityPersonBan},
|
||||
community::{Community, CommunityFollower, CommunityPersonBan, CommunitySafe},
|
||||
person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
|
||||
post::Post,
|
||||
person::{PersonAlias1, PersonSafe, PersonSafeAlias1, Person},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
@ -440,7 +440,7 @@ mod tests {
|
|||
Crud,
|
||||
Likeable,
|
||||
};
|
||||
use lemmy_db_schema::source::{comment::*, community::*, post::*, person::*};
|
||||
use lemmy_db_schema::source::{comment::*, community::*, person::*, post::*};
|
||||
use serial_test::serial;
|
||||
|
||||
#[test]
|
||||
|
@ -646,7 +646,10 @@ mod tests {
|
|||
Community::delete(&conn, inserted_community.id).unwrap();
|
||||
Person::delete(&conn, inserted_person.id).unwrap();
|
||||
|
||||
assert_eq!(expected_comment_view_no_person, read_comment_views_no_person[0]);
|
||||
assert_eq!(
|
||||
expected_comment_view_no_person,
|
||||
read_comment_views_no_person[0]
|
||||
);
|
||||
assert_eq!(
|
||||
expected_comment_view_with_person,
|
||||
read_comment_views_with_person[0]
|
||||
|
|
|
@ -3,8 +3,8 @@ extern crate serial_test;
|
|||
|
||||
pub mod comment_report_view;
|
||||
pub mod comment_view;
|
||||
pub mod local_user_view;
|
||||
pub mod post_report_view;
|
||||
pub mod post_view;
|
||||
pub mod private_message_view;
|
||||
pub mod site_view;
|
||||
pub mod local_user_view;
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
use diesel::{result::Error, *};
|
||||
use lemmy_db_queries::{
|
||||
aggregates::person_aggregates::PersonAggregates,
|
||||
ToSafe,
|
||||
ToSafeSettings,
|
||||
};
|
||||
use lemmy_db_queries::{aggregates::person_aggregates::PersonAggregates, ToSafe, ToSafeSettings};
|
||||
use lemmy_db_schema::{
|
||||
schema::{person, person_aggregates, local_user},
|
||||
source::person::{PersonSafe, Person},
|
||||
source::local_user::{LocalUser, LocalUserSettings},
|
||||
schema::{local_user, person, person_aggregates},
|
||||
source::{
|
||||
local_user::{LocalUser, LocalUserSettings},
|
||||
person::{Person, PersonSafe},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
||||
|
@ -21,14 +19,22 @@ pub struct LocalUserView {
|
|||
type LocalUserViewTuple = (Person, PersonAggregates, LocalUser);
|
||||
|
||||
impl LocalUserView {
|
||||
pub fn read(conn: &PgConnection, person_id: i32) -> Result<Self, Error> {
|
||||
pub fn read_person(conn: &PgConnection, person_id: i32) -> Result<Self, Error> {
|
||||
let (person, counts, local_user) = person::table
|
||||
.find(person_id)
|
||||
.inner_join(person_aggregates::table)
|
||||
.inner_join(local_user::table)
|
||||
.select((person::all_columns, person_aggregates::all_columns, local_user::all_columns))
|
||||
.select((
|
||||
person::all_columns,
|
||||
person_aggregates::all_columns,
|
||||
local_user::all_columns,
|
||||
))
|
||||
.first::<LocalUserViewTuple>(conn)?;
|
||||
Ok(Self { person, counts, local_user })
|
||||
Ok(Self {
|
||||
person,
|
||||
counts,
|
||||
local_user,
|
||||
})
|
||||
}
|
||||
|
||||
// TODO check where this is used
|
||||
|
@ -37,22 +43,57 @@ impl LocalUserView {
|
|||
.filter(person::name.eq(name))
|
||||
.inner_join(person_aggregates::table)
|
||||
.inner_join(local_user::table)
|
||||
.select((person::all_columns, person_aggregates::all_columns, local_user::all_columns))
|
||||
.select((
|
||||
person::all_columns,
|
||||
person_aggregates::all_columns,
|
||||
local_user::all_columns,
|
||||
))
|
||||
.first::<LocalUserViewTuple>(conn)?;
|
||||
Ok(Self { person, counts, local_user })
|
||||
Ok(Self {
|
||||
person,
|
||||
counts,
|
||||
local_user,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn find_by_email_or_name(
|
||||
conn: &PgConnection,
|
||||
name_or_email: &str,
|
||||
) -> Result<Self, Error> {
|
||||
pub fn find_by_email_or_name(conn: &PgConnection, name_or_email: &str) -> Result<Self, Error> {
|
||||
let (person, counts, local_user) = person::table
|
||||
.inner_join(person_aggregates::table)
|
||||
.inner_join(local_user::table)
|
||||
.filter(person::name.ilike(name_or_email).or(local_user::email.ilike(name_or_email)))
|
||||
.select((person::all_columns, person_aggregates::all_columns, local_user::all_columns))
|
||||
.filter(
|
||||
person::name
|
||||
.ilike(name_or_email)
|
||||
.or(local_user::email.ilike(name_or_email)),
|
||||
)
|
||||
.select((
|
||||
person::all_columns,
|
||||
person_aggregates::all_columns,
|
||||
local_user::all_columns,
|
||||
))
|
||||
.first::<LocalUserViewTuple>(conn)?;
|
||||
Ok(Self { person, counts, local_user })
|
||||
Ok(Self {
|
||||
person,
|
||||
counts,
|
||||
local_user,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn find_by_email(conn: &PgConnection, from_email: &str) -> Result<Self, Error> {
|
||||
let (person, counts, local_user) = person::table
|
||||
.inner_join(person_aggregates::table)
|
||||
.inner_join(local_user::table)
|
||||
.filter(local_user::email.eq(from_email))
|
||||
.select((
|
||||
person::all_columns,
|
||||
person_aggregates::all_columns,
|
||||
local_user::all_columns,
|
||||
))
|
||||
.first::<LocalUserViewTuple>(conn)?;
|
||||
Ok(Self {
|
||||
person,
|
||||
counts,
|
||||
local_user,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,8 +112,16 @@ impl LocalUserSettingsView {
|
|||
.find(person_id)
|
||||
.inner_join(person_aggregates::table)
|
||||
.inner_join(local_user::table)
|
||||
.select((Person::safe_columns_tuple(), person_aggregates::all_columns, LocalUser::safe_settings_columns_tuple()))
|
||||
.select((
|
||||
Person::safe_columns_tuple(),
|
||||
person_aggregates::all_columns,
|
||||
LocalUser::safe_settings_columns_tuple(),
|
||||
))
|
||||
.first::<LocalUserSettingsViewTuple>(conn)?;
|
||||
Ok(Self { person, counts, local_user })
|
||||
Ok(Self {
|
||||
person,
|
||||
counts,
|
||||
local_user,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use diesel::{result::Error, *};
|
||||
use lemmy_db_queries::{limit_and_offset, MaybeOptional, ToSafe, ViewToVec};
|
||||
use lemmy_db_schema::{
|
||||
schema::{community, post, post_report, person, person_alias_1, person_alias_2},
|
||||
schema::{community, person, person_alias_1, person_alias_2, post, post_report},
|
||||
source::{
|
||||
community::{Community, CommunitySafe},
|
||||
person::{Person, PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2},
|
||||
post::Post,
|
||||
post_report::PostReport,
|
||||
person::{PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2, Person},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
@ -41,7 +41,9 @@ impl PostReportView {
|
|||
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
||||
.inner_join(person::table.on(post_report::creator_id.eq(person::id)))
|
||||
.inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id)))
|
||||
.left_join(person_alias_2::table.on(post_report::resolver_id.eq(person_alias_2::id.nullable())))
|
||||
.left_join(
|
||||
person_alias_2::table.on(post_report::resolver_id.eq(person_alias_2::id.nullable())),
|
||||
)
|
||||
.select((
|
||||
post_report::all_columns,
|
||||
post::all_columns,
|
||||
|
@ -126,7 +128,9 @@ impl<'a> PostReportQueryBuilder<'a> {
|
|||
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
||||
.inner_join(person::table.on(post_report::creator_id.eq(person::id)))
|
||||
.inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id)))
|
||||
.left_join(person_alias_2::table.on(post_report::resolver_id.eq(person_alias_2::id.nullable())))
|
||||
.left_join(
|
||||
person_alias_2::table.on(post_report::resolver_id.eq(person_alias_2::id.nullable())),
|
||||
)
|
||||
.select((
|
||||
post_report::all_columns,
|
||||
post::all_columns,
|
||||
|
|
|
@ -15,17 +15,17 @@ use lemmy_db_schema::{
|
|||
community,
|
||||
community_follower,
|
||||
community_person_ban,
|
||||
person,
|
||||
post,
|
||||
post_aggregates,
|
||||
post_like,
|
||||
post_read,
|
||||
post_saved,
|
||||
person,
|
||||
},
|
||||
source::{
|
||||
community::{Community, CommunityFollower, CommunitySafe, CommunityPersonBan},
|
||||
community::{Community, CommunityFollower, CommunityPersonBan, CommunitySafe},
|
||||
person::{Person, PersonSafe},
|
||||
post::{Post, PostRead, PostSaved},
|
||||
person::{PersonSafe, Person},
|
||||
},
|
||||
};
|
||||
use log::debug;
|
||||
|
@ -433,7 +433,7 @@ mod tests {
|
|||
ListingType,
|
||||
SortType,
|
||||
};
|
||||
use lemmy_db_schema::source::{community::*, post::*, person::*};
|
||||
use lemmy_db_schema::source::{community::*, person::*, post::*};
|
||||
use serial_test::serial;
|
||||
|
||||
#[test]
|
||||
|
@ -638,11 +638,17 @@ mod tests {
|
|||
expected_post_listing_with_user,
|
||||
read_post_listings_with_person[0]
|
||||
);
|
||||
assert_eq!(expected_post_listing_with_user, read_post_listing_with_person);
|
||||
assert_eq!(
|
||||
expected_post_listing_with_user,
|
||||
read_post_listing_with_person
|
||||
);
|
||||
assert_eq!(1, read_post_listings_with_person.len());
|
||||
|
||||
// Without the user
|
||||
assert_eq!(expected_post_listing_no_person, read_post_listings_no_person[0]);
|
||||
assert_eq!(
|
||||
expected_post_listing_no_person,
|
||||
read_post_listings_no_person[0]
|
||||
);
|
||||
assert_eq!(expected_post_listing_no_person, read_post_listing_no_person);
|
||||
assert_eq!(1, read_post_listings_no_person.len());
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use diesel::{pg::Pg, result::Error, *};
|
||||
use lemmy_db_queries::{limit_and_offset, MaybeOptional, ToSafe, ViewToVec};
|
||||
use lemmy_db_schema::{
|
||||
schema::{private_message, person, person_alias_1},
|
||||
schema::{person, person_alias_1, private_message},
|
||||
source::{
|
||||
person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
|
||||
private_message::PrivateMessage,
|
||||
person::{PersonAlias1, PersonSafe, PersonSafeAlias1, Person},
|
||||
},
|
||||
};
|
||||
use log::debug;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use diesel::{result::Error, *};
|
||||
use lemmy_db_queries::{aggregates::site_aggregates::SiteAggregates, ToSafe};
|
||||
use lemmy_db_schema::{
|
||||
schema::{site, site_aggregates, person},
|
||||
schema::{person, site, site_aggregates},
|
||||
source::{
|
||||
person::{Person, PersonSafe},
|
||||
site::Site,
|
||||
person::{PersonSafe, Person},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
|
|
@ -4,7 +4,7 @@ use lemmy_db_schema::{
|
|||
schema::{community, community_follower, person},
|
||||
source::{
|
||||
community::{Community, CommunitySafe},
|
||||
person::{PersonSafe, Person},
|
||||
person::{Person, PersonSafe},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
@ -22,7 +22,10 @@ impl CommunityFollowerView {
|
|||
let res = community_follower::table
|
||||
.inner_join(community::table)
|
||||
.inner_join(person::table)
|
||||
.select((Community::safe_columns_tuple(), Person::safe_columns_tuple()))
|
||||
.select((
|
||||
Community::safe_columns_tuple(),
|
||||
Person::safe_columns_tuple(),
|
||||
))
|
||||
.filter(community_follower::community_id.eq(community_id))
|
||||
.order_by(community_follower::published)
|
||||
.load::<CommunityFollowerViewTuple>(conn)?;
|
||||
|
@ -34,7 +37,10 @@ impl CommunityFollowerView {
|
|||
let res = community_follower::table
|
||||
.inner_join(community::table)
|
||||
.inner_join(person::table)
|
||||
.select((Community::safe_columns_tuple(), Person::safe_columns_tuple()))
|
||||
.select((
|
||||
Community::safe_columns_tuple(),
|
||||
Person::safe_columns_tuple(),
|
||||
))
|
||||
.filter(community_follower::person_id.eq(person_id))
|
||||
.order_by(community_follower::published)
|
||||
.load::<CommunityFollowerViewTuple>(conn)?;
|
||||
|
|
|
@ -4,7 +4,7 @@ use lemmy_db_schema::{
|
|||
schema::{community, community_moderator, person},
|
||||
source::{
|
||||
community::{Community, CommunitySafe},
|
||||
person::{PersonSafe, Person},
|
||||
person::{Person, PersonSafe},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
@ -22,7 +22,10 @@ impl CommunityModeratorView {
|
|||
let res = community_moderator::table
|
||||
.inner_join(community::table)
|
||||
.inner_join(person::table)
|
||||
.select((Community::safe_columns_tuple(), Person::safe_columns_tuple()))
|
||||
.select((
|
||||
Community::safe_columns_tuple(),
|
||||
Person::safe_columns_tuple(),
|
||||
))
|
||||
.filter(community_moderator::community_id.eq(community_id))
|
||||
.order_by(community_moderator::published)
|
||||
.load::<CommunityModeratorViewTuple>(conn)?;
|
||||
|
@ -34,7 +37,10 @@ impl CommunityModeratorView {
|
|||
let res = community_moderator::table
|
||||
.inner_join(community::table)
|
||||
.inner_join(person::table)
|
||||
.select((Community::safe_columns_tuple(), Person::safe_columns_tuple()))
|
||||
.select((
|
||||
Community::safe_columns_tuple(),
|
||||
Person::safe_columns_tuple(),
|
||||
))
|
||||
.filter(community_moderator::person_id.eq(person_id))
|
||||
.order_by(community_moderator::published)
|
||||
.load::<CommunityModeratorViewTuple>(conn)?;
|
||||
|
|
|
@ -4,7 +4,7 @@ use lemmy_db_schema::{
|
|||
schema::{community, community_person_ban, person},
|
||||
source::{
|
||||
community::{Community, CommunitySafe},
|
||||
person::{PersonSafe, Person},
|
||||
person::{Person, PersonSafe},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
@ -24,7 +24,10 @@ impl CommunityPersonBanView {
|
|||
let (community, person) = community_person_ban::table
|
||||
.inner_join(community::table)
|
||||
.inner_join(person::table)
|
||||
.select((Community::safe_columns_tuple(), Person::safe_columns_tuple()))
|
||||
.select((
|
||||
Community::safe_columns_tuple(),
|
||||
Person::safe_columns_tuple(),
|
||||
))
|
||||
.filter(community_person_ban::community_id.eq(from_community_id))
|
||||
.filter(community_person_ban::person_id.eq(from_person_id))
|
||||
.order_by(community_person_ban::published)
|
||||
|
|
|
@ -15,7 +15,7 @@ use lemmy_db_schema::{
|
|||
schema::{community, community_aggregates, community_follower, person},
|
||||
source::{
|
||||
community::{Community, CommunityFollower, CommunitySafe},
|
||||
person::{PersonSafe, Person},
|
||||
person::{Person, PersonSafe},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
@ -78,8 +78,9 @@ impl CommunityView {
|
|||
&mut CommunityModeratorView::for_community(conn, community_id)
|
||||
.map(|v| v.into_iter().map(|m| m.moderator.id).collect())?,
|
||||
);
|
||||
mods_and_admins
|
||||
.append(&mut PersonViewSafe::admins(conn).map(|v| v.into_iter().map(|a| a.person.id).collect())?);
|
||||
mods_and_admins.append(
|
||||
&mut PersonViewSafe::admins(conn).map(|v| v.into_iter().map(|a| a.person.id).collect())?,
|
||||
);
|
||||
Ok(mods_and_admins)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,17 +17,17 @@ use lemmy_db_schema::{
|
|||
community,
|
||||
community_follower,
|
||||
community_person_ban,
|
||||
post,
|
||||
person,
|
||||
person_alias_1,
|
||||
person_mention,
|
||||
post,
|
||||
},
|
||||
source::{
|
||||
comment::{Comment, CommentSaved},
|
||||
community::{Community, CommunityFollower, CommunitySafe, CommunityPersonBan},
|
||||
post::Post,
|
||||
person::{PersonAlias1, PersonSafe, PersonSafeAlias1, Person},
|
||||
community::{Community, CommunityFollower, CommunityPersonBan, CommunitySafe},
|
||||
person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
|
||||
person_mention::PersonMention,
|
||||
post::Post,
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
|
|
@ -9,8 +9,8 @@ use lemmy_db_queries::{
|
|||
ViewToVec,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
schema::{person, person_aggregates, local_user},
|
||||
source::person::{PersonSafe, Person},
|
||||
schema::{local_user, person, person_aggregates},
|
||||
source::person::{Person, PersonSafe},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use lemmy_db_schema::{
|
|||
source::{
|
||||
community::{Community, CommunitySafe},
|
||||
moderator::ModAddCommunity,
|
||||
person::{PersonAlias1, PersonSafe, PersonSafeAlias1, Person},
|
||||
person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
@ -31,7 +31,9 @@ impl ModAddCommunityView {
|
|||
let mut query = mod_add_community::table
|
||||
.inner_join(person::table.on(mod_add_community::mod_person_id.eq(person::id)))
|
||||
.inner_join(community::table)
|
||||
.inner_join(person_alias_1::table.on(mod_add_community::other_person_id.eq(person_alias_1::id)))
|
||||
.inner_join(
|
||||
person_alias_1::table.on(mod_add_community::other_person_id.eq(person_alias_1::id)),
|
||||
)
|
||||
.select((
|
||||
mod_add_community::all_columns,
|
||||
Person::safe_columns_tuple(),
|
||||
|
|
|
@ -4,7 +4,7 @@ use lemmy_db_schema::{
|
|||
schema::{mod_add, person, person_alias_1},
|
||||
source::{
|
||||
moderator::ModAdd,
|
||||
person::{PersonAlias1, PersonSafe, PersonSafeAlias1, Person},
|
||||
person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
|
|
@ -5,7 +5,7 @@ use lemmy_db_schema::{
|
|||
source::{
|
||||
community::{Community, CommunitySafe},
|
||||
moderator::ModBanFromCommunity,
|
||||
person::{PersonAlias1, PersonSafe, PersonSafeAlias1, Person},
|
||||
person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
@ -18,7 +18,12 @@ pub struct ModBanFromCommunityView {
|
|||
pub banned_person: PersonSafeAlias1,
|
||||
}
|
||||
|
||||
type ModBanFromCommunityViewTuple = (ModBanFromCommunity, PersonSafe, CommunitySafe, PersonSafeAlias1);
|
||||
type ModBanFromCommunityViewTuple = (
|
||||
ModBanFromCommunity,
|
||||
PersonSafe,
|
||||
CommunitySafe,
|
||||
PersonSafeAlias1,
|
||||
);
|
||||
|
||||
impl ModBanFromCommunityView {
|
||||
pub fn list(
|
||||
|
|
|
@ -4,7 +4,7 @@ use lemmy_db_schema::{
|
|||
schema::{mod_ban, person, person_alias_1},
|
||||
source::{
|
||||
moderator::ModBan,
|
||||
person::{PersonAlias1, PersonSafe, PersonSafeAlias1, Person},
|
||||
person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use diesel::{result::Error, *};
|
||||
use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec};
|
||||
use lemmy_db_schema::{
|
||||
schema::{community, mod_lock_post, post, person},
|
||||
schema::{community, mod_lock_post, person, post},
|
||||
source::{
|
||||
community::{Community, CommunitySafe},
|
||||
moderator::ModLockPost,
|
||||
person::{Person, PersonSafe},
|
||||
post::Post,
|
||||
person::{PersonSafe, Person},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use diesel::{result::Error, *};
|
||||
use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec};
|
||||
use lemmy_db_schema::{
|
||||
schema::{comment, community, mod_remove_comment, post, person, person_alias_1},
|
||||
schema::{comment, community, mod_remove_comment, person, person_alias_1, post},
|
||||
source::{
|
||||
comment::Comment,
|
||||
community::{Community, CommunitySafe},
|
||||
moderator::ModRemoveComment,
|
||||
person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
|
||||
post::Post,
|
||||
person::{PersonAlias1, PersonSafe, PersonSafeAlias1, Person},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
|
|
@ -5,7 +5,7 @@ use lemmy_db_schema::{
|
|||
source::{
|
||||
community::{Community, CommunitySafe},
|
||||
moderator::ModRemoveCommunity,
|
||||
person::{PersonSafe, Person},
|
||||
person::{Person, PersonSafe},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use diesel::{result::Error, *};
|
||||
use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec};
|
||||
use lemmy_db_schema::{
|
||||
schema::{community, mod_remove_post, post, person},
|
||||
schema::{community, mod_remove_post, person, post},
|
||||
source::{
|
||||
community::{Community, CommunitySafe},
|
||||
moderator::ModRemovePost,
|
||||
person::{Person, PersonSafe},
|
||||
post::Post,
|
||||
person::{PersonSafe, Person},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use diesel::{result::Error, *};
|
||||
use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec};
|
||||
use lemmy_db_schema::{
|
||||
schema::{community, mod_sticky_post, post, person},
|
||||
schema::{community, mod_sticky_post, person, post},
|
||||
source::{
|
||||
community::{Community, CommunitySafe},
|
||||
moderator::ModStickyPost,
|
||||
person::{Person, PersonSafe},
|
||||
post::Post,
|
||||
person::{PersonSafe, Person},
|
||||
},
|
||||
};
|
||||
use serde::Serialize;
|
||||
|
|
|
@ -19,9 +19,9 @@ use lemmy_db_schema::{
|
|||
source::{
|
||||
comment::Comment,
|
||||
community::{Community, CommunityForm},
|
||||
person::{Person, PersonForm},
|
||||
post::Post,
|
||||
private_message::PrivateMessage,
|
||||
user::{UserForm, User_},
|
||||
},
|
||||
};
|
||||
use lemmy_utils::{apub::generate_actor_keypair, settings::structs::Settings, LemmyError};
|
||||
|
@ -40,52 +40,42 @@ pub fn run_advanced_migrations(conn: &PgConnection) -> Result<(), LemmyError> {
|
|||
}
|
||||
|
||||
fn user_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
|
||||
use lemmy_db_schema::schema::user_::dsl::*;
|
||||
use lemmy_db_schema::schema::person::dsl::*;
|
||||
|
||||
info!("Running user_updates_2020_04_02");
|
||||
|
||||
// Update the actor_id, private_key, and public_key, last_refreshed_at
|
||||
let incorrect_users = user_
|
||||
let incorrect_persons = person
|
||||
.filter(actor_id.like("http://changeme_%"))
|
||||
.filter(local.eq(true))
|
||||
.load::<User_>(conn)?;
|
||||
.load::<Person>(conn)?;
|
||||
|
||||
for cuser in &incorrect_users {
|
||||
for cperson in &incorrect_persons {
|
||||
let keypair = generate_actor_keypair()?;
|
||||
|
||||
let form = UserForm {
|
||||
name: cuser.name.to_owned(),
|
||||
email: Some(cuser.email.to_owned()),
|
||||
matrix_user_id: Some(cuser.matrix_user_id.to_owned()),
|
||||
avatar: Some(cuser.avatar.to_owned()),
|
||||
banner: Some(cuser.banner.to_owned()),
|
||||
password_encrypted: cuser.password_encrypted.to_owned(),
|
||||
preferred_username: Some(cuser.preferred_username.to_owned()),
|
||||
published: Some(cuser.published),
|
||||
let form = PersonForm {
|
||||
name: cperson.name.to_owned(),
|
||||
avatar: None,
|
||||
banner: None,
|
||||
preferred_username: None,
|
||||
published: None,
|
||||
updated: None,
|
||||
admin: cuser.admin,
|
||||
banned: Some(cuser.banned),
|
||||
show_nsfw: cuser.show_nsfw,
|
||||
theme: cuser.theme.to_owned(),
|
||||
default_sort_type: cuser.default_sort_type,
|
||||
default_listing_type: cuser.default_listing_type,
|
||||
lang: cuser.lang.to_owned(),
|
||||
show_avatars: cuser.show_avatars,
|
||||
send_notifications_to_email: cuser.send_notifications_to_email,
|
||||
actor_id: Some(generate_apub_endpoint(EndpointType::Person, &cuser.name)?),
|
||||
bio: Some(cuser.bio.to_owned()),
|
||||
local: cuser.local,
|
||||
private_key: Some(keypair.private_key),
|
||||
public_key: Some(keypair.public_key),
|
||||
banned: None,
|
||||
deleted: None,
|
||||
actor_id: Some(generate_apub_endpoint(EndpointType::Person, &cperson.name)?),
|
||||
bio: None,
|
||||
local: None,
|
||||
private_key: Some(Some(keypair.private_key)),
|
||||
public_key: Some(Some(keypair.public_key)),
|
||||
last_refreshed_at: Some(naive_now()),
|
||||
inbox_url: None,
|
||||
shared_inbox_url: None,
|
||||
};
|
||||
|
||||
User_::update(&conn, cuser.id, &form)?;
|
||||
Person::update(&conn, cperson.id, &form)?;
|
||||
}
|
||||
|
||||
info!("{} user rows updated.", incorrect_users.len());
|
||||
info!("{} person rows updated.", incorrect_persons.len());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -231,20 +221,20 @@ fn post_thumbnail_url_updates_2020_07_27(conn: &PgConnection) -> Result<(), Lemm
|
|||
fn apub_columns_2021_02_02(conn: &PgConnection) -> Result<(), LemmyError> {
|
||||
info!("Running apub_columns_2021_02_02");
|
||||
{
|
||||
use lemmy_db_schema::schema::user_::dsl::*;
|
||||
let users = user_
|
||||
use lemmy_db_schema::schema::person::dsl::*;
|
||||
let persons = person
|
||||
.filter(inbox_url.like("http://changeme_%"))
|
||||
.load::<User_>(conn)?;
|
||||
.load::<Person>(conn)?;
|
||||
|
||||
for u in &users {
|
||||
let inbox_url_ = generate_inbox_url(&u.actor_id)?;
|
||||
let shared_inbox_url_ = generate_shared_inbox_url(&u.actor_id)?;
|
||||
diesel::update(user_.find(u.id))
|
||||
for p in &persons {
|
||||
let inbox_url_ = generate_inbox_url(&p.actor_id)?;
|
||||
let shared_inbox_url_ = generate_shared_inbox_url(&p.actor_id)?;
|
||||
diesel::update(person.find(p.id))
|
||||
.set((
|
||||
inbox_url.eq(inbox_url_),
|
||||
shared_inbox_url.eq(shared_inbox_url_),
|
||||
))
|
||||
.get_result::<User_>(conn)?;
|
||||
.get_result::<Person>(conn)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue