From f1035dacc2191385fe1e8695ab5a29e529aca380 Mon Sep 17 00:00:00 2001 From: Felix Date: Thu, 16 Jan 2020 15:39:08 +0100 Subject: [PATCH] working! --- server/src/api/comment.rs | 41 ++++---- server/src/api/community.rs | 97 ++++++------------ server/src/api/mod.rs | 54 +--------- server/src/api/post.rs | 78 ++++++-------- server/src/api/site.rs | 46 +++------ server/src/api/user.rs | 125 ++++++++-------------- server/src/routes/api.rs | 182 ++++++++++++++++++++++++++++----- server/src/websocket/mod.rs | 43 ++++++++ server/src/websocket/server.rs | 168 ++++++++++++++++-------------- 9 files changed, 436 insertions(+), 398 deletions(-) diff --git a/server/src/api/comment.rs b/server/src/api/comment.rs index 61cc95063..d26c2dce2 100644 --- a/server/src/api/comment.rs +++ b/server/src/api/comment.rs @@ -35,7 +35,6 @@ pub struct SaveComment { #[derive(Serialize, Deserialize, Clone)] pub struct CommentResponse { - op: String, pub comment: CommentView, } @@ -53,7 +52,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -63,12 +62,12 @@ impl Perform for Oper { // Check for a community ban let post = Post::read(&conn, data.post_id)?; if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() { - return Err(APIError::err(&self.op, "community_ban").into()); + return Err(APIError::err("community_ban").into()); } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "site_ban").into()); + return Err(APIError::err("site_ban").into()); } let content_slurs_removed = remove_slurs(&data.content.to_owned()); @@ -86,7 +85,7 @@ impl Perform for Oper { let inserted_comment = match Comment::create(&conn, &comment_form) { Ok(comment) => comment, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_create_comment").into()), + Err(_e) => return Err(APIError::err("couldnt_create_comment").into()), }; // Scan the comment for user mentions, add those rows @@ -193,13 +192,12 @@ impl Perform for Oper { let _inserted_like = match CommentLike::like(&conn, &like_form) { Ok(like) => like, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_like_comment").into()), + Err(_e) => return Err(APIError::err("couldnt_like_comment").into()), }; let comment_view = CommentView::read(&conn, inserted_comment.id, Some(user_id))?; Ok(CommentResponse { - op: self.op.to_string(), comment: comment_view, }) } @@ -211,7 +209,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -231,17 +229,17 @@ impl Perform for Oper { editors.append(&mut UserView::admins(&conn)?.into_iter().map(|a| a.id).collect()); if !editors.contains(&user_id) { - return Err(APIError::err(&self.op, "no_comment_edit_allowed").into()); + return Err(APIError::err("no_comment_edit_allowed").into()); } // Check for a community ban if CommunityUserBanView::get(&conn, user_id, orig_comment.community_id).is_ok() { - return Err(APIError::err(&self.op, "community_ban").into()); + return Err(APIError::err("community_ban").into()); } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "site_ban").into()); + return Err(APIError::err("site_ban").into()); } } @@ -264,7 +262,7 @@ impl Perform for Oper { let _updated_comment = match Comment::update(&conn, data.edit_id, &comment_form) { Ok(comment) => comment, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_comment").into()), + Err(_e) => return Err(APIError::err("couldnt_update_comment").into()), }; // Scan the comment for user mentions, add those rows @@ -310,7 +308,6 @@ impl Perform for Oper { let comment_view = CommentView::read(&conn, data.edit_id, Some(user_id))?; Ok(CommentResponse { - op: self.op.to_string(), comment: comment_view, }) } @@ -322,7 +319,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -335,19 +332,18 @@ impl Perform for Oper { if data.save { match CommentSaved::save(&conn, &comment_saved_form) { Ok(comment) => comment, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_save_comment").into()), + Err(_e) => return Err(APIError::err("couldnt_save_comment").into()), }; } else { match CommentSaved::unsave(&conn, &comment_saved_form) { Ok(comment) => comment, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_save_comment").into()), + Err(_e) => return Err(APIError::err("couldnt_save_comment").into()), }; } let comment_view = CommentView::read(&conn, data.comment_id, Some(user_id))?; Ok(CommentResponse { - op: self.op.to_string(), comment: comment_view, }) } @@ -359,7 +355,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -368,19 +364,19 @@ impl Perform for Oper { if data.score == -1 { let site = SiteView::read(&conn)?; if !site.enable_downvotes { - return Err(APIError::err(&self.op, "downvotes_disabled").into()); + return Err(APIError::err("downvotes_disabled").into()); } } // Check for a community ban let post = Post::read(&conn, data.post_id)?; if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() { - return Err(APIError::err(&self.op, "community_ban").into()); + return Err(APIError::err("community_ban").into()); } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "site_ban").into()); + return Err(APIError::err("site_ban").into()); } let like_form = CommentLikeForm { @@ -398,7 +394,7 @@ impl Perform for Oper { if do_add { let _inserted_like = match CommentLike::like(&conn, &like_form) { Ok(like) => like, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_like_comment").into()), + Err(_e) => return Err(APIError::err("couldnt_like_comment").into()), }; } @@ -406,7 +402,6 @@ impl Perform for Oper { let liked_comment = CommentView::read(&conn, data.comment_id, Some(user_id))?; Ok(CommentResponse { - op: self.op.to_string(), comment: liked_comment, }) } diff --git a/server/src/api/community.rs b/server/src/api/community.rs index 0bf846c3d..c765aa9dd 100644 --- a/server/src/api/community.rs +++ b/server/src/api/community.rs @@ -11,7 +11,6 @@ pub struct GetCommunity { #[derive(Serialize, Deserialize)] pub struct GetCommunityResponse { - op: String, community: CommunityView, moderators: Vec, admins: Vec, @@ -29,7 +28,6 @@ pub struct CreateCommunity { #[derive(Serialize, Deserialize, Clone)] pub struct CommunityResponse { - op: String, pub community: CommunityView, } @@ -43,7 +41,6 @@ pub struct ListCommunities { #[derive(Serialize, Deserialize)] pub struct ListCommunitiesResponse { - op: String, communities: Vec, } @@ -59,7 +56,6 @@ pub struct BanFromCommunity { #[derive(Serialize, Deserialize)] pub struct BanFromCommunityResponse { - op: String, user: UserView, banned: bool, } @@ -74,7 +70,6 @@ pub struct AddModToCommunity { #[derive(Serialize, Deserialize)] pub struct AddModToCommunityResponse { - op: String, moderators: Vec, } @@ -107,7 +102,6 @@ pub struct GetFollowedCommunities { #[derive(Serialize, Deserialize)] pub struct GetFollowedCommunitiesResponse { - op: String, communities: Vec, } @@ -141,19 +135,19 @@ impl Perform for Oper { data.name.to_owned().unwrap_or_else(|| "main".to_string()), ) { Ok(community) => community.id, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_community").into()), + Err(_e) => return Err(APIError::err("couldnt_find_community").into()), } } }; let community_view = match CommunityView::read(&conn, community_id, user_id) { Ok(community) => community, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_community").into()), + Err(_e) => return Err(APIError::err("couldnt_find_community").into()), }; let moderators = match CommunityModeratorView::for_community(&conn, community_id) { Ok(moderators) => moderators, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_community").into()), + Err(_e) => return Err(APIError::err("couldnt_find_community").into()), }; let site_creator_id = Site::read(&conn, 1)?.creator_id; @@ -164,7 +158,6 @@ impl Perform for Oper { // Return the jwt Ok(GetCommunityResponse { - op: self.op.to_string(), community: community_view, moderators, admins, @@ -178,21 +171,21 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; if has_slurs(&data.name) || has_slurs(&data.title) || (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap())) { - return Err(APIError::err(&self.op, "no_slurs").into()); + return Err(APIError::err("no_slurs").into()); } let user_id = claims.id; // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "site_ban").into()); + return Err(APIError::err("site_ban").into()); } // When you create a community, make sure the user becomes a moderator and a follower @@ -210,7 +203,7 @@ impl Perform for Oper { let inserted_community = match Community::create(&conn, &community_form) { Ok(community) => community, - Err(_e) => return Err(APIError::err(&self.op, "community_already_exists").into()), + Err(_e) => return Err(APIError::err("community_already_exists").into()), }; let community_moderator_form = CommunityModeratorForm { @@ -221,9 +214,7 @@ impl Perform for Oper { let _inserted_community_moderator = match CommunityModerator::join(&conn, &community_moderator_form) { Ok(user) => user, - Err(_e) => { - return Err(APIError::err(&self.op, "community_moderator_already_exists").into()) - } + Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()), }; let community_follower_form = CommunityFollowerForm { @@ -234,13 +225,12 @@ impl Perform for Oper { let _inserted_community_follower = match CommunityFollower::follow(&conn, &community_follower_form) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "community_follower_already_exists").into()), + Err(_e) => return Err(APIError::err("community_follower_already_exists").into()), }; let community_view = CommunityView::read(&conn, inserted_community.id, Some(user_id))?; Ok(CommunityResponse { - op: self.op.to_string(), community: community_view, }) } @@ -251,19 +241,19 @@ impl Perform for Oper { let data: &EditCommunity = &self.data; if has_slurs(&data.name) || has_slurs(&data.title) { - return Err(APIError::err(&self.op, "no_slurs").into()); + return Err(APIError::err("no_slurs").into()); } let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "site_ban").into()); + return Err(APIError::err("site_ban").into()); } // Verify its a mod @@ -276,7 +266,7 @@ impl Perform for Oper { ); editors.append(&mut UserView::admins(&conn)?.into_iter().map(|a| a.id).collect()); if !editors.contains(&user_id) { - return Err(APIError::err(&self.op, "no_community_edit_allowed").into()); + return Err(APIError::err("no_community_edit_allowed").into()); } let community_form = CommunityForm { @@ -293,7 +283,7 @@ impl Perform for Oper { let _updated_community = match Community::update(&conn, data.edit_id, &community_form) { Ok(community) => community, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_community").into()), + Err(_e) => return Err(APIError::err("couldnt_update_community").into()), }; // Mod tables @@ -315,7 +305,6 @@ impl Perform for Oper { let community_view = CommunityView::read(&conn, data.edit_id, Some(user_id))?; Ok(CommunityResponse { - op: self.op.to_string(), community: community_view, }) } @@ -354,10 +343,7 @@ impl Perform for Oper { .list()?; // Return the jwt - Ok(ListCommunitiesResponse { - op: self.op.to_string(), - communities, - }) + Ok(ListCommunitiesResponse { communities }) } } @@ -367,7 +353,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -380,19 +366,18 @@ impl Perform for Oper { if data.follow { match CommunityFollower::follow(&conn, &community_follower_form) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "community_follower_already_exists").into()), + Err(_e) => return Err(APIError::err("community_follower_already_exists").into()), }; } else { match CommunityFollower::ignore(&conn, &community_follower_form) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "community_follower_already_exists").into()), + Err(_e) => return Err(APIError::err("community_follower_already_exists").into()), }; } let community_view = CommunityView::read(&conn, data.community_id, Some(user_id))?; Ok(CommunityResponse { - op: self.op.to_string(), community: community_view, }) } @@ -404,7 +389,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -412,14 +397,11 @@ impl Perform for Oper { let communities: Vec = match CommunityFollowerView::for_user(&conn, user_id) { Ok(communities) => communities, - Err(_e) => return Err(APIError::err(&self.op, "system_err_login").into()), + Err(_e) => return Err(APIError::err("system_err_login").into()), }; // Return the jwt - Ok(GetFollowedCommunitiesResponse { - op: self.op.to_string(), - communities, - }) + Ok(GetFollowedCommunitiesResponse { communities }) } } @@ -429,7 +411,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -442,12 +424,12 @@ impl Perform for Oper { if data.ban { match CommunityUserBan::ban(&conn, &community_user_ban_form) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "community_user_already_banned").into()), + Err(_e) => return Err(APIError::err("community_user_already_banned").into()), }; } else { match CommunityUserBan::unban(&conn, &community_user_ban_form) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "community_user_already_banned").into()), + Err(_e) => return Err(APIError::err("community_user_already_banned").into()), }; } @@ -470,7 +452,6 @@ impl Perform for Oper { let user_view = UserView::read(&conn, data.user_id)?; Ok(BanFromCommunityResponse { - op: self.op.to_string(), user: user_view, banned: data.ban, }) @@ -483,7 +464,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -496,16 +477,12 @@ impl Perform for Oper { if data.added { match CommunityModerator::join(&conn, &community_moderator_form) { Ok(user) => user, - Err(_e) => { - return Err(APIError::err(&self.op, "community_moderator_already_exists").into()) - } + Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()), }; } else { match CommunityModerator::leave(&conn, &community_moderator_form) { Ok(user) => user, - Err(_e) => { - return Err(APIError::err(&self.op, "community_moderator_already_exists").into()) - } + Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()), }; } @@ -520,10 +497,7 @@ impl Perform for Oper { let moderators = CommunityModeratorView::for_community(&conn, data.community_id)?; - Ok(AddModToCommunityResponse { - op: self.op.to_string(), - moderators, - }) + Ok(AddModToCommunityResponse { moderators }) } } @@ -533,7 +507,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -548,7 +522,7 @@ impl Perform for Oper { // Make sure user is the creator, or an admin if user_id != read_community.creator_id && !admins.iter().map(|a| a.id).any(|x| x == user_id) { - return Err(APIError::err(&self.op, "not_an_admin").into()); + return Err(APIError::err("not_an_admin").into()); } let community_form = CommunityForm { @@ -565,7 +539,7 @@ impl Perform for Oper { let _updated_community = match Community::update(&conn, data.community_id, &community_form) { Ok(community) => community, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_community").into()), + Err(_e) => return Err(APIError::err("couldnt_update_community").into()), }; // You also have to re-do the community_moderator table, reordering it. @@ -588,9 +562,7 @@ impl Perform for Oper { let _inserted_community_moderator = match CommunityModerator::join(&conn, &community_moderator_form) { Ok(user) => user, - Err(_e) => { - return Err(APIError::err(&self.op, "community_moderator_already_exists").into()) - } + Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()), }; } @@ -605,17 +577,16 @@ impl Perform for Oper { let community_view = match CommunityView::read(&conn, data.community_id, Some(user_id)) { Ok(community) => community, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_community").into()), + Err(_e) => return Err(APIError::err("couldnt_find_community").into()), }; let moderators = match CommunityModeratorView::for_community(&conn, data.community_id) { Ok(moderators) => moderators, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_community").into()), + Err(_e) => return Err(APIError::err("couldnt_find_community").into()), }; // Return the jwt Ok(GetCommunityResponse { - op: self.op.to_string(), community: community_view, moderators, admins, diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs index e35804476..bee7b8fec 100644 --- a/server/src/api/mod.rs +++ b/server/src/api/mod.rs @@ -26,73 +26,27 @@ pub mod post; pub mod site; pub mod user; -#[derive(EnumString, ToString, Debug)] -pub enum UserOperation { - Login, - Register, - CreateCommunity, - CreatePost, - ListCommunities, - ListCategories, - GetPost, - GetCommunity, - CreateComment, - EditComment, - SaveComment, - CreateCommentLike, - GetPosts, - CreatePostLike, - EditPost, - SavePost, - EditCommunity, - FollowCommunity, - GetFollowedCommunities, - GetUserDetails, - GetReplies, - GetUserMentions, - EditUserMention, - GetModlog, - BanFromCommunity, - AddModToCommunity, - CreateSite, - EditSite, - GetSite, - AddAdmin, - BanUser, - Search, - MarkAllAsRead, - SaveUserSettings, - TransferCommunity, - TransferSite, - DeleteAccount, - PasswordReset, - PasswordChange, -} - #[derive(Fail, Debug)] -#[fail(display = "{{\"op\":\"{}\", \"error\":\"{}\"}}", op, message)] +#[fail(display = "{{\"error\":\"{}\"}}", message)] pub struct APIError { - pub op: String, pub message: String, } impl APIError { - pub fn err(op: &UserOperation, msg: &str) -> Self { + pub fn err(msg: &str) -> Self { APIError { - op: op.to_string(), message: msg.to_string(), } } } pub struct Oper { - op: UserOperation, data: T, } impl Oper { - pub fn new(op: UserOperation, data: T) -> Oper { - Oper { op, data } + pub fn new(data: T) -> Oper { + Oper { data } } } diff --git a/server/src/api/post.rs b/server/src/api/post.rs index b0fcdd0c1..3f211453c 100644 --- a/server/src/api/post.rs +++ b/server/src/api/post.rs @@ -14,7 +14,6 @@ pub struct CreatePost { #[derive(Serialize, Deserialize, Clone)] pub struct PostResponse { - op: String, pub post: PostView, } @@ -26,7 +25,6 @@ pub struct GetPost { #[derive(Serialize, Deserialize)] pub struct GetPostResponse { - op: String, post: PostView, comments: Vec, community: CommunityView, @@ -46,7 +44,6 @@ pub struct GetPosts { #[derive(Serialize, Deserialize)] pub struct GetPostsResponse { - op: String, posts: Vec, } @@ -59,7 +56,6 @@ pub struct CreatePostLike { #[derive(Serialize, Deserialize)] pub struct CreatePostLikeResponse { - op: String, post: PostView, } @@ -93,23 +89,23 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; if has_slurs(&data.name) || (data.body.is_some() && has_slurs(&data.body.to_owned().unwrap())) { - return Err(APIError::err(&self.op, "no_slurs").into()); + return Err(APIError::err("no_slurs").into()); } let user_id = claims.id; // Check for a community ban if CommunityUserBanView::get(&conn, user_id, data.community_id).is_ok() { - return Err(APIError::err(&self.op, "community_ban").into()); + return Err(APIError::err("community_ban").into()); } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "site_ban").into()); + return Err(APIError::err("site_ban").into()); } let post_form = PostForm { @@ -128,7 +124,7 @@ impl Perform for Oper { let inserted_post = match Post::create(&conn, &post_form) { Ok(post) => post, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_create_post").into()), + Err(_e) => return Err(APIError::err("couldnt_create_post").into()), }; // They like their own post by default @@ -141,19 +137,16 @@ impl Perform for Oper { // Only add the like if the score isnt 0 let _inserted_like = match PostLike::like(&conn, &like_form) { Ok(like) => like, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_like_post").into()), + Err(_e) => return Err(APIError::err("couldnt_like_post").into()), }; // Refetch the view let post_view = match PostView::read(&conn, inserted_post.id, Some(user_id)) { Ok(post) => post, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_post").into()), + Err(_e) => return Err(APIError::err("couldnt_find_post").into()), }; - Ok(PostResponse { - op: self.op.to_string(), - post: post_view, - }) + Ok(PostResponse { post: post_view }) } } @@ -174,7 +167,7 @@ impl Perform for Oper { let post_view = match PostView::read(&conn, data.id, user_id) { Ok(post) => post, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_post").into()), + Err(_e) => return Err(APIError::err("couldnt_find_post").into()), }; let comments = CommentQueryBuilder::create(&conn) @@ -195,7 +188,6 @@ impl Perform for Oper { // Return the jwt Ok(GetPostResponse { - op: self.op.to_string(), post: post_view, comments, community, @@ -241,13 +233,10 @@ impl Perform for Oper { .list() { Ok(posts) => posts, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_get_posts").into()), + Err(_e) => return Err(APIError::err("couldnt_get_posts").into()), }; - Ok(GetPostsResponse { - op: self.op.to_string(), - posts, - }) + Ok(GetPostsResponse { posts }) } } @@ -257,7 +246,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -266,19 +255,19 @@ impl Perform for Oper { if data.score == -1 { let site = SiteView::read(&conn)?; if !site.enable_downvotes { - return Err(APIError::err(&self.op, "downvotes_disabled").into()); + return Err(APIError::err("downvotes_disabled").into()); } } // Check for a community ban let post = Post::read(&conn, data.post_id)?; if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() { - return Err(APIError::err(&self.op, "community_ban").into()); + return Err(APIError::err("community_ban").into()); } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "site_ban").into()); + return Err(APIError::err("site_ban").into()); } let like_form = PostLikeForm { @@ -295,20 +284,17 @@ impl Perform for Oper { if do_add { let _inserted_like = match PostLike::like(&conn, &like_form) { Ok(like) => like, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_like_post").into()), + Err(_e) => return Err(APIError::err("couldnt_like_post").into()), }; } let post_view = match PostView::read(&conn, data.post_id, Some(user_id)) { Ok(post) => post, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_post").into()), + Err(_e) => return Err(APIError::err("couldnt_find_post").into()), }; // just output the score - Ok(CreatePostLikeResponse { - op: self.op.to_string(), - post: post_view, - }) + Ok(CreatePostLikeResponse { post: post_view }) } } @@ -316,12 +302,12 @@ impl Perform for Oper { fn perform(&self, conn: &PgConnection) -> Result { let data: &EditPost = &self.data; if has_slurs(&data.name) || (data.body.is_some() && has_slurs(&data.body.to_owned().unwrap())) { - return Err(APIError::err(&self.op, "no_slurs").into()); + return Err(APIError::err("no_slurs").into()); } let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -336,17 +322,17 @@ impl Perform for Oper { ); editors.append(&mut UserView::admins(&conn)?.into_iter().map(|a| a.id).collect()); if !editors.contains(&user_id) { - return Err(APIError::err(&self.op, "no_post_edit_allowed").into()); + return Err(APIError::err("no_post_edit_allowed").into()); } // Check for a community ban if CommunityUserBanView::get(&conn, user_id, data.community_id).is_ok() { - return Err(APIError::err(&self.op, "community_ban").into()); + return Err(APIError::err("community_ban").into()); } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "site_ban").into()); + return Err(APIError::err("site_ban").into()); } let post_form = PostForm { @@ -365,7 +351,7 @@ impl Perform for Oper { let _updated_post = match Post::update(&conn, data.edit_id, &post_form) { Ok(post) => post, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_post").into()), + Err(_e) => return Err(APIError::err("couldnt_update_post").into()), }; // Mod tables @@ -399,10 +385,7 @@ impl Perform for Oper { let post_view = PostView::read(&conn, data.edit_id, Some(user_id))?; - Ok(PostResponse { - op: self.op.to_string(), - post: post_view, - }) + Ok(PostResponse { post: post_view }) } } @@ -412,7 +395,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -425,20 +408,17 @@ impl Perform for Oper { if data.save { match PostSaved::save(&conn, &post_saved_form) { Ok(post) => post, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_save_post").into()), + Err(_e) => return Err(APIError::err("couldnt_save_post").into()), }; } else { match PostSaved::unsave(&conn, &post_saved_form) { Ok(post) => post, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_save_post").into()), + Err(_e) => return Err(APIError::err("couldnt_save_post").into()), }; } let post_view = PostView::read(&conn, data.post_id, Some(user_id))?; - Ok(PostResponse { - op: self.op.to_string(), - post: post_view, - }) + Ok(PostResponse { post: post_view }) } } diff --git a/server/src/api/site.rs b/server/src/api/site.rs index a189a0308..1291891b4 100644 --- a/server/src/api/site.rs +++ b/server/src/api/site.rs @@ -7,7 +7,6 @@ pub struct ListCategories; #[derive(Serialize, Deserialize)] pub struct ListCategoriesResponse { - op: String, categories: Vec, } @@ -23,7 +22,6 @@ pub struct Search { #[derive(Serialize, Deserialize)] pub struct SearchResponse { - op: String, type_: String, comments: Vec, posts: Vec, @@ -41,7 +39,6 @@ pub struct GetModlog { #[derive(Serialize, Deserialize)] pub struct GetModlogResponse { - op: String, removed_posts: Vec, locked_posts: Vec, stickied_posts: Vec, @@ -78,13 +75,11 @@ pub struct GetSite; #[derive(Serialize, Deserialize)] pub struct SiteResponse { - op: String, site: SiteView, } #[derive(Serialize, Deserialize)] pub struct GetSiteResponse { - op: String, site: Option, admins: Vec, banned: Vec, @@ -104,10 +99,7 @@ impl Perform for Oper { let categories: Vec = Category::list_all(&conn)?; // Return the jwt - Ok(ListCategoriesResponse { - op: self.op.to_string(), - categories, - }) + Ok(ListCategoriesResponse { categories }) } } @@ -171,7 +163,6 @@ impl Perform for Oper { // Return the jwt Ok(GetModlogResponse { - op: self.op.to_string(), removed_posts, locked_posts, stickied_posts, @@ -191,20 +182,20 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; if has_slurs(&data.name) || (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap())) { - return Err(APIError::err(&self.op, "no_slurs").into()); + return Err(APIError::err("no_slurs").into()); } let user_id = claims.id; // Make sure user is an admin if !UserView::read(&conn, user_id)?.admin { - return Err(APIError::err(&self.op, "not_an_admin").into()); + return Err(APIError::err("not_an_admin").into()); } let site_form = SiteForm { @@ -219,15 +210,12 @@ impl Perform for Oper { match Site::create(&conn, &site_form) { Ok(site) => site, - Err(_e) => return Err(APIError::err(&self.op, "site_already_exists").into()), + Err(_e) => return Err(APIError::err("site_already_exists").into()), }; let site_view = SiteView::read(&conn)?; - Ok(SiteResponse { - op: self.op.to_string(), - site: site_view, - }) + Ok(SiteResponse { site: site_view }) } } @@ -237,20 +225,20 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; if has_slurs(&data.name) || (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap())) { - return Err(APIError::err(&self.op, "no_slurs").into()); + return Err(APIError::err("no_slurs").into()); } let user_id = claims.id; // Make sure user is an admin if !UserView::read(&conn, user_id)?.admin { - return Err(APIError::err(&self.op, "not_an_admin").into()); + return Err(APIError::err("not_an_admin").into()); } let found_site = Site::read(&conn, 1)?; @@ -267,15 +255,12 @@ impl Perform for Oper { match Site::update(&conn, 1, &site_form) { Ok(site) => site, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_site").into()), + Err(_e) => return Err(APIError::err("couldnt_update_site").into()), }; let site_view = SiteView::read(&conn)?; - Ok(SiteResponse { - op: self.op.to_string(), - site: site_view, - }) + Ok(SiteResponse { site: site_view }) } } @@ -300,7 +285,6 @@ impl Perform for Oper { let banned = UserView::banned(&conn)?; Ok(GetSiteResponse { - op: self.op.to_string(), site: site_view, admins, banned, @@ -403,7 +387,6 @@ impl Perform for Oper { // Return the jwt Ok(SearchResponse { - op: self.op.to_string(), type_: data.type_.to_owned(), comments, posts, @@ -419,7 +402,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -428,7 +411,7 @@ impl Perform for Oper { // Make sure user is the creator if read_site.creator_id != user_id { - return Err(APIError::err(&self.op, "not_an_admin").into()); + return Err(APIError::err("not_an_admin").into()); } let site_form = SiteForm { @@ -443,7 +426,7 @@ impl Perform for Oper { match Site::update(&conn, 1, &site_form) { Ok(site) => site, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_site").into()), + Err(_e) => return Err(APIError::err("couldnt_update_site").into()), }; // Mod tables @@ -468,7 +451,6 @@ impl Perform for Oper { let banned = UserView::banned(&conn)?; Ok(GetSiteResponse { - op: self.op.to_string(), site: Some(site_view), admins, banned, diff --git a/server/src/api/user.rs b/server/src/api/user.rs index ac700acad..e1ddb1cae 100644 --- a/server/src/api/user.rs +++ b/server/src/api/user.rs @@ -40,7 +40,6 @@ pub struct SaveUserSettings { #[derive(Serialize, Deserialize)] pub struct LoginResponse { - op: String, jwt: String, } @@ -58,7 +57,6 @@ pub struct GetUserDetails { #[derive(Serialize, Deserialize)] pub struct GetUserDetailsResponse { - op: String, user: UserView, follows: Vec, moderates: Vec, @@ -69,13 +67,11 @@ pub struct GetUserDetailsResponse { #[derive(Serialize, Deserialize)] pub struct GetRepliesResponse { - op: String, replies: Vec, } #[derive(Serialize, Deserialize)] pub struct GetUserMentionsResponse { - op: String, mentions: Vec, } @@ -93,7 +89,6 @@ pub struct AddAdmin { #[derive(Serialize, Deserialize)] pub struct AddAdminResponse { - op: String, admins: Vec, } @@ -108,7 +103,6 @@ pub struct BanUser { #[derive(Serialize, Deserialize)] pub struct BanUserResponse { - op: String, user: UserView, banned: bool, } @@ -140,7 +134,6 @@ pub struct EditUserMention { #[derive(Serialize, Deserialize, Clone)] pub struct UserMentionResponse { - op: String, mention: UserMentionView, } @@ -156,9 +149,7 @@ pub struct PasswordReset { } #[derive(Serialize, Deserialize, Clone)] -pub struct PasswordResetResponse { - op: String, -} +pub struct PasswordResetResponse {} #[derive(Serialize, Deserialize)] pub struct PasswordChange { @@ -174,20 +165,17 @@ impl Perform for Oper { // Fetch that username / email let user: User_ = match User_::find_by_email_or_username(&conn, &data.username_or_email) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "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(&self.op, "password_incorrect").into()); + return Err(APIError::err("password_incorrect").into()); } // Return the jwt - Ok(LoginResponse { - op: self.op.to_string(), - jwt: user.jwt(), - }) + Ok(LoginResponse { jwt: user.jwt() }) } } @@ -198,22 +186,22 @@ impl Perform for Oper { // Make sure site has open registration if let Ok(site) = SiteView::read(&conn) { if !site.open_registration { - return Err(APIError::err(&self.op, "registration_closed").into()); + return Err(APIError::err("registration_closed").into()); } } // Make sure passwords match if data.password != data.password_verify { - return Err(APIError::err(&self.op, "passwords_dont_match").into()); + return Err(APIError::err("passwords_dont_match").into()); } if has_slurs(&data.username) { - return Err(APIError::err(&self.op, "no_slurs").into()); + return Err(APIError::err("no_slurs").into()); } // Make sure there are no admins if data.admin && !UserView::admins(&conn)?.is_empty() { - return Err(APIError::err(&self.op, "admin_already_created").into()); + return Err(APIError::err("admin_already_created").into()); } // Register the new user @@ -248,7 +236,7 @@ impl Perform for Oper { "user_already_exists" }; - return Err(APIError::err(&self.op, err_type).into()); + return Err(APIError::err(err_type).into()); } }; @@ -280,7 +268,7 @@ impl Perform for Oper { let _inserted_community_follower = match CommunityFollower::follow(&conn, &community_follower_form) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "community_follower_already_exists").into()), + Err(_e) => return Err(APIError::err("community_follower_already_exists").into()), }; // If its an admin, add them as a mod and follower to main @@ -293,15 +281,12 @@ impl Perform for Oper { let _inserted_community_moderator = match CommunityModerator::join(&conn, &community_moderator_form) { Ok(user) => user, - Err(_e) => { - return Err(APIError::err(&self.op, "community_moderator_already_exists").into()) - } + Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()), }; } // Return the jwt Ok(LoginResponse { - op: self.op.to_string(), jwt: inserted_user.jwt(), }) } @@ -313,7 +298,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -331,7 +316,7 @@ impl Perform for Oper { Some(new_password_verify) => { // Make sure passwords match if new_password != new_password_verify { - return Err(APIError::err(&self.op, "passwords_dont_match").into()); + return Err(APIError::err("passwords_dont_match").into()); } // Check the old password @@ -340,14 +325,14 @@ impl Perform for Oper { let valid: bool = verify(old_password, &read_user.password_encrypted).unwrap_or(false); if !valid { - return Err(APIError::err(&self.op, "password_incorrect").into()); + return Err(APIError::err("password_incorrect").into()); } User_::update_password(&conn, user_id, &new_password)?.password_encrypted } - None => return Err(APIError::err(&self.op, "password_incorrect").into()), + None => return Err(APIError::err("password_incorrect").into()), } } - None => return Err(APIError::err(&self.op, "passwords_dont_match").into()), + None => return Err(APIError::err("passwords_dont_match").into()), } } None => read_user.password_encrypted, @@ -383,13 +368,12 @@ impl Perform for Oper { "user_already_exists" }; - return Err(APIError::err(&self.op, err_type).into()); + return Err(APIError::err(err_type).into()); } }; // Return the jwt Ok(LoginResponse { - op: self.op.to_string(), jwt: updated_user.jwt(), }) } @@ -430,9 +414,7 @@ impl Perform for Oper { .unwrap_or_else(|| "admin".to_string()), ) { Ok(user) => user.id, - Err(_e) => { - return Err(APIError::err(&self.op, "couldnt_find_that_username_or_email").into()) - } + Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()), } } }; @@ -475,7 +457,6 @@ impl Perform for Oper { // Return the jwt Ok(GetUserDetailsResponse { - op: self.op.to_string(), user: user_view, follows, moderates, @@ -492,14 +473,14 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; // Make sure user is an admin if !UserView::read(&conn, user_id)?.admin { - return Err(APIError::err(&self.op, "not_an_admin").into()); + return Err(APIError::err("not_an_admin").into()); } let read_user = User_::read(&conn, data.user_id)?; @@ -525,7 +506,7 @@ impl Perform for Oper { match User_::update(&conn, data.user_id, &user_form) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_user").into()), + Err(_e) => return Err(APIError::err("couldnt_update_user").into()), }; // Mod tables @@ -543,10 +524,7 @@ impl Perform for Oper { let creator_user = admins.remove(creator_index); admins.insert(0, creator_user); - Ok(AddAdminResponse { - op: self.op.to_string(), - admins, - }) + Ok(AddAdminResponse { admins }) } } @@ -556,14 +534,14 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; // Make sure user is an admin if !UserView::read(&conn, user_id)?.admin { - return Err(APIError::err(&self.op, "not_an_admin").into()); + return Err(APIError::err("not_an_admin").into()); } let read_user = User_::read(&conn, data.user_id)?; @@ -589,7 +567,7 @@ impl Perform for Oper { match User_::update(&conn, data.user_id, &user_form) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_user").into()), + Err(_e) => return Err(APIError::err("couldnt_update_user").into()), }; // Mod tables @@ -611,7 +589,6 @@ impl Perform for Oper { let user_view = UserView::read(&conn, data.user_id)?; Ok(BanUserResponse { - op: self.op.to_string(), user: user_view, banned: data.ban, }) @@ -624,7 +601,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -638,10 +615,7 @@ impl Perform for Oper { .limit(data.limit) .list()?; - Ok(GetRepliesResponse { - op: self.op.to_string(), - replies, - }) + Ok(GetRepliesResponse { replies }) } } @@ -651,7 +625,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -665,10 +639,7 @@ impl Perform for Oper { .limit(data.limit) .list()?; - Ok(GetUserMentionsResponse { - op: self.op.to_string(), - mentions, - }) + Ok(GetUserMentionsResponse { mentions }) } } @@ -678,7 +649,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -694,13 +665,12 @@ impl Perform for Oper { let _updated_user_mention = match UserMention::update(&conn, user_mention.id, &user_mention_form) { Ok(comment) => comment, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_comment").into()), + Err(_e) => return Err(APIError::err("couldnt_update_comment").into()), }; let user_mention_view = UserMentionView::read(&conn, user_mention.id, user_id)?; Ok(UserMentionResponse { - op: self.op.to_string(), mention: user_mention_view, }) } @@ -712,7 +682,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -737,7 +707,7 @@ impl Perform for Oper { let _updated_comment = match Comment::update(&conn, reply.id, &comment_form) { Ok(comment) => comment, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_comment").into()), + Err(_e) => return Err(APIError::err("couldnt_update_comment").into()), }; } @@ -758,14 +728,11 @@ impl Perform for Oper { let _updated_mention = match UserMention::update(&conn, mention.user_mention_id, &mention_form) { Ok(mention) => mention, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_comment").into()), + Err(_e) => return Err(APIError::err("couldnt_update_comment").into()), }; } - Ok(GetRepliesResponse { - op: self.op.to_string(), - replies: vec![], - }) + Ok(GetRepliesResponse { replies: vec![] }) } } @@ -775,7 +742,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, - Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()), + Err(_e) => return Err(APIError::err("not_logged_in").into()), }; let user_id = claims.id; @@ -785,7 +752,7 @@ impl Perform for Oper { // Verify the password let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false); if !valid { - return Err(APIError::err(&self.op, "password_incorrect").into()); + return Err(APIError::err("password_incorrect").into()); } // Comments @@ -808,7 +775,7 @@ impl Perform for Oper { let _updated_comment = match Comment::update(&conn, comment.id, &comment_form) { Ok(comment) => comment, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_comment").into()), + Err(_e) => return Err(APIError::err("couldnt_update_comment").into()), }; } @@ -836,12 +803,11 @@ impl Perform for Oper { let _updated_post = match Post::update(&conn, post.id, &post_form) { Ok(post) => post, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_post").into()), + Err(_e) => return Err(APIError::err("couldnt_update_post").into()), }; } Ok(LoginResponse { - op: self.op.to_string(), jwt: data.auth.to_owned(), }) } @@ -854,7 +820,7 @@ impl Perform for Oper { // Fetch that email let user: User_ = match User_::find_by_email(&conn, &data.email) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_that_username_or_email").into()), + Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()), }; // Generate a random token @@ -871,12 +837,10 @@ impl Perform for Oper { let html = &format!("

Password Reset Request for {}


Click here to reset your password", user.name, hostname, &token); match send_email(subject, user_email, &user.name, html) { Ok(_o) => _o, - Err(_e) => return Err(APIError::err(&self.op, &_e).into()), + Err(_e) => return Err(APIError::err(&_e).into()), }; - Ok(PasswordResetResponse { - op: self.op.to_string(), - }) + Ok(PasswordResetResponse {}) } } @@ -889,18 +853,17 @@ impl Perform for Oper { // Make sure passwords match if data.password != data.password_verify { - return Err(APIError::err(&self.op, "passwords_dont_match").into()); + return Err(APIError::err("passwords_dont_match").into()); } // Update the user with the new password let updated_user = match User_::update_password(&conn, user_id, &data.password) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_user").into()), + Err(_e) => return Err(APIError::err("couldnt_update_user").into()), }; // Return the jwt Ok(LoginResponse { - op: self.op.to_string(), jwt: updated_user.jwt(), }) } diff --git a/server/src/routes/api.rs b/server/src/routes/api.rs index 11919b8cc..70e686883 100644 --- a/server/src/routes/api.rs +++ b/server/src/routes/api.rs @@ -1,7 +1,8 @@ -use crate::api::community::{ - GetCommunity, GetCommunityResponse, ListCommunities, ListCommunitiesResponse, -}; -use crate::api::UserOperation; +use crate::api::comment::*; +use crate::api::community::*; +use crate::api::post::*; +use crate::api::site::*; +use crate::api::user::*; use crate::api::{Oper, Perform}; use actix_web::{web, HttpResponse}; use diesel::r2d2::{ConnectionManager, Pool}; @@ -13,26 +14,165 @@ type DbParam = web::Data>>; pub fn config(cfg: &mut web::ServiceConfig) { cfg - // TODO: need to repeat this for every endpoint + .route( + "/api/v1/login", + web::post().to(route::), + ) + .route( + "/api/v1/register", + web::post().to(route::), + ) + .route( + "/api/v1/create_community", + web::post().to(route::), + ) + .route( + "/api/v1/create_post", + web::post().to(route::), + ) .route( "/api/v1/list_communities", - web::get().to( - route::(UserOperation::ListCommunities) - ), + web::get().to(route::), + ) + .route( + "/api/v1/list_categories", + web::get().to(route::), + ) + .route( + "/api/v1/get_post", + web::get().to(route::), ) .route( "/api/v1/get_community", - web::get().to(route::( - UserOperation::GetCommunity, - )), + web::get().to(route::), + ) + .route( + "/api/v1/create_communent", + web::post().to(route::), + ) + .route( + "/api/v1/edit_comment", + web::post().to(route::), + ) + .route( + "/api/v1/save_comment", + web::post().to(route::), + ) + .route( + "/api/v1/create_comment_like", + web::post().to(route::), + ) + .route( + "/api/v1/get_posts", + web::get().to(route::), + ) + .route( + "/api/v1/create_post_like", + web::post().to(route::), + ) + .route( + "/api/v1/edit_post", + web::post().to(route::), + ) + .route( + "/api/v1/save_post", + web::post().to(route::), + ) + .route( + "/api/v1/edit_community", + web::post().to(route::), + ) + .route( + "/api/v1/follow_community", + web::post().to(route::), + ) + .route( + "/api/v1/get_followed_communities", + web::get().to(route::), + ) + .route( + "/api/v1/get_user_details", + web::get().to(route::), + ) + .route( + "/api/v1/get_replies", + web::get().to(route::), + ) + .route( + "/api/v1/get_user_mentions", + web::get().to(route::), + ) + .route( + "/api/v1/edit_user_mention", + web::post().to(route::), + ) + .route( + "/api/v1/get_modlog", + web::get().to(route::), + ) + .route( + "/api/v1/ban_from_community", + web::post().to(route::), + ) + .route( + "/api/v1/add_mod_to_community", + web::post().to(route::), + ) + .route( + "/api/v1/create_site", + web::post().to(route::), + ) + .route( + "/api/v1/edit_site", + web::post().to(route::), + ) + .route( + "/api/v1/get_site", + web::get().to(route::), + ) + .route( + "/api/v1/add_admin", + web::post().to(route::), + ) + .route( + "/api/v1/ban_user", + web::post().to(route::), + ) + .route( + "/api/v1/search", + web::post().to(route::), + ) + .route( + "/api/v1/mark_all_as_read", + web::post().to(route::), + ) + .route( + "/api/v1/save_user_settings", + web::post().to(route::), + ) + .route( + "/api/v1/transfer_community", + web::post().to(route::), + ) + .route( + "/api/v1/transfer_site", + web::post().to(route::), + ) + .route( + "/api/v1/delete_account", + web::post().to(route::), + ) + .route( + "/api/v1/password_reset", + web::post().to(route::), + ) + .route( + "/api/v1/password_change", + web::post().to(route::), ); } -fn perform( - op: UserOperation, - data: Request, - db: DbParam, -) -> Result +fn perform(data: Request, db: DbParam) -> Result where Response: Serialize, Oper: Perform, @@ -41,20 +181,16 @@ where Ok(c) => c, Err(e) => return Err(format_err!("{}", e)), }; - let oper: Oper = Oper::new(op, data); + let oper: Oper = Oper::new(data); let response = oper.perform(&conn); Ok(HttpResponse::Ok().json(response?)) } -fn route( - op: UserOperation, -) -> Box<(dyn Fn(web::Query, DbParam) -> Result + 'static)> +async fn route(data: web::Query, db: DbParam) -> Result where Data: Serialize, Response: Serialize, Oper: Perform, { - // TODO: want an implementation like this, where useroperation is passed without explicitly passing the other params - // maybe with a higher order functions? (but that would probably have worse performance) - Box::new(|data, db| perform::(op, data.0, db)) + perform::(data.0, db) } diff --git a/server/src/websocket/mod.rs b/server/src/websocket/mod.rs index 74f47ad34..1be3a8e0e 100644 --- a/server/src/websocket/mod.rs +++ b/server/src/websocket/mod.rs @@ -1 +1,44 @@ pub mod server; + +#[derive(EnumString, ToString, Debug)] +pub enum UserOperation { + Login, + Register, + CreateCommunity, + CreatePost, + ListCommunities, + ListCategories, + GetPost, + GetCommunity, + CreateComment, + EditComment, + SaveComment, + CreateCommentLike, + GetPosts, + CreatePostLike, + EditPost, + SavePost, + EditCommunity, + FollowCommunity, + GetFollowedCommunities, + GetUserDetails, + GetReplies, + GetUserMentions, + EditUserMention, + GetModlog, + BanFromCommunity, + AddModToCommunity, + CreateSite, + EditSite, + GetSite, + AddAdmin, + BanUser, + Search, + MarkAllAsRead, + SaveUserSettings, + TransferCommunity, + TransferSite, + DeleteAccount, + PasswordReset, + PasswordChange, +} diff --git a/server/src/websocket/server.rs b/server/src/websocket/server.rs index 957c5f643..0386ba4e1 100644 --- a/server/src/websocket/server.rs +++ b/server/src/websocket/server.rs @@ -19,6 +19,7 @@ use crate::api::post::*; use crate::api::site::*; use crate::api::user::*; use crate::api::*; +use crate::websocket::UserOperation; use crate::Settings; /// Chat server sends this messages to session @@ -201,7 +202,6 @@ impl ChatServer { ); Err( APIError { - op: "Rate Limit".to_string(), message: format!("Too many requests. {} per {} seconds", rate, per), } .into(), @@ -295,11 +295,25 @@ impl Handler for ChatServer { } } +fn to_json_string(op: UserOperation, data: T) -> Result +where + T: Serialize, +{ + dbg!(&op); + let mut json = serde_json::to_value(&data)?; + match json.as_object_mut() { + Some(j) => j.insert("op".to_string(), serde_json::to_value(op.to_string())?), + None => return Err(format_err!("")), + }; + // TODO: it seems like this is never called? + let x = serde_json::to_string(&json)?; + Ok(x) +} + fn parse_json_message(chat: &mut ChatServer, msg: StandardMessage) -> Result { let json: Value = serde_json::from_str(&msg.msg)?; let data = &json["data"].to_string(); let op = &json["op"].as_str().ok_or(APIError { - op: "Unknown op type".to_string(), message: "Unknown op type".to_string(), })?; @@ -310,12 +324,12 @@ fn parse_json_message(chat: &mut ChatServer, msg: StandardMessage) -> Result { let login: Login = serde_json::from_str(data)?; - let res = Oper::new(user_operation, login).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(login).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::Register => { let register: Register = serde_json::from_str(data)?; - let res = Oper::new(user_operation, register).perform(&conn); + let res = Oper::new(register).perform(&conn); if res.is_ok() { chat.check_rate_limit_register(msg.id)?; } @@ -323,84 +337,84 @@ fn parse_json_message(chat: &mut ChatServer, msg: StandardMessage) -> Result { let get_user_details: GetUserDetails = serde_json::from_str(data)?; - let res = Oper::new(user_operation, get_user_details).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(get_user_details).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::SaveUserSettings => { let save_user_settings: SaveUserSettings = serde_json::from_str(data)?; - let res = Oper::new(user_operation, save_user_settings).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(save_user_settings).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::AddAdmin => { let add_admin: AddAdmin = serde_json::from_str(data)?; - let res = Oper::new(user_operation, add_admin).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(add_admin).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::BanUser => { let ban_user: BanUser = serde_json::from_str(data)?; - let res = Oper::new(user_operation, ban_user).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(ban_user).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::GetReplies => { let get_replies: GetReplies = serde_json::from_str(data)?; - let res = Oper::new(user_operation, get_replies).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(get_replies).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::GetUserMentions => { let get_user_mentions: GetUserMentions = serde_json::from_str(data)?; - let res = Oper::new(user_operation, get_user_mentions).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(get_user_mentions).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::EditUserMention => { let edit_user_mention: EditUserMention = serde_json::from_str(data)?; - let res = Oper::new(user_operation, edit_user_mention).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(edit_user_mention).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::MarkAllAsRead => { let mark_all_as_read: MarkAllAsRead = serde_json::from_str(data)?; - let res = Oper::new(user_operation, mark_all_as_read).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(mark_all_as_read).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::GetCommunity => { let get_community: GetCommunity = serde_json::from_str(data)?; - let res = Oper::new(user_operation, get_community).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(get_community).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::ListCommunities => { let list_communities: ListCommunities = serde_json::from_str(data)?; - let res = Oper::new(user_operation, list_communities).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(list_communities).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::CreateCommunity => { chat.check_rate_limit_register(msg.id)?; let create_community: CreateCommunity = serde_json::from_str(data)?; - let res = Oper::new(user_operation, create_community).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(create_community).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::EditCommunity => { let edit_community: EditCommunity = serde_json::from_str(data)?; - let res = Oper::new(user_operation, edit_community).perform(&conn)?; + let res = Oper::new(edit_community).perform(&conn)?; let mut community_sent: CommunityResponse = res.clone(); community_sent.community.user_id = None; community_sent.community.subscribed = None; let community_sent_str = serde_json::to_string(&community_sent)?; chat.send_community_message(community_sent.community.id, &community_sent_str, msg.id)?; - Ok(serde_json::to_string(&res)?) + to_json_string(user_operation, &res) } UserOperation::FollowCommunity => { let follow_community: FollowCommunity = serde_json::from_str(data)?; - let res = Oper::new(user_operation, follow_community).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(follow_community).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::GetFollowedCommunities => { let followed_communities: GetFollowedCommunities = serde_json::from_str(data)?; - let res = Oper::new(user_operation, followed_communities).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(followed_communities).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::BanFromCommunity => { let ban_from_community: BanFromCommunity = serde_json::from_str(data)?; let community_id = ban_from_community.community_id; - let res = Oper::new(user_operation, ban_from_community).perform(&conn)?; + let res = Oper::new(ban_from_community).perform(&conn)?; let res_str = serde_json::to_string(&res)?; chat.send_community_message(community_id, &res_str, msg.id)?; Ok(res_str) @@ -408,144 +422,144 @@ fn parse_json_message(chat: &mut ChatServer, msg: StandardMessage) -> Result { let mod_add_to_community: AddModToCommunity = serde_json::from_str(data)?; let community_id = mod_add_to_community.community_id; - let res = Oper::new(user_operation, mod_add_to_community).perform(&conn)?; + let res = Oper::new(mod_add_to_community).perform(&conn)?; let res_str = serde_json::to_string(&res)?; chat.send_community_message(community_id, &res_str, msg.id)?; Ok(res_str) } UserOperation::ListCategories => { let list_categories: ListCategories = ListCategories; - let res = Oper::new(user_operation, list_categories).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(list_categories).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::CreatePost => { chat.check_rate_limit_post(msg.id)?; let create_post: CreatePost = serde_json::from_str(data)?; - let res = Oper::new(user_operation, create_post).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(create_post).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::GetPost => { let get_post: GetPost = serde_json::from_str(data)?; chat.join_room(get_post.id, msg.id); - let res = Oper::new(user_operation, get_post).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(get_post).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::GetPosts => { let get_posts: GetPosts = serde_json::from_str(data)?; - let res = Oper::new(user_operation, get_posts).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(get_posts).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::CreatePostLike => { chat.check_rate_limit_message(msg.id)?; let create_post_like: CreatePostLike = serde_json::from_str(data)?; - let res = Oper::new(user_operation, create_post_like).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(create_post_like).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::EditPost => { let edit_post: EditPost = serde_json::from_str(data)?; - let res = Oper::new(user_operation, edit_post).perform(&conn)?; + let res = Oper::new(edit_post).perform(&conn)?; let mut post_sent = res.clone(); post_sent.post.my_vote = None; let post_sent_str = serde_json::to_string(&post_sent)?; chat.send_room_message(post_sent.post.id, &post_sent_str, msg.id); - Ok(serde_json::to_string(&res)?) + to_json_string(user_operation, &res) } UserOperation::SavePost => { let save_post: SavePost = serde_json::from_str(data)?; - let res = Oper::new(user_operation, save_post).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(save_post).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::CreateComment => { chat.check_rate_limit_message(msg.id)?; let create_comment: CreateComment = serde_json::from_str(data)?; let post_id = create_comment.post_id; - let res = Oper::new(user_operation, create_comment).perform(&conn)?; + let res = Oper::new(create_comment).perform(&conn)?; let mut comment_sent = res.clone(); comment_sent.comment.my_vote = None; comment_sent.comment.user_id = None; let comment_sent_str = serde_json::to_string(&comment_sent)?; chat.send_room_message(post_id, &comment_sent_str, msg.id); - Ok(serde_json::to_string(&res)?) + to_json_string(user_operation, &res) } UserOperation::EditComment => { let edit_comment: EditComment = serde_json::from_str(data)?; let post_id = edit_comment.post_id; - let res = Oper::new(user_operation, edit_comment).perform(&conn)?; + let res = Oper::new(edit_comment).perform(&conn)?; let mut comment_sent = res.clone(); comment_sent.comment.my_vote = None; comment_sent.comment.user_id = None; let comment_sent_str = serde_json::to_string(&comment_sent)?; chat.send_room_message(post_id, &comment_sent_str, msg.id); - Ok(serde_json::to_string(&res)?) + to_json_string(user_operation, &res) } UserOperation::SaveComment => { let save_comment: SaveComment = serde_json::from_str(data)?; - let res = Oper::new(user_operation, save_comment).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(save_comment).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::CreateCommentLike => { chat.check_rate_limit_message(msg.id)?; let create_comment_like: CreateCommentLike = serde_json::from_str(data)?; let post_id = create_comment_like.post_id; - let res = Oper::new(user_operation, create_comment_like).perform(&conn)?; + let res = Oper::new(create_comment_like).perform(&conn)?; let mut comment_sent = res.clone(); comment_sent.comment.my_vote = None; comment_sent.comment.user_id = None; let comment_sent_str = serde_json::to_string(&comment_sent)?; chat.send_room_message(post_id, &comment_sent_str, msg.id); - Ok(serde_json::to_string(&res)?) + to_json_string(user_operation, &res) } UserOperation::GetModlog => { let get_modlog: GetModlog = serde_json::from_str(data)?; - let res = Oper::new(user_operation, get_modlog).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(get_modlog).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::CreateSite => { let create_site: CreateSite = serde_json::from_str(data)?; - let res = Oper::new(user_operation, create_site).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(create_site).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::EditSite => { let edit_site: EditSite = serde_json::from_str(data)?; - let res = Oper::new(user_operation, edit_site).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(edit_site).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::GetSite => { let online: usize = chat.sessions.len(); let get_site: GetSite = serde_json::from_str(data)?; - let mut res = Oper::new(user_operation, get_site).perform(&conn)?; + let mut res = Oper::new(get_site).perform(&conn)?; res.online = online; - Ok(serde_json::to_string(&res)?) + to_json_string(user_operation, &res) } UserOperation::Search => { let search: Search = serde_json::from_str(data)?; - let res = Oper::new(user_operation, search).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(search).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::TransferCommunity => { let transfer_community: TransferCommunity = serde_json::from_str(data)?; - let res = Oper::new(user_operation, transfer_community).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(transfer_community).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::TransferSite => { let transfer_site: TransferSite = serde_json::from_str(data)?; - let res = Oper::new(user_operation, transfer_site).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(transfer_site).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::DeleteAccount => { let delete_account: DeleteAccount = serde_json::from_str(data)?; - let res = Oper::new(user_operation, delete_account).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(delete_account).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::PasswordReset => { let password_reset: PasswordReset = serde_json::from_str(data)?; - let res = Oper::new(user_operation, password_reset).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(password_reset).perform(&conn)?; + to_json_string(user_operation, &res) } UserOperation::PasswordChange => { let password_change: PasswordChange = serde_json::from_str(data)?; - let res = Oper::new(user_operation, password_change).perform(&conn)?; - Ok(serde_json::to_string(&res)?) + let res = Oper::new(password_change).perform(&conn)?; + to_json_string(user_operation, &res) } } }