##// END OF EJS Templates
security: make sure the admin of repo can only delete comments which are from the same repo....
ergo -
r1818:1ced1b24 default
parent child Browse files
Show More
@@ -40,7 +40,7 b' from rhodecode.lib.compat import Ordered'
40 from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
40 from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
41 import rhodecode.lib.helpers as h
41 import rhodecode.lib.helpers as h
42 from rhodecode.lib.utils import jsonify
42 from rhodecode.lib.utils import jsonify
43 from rhodecode.lib.utils2 import safe_unicode
43 from rhodecode.lib.utils2 import safe_unicode, safe_int
44 from rhodecode.lib.vcs.backends.base import EmptyCommit
44 from rhodecode.lib.vcs.backends.base import EmptyCommit
45 from rhodecode.lib.vcs.exceptions import (
45 from rhodecode.lib.vcs.exceptions import (
46 RepositoryError, CommitDoesNotExistError, NodeDoesNotExistError)
46 RepositoryError, CommitDoesNotExistError, NodeDoesNotExistError)
@@ -431,15 +431,19 b' class ChangesetController(BaseRepoContro'
431 @auth.CSRFRequired()
431 @auth.CSRFRequired()
432 @jsonify
432 @jsonify
433 def delete_comment(self, repo_name, comment_id):
433 def delete_comment(self, repo_name, comment_id):
434 comment = ChangesetComment.get(comment_id)
434 comment = ChangesetComment.get_or_404(safe_int(comment_id))
435 if not comment:
435 if not comment:
436 log.debug('Comment with id:%s not found, skipping', comment_id)
436 log.debug('Comment with id:%s not found, skipping', comment_id)
437 # comment already deleted in another call probably
437 # comment already deleted in another call probably
438 return True
438 return True
439
439
440 owner = (comment.author.user_id == c.rhodecode_user.user_id)
441 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name)
440 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name)
442 if h.HasPermissionAny('hg.admin')() or is_repo_admin or owner:
441 super_admin = h.HasPermissionAny('hg.admin')()
442 comment_owner = (comment.author.user_id == c.rhodecode_user.user_id)
443 is_repo_comment = comment.repo.repo_name == c.repo_name
444 comment_repo_admin = is_repo_admin and is_repo_comment
445
446 if super_admin or comment_owner or comment_repo_admin:
443 CommentsModel().delete(comment=comment, user=c.rhodecode_user)
447 CommentsModel().delete(comment=comment, user=c.rhodecode_user)
444 Session().commit()
448 Session().commit()
445 return True
449 return True
@@ -987,25 +987,30 b' class PullrequestsController(BaseRepoCon'
987 @auth.CSRFRequired()
987 @auth.CSRFRequired()
988 @jsonify
988 @jsonify
989 def delete_comment(self, repo_name, comment_id):
989 def delete_comment(self, repo_name, comment_id):
990 return self._delete_comment(comment_id)
990 comment = ChangesetComment.get_or_404(safe_int(comment_id))
991 if not comment:
992 log.debug('Comment with id:%s not found, skipping', comment_id)
993 # comment already deleted in another call probably
994 return True
991
995
992 def _delete_comment(self, comment_id):
996 if comment.pull_request.is_closed():
993 comment_id = safe_int(comment_id)
994 co = ChangesetComment.get_or_404(comment_id)
995 if co.pull_request.is_closed():
996 # don't allow deleting comments on closed pull request
997 # don't allow deleting comments on closed pull request
997 raise HTTPForbidden()
998 raise HTTPForbidden()
998
999
999 is_owner = co.author.user_id == c.rhodecode_user.user_id
1000 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name)
1000 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name)
1001 if h.HasPermissionAny('hg.admin')() or is_repo_admin or is_owner:
1001 super_admin = h.HasPermissionAny('hg.admin')()
1002 old_calculated_status = co.pull_request.calculated_review_status()
1002 comment_owner = comment.author.user_id == c.rhodecode_user.user_id
1003 CommentsModel().delete(comment=co, user=c.rhodecode_user)
1003 is_repo_comment = comment.repo.repo_name == c.repo_name
1004 comment_repo_admin = is_repo_admin and is_repo_comment
1005
1006 if super_admin or comment_owner or comment_repo_admin:
1007 old_calculated_status = comment.pull_request.calculated_review_status()
1008 CommentsModel().delete(comment=comment, user=c.rhodecode_user)
1004 Session().commit()
1009 Session().commit()
1005 calculated_status = co.pull_request.calculated_review_status()
1010 calculated_status = comment.pull_request.calculated_review_status()
1006 if old_calculated_status != calculated_status:
1011 if old_calculated_status != calculated_status:
1007 PullRequestModel()._trigger_pull_request_hook(
1012 PullRequestModel()._trigger_pull_request_hook(
1008 co.pull_request, c.rhodecode_user, 'review_status_change')
1013 comment.pull_request, c.rhodecode_user, 'review_status_change')
1009 return True
1014 return True
1010 else:
1015 else:
1011 raise HTTPForbidden()
1016 raise HTTPForbidden()
@@ -1060,6 +1060,17 b' class TestPullrequestsControllerDelete(o'
1060 response.mustcontain('id="delete_pullrequest"')
1060 response.mustcontain('id="delete_pullrequest"')
1061 response.mustcontain(no=['Confirm to delete this pull request'])
1061 response.mustcontain(no=['Confirm to delete this pull request'])
1062
1062
1063 def test_delete_comment_returns_404_if_comment_does_not_exist(
1064 self, autologin_user, pr_util, user_admin):
1065
1066 pull_request = pr_util.create_pull_request(
1067 author=user_admin.username, enable_notifications=False)
1068
1069 self.app.get(url(
1070 controller='pullrequests', action='delete_comment',
1071 repo_name=pull_request.target_repo.scm_instance().name,
1072 comment_id=1024404), status=404)
1073
1063
1074
1064 def assert_pull_request_status(pull_request, expected_status):
1075 def assert_pull_request_status(pull_request, expected_status):
1065 status = ChangesetStatusModel().calculated_review_status(
1076 status = ChangesetStatusModel().calculated_review_status(
@@ -1081,13 +1092,3 b' def test_redirects_to_repo_summary_for_s'
1081
1092
1082 # URL adds leading slash and path doesn't have it
1093 # URL adds leading slash and path doesn't have it
1083 assert redirected.request.path == summary_url
1094 assert redirected.request.path == summary_url
1084
1085
1086 def test_delete_comment_returns_404_if_comment_does_not_exist(pylonsapp):
1087 # TODO: johbo: Global import not possible because models.forms blows up
1088 from rhodecode.controllers.pullrequests import PullrequestsController
1089 controller = PullrequestsController()
1090 patcher = mock.patch(
1091 'rhodecode.model.db.BaseModel.get', return_value=None)
1092 with pytest.raises(HTTPNotFound), patcher:
1093 controller._delete_comment(1)
General Comments 0
You need to be logged in to leave comments. Login now