##// END OF EJS Templates
Forbid changing changset status when it is associated with a closed pull request...
marcink -
r2677:4fbbc65e beta
parent child Browse files
Show More
@@ -49,6 +49,7 b' from rhodecode.model.changeset_status im'
49 from rhodecode.model.meta import Session
49 from rhodecode.model.meta import Session
50 from rhodecode.lib.diffs import wrapped_diff
50 from rhodecode.lib.diffs import wrapped_diff
51 from rhodecode.model.repo import RepoModel
51 from rhodecode.model.repo import RepoModel
52 from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
52
53
53 log = logging.getLogger(__name__)
54 log = logging.getLogger(__name__)
54
55
@@ -388,18 +389,31 b' class ChangesetController(BaseRepoContro'
388
389
389 # get status if set !
390 # get status if set !
390 if status and change_status:
391 if status and change_status:
391 ChangesetStatusModel().set_status(
392 # if latest status was from pull request and it's closed
392 c.rhodecode_db_repo.repo_id,
393 # disallow changing status !
393 status,
394 # dont_allow_on_closed_pull_request = True !
394 c.rhodecode_user.user_id,
395
395 comm,
396 try:
396 revision=revision,
397 ChangesetStatusModel().set_status(
397 )
398 c.rhodecode_db_repo.repo_id,
399 status,
400 c.rhodecode_user.user_id,
401 comm,
402 revision=revision,
403 dont_allow_on_closed_pull_request=True
404 )
405 except StatusChangeOnClosedPullRequestError:
406 log.error(traceback.format_exc())
407 msg = _('Changing status on a changeset associated with'
408 'a closed pull request is not allowed')
409 h.flash(msg, category='warning')
410 return redirect(h.url('changeset_home', repo_name=repo_name,
411 revision=revision))
398 action_logger(self.rhodecode_user,
412 action_logger(self.rhodecode_user,
399 'user_commented_revision:%s' % revision,
413 'user_commented_revision:%s' % revision,
400 c.rhodecode_db_repo, self.ip_addr, self.sa)
414 c.rhodecode_db_repo, self.ip_addr, self.sa)
401
415
402 Session.commit()
416 Session().commit()
403
417
404 if not request.environ.get('HTTP_X_PARTIAL_XHR'):
418 if not request.environ.get('HTTP_X_PARTIAL_XHR'):
405 return redirect(h.url('changeset_home', repo_name=repo_name,
419 return redirect(h.url('changeset_home', repo_name=repo_name,
@@ -422,7 +436,7 b' class ChangesetController(BaseRepoContro'
422 owner = lambda: co.author.user_id == c.rhodecode_user.user_id
436 owner = lambda: co.author.user_id == c.rhodecode_user.user_id
423 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
437 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
424 ChangesetCommentsModel().delete(comment=co)
438 ChangesetCommentsModel().delete(comment=co)
425 Session.commit()
439 Session().commit()
426 return True
440 return True
427 else:
441 else:
428 raise HTTPForbidden()
442 raise HTTPForbidden()
@@ -50,3 +50,7 b' class UserOwnsReposException(Exception):'
50
50
51 class UsersGroupsAssignedException(Exception):
51 class UsersGroupsAssignedException(Exception):
52 pass
52 pass
53
54
55 class StatusChangeOnClosedPullRequestError(Exception):
56 pass No newline at end of file
@@ -28,6 +28,7 b' from collections import defaultdict'
28
28
29 from rhodecode.model import BaseModel
29 from rhodecode.model import BaseModel
30 from rhodecode.model.db import ChangesetStatus, PullRequest
30 from rhodecode.model.db import ChangesetStatus, PullRequest
31 from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
31
32
32 log = logging.getLogger(__name__)
33 log = logging.getLogger(__name__)
33
34
@@ -111,7 +112,7 b' class ChangesetStatusModel(BaseModel):'
111 return str(st)
112 return str(st)
112
113
113 def set_status(self, repo, status, user, comment, revision=None,
114 def set_status(self, repo, status, user, comment, revision=None,
114 pull_request=None):
115 pull_request=None, dont_allow_on_closed_pull_request=False):
115 """
116 """
116 Creates new status for changeset or updates the old ones bumping their
117 Creates new status for changeset or updates the old ones bumping their
117 version, leaving the current status at
118 version, leaving the current status at
@@ -126,6 +127,9 b' class ChangesetStatusModel(BaseModel):'
126 :type user:
127 :type user:
127 :param comment:
128 :param comment:
128 :type comment:
129 :type comment:
130 :param dont_allow_on_closed_pull_request: don't allow a status change
131 if last status was for pull request and it's closed. We shouldn't
132 mess around this manually
129 """
133 """
130 repo = self._get_repo(repo)
134 repo = self._get_repo(repo)
131
135
@@ -140,6 +144,14 b' class ChangesetStatusModel(BaseModel):'
140 q = q.filter(ChangesetStatus.pull_request == pull_request)
144 q = q.filter(ChangesetStatus.pull_request == pull_request)
141 cur_statuses = q.all()
145 cur_statuses = q.all()
142
146
147 #if statuses exists and last is associated with a closed pull request
148 # we need to check if we can allow this status change
149 if (dont_allow_on_closed_pull_request and cur_statuses
150 and cur_statuses[0].pull_request.status == PullRequest.STATUS_CLOSED):
151 raise StatusChangeOnClosedPullRequestError(
152 'Changing status on closed pull request is not allowed'
153 )
154
143 if cur_statuses:
155 if cur_statuses:
144 for st in cur_statuses:
156 for st in cur_statuses:
145 st.version += 1
157 st.version += 1
@@ -1449,7 +1449,7 b' class ChangesetComment(Base, BaseModel):'
1449
1449
1450 author = relationship('User', lazy='joined')
1450 author = relationship('User', lazy='joined')
1451 repo = relationship('Repository')
1451 repo = relationship('Repository')
1452 status_change = relationship('ChangesetStatus', uselist=False)
1452 status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan")
1453 pull_request = relationship('PullRequest', lazy='joined')
1453 pull_request = relationship('PullRequest', lazy='joined')
1454
1454
1455 @classmethod
1455 @classmethod
@@ -17,8 +17,8 b''
17 %if co.status_change:
17 %if co.status_change:
18 <div style="float:left" class="changeset-status-container">
18 <div style="float:left" class="changeset-status-container">
19 <div style="float:left;padding:0px 2px 0px 2px"><span style="font-size: 18px;">&rsaquo;</span></div>
19 <div style="float:left;padding:0px 2px 0px 2px"><span style="font-size: 18px;">&rsaquo;</span></div>
20 <div title="${_('Changeset status')}" class="changeset-status-lbl"> ${co.status_change.status_lbl}</div>
20 <div title="${_('Changeset status')}" class="changeset-status-lbl"> ${co.status_change[0].status_lbl}</div>
21 <div class="changeset-status-ico"><img src="${h.url(str('/images/icons/flag_status_%s.png' % co.status_change.status))}" /></div>
21 <div class="changeset-status-ico"><img src="${h.url(str('/images/icons/flag_status_%s.png' % co.status_change[0].status))}" /></div>
22 </div>
22 </div>
23 %endif
23 %endif
24 %if h.HasPermissionAny('hg.admin', 'repository.admin')() or co.author.user_id == c.rhodecode_user.user_id:
24 %if h.HasPermissionAny('hg.admin', 'repository.admin')() or co.author.user_id == c.rhodecode_user.user_id:
General Comments 0
You need to be logged in to leave comments. Login now