Changeset - 4fbbc65e8cd5
[Not reviewed]
beta
0 5 0
Marcin Kuzminski - 13 years ago 2012-07-30 23:29:03
marcin@python-works.com
Forbid changing changset status when it is associated with a closed pull request
- fixed some issues with cascade deleting repos with changeset statuses attached
5 files changed with 43 insertions and 13 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/changeset.py
Show inline comments
 
@@ -46,12 +46,13 @@ from rhodecode.lib import diffs
 
from rhodecode.model.db import ChangesetComment, ChangesetStatus
 
from rhodecode.model.comment import ChangesetCommentsModel
 
from rhodecode.model.changeset_status import ChangesetStatusModel
 
from rhodecode.model.meta import Session
 
from rhodecode.lib.diffs import wrapped_diff
 
from rhodecode.model.repo import RepoModel
 
from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def _update_with_GET(params, GET):
 
    for k in ['diff1', 'diff2', 'diff']:
 
@@ -385,24 +386,37 @@ class ChangesetController(BaseRepoContro
 
            status_change=(ChangesetStatus.get_status_lbl(status)
 
                           if status and change_status else None)
 
        )
 

	
 
        # get status if set !
 
        if status and change_status:
 
            ChangesetStatusModel().set_status(
 
                c.rhodecode_db_repo.repo_id,
 
                status,
 
                c.rhodecode_user.user_id,
 
                comm,
 
                revision=revision,
 
            )
 
            # if latest status was from pull request and it's closed
 
            # disallow changing status ! 
 
            # dont_allow_on_closed_pull_request = True !
 

	
 
            try:
 
                ChangesetStatusModel().set_status(
 
                    c.rhodecode_db_repo.repo_id,
 
                    status,
 
                    c.rhodecode_user.user_id,
 
                    comm,
 
                    revision=revision,
 
                    dont_allow_on_closed_pull_request=True
 
                )
 
            except StatusChangeOnClosedPullRequestError:
 
                log.error(traceback.format_exc())
 
                msg = _('Changing status on a changeset associated with'
 
                        'a closed pull request is not allowed')
 
                h.flash(msg, category='warning')
 
                return redirect(h.url('changeset_home', repo_name=repo_name,
 
                                      revision=revision))
 
        action_logger(self.rhodecode_user,
 
                      'user_commented_revision:%s' % revision,
 
                      c.rhodecode_db_repo, self.ip_addr, self.sa)
 

	
 
        Session.commit()
 
        Session().commit()
 

	
 
        if not request.environ.get('HTTP_X_PARTIAL_XHR'):
 
            return redirect(h.url('changeset_home', repo_name=repo_name,
 
                                  revision=revision))
 

	
 
        data = {
 
@@ -419,10 +433,10 @@ class ChangesetController(BaseRepoContro
 
    @jsonify
 
    def delete_comment(self, repo_name, comment_id):
 
        co = ChangesetComment.get(comment_id)
 
        owner = lambda: co.author.user_id == c.rhodecode_user.user_id
 
        if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
 
            ChangesetCommentsModel().delete(comment=co)
 
            Session.commit()
 
            Session().commit()
 
            return True
 
        else:
 
            raise HTTPForbidden()
rhodecode/lib/exceptions.py
Show inline comments
 
@@ -47,6 +47,10 @@ class DefaultUserException(Exception):
 
class UserOwnsReposException(Exception):
 
    pass
 

	
 

	
 
class UsersGroupsAssignedException(Exception):
 
    pass
 

	
 

	
 
class StatusChangeOnClosedPullRequestError(Exception):
 
    pass
 
\ No newline at end of file
rhodecode/model/changeset_status.py
Show inline comments
 
@@ -25,12 +25,13 @@
 

	
 
import logging
 
from collections import  defaultdict
 

	
 
from rhodecode.model import BaseModel
 
from rhodecode.model.db import ChangesetStatus, PullRequest
 
from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class ChangesetStatusModel(BaseModel):
 

	
 
@@ -108,13 +109,13 @@ class ChangesetStatusModel(BaseModel):
 
        status = q.first()
 
        status = status.status if status else status
 
        st = status or ChangesetStatus.DEFAULT
 
        return str(st)
 

	
 
    def set_status(self, repo, status, user, comment, revision=None,
 
                   pull_request=None):
 
                   pull_request=None, dont_allow_on_closed_pull_request=False):
 
        """
 
        Creates new status for changeset or updates the old ones bumping their
 
        version, leaving the current status at
 

	
 
        :param repo:
 
        :type repo:
 
@@ -123,12 +124,15 @@ class ChangesetStatusModel(BaseModel):
 
        :param status:
 
        :type status:
 
        :param user:
 
        :type user:
 
        :param comment:
 
        :type comment:
 
        :param dont_allow_on_closed_pull_request: don't allow a status change
 
            if last status was for pull request and it's closed. We shouldn't
 
            mess around this manually
 
        """
 
        repo = self._get_repo(repo)
 

	
 
        q = ChangesetStatus.query()
 

	
 
        if revision:
 
@@ -137,12 +141,20 @@ class ChangesetStatusModel(BaseModel):
 
        elif pull_request:
 
            pull_request = self.__get_pull_request(pull_request)
 
            q = q.filter(ChangesetStatus.repo == pull_request.org_repo)
 
            q = q.filter(ChangesetStatus.pull_request == pull_request)
 
        cur_statuses = q.all()
 

	
 
        #if statuses exists and last is associated with a closed pull request
 
        # we need to check if we can allow this status change
 
        if (dont_allow_on_closed_pull_request and cur_statuses 
 
            and cur_statuses[0].pull_request.status == PullRequest.STATUS_CLOSED):
 
            raise StatusChangeOnClosedPullRequestError(
 
                'Changing status on closed pull request is not allowed'
 
            )
 

	
 
        if cur_statuses:
 
            for st in cur_statuses:
 
                st.version += 1
 
                self.sa.add(st)
 

	
 
        def _create_status(user, repo, status, comment, revision, pull_request):
rhodecode/model/db.py
Show inline comments
 
@@ -1446,13 +1446,13 @@ class ChangesetComment(Base, BaseModel):
 
    text = Column('text', Unicode(25000), nullable=False)
 
    created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
 
    modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
 

	
 
    author = relationship('User', lazy='joined')
 
    repo = relationship('Repository')
 
    status_change = relationship('ChangesetStatus', uselist=False)
 
    status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan")
 
    pull_request = relationship('PullRequest', lazy='joined')
 

	
 
    @classmethod
 
    def get_users(cls, revision=None, pull_request_id=None):
 
        """
 
        Returns user associated with this ChangesetComment. ie those
rhodecode/templates/changeset/changeset_file_comment.html
Show inline comments
 
@@ -14,14 +14,14 @@
 
  		<div class="date">
 
  			${h.age(co.modified_at)}
 
  		</div>
 
        %if co.status_change:
 
           <div  style="float:left" class="changeset-status-container">
 
             <div style="float:left;padding:0px 2px 0px 2px"><span style="font-size: 18px;">&rsaquo;</span></div>
 
             <div title="${_('Changeset status')}" class="changeset-status-lbl"> ${co.status_change.status_lbl}</div>
 
             <div class="changeset-status-ico"><img src="${h.url(str('/images/icons/flag_status_%s.png' % co.status_change.status))}" /></div>
 
             <div title="${_('Changeset status')}" class="changeset-status-lbl"> ${co.status_change[0].status_lbl}</div>
 
             <div class="changeset-status-ico"><img src="${h.url(str('/images/icons/flag_status_%s.png' % co.status_change[0].status))}" /></div>
 
           </div>
 
        %endif
 
      %if h.HasPermissionAny('hg.admin', 'repository.admin')() or co.author.user_id == c.rhodecode_user.user_id:
 
        <div class="buttons">
 
          <span onClick="deleteComment(${co.comment_id})" class="delete-comment ui-btn">${_('Delete')}</span>
 
        </div>
0 comments (0 inline, 0 general)