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