summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/.rustfmt.toml2
-rw-r--r--server/migrations/2020-01-21-001001_create_private_message/down.sql34
-rw-r--r--server/migrations/2020-01-21-001001_create_private_message/up.sql90
-rw-r--r--server/src/api/comment.rs45
-rw-r--r--server/src/api/community.rs97
-rw-r--r--server/src/api/mod.rs56
-rw-r--r--server/src/api/post.rs78
-rw-r--r--server/src/api/site.rs46
-rw-r--r--server/src/api/user.rs328
-rw-r--r--server/src/apub/mod.rs1
-rw-r--r--server/src/db/comment.rs1
-rw-r--r--server/src/db/comment_view.rs1
-rw-r--r--server/src/db/community.rs1
-rw-r--r--server/src/db/mod.rs2
-rw-r--r--server/src/db/moderator.rs2
-rw-r--r--server/src/db/password_reset_request.rs1
-rw-r--r--server/src/db/post.rs1
-rw-r--r--server/src/db/post_view.rs1
-rw-r--r--server/src/db/private_message.rs144
-rw-r--r--server/src/db/private_message_view.rs140
-rw-r--r--server/src/db/user.rs4
-rw-r--r--server/src/db/user_mention.rs2
-rw-r--r--server/src/db/user_view.rs3
-rw-r--r--server/src/lib.rs4
-rw-r--r--server/src/main.rs3
-rw-r--r--server/src/routes/api.rs103
-rw-r--r--server/src/routes/index.rs1
-rw-r--r--server/src/routes/mod.rs1
-rw-r--r--server/src/schema.rs15
-rw-r--r--server/src/websocket/mod.rs46
-rw-r--r--server/src/websocket/server.rs226
31 files changed, 1053 insertions, 426 deletions
diff --git a/server/.rustfmt.toml b/server/.rustfmt.toml
index b1fce9c9..684a7f8a 100644
--- a/server/.rustfmt.toml
+++ b/server/.rustfmt.toml
@@ -1,2 +1,2 @@
tab_spaces = 2
-edition="2018"
+edition="2018" \ No newline at end of file
diff --git a/server/migrations/2020-01-21-001001_create_private_message/down.sql b/server/migrations/2020-01-21-001001_create_private_message/down.sql
new file mode 100644
index 00000000..0d951e3e
--- /dev/null
+++ b/server/migrations/2020-01-21-001001_create_private_message/down.sql
@@ -0,0 +1,34 @@
+-- Drop the triggers
+drop trigger refresh_private_message on private_message;
+drop function refresh_private_message();
+
+-- Drop the view and table
+drop view private_message_view cascade;
+drop table private_message;
+
+-- Rebuild the old views
+drop view user_view cascade;
+create view user_view as
+select
+u.id,
+u.name,
+u.avatar,
+u.email,
+u.fedi_name,
+u.admin,
+u.banned,
+u.show_avatars,
+u.send_notifications_to_email,
+u.published,
+(select count(*) from post p where p.creator_id = u.id) as number_of_posts,
+(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score,
+(select count(*) from comment c where c.creator_id = u.id) as number_of_comments,
+(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score
+from user_ u;
+
+create materialized view user_mview as select * from user_view;
+
+create unique index idx_user_mview_id on user_mview (id);
+
+-- Drop the columns
+alter table user_ drop column matrix_user_id;
diff --git a/server/migrations/2020-01-21-001001_create_private_message/up.sql b/server/migrations/2020-01-21-001001_create_private_message/up.sql
new file mode 100644
index 00000000..48e16dd8
--- /dev/null
+++ b/server/migrations/2020-01-21-001001_create_private_message/up.sql
@@ -0,0 +1,90 @@
+-- Creating private message
+create table private_message (
+ id serial primary key,
+ creator_id int references user_ on update cascade on delete cascade not null,
+ recipient_id int references user_ on update cascade on delete cascade not null,
+ content text not null,
+ deleted boolean default false not null,
+ read boolean default false not null,
+ published timestamp not null default now(),
+ updated timestamp
+);
+
+-- Create the view and materialized view which has the avatar and creator name
+create view private_message_view as
+select
+pm.*,
+u.name as creator_name,
+u.avatar as creator_avatar,
+u2.name as recipient_name,
+u2.avatar as recipient_avatar
+from private_message pm
+inner join user_ u on u.id = pm.creator_id
+inner join user_ u2 on u2.id = pm.recipient_id;
+
+create materialized view private_message_mview as select * from private_message_view;
+
+create unique index idx_private_message_mview_id on private_message_mview (id);
+
+-- Create the triggers
+create or replace function refresh_private_message()
+returns trigger language plpgsql
+as $$
+begin
+ refresh materialized view concurrently private_message_mview;
+ return null;
+end $$;
+
+create trigger refresh_private_message
+after insert or update or delete or truncate
+on private_message
+for each statement
+execute procedure refresh_private_message();
+
+-- Update user to include matrix id
+alter table user_ add column matrix_user_id text unique;
+
+drop view user_view cascade;
+create view user_view as
+select
+u.id,
+u.name,
+u.avatar,
+u.email,
+u.matrix_user_id,
+u.fedi_name,
+u.admin,
+u.banned,
+u.show_avatars,
+u.send_notifications_to_email,
+u.published,
+(select count(*) from post p where p.creator_id = u.id) as number_of_posts,
+(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score,
+(select count(*) from comment c where c.creator_id = u.id) as number_of_comments,
+(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score
+from user_ u;
+
+create materialized view user_mview as select * from user_view;
+
+create unique index idx_user_mview_id on user_mview (id);
+
+-- This is what a group pm table would look like
+-- Not going to do it now because of the complications
+--
+-- create table private_message (
+-- id serial primary key,
+-- creator_id int references user_ on update cascade on delete cascade not null,
+-- content text not null,
+-- deleted boolean default false not null,
+-- published timestamp not null default now(),
+-- updated timestamp
+-- );
+--
+-- create table private_message_recipient (
+-- id serial primary key,
+-- private_message_id int references private_message on update cascade on delete cascade not null,
+-- recipient_id int references user_ on update cascade on delete cascade not null,
+-- read boolean default false not null,
+-- published timestamp not null default now(),
+-- unique(private_message_id, recipient_id)
+-- )
diff --git a/server/src/api/comment.rs b/server/src/api/comment.rs
index 61cc9506..8efb30fb 100644
--- a/server/src/api/comment.rs
+++ b/server/src/api/comment.rs
@@ -7,7 +7,7 @@ use diesel::PgConnection;
pub struct CreateComment {
content: String,
parent_id: Option<i32>,
- edit_id: Option<i32>,
+ edit_id: Option<i32>, // TODO this isn't used
pub post_id: i32,
auth: String,
}
@@ -15,7 +15,7 @@ pub struct CreateComment {
#[derive(Serialize, Deserialize)]
pub struct EditComment {
content: String,
- parent_id: Option<i32>,
+ parent_id: Option<i32>, // TODO why are the parent_id, creator_id, post_id, etc fields required? They aren't going to change
edit_id: i32,
creator_id: i32,
pub post_id: i32,
@@ -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,
})
}
diff --git a/server/src/api/community.rs b/server/src/api/community.rs
index 0bf846c3..c765aa9d 100644
--- a/server/src/api/community.rs
+++ b/server/src/api/community.rs
@@ -11,7 +11,6 @@ pub struct GetCommunity {
#[derive(Serialize, Deserialize)]
pub struct GetCommunityResponse {
- op: String,
community: CommunityView,
moderators: Vec<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,
diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs
index e3580447..cb09d7fa 100644
--- a/server/src/api/mod.rs
+++ b/server/src/api/mod.rs
@@ -8,6 +8,8 @@ use crate::db::moderator_views::*;
use crate::db::password_reset_request::*;
use crate::db::post::*;
use crate::db::post_view::*;
+use crate::db::private_message::*;
+use crate::db::private_message_view::*;
use crate::db::site::*;
use crate::db::site_view::*;
use crate::db::user::*;
@@ -26,73 +28,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,