#[derive(Serialize, Deserialize, Clone)]
pub struct CommentResponse {
- op: String,
pub comment: CommentView,
}
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 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());
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
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,
})
}
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;
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());
}
}
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
let comment_view = CommentView::read(&conn, data.edit_id, Some(user_id))?;
Ok(CommentResponse {
- op: self.op.to_string(),
comment: comment_view,
})
}
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;
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,
})
}
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;
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 {
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()),
};
}
let liked_comment = CommentView::read(&conn, data.comment_id, Some(user_id))?;
Ok(CommentResponse {
- op: self.op.to_string(),
comment: liked_comment,
})
}
#[derive(Serialize, Deserialize)]
pub struct GetCommunityResponse {
- op: String,
community: CommunityView,
moderators: Vec<CommunityModeratorView>,
admins: Vec<UserView>,
#[derive(Serialize, Deserialize, Clone)]
pub struct CommunityResponse {
- op: String,
pub community: CommunityView,
}
#[derive(Serialize, Deserialize)]
pub struct ListCommunitiesResponse {
- op: String,
communities: Vec<CommunityView>,
}
#[derive(Serialize, Deserialize)]
pub struct BanFromCommunityResponse {
- op: String,
user: UserView,
banned: bool,
}
#[derive(Serialize, Deserialize)]
pub struct AddModToCommunityResponse {
- op: String,
moderators: Vec<CommunityModeratorView>,
}
#[derive(Serialize, Deserialize)]
pub struct GetFollowedCommunitiesResponse {
- op: String,
communities: Vec<CommunityFollowerView>,
}
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;
// Return the jwt
Ok(GetCommunityResponse {
- op: self.op.to_string(),
community: community_view,
moderators,
admins,
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
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 {
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 {
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,
})
}
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
);
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 {
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
let community_view = CommunityView::read(&conn, data.edit_id, Some(user_id))?;
Ok(CommunityResponse {
- op: self.op.to_string(),
community: community_view,
})
}
.list()?;
// Return the jwt
- Ok(ListCommunitiesResponse {
- op: self.op.to_string(),
- communities,
- })
+ Ok(ListCommunitiesResponse { communities })
}
}
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;
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,
})
}
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;
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 })
}
}
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;
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()),
};
}
let user_view = UserView::read(&conn, data.user_id)?;
Ok(BanFromCommunityResponse {
- op: self.op.to_string(),
user: user_view,
banned: data.ban,
})
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;
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()),
};
}
let moderators = CommunityModeratorView::for_community(&conn, data.community_id)?;
- Ok(AddModToCommunityResponse {
- op: self.op.to_string(),
- moderators,
- })
+ Ok(AddModToCommunityResponse { moderators })
}
}
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 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 {
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.
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_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,
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 }
}
}
#[derive(Serialize, Deserialize, Clone)]
pub struct PostResponse {
- op: String,
pub post: PostView,
}
#[derive(Serialize, Deserialize)]
pub struct GetPostResponse {
- op: String,
post: PostView,
comments: Vec<CommentView>,
community: CommunityView,
#[derive(Serialize, Deserialize)]
pub struct GetPostsResponse {
- op: String,
posts: Vec<PostView>,
}
#[derive(Serialize, Deserialize)]
pub struct CreatePostLikeResponse {
- op: String,
post: PostView,
}
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 {
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
// 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 })
}
}
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)
// Return the jwt
Ok(GetPostResponse {
- op: self.op.to_string(),
post: post_view,
comments,
community,
.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 })
}
}
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;
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 {
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 })
}
}
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;
);
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 {
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
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 })
}
}
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;
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 })
}
}
#[derive(Serialize, Deserialize)]
pub struct ListCategoriesResponse {
- op: String,
categories: Vec<Category>,
}
#[derive(Serialize, Deserialize)]
pub struct SearchResponse {
- op: String,
type_: String,
comments: Vec<CommentView>,
posts: Vec<PostView>,
#[derive(Serialize, Deserialize)]
pub struct GetModlogResponse {
- op: String,
removed_posts: Vec<ModRemovePostView>,
locked_posts: Vec<ModLockPostView>,
stickied_posts: Vec<ModStickyPostView>,
#[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>,
let categories: Vec<Category> = Category::list_all(&conn)?;
// Return the jwt
- Ok(ListCategoriesResponse {
- op: self.op.to_string(),
- categories,
- })
+ Ok(ListCategoriesResponse { categories })
}
}
// Return the jwt
Ok(GetModlogResponse {
- op: self.op.to_string(),
removed_posts,
locked_posts,
stickied_posts,
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 {
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 })
}
}
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)?;
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 })
}
}
let banned = UserView::banned(&conn)?;
Ok(GetSiteResponse {
- op: self.op.to_string(),
site: site_view,
admins,
banned,
// Return the jwt
Ok(SearchResponse {
- op: self.op.to_string(),
type_: data.type_.to_owned(),
comments,
posts,
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 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 {
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
let banned = UserView::banned(&conn)?;
Ok(GetSiteResponse {
- op: self.op.to_string(),
site: Some(site_view),
admins,
banned,
#[derive(Serialize, Deserialize)]
pub struct LoginResponse {
- op: String,
jwt: String,
}
#[derive(Serialize, Deserialize)]
pub struct GetUserDetailsResponse {
- op: String,
user: UserView,
follows: Vec<CommunityFollowerView>,
moderates: Vec<CommunityModeratorView>,
#[derive(Serialize, Deserialize)]
pub struct GetRepliesResponse {
- op: String,
replies: Vec<ReplyView>,
}
#[derive(Serialize, Deserialize)]
pub struct GetUserMentionsResponse {
- op: String,
mentions: Vec<UserMentionView>,
}
#[derive(Serialize, Deserialize)]
pub struct AddAdminResponse {
- op: String,
admins: Vec<UserView>,
}
#[derive(Serialize, Deserialize)]
pub struct BanUserResponse {
- op: String,
user: UserView,
banned: bool,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct UserMentionResponse {
- op: String,
mention: UserMentionView,
}
}
#[derive(Serialize, Deserialize, Clone)]
-pub struct PasswordResetResponse {
- op: String,
-}
+pub struct PasswordResetResponse {}
#[derive(Serialize, Deserialize)]
pub struct PasswordChange {
// 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() })
}
}
// 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
"user_already_exists"
};
- return Err(APIError::err(&self.op, err_type).into());
+ return Err(APIError::err(err_type).into());
}
};
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
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(),
})
}
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;
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
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,
"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(),
})
}
.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()),
}
}
};
// Return the jwt
Ok(GetUserDetailsResponse {
- op: self.op.to_string(),
user: user_view,
follows,
moderates,
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)?;
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
let creator_user = admins.remove(creator_index);
admins.insert(0, creator_user);
- Ok(AddAdminResponse {
- op: self.op.to_string(),
- admins,
- })
+ Ok(AddAdminResponse { admins })
}
}
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)?;
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
let user_view = UserView::read(&conn, data.user_id)?;
Ok(BanUserResponse {
- op: self.op.to_string(),
user: user_view,
banned: data.ban,
})
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;
.limit(data.limit)
.list()?;
- Ok(GetRepliesResponse {
- op: self.op.to_string(),
- replies,
- })
+ Ok(GetRepliesResponse { replies })
}
}
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;
.limit(data.limit)
.list()?;
- Ok(GetUserMentionsResponse {
- op: self.op.to_string(),
- mentions,
- })
+ Ok(GetUserMentionsResponse { mentions })
}
}
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;
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,
})
}
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;
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()),
};
}
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![] })
}
}
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;
// 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
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()),
};
}
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(),
})
}
// 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
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 {})
}
}
// 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(),
})
}
-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};
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>,
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)
}
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,
+}
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
);
Err(
APIError {
- op: "Rate Limit".to_string(),
message: format!("Too many requests. {} per {} seconds", rate, per),
}
.into(),
}
}
+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(),
})?;
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)?;
}
}
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)
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)
}
}
}