use lemmy_structs::{blocking, comment::*, send_local_notifs};
use lemmy_utils::{
utils::{remove_slurs, scrape_text_for_mentions},
- APIError,
+ ApiError,
ConnectionId,
LemmyError,
};
// Check if post is locked, no new comments
if post.locked {
- return Err(APIError::err("locked").into());
+ return Err(ApiError::err("locked").into());
}
// If there's a parent_id, check to make sure that comment is in that post
let parent =
match blocking(context.pool(), move |conn| Comment::read(&conn, parent_id)).await? {
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err("couldnt_create_comment").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_create_comment").into()),
};
if parent.post_id != post_id {
- return Err(APIError::err("couldnt_create_comment").into());
+ return Err(ApiError::err("couldnt_create_comment").into());
}
}
.await?
{
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err("couldnt_create_comment").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_create_comment").into()),
};
// Necessary to update the ap_id
.await?
{
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err("couldnt_create_comment").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_create_comment").into()),
};
updated_comment.send_create(&user, context).await?;
let like = move |conn: &'_ _| CommentLike::like(&conn, &like_form);
if blocking(context.pool(), like).await?.is_err() {
- return Err(APIError::err("couldnt_like_comment").into());
+ return Err(ApiError::err("couldnt_like_comment").into());
}
updated_comment.send_like(&user, context).await?;
.await?
{
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_comment").into()),
};
comment_view.comment.read = true;
}
// Verify that only the creator can edit
if user.id != orig_comment.creator.id {
- return Err(APIError::err("no_comment_edit_allowed").into());
+ return Err(ApiError::err("no_comment_edit_allowed").into());
}
// Do the update
.await?
{
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_comment").into()),
};
// Send the apub update
// Verify that only the creator can delete
if user.id != orig_comment.creator.id {
- return Err(APIError::err("no_comment_edit_allowed").into());
+ return Err(ApiError::err("no_comment_edit_allowed").into());
}
// Do the delete
.await?
{
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_comment").into()),
};
// Send the apub message
.await?
{
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_comment").into()),
};
// Mod tables
// Verify that only the recipient can mark as read
if user.id != orig_comment.get_recipient_id() {
- return Err(APIError::err("no_comment_edit_allowed").into());
+ return Err(ApiError::err("no_comment_edit_allowed").into());
}
// Do the mark as read
.await?
{
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_comment").into()),
};
// Refetch it
if data.save {
let save_comment = move |conn: &'_ _| CommentSaved::save(conn, &comment_saved_form);
if blocking(context.pool(), save_comment).await?.is_err() {
- return Err(APIError::err("couldnt_save_comment").into());
+ return Err(ApiError::err("couldnt_save_comment").into());
}
} else {
let unsave_comment = move |conn: &'_ _| CommentSaved::unsave(conn, &comment_saved_form);
if blocking(context.pool(), unsave_comment).await?.is_err() {
- return Err(APIError::err("couldnt_save_comment").into());
+ return Err(ApiError::err("couldnt_save_comment").into());
}
}
let like_form2 = like_form.clone();
let like = move |conn: &'_ _| CommentLike::like(conn, &like_form2);
if blocking(context.pool(), like).await?.is_err() {
- return Err(APIError::err("couldnt_like_comment").into());
+ return Err(ApiError::err("couldnt_like_comment").into());
}
if like_form.score == 1 {
.await?;
let comments = match comments {
Ok(comments) => comments,
- Err(_) => return Err(APIError::err("couldnt_get_comments").into()),
+ Err(_) => return Err(ApiError::err("couldnt_get_comments").into()),
};
Ok(GetCommentsResponse { comments })
// check size of report and check for whitespace
let reason = data.reason.trim();
if reason.is_empty() {
- return Err(APIError::err("report_reason_required").into());
+ return Err(ApiError::err("report_reason_required").into());
}
if reason.chars().count() > 1000 {
- return Err(APIError::err("report_too_long").into());
+ return Err(ApiError::err("report_too_long").into());
}
let user_id = user.id;
.await?
{
Ok(report) => report,
- Err(_e) => return Err(APIError::err("couldnt_create_report").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_create_report").into()),
};
let res = CreateCommentReportResponse { success: true };
};
if blocking(context.pool(), resolve_fun).await?.is_err() {
- return Err(APIError::err("couldnt_resolve_report").into());
+ return Err(ApiError::err("couldnt_resolve_report").into());
};
let report_id = data.report_id;
apub::generate_actor_keypair,
location_info,
utils::{check_slurs, check_slurs_opt, is_valid_community_name, naive_from_unix},
- APIError,
+ ApiError,
ConnectionId,
LemmyError,
};
.await?
{
Ok(community) => community,
- Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_find_community").into()),
}
.id
}
.await?
{
Ok(community) => community,
- Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_find_community").into()),
};
let moderators: Vec<CommunityModeratorView> = match blocking(context.pool(), move |conn| {
.await?
{
Ok(moderators) => moderators,
- Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_find_community").into()),
};
let online = context
check_slurs_opt(&data.description)?;
if !is_valid_community_name(&data.name) {
- return Err(APIError::err("invalid_community_name").into());
+ return Err(ApiError::err("invalid_community_name").into());
}
// Double check for duplicate community actor_ids
})
.await?;
if community_dupe.is_ok() {
- return Err(APIError::err("community_already_exists").into());
+ return Err(ApiError::err("community_already_exists").into());
}
// Check to make sure the icon and banners are urls
.await?
{
Ok(community) => community,
- Err(_e) => return Err(APIError::err("community_already_exists").into()),
+ Err(_e) => return Err(ApiError::err("community_already_exists").into()),
};
// The community creator becomes a moderator
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
if blocking(context.pool(), join).await?.is_err() {
- return Err(APIError::err("community_moderator_already_exists").into());
+ return Err(ApiError::err("community_moderator_already_exists").into());
}
// Follow your own community
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
if blocking(context.pool(), follow).await?.is_err() {
- return Err(APIError::err("community_follower_already_exists").into());
+ return Err(ApiError::err("community_follower_already_exists").into());
}
let user_id = user.id;
})
.await??;
if !mods.contains(&user.id) {
- return Err(APIError::err("not_a_moderator").into());
+ return Err(ApiError::err("not_a_moderator").into());
}
let community_id = data.community_id;
.await?
{
Ok(community) => community,
- Err(_e) => return Err(APIError::err("couldnt_update_community").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_community").into()),
};
// TODO there needs to be some kind of an apub update
})
.await??;
if read_community.creator_id != user.id {
- return Err(APIError::err("no_community_edit_allowed").into());
+ return Err(ApiError::err("no_community_edit_allowed").into());
}
// Do the delete
.await?
{
Ok(community) => community,
- Err(_e) => return Err(APIError::err("couldnt_update_community").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_community").into()),
};
// Send apub messages
.await?
{
Ok(community) => community,
- Err(_e) => return Err(APIError::err("couldnt_update_community").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_community").into()),
};
// Mod tables
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
if blocking(context.pool(), follow).await?.is_err() {
- return Err(APIError::err("community_follower_already_exists").into());
+ return Err(ApiError::err("community_follower_already_exists").into());
}
} else {
let unfollow =
move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form);
if blocking(context.pool(), unfollow).await?.is_err() {
- return Err(APIError::err("community_follower_already_exists").into());
+ return Err(ApiError::err("community_follower_already_exists").into());
}
}
} else if data.follow {
user.send_unfollow(&community.actor_id(), context).await?;
let unfollow = move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form);
if blocking(context.pool(), unfollow).await?.is_err() {
- return Err(APIError::err("community_follower_already_exists").into());
+ return Err(ApiError::err("community_follower_already_exists").into());
}
}
.await?
{
Ok(communities) => communities,
- _ => return Err(APIError::err("system_err_login").into()),
+ _ => return Err(ApiError::err("system_err_login").into()),
};
// Return the jwt
if data.ban {
let ban = move |conn: &'_ _| CommunityUserBan::ban(conn, &community_user_ban_form);
if blocking(context.pool(), ban).await?.is_err() {
- return Err(APIError::err("community_user_already_banned").into());
+ return Err(ApiError::err("community_user_already_banned").into());
}
// Also unsubscribe them from the community, if they are subscribed
} else {
let unban = move |conn: &'_ _| CommunityUserBan::unban(conn, &community_user_ban_form);
if blocking(context.pool(), unban).await?.is_err() {
- return Err(APIError::err("community_user_already_banned").into());
+ return Err(ApiError::err("community_user_already_banned").into());
}
}
if data.added {
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
if blocking(context.pool(), join).await?.is_err() {
- return Err(APIError::err("community_moderator_already_exists").into());
+ return Err(ApiError::err("community_moderator_already_exists").into());
}
} else {
let leave = move |conn: &'_ _| CommunityModerator::leave(conn, &community_moderator_form);
if blocking(context.pool(), leave).await?.is_err() {
- return Err(APIError::err("community_moderator_already_exists").into());
+ return Err(ApiError::err("community_moderator_already_exists").into());
}
}
if user.id != read_community.creator_id
&& !admins.iter().map(|a| a.user.id).any(|x| x == user.id)
{
- return Err(APIError::err("not_an_admin").into());
+ return Err(ApiError::err("not_an_admin").into());
}
let community_id = data.community_id;
let new_creator = data.user_id;
let update = move |conn: &'_ _| Community::update_creator(conn, community_id, new_creator);
if blocking(context.pool(), update).await?.is_err() {
- return Err(APIError::err("couldnt_update_community").into());
+ return Err(ApiError::err("couldnt_update_community").into());
};
// You also have to re-do the community_moderator table, reordering it.
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
if blocking(context.pool(), join).await?.is_err() {
- return Err(APIError::err("community_moderator_already_exists").into());
+ return Err(ApiError::err("community_moderator_already_exists").into());
}
}
.await?
{
Ok(community) => community,
- Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_find_community").into()),
};
let community_id = data.community_id;
.await?
{
Ok(moderators) => moderators,
- Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_find_community").into()),
};
// Return the jwt
community_view::CommunityView,
};
use lemmy_structs::{blocking, comment::*, community::*, post::*, site::*, user::*, websocket::*};
-use lemmy_utils::{claims::Claims, settings::Settings, APIError, ConnectionId, LemmyError};
+use lemmy_utils::{claims::Claims, settings::Settings, ApiError, ConnectionId, LemmyError};
use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperation};
use serde::Deserialize;
use std::process::Command;
})
.await?;
if !is_mod_or_admin {
- return Err(APIError::err("not_a_mod_or_admin").into());
+ return Err(ApiError::err("not_a_mod_or_admin").into());
}
Ok(())
}
pub async fn is_admin(pool: &DbPool, user_id: i32) -> Result<(), LemmyError> {
let user = blocking(pool, move |conn| User_::read(conn, user_id)).await??;
if !user.admin {
- return Err(APIError::err("not_an_admin").into());
+ return Err(ApiError::err("not_an_admin").into());
}
Ok(())
}
pub(crate) async fn get_post(post_id: i32, pool: &DbPool) -> Result<Post, LemmyError> {
match blocking(pool, move |conn| Post::read(conn, post_id)).await? {
Ok(post) => Ok(post),
- Err(_e) => Err(APIError::err("couldnt_find_post").into()),
+ Err(_e) => Err(ApiError::err("couldnt_find_post").into()),
}
}
pub(crate) async fn get_user_from_jwt(jwt: &str, pool: &DbPool) -> Result<User_, LemmyError> {
let claims = match Claims::decode(&jwt) {
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 user_id = claims.id;
let user = blocking(pool, move |conn| User_::read(conn, user_id)).await??;
// Check for a site ban
if user.banned {
- return Err(APIError::err("site_ban").into());
+ return Err(ApiError::err("site_ban").into());
}
Ok(user)
}
) -> Result<UserSafeSettings, LemmyError> {
let claims = match Claims::decode(&jwt) {
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 user_id = claims.id;
let user = blocking(pool, move |conn| UserSafeSettings::read(conn, user_id)).await??;
// Check for a site ban
if user.banned {
- return Err(APIError::err("site_ban").into());
+ return Err(ApiError::err("site_ban").into());
}
Ok(user)
}
) -> Result<(), LemmyError> {
let is_banned = move |conn: &'_ _| CommunityUserBanView::get(conn, user_id, community_id).is_ok();
if blocking(pool, is_banned).await? {
- Err(APIError::err("community_ban").into())
+ Err(ApiError::err("community_ban").into())
} else {
Ok(())
}
if score == -1 {
let site = blocking(pool, move |conn| Site::read_simple(conn)).await??;
if !site.enable_downvotes {
- return Err(APIError::err("downvotes_disabled").into());
+ return Err(ApiError::err("downvotes_disabled").into());
}
}
Ok(())
pub(crate) fn check_optional_url(item: &Option<Option<String>>) -> Result<(), LemmyError> {
if let Some(Some(item)) = &item {
if Url::parse(item).is_err() {
- return Err(APIError::err("invalid_url").into());
+ return Err(ApiError::err("invalid_url").into());
}
}
Ok(())
use lemmy_utils::{
request::fetch_iframely_and_pictrs_data,
utils::{check_slurs, check_slurs_opt, is_valid_post_title},
- APIError,
+ ApiError,
ConnectionId,
LemmyError,
};
check_slurs_opt(&data.body)?;
if !is_valid_post_title(&data.name) {
- return Err(APIError::err("invalid_post_title").into());
+ return Err(ApiError::err("invalid_post_title").into());
}
check_community_ban(user.id, data.community_id, context.pool()).await?;
"couldnt_create_post"
};
- return Err(APIError::err(err_type).into());
+ return Err(ApiError::err(err_type).into());
}
};
.await?
{
Ok(post) => post,
- Err(_e) => return Err(APIError::err("couldnt_create_post").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_create_post").into()),
};
updated_post.send_create(&user, context).await?;
let like = move |conn: &'_ _| PostLike::like(conn, &like_form);
if blocking(context.pool(), like).await?.is_err() {
- return Err(APIError::err("couldnt_like_post").into());
+ return Err(ApiError::err("couldnt_like_post").into());
}
updated_post.send_like(&user, context).await?;
.await?
{
Ok(post) => post,
- Err(_e) => return Err(APIError::err("couldnt_find_post").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_find_post").into()),
};
let res = PostResponse { post_view };
.await?
{
Ok(post) => post,
- Err(_e) => return Err(APIError::err("couldnt_find_post").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_find_post").into()),
};
let id = data.id;
.await?
{
Ok(community) => community,
- Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_find_community").into()),
};
let online = context
.await?
{
Ok(posts) => posts,
- Err(_e) => return Err(APIError::err("couldnt_get_posts").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_get_posts").into()),
};
Ok(GetPostsResponse { posts })
let like_form2 = like_form.clone();
let like = move |conn: &'_ _| PostLike::like(conn, &like_form2);
if blocking(context.pool(), like).await?.is_err() {
- return Err(APIError::err("couldnt_like_post").into());
+ return Err(ApiError::err("couldnt_like_post").into());
}
if like_form.score == 1 {
.await?
{
Ok(post) => post,
- Err(_e) => return Err(APIError::err("couldnt_find_post").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_find_post").into()),
};
let res = PostResponse { post_view };
check_slurs_opt(&data.body)?;
if !is_valid_post_title(&data.name) {
- return Err(APIError::err("invalid_post_title").into());
+ return Err(ApiError::err("invalid_post_title").into());
}
let post_id = data.post_id;
// Verify that only the creator can edit
if !Post::is_post_creator(user.id, orig_post.creator_id) {
- return Err(APIError::err("no_post_edit_allowed").into());
+ return Err(ApiError::err("no_post_edit_allowed").into());
}
// Fetch Iframely and Pictrs cached image
"couldnt_update_post"
};
- return Err(APIError::err(err_type).into());
+ return Err(ApiError::err(err_type).into());
}
};
// Verify that only the creator can delete
if !Post::is_post_creator(user.id, orig_post.creator_id) {
- return Err(APIError::err("no_post_edit_allowed").into());
+ return Err(ApiError::err("no_post_edit_allowed").into());
}
// Update the post
if data.save {
let save = move |conn: &'_ _| PostSaved::save(conn, &post_saved_form);
if blocking(context.pool(), save).await?.is_err() {
- return Err(APIError::err("couldnt_save_post").into());
+ return Err(ApiError::err("couldnt_save_post").into());
}
} else {
let unsave = move |conn: &'_ _| PostSaved::unsave(conn, &post_saved_form);
if blocking(context.pool(), unsave).await?.is_err() {
- return Err(APIError::err("couldnt_save_post").into());
+ return Err(ApiError::err("couldnt_save_post").into());
}
}
// check size of report and check for whitespace
let reason = data.reason.trim();
if reason.is_empty() {
- return Err(APIError::err("report_reason_required").into());
+ return Err(ApiError::err("report_reason_required").into());
}
if reason.chars().count() > 1000 {
- return Err(APIError::err("report_too_long").into());
+ return Err(ApiError::err("report_too_long").into());
}
let user_id = user.id;
.await?
{
Ok(report) => report,
- Err(_e) => return Err(APIError::err("couldnt_create_report").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_create_report").into()),
};
let res = CreatePostReportResponse { success: true };
};
if blocking(context.pool(), resolve_fun).await?.is_err() {
- return Err(APIError::err("couldnt_resolve_report").into());
+ return Err(ApiError::err("couldnt_resolve_report").into());
};
context.chat_server().do_send(SendModRoomMessage {
settings::Settings,
utils::{check_slurs, check_slurs_opt},
version,
- APIError,
+ ApiError,
ConnectionId,
LemmyError,
};
let read_site = move |conn: &'_ _| Site::read_simple(conn);
if blocking(context.pool(), read_site).await?.is_ok() {
- return Err(APIError::err("site_already_exists").into());
+ return Err(ApiError::err("site_already_exists").into());
};
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
let create_site = move |conn: &'_ _| Site::create(conn, &site_form);
if blocking(context.pool(), create_site).await?.is_err() {
- return Err(APIError::err("site_already_exists").into());
+ return Err(ApiError::err("site_already_exists").into());
}
let site_view = blocking(context.pool(), move |conn| SiteView::read(conn)).await??;
let update_site = move |conn: &'_ _| Site::update(conn, 1, &site_form);
if blocking(context.pool(), update_site).await?.is_err() {
- return Err(APIError::err("couldnt_update_site").into());
+ return Err(ApiError::err("couldnt_update_site").into());
}
let site_view = blocking(context.pool(), move |conn| SiteView::read(conn)).await??;
// Make sure user is the creator
if read_site.creator_id != user.id {
- return Err(APIError::err("not_an_admin").into());
+ return Err(ApiError::err("not_an_admin").into());
}
let new_creator_id = data.user_id;
let transfer_site = move |conn: &'_ _| Site::transfer(conn, new_creator_id);
if blocking(context.pool(), transfer_site).await?.is_err() {
- return Err(APIError::err("couldnt_update_site").into());
+ return Err(ApiError::err("couldnt_update_site").into());
};
// Mod tables
// Make sure docker doesn't have :ro at the end of the volume, so its not a read-only filesystem
let config_hjson = match Settings::save_config_file(&data.config_hjson) {
Ok(config_hjson) => config_hjson,
- Err(_e) => return Err(APIError::err("couldnt_update_site").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_site").into()),
};
Ok(GetSiteConfigResponse { config_hjson })
naive_from_unix,
remove_slurs,
},
- APIError,
+ ApiError,
ConnectionId,
LemmyError,
};
.await?
{
Ok(user) => user,
- 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()),
};
// Verify the password
let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
if !valid {
- return Err(APIError::err("password_incorrect").into());
+ return Err(ApiError::err("password_incorrect").into());
}
// Return the jwt
// Make sure site has open registration
if let Ok(site) = blocking(context.pool(), move |conn| Site::read_simple(conn)).await? {
if !site.open_registration {
- return Err(APIError::err("registration_closed").into());
+ return Err(ApiError::err("registration_closed").into());
}
}
// Password length check
if data.password.len() > 60 {
- return Err(APIError::err("invalid_password").into());
+ return Err(ApiError::err("invalid_password").into());
}
// Make sure passwords match
if data.password != data.password_verify {
- return Err(APIError::err("passwords_dont_match").into());
+ return Err(ApiError::err("passwords_dont_match").into());
}
// Check if there are admins. False if admins exist
})
.await?;
if !check {
- return Err(APIError::err("captcha_incorrect").into());
+ return Err(ApiError::err("captcha_incorrect").into());
}
}
let user_keypair = generate_actor_keypair()?;
if !is_valid_username(&data.username) {
- return Err(APIError::err("invalid_username").into());
+ return Err(ApiError::err("invalid_username").into());
}
let user_actor_id = generate_apub_endpoint(EndpointType::User, &data.username)?;
"user_already_exists"
};
- return Err(APIError::err(err_type).into());
+ return Err(ApiError::err(err_type).into());
}
};
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
if blocking(context.pool(), follow).await?.is_err() {
- return Err(APIError::err("community_follower_already_exists").into());
+ return Err(ApiError::err("community_follower_already_exists").into());
};
// If its an admin, add them as a mod and follower to main
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
if blocking(context.pool(), join).await?.is_err() {
- return Err(APIError::err("community_moderator_already_exists").into());
+ return Err(ApiError::err("community_moderator_already_exists").into());
}
}
if let Some(Some(bio)) = &bio {
if bio.chars().count() > 300 {
- return Err(APIError::err("bio_length_overflow").into());
+ return Err(ApiError::err("bio_length_overflow").into());
}
}
if let Some(Some(preferred_username)) = &preferred_username {
if !is_valid_preferred_username(preferred_username.trim()) {
- return Err(APIError::err("invalid_username").into());
+ return Err(ApiError::err("invalid_username").into());
}
}
Some(new_password_verify) => {
// Make sure passwords match
if new_password != new_password_verify {
- return Err(APIError::err("passwords_dont_match").into());
+ return Err(ApiError::err("passwords_dont_match").into());
}
// Check the old password
Some(old_password) => {
let valid: bool = verify(old_password, &user.password_encrypted).unwrap_or(false);
if !valid {
- return Err(APIError::err("password_incorrect").into());
+ return Err(ApiError::err("password_incorrect").into());
}
let new_password = new_password.to_owned();
let user = blocking(context.pool(), move |conn| {
.await??;
user.password_encrypted
}
- None => return Err(APIError::err("password_incorrect").into()),
+ None => return Err(ApiError::err("password_incorrect").into()),
}
}
- None => return Err(APIError::err("passwords_dont_match").into()),
+ None => return Err(ApiError::err("passwords_dont_match").into()),
}
}
None => user.password_encrypted,
"user_already_exists"
};
- return Err(APIError::err(err_type).into());
+ return Err(ApiError::err(err_type).into());
}
};
.await?;
match user {
Ok(user) => user.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 added_user_id = data.user_id;
let add_admin = move |conn: &'_ _| User_::add_admin(conn, added_user_id, added);
if blocking(context.pool(), add_admin).await?.is_err() {
- return Err(APIError::err("couldnt_update_user").into());
+ return Err(ApiError::err("couldnt_update_user").into());
}
// Mod tables
let banned_user_id = data.user_id;
let ban_user = move |conn: &'_ _| User_::ban_user(conn, banned_user_id, ban);
if blocking(context.pool(), ban_user).await?.is_err() {
- return Err(APIError::err("couldnt_update_user").into());
+ return Err(ApiError::err("couldnt_update_user").into());
}
// Remove their data if that's desired
.await??;
if user.id != read_user_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 read = data.read;
let update_mention = move |conn: &'_ _| UserMention::update_read(conn, user_mention_id, read);
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 reply_id = comment_view.comment.id;
let mark_as_read = move |conn: &'_ _| Comment::update_read(conn, reply_id, true);
if blocking(context.pool(), mark_as_read).await?.is_err() {
- return Err(APIError::err("couldnt_update_comment").into());
+ return Err(ApiError::err("couldnt_update_comment").into());
}
}
.await?
.is_err()
{
- return Err(APIError::err("couldnt_update_comment").into());
+ return Err(ApiError::err("couldnt_update_comment").into());
}
// Mark all private_messages as read
let update_pm = move |conn: &'_ _| PrivateMessage::mark_all_as_read(conn, user_id);
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());
}
Ok(GetRepliesResponse { replies: vec![] })
// Verify the password
let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
if !valid {
- return Err(APIError::err("password_incorrect").into());
+ return Err(ApiError::err("password_incorrect").into());
}
// Comments
let user_id = user.id;
let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, user_id);
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
let permadelete = move |conn: &'_ _| Post::permadelete_for_creator(conn, user_id);
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| {
.await?
{
Ok(user) => user,
- 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()),
};
// Generate a random token
let html = &format!("<h1>Password Reset Request for {}</h1><br><a href={}/password_change/{}>Click here to reset your password</a>", user.name, hostname, &token);
match send_email(subject, user_email, &user.name, html) {
Ok(_o) => _o,
- Err(_e) => return Err(APIError::err(&_e).into()),
+ Err(_e) => return Err(ApiError::err(&_e).into()),
};
Ok(PasswordResetResponse {})
// Make sure passwords match
if data.password != data.password_verify {
- return Err(APIError::err("passwords_dont_match").into());
+ return Err(ApiError::err("passwords_dont_match").into());
}
// Update the user with the new password
.await?
{
Ok(user) => user,
- Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_user").into()),
};
// Return the jwt
{
Ok(private_message) => private_message,
Err(_e) => {
- return Err(APIError::err("couldnt_create_private_message").into());
+ return Err(ApiError::err("couldnt_create_private_message").into());
}
};
.await?
{
Ok(private_message) => private_message,
- 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?;
})
.await??;
if user.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());
}
// Doing the update
.await?
{
Ok(private_message) => private_message,
- Err(_e) => return Err(APIError::err("couldnt_update_private_message").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_private_message").into()),
};
// Send the apub update
})
.await??;
if user.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());
}
// Doing the update
.await?
{
Ok(private_message) => private_message,
- Err(_e) => return Err(APIError::err("couldnt_update_private_message").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_private_message").into()),
};
// Send the apub update
})
.await??;
if user.id != orig_private_message.recipient_id {
- return Err(APIError::err("couldnt_update_private_message").into());
+ return Err(ApiError::err("couldnt_update_private_message").into());
}
// Doing the update
.await?
{
Ok(private_message) => private_message,
- Err(_e) => return Err(APIError::err("couldnt_update_private_message").into()),
+ Err(_e) => return Err(ApiError::err("couldnt_update_private_message").into()),
};
// No need to send an apub update
pub type PostId = i32;
pub type CommunityId = i32;
pub type UserId = i32;
-pub type IPAddr = String;
+pub type IpAddr = String;
#[macro_export]
macro_rules! location_info {
#[derive(Debug, Error)]
#[error("{{\"error\":\"{message}\"}}")]
-pub struct APIError {
+pub struct ApiError {
pub message: String,
}
-impl APIError {
+impl ApiError {
pub fn err(msg: &str) -> Self {
- APIError {
+ ApiError {
message: msg.to_string(),
}
}
-use crate::{APIError, IPAddr, LemmyError};
+use crate::{ApiError, IpAddr, LemmyError};
use log::debug;
use std::{collections::HashMap, time::SystemTime};
use strum::IntoEnumIterator;
/// Rate limiting based on rate type and IP addr
#[derive(Debug, Clone)]
pub struct RateLimiter {
- buckets: HashMap<RateLimitType, HashMap<IPAddr, RateLimitBucket>>,
+ buckets: HashMap<RateLimitType, HashMap<IpAddr, RateLimitBucket>>,
}
impl Default for RateLimiter {
fn default() -> Self {
Self {
- buckets: HashMap::<RateLimitType, HashMap<IPAddr, RateLimitBucket>>::new(),
+ buckets: HashMap::<RateLimitType, HashMap<IpAddr, RateLimitBucket>>::new(),
}
}
}
rate_limit.allowance
);
Err(
- APIError {
+ ApiError {
message: format!(
"Too many requests. type: {}, IP: {}, {} per {} seconds",
type_.as_ref(),
-use crate::{settings::Settings, APIError};
+use crate::{settings::Settings, ApiError};
use actix_web::dev::ConnectionInfo;
use chrono::{DateTime, FixedOffset, NaiveDateTime};
use itertools::Itertools;
}
}
-pub fn check_slurs(text: &str) -> Result<(), APIError> {
+pub fn check_slurs(text: &str) -> Result<(), ApiError> {
if let Err(slurs) = slur_check(text) {
- Err(APIError::err(&slurs_vec_to_str(slurs)))
+ Err(ApiError::err(&slurs_vec_to_str(slurs)))
} else {
Ok(())
}
}
-pub fn check_slurs_opt(text: &Option<String>) -> Result<(), APIError> {
+pub fn check_slurs_opt(text: &Option<String>) -> Result<(), ApiError> {
match text {
Some(t) => check_slurs(t),
None => Ok(()),
use lemmy_utils::{
location_info,
rate_limit::RateLimit,
- APIError,
+ ApiError,
CommunityId,
ConnectionId,
- IPAddr,
+ IpAddr,
LemmyError,
PostId,
UserId,
}
pub struct SessionInfo {
- pub addr: Recipient<WSMessage>,
- pub ip: IPAddr,
+ pub addr: Recipient<WsMessage>,
+ pub ip: IpAddr,
}
/// `ChatServer` is an actor. It maintains list of connection client session.
fn sendit(&self, message: &str, id: ConnectionId) {
if let Some(info) = self.sessions.get(&id) {
- let _ = info.addr.do_send(WSMessage(message.to_owned()));
+ let _ = info.addr.do_send(WsMessage(message.to_owned()));
}
}
) -> impl Future<Output = Result<String, LemmyError>> {
let rate_limiter = self.rate_limiter.clone();
- let ip: IPAddr = match self.sessions.get(&msg.id) {
+ let ip: IpAddr = match self.sessions.get(&msg.id) {
Some(info) => info.ip.to_owned(),
None => "blank_ip".to_string(),
};
async move {
let json: Value = serde_json::from_str(&msg.msg)?;
let data = &json["data"].to_string();
- let op = &json["op"].as_str().ok_or(APIError {
+ let op = &json["op"].as_str().ok_or(ApiError {
message: "Unknown op type".to_string(),
})?;
use crate::UserOperation;
use actix::{prelude::*, Recipient};
use lemmy_structs::{comment::CommentResponse, post::PostResponse};
-use lemmy_utils::{CommunityId, ConnectionId, IPAddr, PostId, UserId};
+use lemmy_utils::{CommunityId, ConnectionId, IpAddr, PostId, UserId};
use serde::{Deserialize, Serialize};
/// Chat server sends this messages to session
#[derive(Message)]
#[rtype(result = "()")]
-pub struct WSMessage(pub String);
+pub struct WsMessage(pub String);
/// Message for chat server communications
#[derive(Message)]
#[rtype(usize)]
pub struct Connect {
- pub addr: Recipient<WSMessage>,
- pub ip: IPAddr,
+ pub addr: Recipient<WsMessage>,
+ pub ip: IpAddr,
}
/// Session is disconnected
#[rtype(result = "()")]
pub struct Disconnect {
pub id: ConnectionId,
- pub ip: IPAddr,
+ pub ip: IpAddr,
}
/// The messages sent to websocket clients
use crate::{
chat_server::ChatServer,
- messages::{Connect, Disconnect, StandardMessage, WSMessage},
+ messages::{Connect, Disconnect, StandardMessage, WsMessage},
LemmyContext,
};
use actix::prelude::*;
context: web::Data<LemmyContext>,
) -> Result<HttpResponse, Error> {
ws::start(
- WSSession {
+ WsSession {
cs_addr: context.chat_server().to_owned(),
id: 0,
hb: Instant::now(),
)
}
-struct WSSession {
+struct WsSession {
cs_addr: Addr<ChatServer>,
/// unique session id
id: usize,
hb: Instant,
}
-impl Actor for WSSession {
+impl Actor for WsSession {
type Context = ws::WebsocketContext<Self>;
/// Method is called on actor start.
/// Handle messages from chat server, we simply send it to peer websocket
/// These are room messages, IE sent to others in the room
-impl Handler<WSMessage> for WSSession {
+impl Handler<WsMessage> for WsSession {
type Result = ();
- fn handle(&mut self, msg: WSMessage, ctx: &mut Self::Context) {
+ fn handle(&mut self, msg: WsMessage, ctx: &mut Self::Context) {
ctx.text(msg.0);
}
}
/// WebSocket message handler
-impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WSSession {
+impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WsSession {
fn handle(&mut self, result: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
let message = match result {
Ok(m) => m,
}
}
-impl WSSession {
+impl WsSession {
/// helper method that sends ping to client every second.
///
/// also this method checks heartbeats from client