diff --git a/internal/controller/comment_controller.go b/internal/controller/comment_controller.go index 17e65d49..20f623bf 100644 --- a/internal/controller/comment_controller.go +++ b/internal/controller/comment_controller.go @@ -157,20 +157,23 @@ func (cc *CommentController) UpdateComment(ctx *gin.Context) { } req.UserID = middleware.GetLoginUserIDFromContext(ctx) + req.IsAdmin = middleware.GetIsAdminFromContext(ctx) canList, err := cc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{ - permission.CommentAdd, permission.CommentEdit, - permission.CommentDelete, permission.LinkUrlLimit, }) if err != nil { handler.HandleResponse(ctx, err, nil) return } - linkUrlLimitUser := canList[3] - req.IsAdmin = middleware.GetIsAdminFromContext(ctx) - isAdmin := middleware.GetUserIsAdminModerator(ctx) - if !isAdmin || !linkUrlLimitUser { + req.CanEdit = canList[0] || cc.rankService.CheckOperationObjectOwner(ctx, req.UserID, req.CommentID) + linkUrlLimitUser := canList[1] + if !req.CanEdit { + handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil) + return + } + + if !req.IsAdmin || !linkUrlLimitUser { captchaPass := cc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionEdit, req.UserID, req.CaptchaID, req.CaptchaCode) if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ @@ -182,21 +185,8 @@ func (cc *CommentController) UpdateComment(ctx *gin.Context) { } } - req.CanAdd = canList[0] - req.CanEdit = canList[1] - req.CanDelete = canList[2] - can, err := cc.rankService.CheckOperationPermission(ctx, req.UserID, permission.CommentEdit, req.CommentID) - if err != nil { - handler.HandleResponse(ctx, err, nil) - return - } - if !can { - handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil) - return - } - resp, err := cc.commentService.UpdateComment(ctx, req) - if !isAdmin || !linkUrlLimitUser { + if !req.IsAdmin || !linkUrlLimitUser { cc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionEdit, req.UserID) } handler.HandleResponse(ctx, err, resp) diff --git a/internal/repo/comment/comment_repo.go b/internal/repo/comment/comment_repo.go index d3b3d8ac..f1863fb3 100644 --- a/internal/repo/comment/comment_repo.go +++ b/internal/repo/comment/comment_repo.go @@ -58,9 +58,13 @@ func (cr *commentRepo) RemoveComment(ctx context.Context, commentID string) (err return } -// UpdateComment update comment -func (cr *commentRepo) UpdateComment(ctx context.Context, comment *entity.Comment) (err error) { - _, err = cr.data.DB.Context(ctx).ID(comment.ID).Where("user_id = ?", comment.UserID).Update(comment) +// UpdateCommentContent update comment +func (cr *commentRepo) UpdateCommentContent( + ctx context.Context, commentID string, originalText string, parsedText string) (err error) { + _, err = cr.data.DB.Context(ctx).ID(commentID).Update(&entity.Comment{ + OriginalText: originalText, + ParsedText: parsedText, + }) if err != nil { err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() } @@ -69,8 +73,7 @@ func (cr *commentRepo) UpdateComment(ctx context.Context, comment *entity.Commen // GetComment get comment one func (cr *commentRepo) GetComment(ctx context.Context, commentID string) ( - comment *entity.Comment, exist bool, err error, -) { + comment *entity.Comment, exist bool, err error) { comment = &entity.Comment{} exist, err = cr.data.DB.Context(ctx).ID(commentID).Get(comment) if err != nil { diff --git a/internal/repo/repo_test/comment_repo_test.go b/internal/repo/repo_test/comment_repo_test.go index b482cbf1..8885de7c 100644 --- a/internal/repo/repo_test/comment_repo_test.go +++ b/internal/repo/repo_test/comment_repo_test.go @@ -65,7 +65,7 @@ func Test_commentRepo_UpdateComment(t *testing.T) { assert.NoError(t, err) testCommentEntity.ParsedText = "test" - err = commentRepo.UpdateComment(context.TODO(), testCommentEntity) + err = commentRepo.UpdateCommentContent(context.TODO(), testCommentEntity, "", "") assert.NoError(t, err) newComment, exist, err := commonCommentRepo.GetComment(context.TODO(), testCommentEntity.ID) diff --git a/internal/schema/comment_schema.go b/internal/schema/comment_schema.go index caba2cea..8865795d 100644 --- a/internal/schema/comment_schema.go +++ b/internal/schema/comment_schema.go @@ -58,11 +58,10 @@ type UpdateCommentReq struct { UserID string `json:"-"` IsAdmin bool `json:"-"` - CanAdd bool `json:"-"` // whether user can edit it CanEdit bool `json:"-"` + // whether user can delete it - CanDelete bool `json:"-"` CaptchaID string `json:"captcha_id"` // captcha_id CaptchaCode string `json:"captcha_code"` } @@ -72,6 +71,15 @@ func (req *UpdateCommentReq) Check() (errFields []*validator.FormErrorField, err return nil, nil } +type UpdateCommentResp struct { + // comment id + CommentID string `json:"comment_id"` + // original comment content + OriginalText string `json:"original_text"` + // parsed comment content + ParsedText string `json:"parsed_text"` +} + // GetCommentListReq get comment list all request type GetCommentListReq struct { // user id diff --git a/internal/service/comment/comment_service.go b/internal/service/comment/comment_service.go index 295572f1..b59cd958 100644 --- a/internal/service/comment/comment_service.go +++ b/internal/service/comment/comment_service.go @@ -29,7 +29,7 @@ import ( type CommentRepo interface { AddComment(ctx context.Context, comment *entity.Comment) (err error) RemoveComment(ctx context.Context, commentID string) (err error) - UpdateComment(ctx context.Context, comment *entity.Comment) (err error) + UpdateCommentContent(ctx context.Context, commentID string, original string, parsedText string) (err error) GetComment(ctx context.Context, commentID string) (comment *entity.Comment, exist bool, err error) GetCommentPage(ctx context.Context, commentQuery *CommentQuery) ( comments []*entity.Comment, total int64, err error) @@ -224,39 +224,34 @@ func (cs *CommentService) RemoveComment(ctx context.Context, req *schema.RemoveC // UpdateComment update comment func (cs *CommentService) UpdateComment(ctx context.Context, req *schema.UpdateCommentReq) ( - resp *schema.GetCommentResp, err error) { - resp = &schema.GetCommentResp{} - + resp *schema.UpdateCommentResp, err error) { old, exist, err := cs.commentCommonRepo.GetComment(ctx, req.CommentID) - if err != nil { - return - } - if !exist { - return resp, errors.BadRequest(reason.CommentNotFound) - } - - // user can edit the comment that was posted by himself before deadline. - if !req.IsAdmin && (time.Now().After(old.CreatedAt.Add(constant.CommentEditDeadline))) { - return resp, errors.BadRequest(reason.CommentCannotEditAfterDeadline) - } - - comment := &entity.Comment{} - _ = copier.Copy(comment, req) - comment.ID = req.CommentID - resp.SetFromComment(comment) - resp.MemberActions = permission.GetCommentPermission(ctx, req.UserID, resp.UserID, - time.Now(), req.CanEdit, req.CanDelete) - userInfo, exist, err := cs.userCommon.GetUserBasicInfoByID(ctx, resp.UserID) if err != nil { return nil, err } - if exist { - resp.Username = userInfo.Username - resp.UserDisplayName = userInfo.DisplayName - resp.UserAvatar = userInfo.Avatar - resp.UserStatus = userInfo.Status + if !exist { + return nil, errors.BadRequest(reason.CommentNotFound) } - return resp, cs.commentRepo.UpdateComment(ctx, comment) + // user can't edit the comment that was posted by others except admin + if !req.IsAdmin && req.UserID != old.UserID { + return nil, errors.BadRequest(reason.CommentNotFound) + } + + // user can edit the comment that was posted by himself before deadline. + // admin can edit it at any time + if !req.IsAdmin && (time.Now().After(old.CreatedAt.Add(constant.CommentEditDeadline))) { + return nil, errors.BadRequest(reason.CommentCannotEditAfterDeadline) + } + + if err = cs.commentRepo.UpdateCommentContent(ctx, old.ID, req.OriginalText, req.ParsedText); err != nil { + return nil, err + } + resp = &schema.UpdateCommentResp{ + CommentID: old.ID, + OriginalText: req.OriginalText, + ParsedText: req.ParsedText, + } + return resp, nil } // GetComment get comment one