This commit is contained in:
Felix 2020-01-16 15:39:08 +01:00
parent 7a97c981a0
commit 415040a1e9
9 changed files with 436 additions and 398 deletions

View file

@ -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<CommentResponse> for Oper<CreateComment> {
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<CommentResponse> for Oper<CreateComment> {
// 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<CommentResponse> for Oper<CreateComment> {
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<CommentResponse> for Oper<CreateComment> {
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<CommentResponse> for Oper<EditComment> {
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<CommentResponse> for Oper<EditComment> {
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<CommentResponse> for Oper<EditComment> {
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<CommentResponse> for Oper<EditComment> {
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<CommentResponse> for Oper<SaveComment> {
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<CommentResponse> for Oper<SaveComment> {
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<CommentResponse> for Oper<CreateCommentLike> {
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<CommentResponse> for Oper<CreateCommentLike> {
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<CommentResponse> for Oper<CreateCommentLike> {
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<CommentResponse> for Oper<CreateCommentLike> {
let liked_comment = CommentView::read(&conn, data.comment_id, Some(user_id))?;
Ok(CommentResponse {
op: self.op.to_string(),
comment: liked_comment,
})
}

View file

@ -11,7 +11,6 @@ pub struct GetCommunity {
#[derive(Serialize, Deserialize)]
pub struct GetCommunityResponse {
op: String,
community: CommunityView,
moderators: Vec<CommunityModeratorView>,
admins: Vec<UserView>,
@ -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<CommunityView>,
}
@ -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<CommunityModeratorView>,
}
@ -107,7 +102,6 @@ pub struct GetFollowedCommunities {
#[derive(Serialize, Deserialize)]
pub struct GetFollowedCommunitiesResponse {
op: String,
communities: Vec<CommunityFollowerView>,
}
@ -141,19 +135,19 @@ impl Perform<GetCommunityResponse> for Oper<GetCommunity> {
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<GetCommunityResponse> for Oper<GetCommunity> {
// Return the jwt
Ok(GetCommunityResponse {
op: self.op.to_string(),
community: community_view,
moderators,
admins,
@ -178,21 +171,21 @@ impl Perform<CommunityResponse> for Oper<CreateCommunity> {
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<CommunityResponse> for Oper<CreateCommunity> {
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<CommunityResponse> for Oper<CreateCommunity> {
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<CommunityResponse> for Oper<CreateCommunity> {
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<CommunityResponse> for Oper<EditCommunity> {
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<CommunityResponse> for Oper<EditCommunity> {
);
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<CommunityResponse> for Oper<EditCommunity> {
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<CommunityResponse> for Oper<EditCommunity> {
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<ListCommunitiesResponse> for Oper<ListCommunities> {
.list()?;
// Return the jwt
Ok(ListCommunitiesResponse {
op: self.op.to_string(),
communities,
})
Ok(ListCommunitiesResponse { communities })
}
}
@ -367,7 +353,7 @@ impl Perform<CommunityResponse> for Oper<FollowCommunity> {
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<CommunityResponse> for Oper<FollowCommunity> {
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<GetFollowedCommunitiesResponse> for Oper<GetFollowedCommunities> {
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<GetFollowedCommunitiesResponse> for Oper<GetFollowedCommunities> {
let communities: Vec<CommunityFollowerView> =
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<BanFromCommunityResponse> for Oper<BanFromCommunity> {
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<BanFromCommunityResponse> for Oper<BanFromCommunity> {
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<BanFromCommunityResponse> for Oper<BanFromCommunity> {
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<AddModToCommunityResponse> for Oper<AddModToCommunity> {
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<AddModToCommunityResponse> for Oper<AddModToCommunity> {
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<AddModToCommunityResponse> for Oper<AddModToCommunity> {
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<GetCommunityResponse> for Oper<TransferCommunity> {
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<GetCommunityResponse> for Oper<TransferCommunity> {
// 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<GetCommunityResponse> for Oper<TransferCommunity> {
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<GetCommunityResponse> for Oper<TransferCommunity> {
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<GetCommunityResponse> for Oper<TransferCommunity> {
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,

View file

@ -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<T> {
op: UserOperation,
data: T,
}
impl<T> Oper<T> {
pub fn new(op: UserOperation, data: T) -> Oper<T> {
Oper { op, data }
pub fn new(data: T) -> Oper<T> {
Oper { data }
}
}

View file

@ -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<CommentView>,
community: CommunityView,
@ -46,7 +44,6 @@ pub struct GetPosts {
#[derive(Serialize, Deserialize)]
pub struct GetPostsResponse {
op: String,
posts: Vec<PostView>,
}
@ -59,7 +56,6 @@ pub struct CreatePostLike {
#[derive(Serialize, Deserialize)]
pub struct CreatePostLikeResponse {
op: String,
post: PostView,
}
@ -93,23 +89,23 @@ impl Perform<PostResponse> for Oper<CreatePost> {
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<PostResponse> for Oper<CreatePost> {
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<PostResponse> for Oper<CreatePost> {
// 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<GetPostResponse> for Oper<GetPost> {
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<GetPostResponse> for Oper<GetPost> {
// Return the jwt
Ok(GetPostResponse {
op: self.op.to_string(),
post: post_view,
comments,
community,
@ -241,13 +233,10 @@ impl Perform<GetPostsResponse> for Oper<GetPosts> {
.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<CreatePostLikeResponse> for Oper<CreatePostLike> {
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<CreatePostLikeResponse> for Oper<CreatePostLike> {
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<CreatePostLikeResponse> for Oper<CreatePostLike> {
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<PostResponse> for Oper<EditPost> {
fn perform(&self, conn: &PgConnection) -> Result<PostResponse, Error> {
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<PostResponse> for Oper<EditPost> {
);
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<PostResponse> for Oper<EditPost> {
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<PostResponse> for Oper<EditPost> {
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<PostResponse> for Oper<SavePost> {
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<PostResponse> for Oper<SavePost> {
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 })
}
}

View file

@ -7,7 +7,6 @@ pub struct ListCategories;
#[derive(Serialize, Deserialize)]
pub struct ListCategoriesResponse {
op: String,
categories: Vec<Category>,
}
@ -23,7 +22,6 @@ pub struct Search {
#[derive(Serialize, Deserialize)]
pub struct SearchResponse {
op: String,
type_: String,
comments: Vec<CommentView>,
posts: Vec<PostView>,
@ -41,7 +39,6 @@ pub struct GetModlog {
#[derive(Serialize, Deserialize)]
pub struct GetModlogResponse {
op: String,
removed_posts: Vec<ModRemovePostView>,
locked_posts: Vec<ModLockPostView>,
stickied_posts: Vec<ModStickyPostView>,
@ -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<SiteView>,
admins: Vec<UserView>,
banned: Vec<UserView>,
@ -104,10 +99,7 @@ impl Perform<ListCategoriesResponse> for Oper<ListCategories> {
let categories: Vec<Category> = Category::list_all(&conn)?;
// Return the jwt
Ok(ListCategoriesResponse {
op: self.op.to_string(),
categories,
})
Ok(ListCategoriesResponse { categories })
}
}
@ -171,7 +163,6 @@ impl Perform<GetModlogResponse> for Oper<GetModlog> {
// Return the jwt
Ok(GetModlogResponse {
op: self.op.to_string(),
removed_posts,
locked_posts,
stickied_posts,
@ -191,20 +182,20 @@ impl Perform<SiteResponse> for Oper<CreateSite> {
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<SiteResponse> for Oper<CreateSite> {
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<SiteResponse> for Oper<EditSite> {
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<SiteResponse> for Oper<EditSite> {
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<GetSiteResponse> for Oper<GetSite> {
let banned = UserView::banned(&conn)?;
Ok(GetSiteResponse {
op: self.op.to_string(),
site: site_view,
admins,
banned,
@ -403,7 +387,6 @@ impl Perform<SearchResponse> for Oper<Search> {
// Return the jwt
Ok(SearchResponse {
op: self.op.to_string(),
type_: data.type_.to_owned(),
comments,
posts,
@ -419,7 +402,7 @@ impl Perform<GetSiteResponse> for Oper<TransferSite> {
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<GetSiteResponse> for Oper<TransferSite> {
// 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<GetSiteResponse> for Oper<TransferSite> {
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<GetSiteResponse> for Oper<TransferSite> {
let banned = UserView::banned(&conn)?;
Ok(GetSiteResponse {
op: self.op.to_string(),
site: Some(site_view),
admins,
banned,

View file

@ -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<CommunityFollowerView>,
moderates: Vec<CommunityModeratorView>,
@ -69,13 +67,11 @@ pub struct GetUserDetailsResponse {
#[derive(Serialize, Deserialize)]
pub struct GetRepliesResponse {
op: String,
replies: Vec<ReplyView>,
}
#[derive(Serialize, Deserialize)]
pub struct GetUserMentionsResponse {
op: String,
mentions: Vec<UserMentionView>,
}
@ -93,7 +89,6 @@ pub struct AddAdmin {
#[derive(Serialize, Deserialize)]
pub struct AddAdminResponse {
op: String,
admins: Vec<UserView>,
}
@ -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<LoginResponse> for Oper<Login> {
// 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<LoginResponse> for Oper<Register> {
// 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<LoginResponse> for Oper<Register> {
"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<LoginResponse> for Oper<Register> {
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<LoginResponse> for Oper<Register> {
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<LoginResponse> for Oper<SaveUserSettings> {
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<LoginResponse> for Oper<SaveUserSettings> {
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<LoginResponse> for Oper<SaveUserSettings> {
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<LoginResponse> for Oper<SaveUserSettings> {
"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<GetUserDetailsResponse> for Oper<GetUserDetails> {
.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<GetUserDetailsResponse> for Oper<GetUserDetails> {
// Return the jwt
Ok(GetUserDetailsResponse {
op: self.op.to_string(),
user: user_view,
follows,
moderates,
@ -492,14 +473,14 @@ impl Perform<AddAdminResponse> for Oper<AddAdmin> {
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<AddAdminResponse> for Oper<AddAdmin> {
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<AddAdminResponse> for Oper<AddAdmin> {
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<BanUserResponse> for Oper<BanUser> {
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<BanUserResponse> for Oper<BanUser> {
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<BanUserResponse> for Oper<BanUser> {
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<GetRepliesResponse> for Oper<GetReplies> {
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<GetRepliesResponse> for Oper<GetReplies> {
.limit(data.limit)
.list()?;
Ok(GetRepliesResponse {
op: self.op.to_string(),
replies,
})
Ok(GetRepliesResponse { replies })
}
}
@ -651,7 +625,7 @@ impl Perform<GetUserMentionsResponse> for Oper<GetUserMentions> {
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<GetUserMentionsResponse> for Oper<GetUserMentions> {
.limit(data.limit)
.list()?;
Ok(GetUserMentionsResponse {
op: self.op.to_string(),
mentions,
})
Ok(GetUserMentionsResponse { mentions })
}
}
@ -678,7 +649,7 @@ impl Perform<UserMentionResponse> for Oper<EditUserMention> {
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<UserMentionResponse> for Oper<EditUserMention> {
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<GetRepliesResponse> for Oper<MarkAllAsRead> {
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<GetRepliesResponse> for Oper<MarkAllAsRead> {
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<GetRepliesResponse> for Oper<MarkAllAsRead> {
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<LoginResponse> for Oper<DeleteAccount> {
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<LoginResponse> for Oper<DeleteAccount> {
// 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<LoginResponse> for Oper<DeleteAccount> {
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<LoginResponse> for Oper<DeleteAccount> {
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<PasswordResetResponse> for Oper<PasswordReset> {
// 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<PasswordResetResponse> for Oper<PasswordReset> {
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(&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<LoginResponse> for Oper<PasswordChange> {
// 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(),
})
}

View file

@ -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<Pool<ConnectionManager<PgConnection>>>;
pub fn config(cfg: &mut web::ServiceConfig) {
cfg
// TODO: need to repeat this for every endpoint
.route(
"/api/v1/login",
web::post().to(route::<Login, LoginResponse>),
)
.route(
"/api/v1/register",
web::post().to(route::<Register, LoginResponse>),
)
.route(
"/api/v1/create_community",
web::post().to(route::<CreateCommunity, CommunityResponse>),
)
.route(
"/api/v1/create_post",
web::post().to(route::<CreatePost, PostResponse>),
)
.route(
"/api/v1/list_communities",
web::get().to(
route::<ListCommunities, ListCommunitiesResponse>(UserOperation::ListCommunities)
),
web::get().to(route::<ListCommunities, ListCommunitiesResponse>),
)
.route(
"/api/v1/list_categories",
web::get().to(route::<ListCategories, ListCategoriesResponse>),
)
.route(
"/api/v1/get_post",
web::get().to(route::<GetPost, GetPostResponse>),
)
.route(
"/api/v1/get_community",
web::get().to(route::<GetCommunity, GetCommunityResponse>(
UserOperation::GetCommunity,
)),
web::get().to(route::<GetCommunity, GetCommunityResponse>),
)
.route(
"/api/v1/create_communent",
web::post().to(route::<CreateComment, CommentResponse>),
)
.route(
"/api/v1/edit_comment",
web::post().to(route::<EditComment, CommentResponse>),
)
.route(
"/api/v1/save_comment",
web::post().to(route::<SaveComment, CommentResponse>),
)
.route(
"/api/v1/create_comment_like",
web::post().to(route::<CreateCommentLike, CommentResponse>),
)
.route(
"/api/v1/get_posts",
web::get().to(route::<GetPosts, GetPostsResponse>),
)
.route(
"/api/v1/create_post_like",
web::post().to(route::<CreatePostLike, CreatePostLikeResponse>),
)
.route(
"/api/v1/edit_post",
web::post().to(route::<EditPost, PostResponse>),
)
.route(
"/api/v1/save_post",
web::post().to(route::<SavePost, PostResponse>),
)
.route(
"/api/v1/edit_community",
web::post().to(route::<EditCommunity, CommunityResponse>),
)
.route(
"/api/v1/follow_community",
web::post().to(route::<FollowCommunity, CommunityResponse>),
)
.route(
"/api/v1/get_followed_communities",
web::get().to(route::<GetFollowedCommunities, GetFollowedCommunitiesResponse>),
)
.route(
"/api/v1/get_user_details",
web::get().to(route::<GetUserDetails, GetUserDetailsResponse>),
)
.route(
"/api/v1/get_replies",
web::get().to(route::<GetReplies, GetRepliesResponse>),
)
.route(
"/api/v1/get_user_mentions",
web::get().to(route::<GetUserMentions, GetUserMentionsResponse>),
)
.route(
"/api/v1/edit_user_mention",
web::post().to(route::<EditUserMention, UserMentionResponse>),
)
.route(
"/api/v1/get_modlog",
web::get().to(route::<GetModlog, GetModlogResponse>),
)
.route(
"/api/v1/ban_from_community",
web::post().to(route::<BanFromCommunity, BanFromCommunityResponse>),
)
.route(
"/api/v1/add_mod_to_community",
web::post().to(route::<AddModToCommunity, AddModToCommunityResponse>),
)
.route(
"/api/v1/create_site",
web::post().to(route::<CreateSite, SiteResponse>),
)
.route(
"/api/v1/edit_site",
web::post().to(route::<EditSite, SiteResponse>),
)
.route(
"/api/v1/get_site",
web::get().to(route::<GetSite, GetSiteResponse>),
)
.route(
"/api/v1/add_admin",
web::post().to(route::<AddAdmin, AddAdminResponse>),
)
.route(
"/api/v1/ban_user",
web::post().to(route::<BanUser, BanUserResponse>),
)
.route(
"/api/v1/search",
web::post().to(route::<Search, SearchResponse>),
)
.route(
"/api/v1/mark_all_as_read",
web::post().to(route::<MarkAllAsRead, GetRepliesResponse>),
)
.route(
"/api/v1/save_user_settings",
web::post().to(route::<SaveUserSettings, LoginResponse>),
)
.route(
"/api/v1/transfer_community",
web::post().to(route::<TransferCommunity, GetCommunityResponse>),
)
.route(
"/api/v1/transfer_site",
web::post().to(route::<TransferSite, GetSiteResponse>),
)
.route(
"/api/v1/delete_account",
web::post().to(route::<DeleteAccount, LoginResponse>),
)
.route(
"/api/v1/password_reset",
web::post().to(route::<PasswordReset, PasswordResetResponse>),
)
.route(
"/api/v1/password_change",
web::post().to(route::<PasswordChange, LoginResponse>),
);
}
fn perform<Request, Response>(
op: UserOperation,
data: Request,
db: DbParam,
) -> Result<HttpResponse, Error>
fn perform<Request, Response>(data: Request, db: DbParam) -> Result<HttpResponse, Error>
where
Response: Serialize,
Oper<Request>: Perform<Response>,
@ -41,20 +181,16 @@ where
Ok(c) => c,
Err(e) => return Err(format_err!("{}", e)),
};
let oper: Oper<Request> = Oper::new(op, data);
let oper: Oper<Request> = Oper::new(data);
let response = oper.perform(&conn);
Ok(HttpResponse::Ok().json(response?))
}
fn route<Data, Response>(
op: UserOperation,
) -> Box<(dyn Fn(web::Query<Data>, DbParam) -> Result<HttpResponse, Error> + 'static)>
async fn route<Data, Response>(data: web::Query<Data>, db: DbParam) -> Result<HttpResponse, Error>
where
Data: Serialize,
Response: Serialize,
Oper<Data>: Perform<Response>,
{
// 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::<Data, Response>(op, data.0, db))
perform::<Data, Response>(data.0, db)
}

View file

@ -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,
}

View file

@ -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<StandardMessage> for ChatServer {
}
}
fn to_json_string<T>(op: UserOperation, data: T) -> Result<String, Error>
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<String, Error> {
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<Str
match user_operation {
UserOperation::Login => {
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<Str
}
UserOperation::GetUserDetails => {
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<Str
UserOperation::AddModToCommunity => {
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)
}
}
}