summaryrefslogtreecommitdiffstats
path: root/server/src/api/comment.rs
diff options
context:
space:
mode:
authorDessalines <tyhou13@gmx.com>2019-05-04 22:20:38 -0700
committerDessalines <tyhou13@gmx.com>2019-05-04 22:20:38 -0700
commit7fb6a0b1387d4c256061fd9402ac8405fcedcf83 (patch)
tree3b239ae2802cf2a1c1429144b75f295e341f8e9f /server/src/api/comment.rs
parent1a884a83534accf800f228e050b8fcf9338f6e4b (diff)
Mostly done with reorg.
Diffstat (limited to 'server/src/api/comment.rs')
-rw-r--r--server/src/api/comment.rs316
1 files changed, 316 insertions, 0 deletions
diff --git a/server/src/api/comment.rs b/server/src/api/comment.rs
new file mode 100644
index 00000000..36a44b36
--- /dev/null
+++ b/server/src/api/comment.rs
@@ -0,0 +1,316 @@
+use super::*;
+
+#[derive(Serialize, Deserialize)]
+pub struct CreateComment {
+ content: String,
+ parent_id: Option<i32>,
+ edit_id: Option<i32>,
+ pub post_id: i32,
+ auth: String
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct EditComment {
+ content: String,
+ parent_id: Option<i32>,
+ edit_id: i32,
+ creator_id: i32,
+ pub post_id: i32,
+ removed: Option<bool>,
+ deleted: Option<bool>,
+ reason: Option<String>,
+ read: Option<bool>,
+ auth: String
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct SaveComment {
+ comment_id: i32,
+ save: bool,
+ auth: String
+}
+
+#[derive(Serialize, Deserialize, Clone)]
+pub struct CommentResponse {
+ op: String,
+ pub comment: CommentView
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct CreateCommentLike {
+ comment_id: i32,
+ pub post_id: i32,
+ score: i16,
+ auth: String
+}
+
+
+impl Perform<CommentResponse> for Oper<CreateComment> {
+ fn perform(&self) -> Result<CommentResponse, Error> {
+ let data: CreateComment = self.data;
+ let conn = establish_connection();
+
+ let claims = match Claims::decode(&data.auth) {
+ Ok(claims) => claims.claims,
+ Err(_e) => {
+ return Err(APIError::err(self.op, "Not logged in."))?
+ }
+ };
+
+ 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, "You have been banned from this community"))?
+ }
+
+ // Check for a site ban
+ if UserView::read(&conn, user_id)?.banned {
+ return Err(APIError::err(self.op, "You have been banned from the site"))?
+ }
+
+ let content_slurs_removed = remove_slurs(&data.content.to_owned());
+
+ let comment_form = CommentForm {
+ content: content_slurs_removed,
+ parent_id: data.parent_id.to_owned(),
+ post_id: data.post_id,
+ creator_id: user_id,
+ removed: None,
+ deleted: None,
+ read: None,
+ updated: None
+ };
+
+ let inserted_comment = match Comment::create(&conn, &comment_form) {
+ Ok(comment) => comment,
+ Err(_e) => {
+ return Err(APIError::err(self.op, "Couldn't create Comment"))?
+ }
+ };
+
+ // You like your own comment by default
+ let like_form = CommentLikeForm {
+ comment_id: inserted_comment.id,
+ post_id: data.post_id,
+ user_id: user_id,
+ score: 1
+ };
+
+ let _inserted_like = match CommentLike::like(&conn, &like_form) {
+ Ok(like) => like,
+ Err(_e) => {
+ return Err(APIError::err(self.op, "Couldn't like comment."))?
+ }
+ };
+
+ let comment_view = CommentView::read(&conn, inserted_comment.id, Some(user_id))?;
+
+ Ok(
+ CommentResponse {
+ op: self.op.to_string(),
+ comment: comment_view
+ }
+ )
+ }
+}
+
+impl Perform<CommentResponse> for Oper<EditComment> {
+ fn perform(&self) -> Result<CommentResponse, Error> {
+ let data: EditComment = self.data;
+ let conn = establish_connection();
+
+ let claims = match Claims::decode(&data.auth) {
+ Ok(claims) => claims.claims,
+ Err(_e) => {
+ return Err(APIError::err(self.op, "Not logged in."))?
+ }
+ };
+
+ let user_id = claims.id;
+
+ let orig_comment = CommentView::read(&conn, data.edit_id, None)?;
+
+ // You are allowed to mark the comment as read even if you're banned.
+ if data.read.is_none() {
+
+ // Verify its the creator or a mod, or an admin
+ let mut editors: Vec<i32> = vec![data.creator_id];
+ editors.append(
+ &mut CommunityModeratorView::for_community(&conn, orig_comment.community_id)
+ ?
+ .into_iter()
+ .map(|m| m.user_id)
+ .collect()
+ );
+ editors.append(
+ &mut UserView::admins(&conn)
+ ?
+ .into_iter()
+ .map(|a| a.id)
+ .collect()
+ );
+
+ if !editors.contains(&user_id) {
+ return Err(APIError::err(self.op, "Not allowed to edit comment."))?
+ }
+
+ // Check for a community ban
+ if CommunityUserBanView::get(&conn, user_id, orig_comment.community_id).is_ok() {
+ return Err(APIError::err(self.op, "You have been banned from this community"))?
+ }
+
+ // Check for a site ban
+ if UserView::read(&conn, user_id)?.banned {
+ return Err(APIError::err(self.op, "You have been banned from the site"))?
+ }
+
+ }
+
+ let content_slurs_removed = remove_slurs(&data.content.to_owned());
+
+ let comment_form = CommentForm {
+ content: content_slurs_removed,
+ parent_id: data.parent_id,
+ post_id: data.post_id,
+ creator_id: data.creator_id,
+ removed: data.removed.to_owned(),
+ deleted: data.deleted.to_owned(),
+ read: data.read.to_owned(),
+ updated: if data.read.is_some() { orig_comment.updated } else {Some(naive_now())}
+ };
+
+ let _updated_comment = match Comment::update(&conn, data.edit_id, &comment_form) {
+ Ok(comment) => comment,
+ Err(_e) => {
+ return Err(APIError::err(self.op, "Couldn't update Comment"))?
+ }
+ };
+
+ // Mod tables
+ if let Some(removed) = data.removed.to_owned() {
+ let form = ModRemoveCommentForm {
+ mod_user_id: user_id,
+ comment_id: data.edit_id,
+ removed: Some(removed),
+ reason: data.reason.to_owned(),
+ };
+ ModRemoveComment::create(&conn, &form)?;
+ }
+
+
+ let comment_view = CommentView::read(&conn, data.edit_id, Some(user_id))?;
+
+ Ok(
+ CommentResponse {
+ op: self.op.to_string(),
+ comment: comment_view
+ }
+ )
+
+ }
+}
+
+impl Perform<CommentResponse> for Oper<SaveComment> {
+ fn perform(&self) -> Result<CommentResponse, Error> {
+ let data: SaveComment = self.data;
+ let conn = establish_connection();
+
+ let claims = match Claims::decode(&data.auth) {
+ Ok(claims) => claims.claims,
+ Err(_e) => {
+ return Err(APIError::err(self.op, "Not logged in."))?
+ }
+ };
+
+ let user_id = claims.id;
+
+ let comment_saved_form = CommentSavedForm {
+ comment_id: data.comment_id,
+ user_id: user_id,
+ };
+
+ if data.save {
+ match CommentSaved::save(&conn, &comment_saved_form) {
+ Ok(comment) => comment,
+ Err(_e) => {
+ return Err(APIError::err(self.op, "Couldnt do comment save"))?
+ }
+ };
+ } else {
+ match CommentSaved::unsave(&conn, &comment_saved_form) {
+ Ok(comment) => comment,
+ Err(_e) => {
+ return Err(APIError::err(self.op, "Couldnt do comment save"))?
+ }
+ };
+ }
+
+ let comment_view = CommentView::read(&conn, data.comment_id, Some(user_id))?;
+
+ Ok(
+ CommentResponse {
+ op: self.op.to_string(),
+ comment: comment_view
+ }
+ )
+ }
+}
+
+impl Perform<CommentResponse> for Oper<CreateCommentLike> {
+ fn perform(&self) -> Result<CommentResponse, Error> {
+ let data: CreateCommentLike = self.data;
+ let conn = establish_connection();
+
+ let claims = match Claims::decode(&data.auth) {
+ Ok(claims) => claims.claims,
+ Err(_e) => {
+ return Err(APIError::err(self.op, "Not logged in."))?
+ }
+ };
+
+ 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, "You have been banned from this community"))?
+ }
+
+ // Check for a site ban
+ if UserView::read(&conn, user_id)?.banned {
+ return Err(APIError::err(self.op, "You have been banned from the site"))?
+ }
+
+ let like_form = CommentLikeForm {
+ comment_id: data.comment_id,
+ post_id: data.post_id,
+ user_id: user_id,
+ score: data.score
+ };
+
+ // Remove any likes first
+ CommentLike::remove(&conn, &like_form)?;
+
+ // Only add the like if the score isnt 0
+ if &like_form.score != &0 {
+ let _inserted_like = match CommentLike::like(&conn, &like_form) {
+ Ok(like) => like,
+ Err(_e) => {
+ return Err(APIError::err(self.op, "Couldn't like comment."))?
+ }
+ };
+ }
+
+ // Have to refetch the comment to get the current state
+ let liked_comment = CommentView::read(&conn, data.comment_id, Some(user_id))?;
+
+ Ok(
+ CommentResponse {
+ op: self.op.to_string(),
+ comment: liked_comment
+ }
+ )
+ }
+}