예제 #1
0
    def post(self, repo_name, pull_request_id):
        pull_request = PullRequest.get_or_404(pull_request_id)
        if pull_request.is_closed():
            raise HTTPForbidden()
        assert pull_request.other_repo.repo_name == repo_name
        #only owner or admin can update it
        owner = pull_request.author.user_id == c.authuser.user_id
        repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name)
        if not (h.HasPermissionAny('hg.admin') or repo_admin or owner):
            raise HTTPForbidden()

        _form = PullRequestPostForm()().to_python(request.POST)
        reviewers_ids = [int(s) for s in _form['review_members']]

        if _form['updaterev']:
            return self.create_update(pull_request, _form['updaterev'],
                                      _form['pullrequest_title'],
                                      _form['pullrequest_desc'], reviewers_ids)

        old_description = pull_request.description
        pull_request.title = _form['pullrequest_title']
        pull_request.description = _form['pullrequest_desc'].strip() or _(
            'No description')
        PullRequestModel().mention_from_description(pull_request,
                                                    old_description)

        PullRequestModel().update_reviewers(pull_request_id, reviewers_ids)

        Session().commit()
        h.flash(_('Pull request updated'), category='success')

        return redirect(pull_request.url())
예제 #2
0
    def post(self, repo_name, pull_request_id):
        pull_request = PullRequest.get_or_404(pull_request_id)
        if pull_request.is_closed():
            raise HTTPForbidden()
        assert pull_request.other_repo.repo_name == repo_name
        # only owner or admin can update it
        owner = pull_request.owner_id == request.authuser.user_id
        repo_admin = h.HasRepoPermissionLevel('admin')(c.repo_name)
        if not (h.HasPermissionAny('hg.admin')() or repo_admin or owner):
            raise HTTPForbidden()

        _form = PullRequestPostForm()().to_python(request.POST)

        cur_reviewers = set(pull_request.get_reviewer_users())
        new_reviewers = set(_get_reviewer(s) for s in _form['review_members'])
        old_reviewers = set(
            _get_reviewer(s) for s in _form['org_review_members'])

        other_added = cur_reviewers - old_reviewers
        other_removed = old_reviewers - cur_reviewers

        if other_added:
            h.flash(
                _('Meanwhile, the following reviewers have been added: %s') %
                (', '.join(u.username for u in other_added)),
                category='warning')
        if other_removed:
            h.flash(
                _('Meanwhile, the following reviewers have been removed: %s') %
                (', '.join(u.username for u in other_removed)),
                category='warning')

        if _form['updaterev']:
            return self.create_new_iteration(pull_request, _form['updaterev'],
                                             _form['pullrequest_title'],
                                             _form['pullrequest_desc'],
                                             new_reviewers)

        added_reviewers = new_reviewers - old_reviewers - cur_reviewers
        removed_reviewers = (old_reviewers - new_reviewers) & cur_reviewers

        old_description = pull_request.description
        pull_request.title = _form['pullrequest_title']
        pull_request.description = _form['pullrequest_desc'].strip() or _(
            'No description')
        pull_request.owner = User.get_by_username(_form['owner'])
        user = User.get(request.authuser.user_id)

        PullRequestModel().mention_from_description(user, pull_request,
                                                    old_description)
        PullRequestModel().add_reviewers(user, pull_request, added_reviewers)
        PullRequestModel().remove_reviewers(user, pull_request,
                                            removed_reviewers)

        Session().commit()
        h.flash(_('Pull request updated'), category='success')

        raise HTTPFound(location=pull_request.url())
예제 #3
0
 def delete_comment(self, repo_name, comment_id):
     co = ChangesetComment.get(comment_id)
     if not co:
         raise HTTPBadRequest()
     owner = co.author.user_id == c.authuser.user_id
     repo_admin = h.HasRepoPermissionAny('repository.admin')
     if h.HasPermissionAny('hg.admin')() or repo_admin or owner:
         ChangesetCommentsModel().delete(comment=co)
         Session().commit()
         return True
     else:
         raise HTTPForbidden()
예제 #4
0
 def delete_comment(self, repo_name, comment_id):
     co = ChangesetComment.get_or_404(comment_id)
     if co.repo.repo_name != repo_name:
         raise HTTPNotFound()
     owner = co.author_id == request.authuser.user_id
     repo_admin = h.HasRepoPermissionLevel('admin')(repo_name)
     if h.HasPermissionAny('hg.admin')() or repo_admin or owner:
         ChangesetCommentsModel().delete(comment=co)
         Session().commit()
         return True
     else:
         raise HTTPForbidden()
예제 #5
0
    def delete(self, gist_id):
        gist = GistModel().get_gist(gist_id)
        owner = gist.owner_id == request.authuser.user_id
        if h.HasPermissionAny('hg.admin')() or owner:
            GistModel().delete(gist)
            Session().commit()
            h.flash(_('Deleted gist %s') % gist.gist_access_id,
                    category='success')
        else:
            raise HTTPForbidden()

        raise HTTPFound(location=url('gists'))
예제 #6
0
 def update(self, notification_id):
     try:
         no = Notification.get(notification_id)
         owner = all(un.user_id == request.authuser.user_id
                     for un in no.notifications_to_users)
         if h.HasPermissionAny('hg.admin')() or owner:
             # deletes only notification2user
             NotificationModel().mark_read(request.authuser.user_id, no)
             Session().commit()
             return 'ok'
     except Exception:
         Session().rollback()
         log.error(traceback.format_exc())
     raise HTTPBadRequest()
예제 #7
0
    def delete_comment(self, repo_name, comment_id):
        co = ChangesetComment.get(comment_id)
        if co.pull_request.is_closed():
            #don't allow deleting comments on closed pull request
            raise HTTPForbidden()

        owner = co.author_id == request.authuser.user_id
        repo_admin = h.HasRepoPermissionLevel('admin')(c.repo_name)
        if h.HasPermissionAny('hg.admin')() or repo_admin or owner:
            ChangesetCommentsModel().delete(comment=co)
            Session().commit()
            return True
        else:
            raise HTTPForbidden()
예제 #8
0
    def is_user_authorized(old_pull_request):
        """Performs authorization check with only the minimum amount of
        information needed for such a check, rather than a full command
        object.
        """
        if h.HasPermissionAny('hg.admin')():
            return True

        # Authorized to edit the old PR?
        if request.authuser.user_id != old_pull_request.owner_id:
            return False

        # Authorized to create a new PR?
        if not CreatePullRequestAction.is_user_authorized(old_pull_request.org_repo, old_pull_request.other_repo):
            return False

        return True
예제 #9
0
def delete_cs_pr_comment(repo_name, comment_id):
    """Delete a comment from a changeset or pull request"""
    co = ChangesetComment.get_or_404(comment_id)
    if co.repo.repo_name != repo_name:
        raise HTTPNotFound()
    if co.pull_request and co.pull_request.is_closed():
        # don't allow deleting comments on closed pull request
        raise HTTPForbidden()

    owner = co.author_id == request.authuser.user_id
    repo_admin = h.HasRepoPermissionLevel('admin')(repo_name)
    if h.HasPermissionAny('hg.admin')() or repo_admin or owner:
        ChangesetCommentsModel().delete(comment=co)
        Session().commit()
        return True
    else:
        raise HTTPForbidden()
예제 #10
0
    def delete(self, gist_id):
        """DELETE /admin/gists/gist_id: Delete an existing item"""
        # Forms posted to this method should contain a hidden field:
        #    <input type="hidden" name="_method" value="DELETE" />
        # Or using helpers:
        #    h.form(url('gist', gist_id=ID),
        #           method='delete')
        # url('gist', gist_id=ID)
        gist = GistModel().get_gist(gist_id)
        owner = gist.gist_owner == c.authuser.user_id
        if h.HasPermissionAny('hg.admin')() or owner:
            GistModel().delete(gist)
            Session().commit()
            h.flash(_('Deleted gist %s') % gist.gist_access_id, category='success')
        else:
            raise HTTPForbidden()

        return redirect(url('gists'))
예제 #11
0
 def delete(self, notification_id):
     """DELETE /_admin/notifications/id: Delete an existing item"""
     # Forms posted to this method should contain a hidden field:
     #    <input type="hidden" name="_method" value="DELETE" />
     # Or using helpers:
     #    h.form(url('notification', notification_id=ID),
     #           method='delete')
     # url('notification', notification_id=ID)
     try:
         no = Notification.get(notification_id)
         owner = any(un.user.user_id == c.authuser.user_id
                     for un in no.notifications_to_users)
         if h.HasPermissionAny('hg.admin')() or owner:
             # deletes only notification2user
             NotificationModel().delete(c.authuser.user_id, no)
             Session().commit()
             return 'ok'
     except Exception:
         Session().rollback()
         log.error(traceback.format_exc())
     raise HTTPBadRequest()
예제 #12
0
    def show(self, notification_id, format='html'):
        """GET /_admin/notifications/id: Show a specific item"""
        # url('notification', notification_id=ID)
        c.user = self.authuser
        no = Notification.get(notification_id)

        owner = any(un.user.user_id == c.authuser.user_id
                    for un in no.notifications_to_users)
        repo_admin = h.HasRepoPermissionAny('repository.admin')
        if no and (h.HasPermissionAny('hg.admin')() or repo_admin or owner):
            unotification = NotificationModel()\
                            .get_user_notification(c.user.user_id, no)

            # if this association to user is not valid, we don't want to show
            # this message
            if unotification:
                if not unotification.read:
                    unotification.mark_as_read()
                    Session().commit()
                c.notification = no

                return render('admin/notifications/show_notification.html')

        return abort(403)
예제 #13
0
def create_cs_pr_comment(repo_name,
                         revision=None,
                         pull_request=None,
                         allowed_to_change_status=True):
    """
    Add a comment to the specified changeset or pull request, using POST values
    from the request.

    Comments can be inline (when a file path and line number is specified in
    POST) or general comments.
    A comment can be accompanied by a review status change (accepted, rejected,
    etc.). Pull requests can be closed or deleted.

    Parameter 'allowed_to_change_status' is used for both status changes and
    closing of pull requests. For deleting of pull requests, more specific
    checks are done.
    """

    assert request.environ.get('HTTP_X_PARTIAL_XHR')
    if pull_request:
        pull_request_id = pull_request.pull_request_id
    else:
        pull_request_id = None

    status = request.POST.get('changeset_status')
    close_pr = request.POST.get('save_close')
    delete = request.POST.get('save_delete')
    f_path = request.POST.get('f_path')
    line_no = request.POST.get('line')

    if (status or close_pr or delete) and (f_path or line_no):
        # status votes and closing is only possible in general comments
        raise HTTPBadRequest()

    if not allowed_to_change_status:
        if status or close_pr:
            h.flash(_('No permission to change status'), 'error')
            raise HTTPForbidden()

    if pull_request and delete == "delete":
        if (pull_request.owner_id == request.authuser.user_id
                or h.HasPermissionAny('hg.admin')()
                or h.HasRepoPermissionLevel('admin')(
                    pull_request.org_repo.repo_name)
                or h.HasRepoPermissionLevel('admin')(
                    pull_request.other_repo.repo_name)
            ) and not pull_request.is_closed():
            PullRequestModel().delete(pull_request)
            Session().commit()
            h.flash(_('Successfully deleted pull request %s') %
                    pull_request_id,
                    category='success')
            return {
                'location': h.url('my_pullrequests'),  # or repo pr list?
            }
        raise HTTPForbidden()

    text = request.POST.get('text', '').strip()

    comment = ChangesetCommentsModel().create(
        text=text,
        repo=c.db_repo.repo_id,
        author=request.authuser.user_id,
        revision=revision,
        pull_request=pull_request_id,
        f_path=f_path or None,
        line_no=line_no or None,
        status_change=ChangesetStatus.get_status_lbl(status)
        if status else None,
        closing_pr=close_pr,
    )

    if status:
        ChangesetStatusModel().set_status(
            c.db_repo.repo_id,
            status,
            request.authuser.user_id,
            comment,
            revision=revision,
            pull_request=pull_request_id,
        )

    if pull_request:
        action = 'user_commented_pull_request:%s' % pull_request_id
    else:
        action = 'user_commented_revision:%s' % revision
    action_logger(request.authuser, action, c.db_repo, request.ip_addr)

    if pull_request and close_pr:
        PullRequestModel().close_pull_request(pull_request_id)
        action_logger(request.authuser,
                      'user_closed_pull_request:%s' % pull_request_id,
                      c.db_repo, request.ip_addr)

    Session().commit()

    data = {
        'target_id': h.safeid(request.POST.get('f_path')),
    }
    if comment is not None:
        c.comment = comment
        data.update(comment.get_dict())
        data.update({
            'rendered_text':
            render('changeset/changeset_comment_block.html')
        })

    return data
예제 #14
0
    def comment(self, repo_name, pull_request_id):
        pull_request = PullRequest.get_or_404(pull_request_id)

        status = request.POST.get('changeset_status')
        close_pr = request.POST.get('save_close')
        delete = request.POST.get('save_delete')
        f_path = request.POST.get('f_path')
        line_no = request.POST.get('line')

        if (status or close_pr or delete) and (f_path or line_no):
            # status votes and closing is only possible in general comments
            raise HTTPBadRequest()

        allowed_to_change_status = self._get_is_allowed_change_status(pull_request)
        if not allowed_to_change_status:
            if status or close_pr:
                h.flash(_('No permission to change pull request status'), 'error')
                raise HTTPForbidden()

        if delete == "delete":
            if (pull_request.owner_id == request.authuser.user_id or
                h.HasPermissionAny('hg.admin')() or
                h.HasRepoPermissionLevel('admin')(pull_request.org_repo.repo_name) or
                h.HasRepoPermissionLevel('admin')(pull_request.other_repo.repo_name)
                ) and not pull_request.is_closed():
                PullRequestModel().delete(pull_request)
                Session().commit()
                h.flash(_('Successfully deleted pull request %s') % pull_request_id,
                        category='success')
                return {
                   'location': url('my_pullrequests'), # or repo pr list?
                }
                raise HTTPFound(location=url('my_pullrequests')) # or repo pr list?
            raise HTTPForbidden()

        text = request.POST.get('text', '').strip()

        comment = create_comment(
            text,
            status,
            pull_request_id=pull_request_id,
            f_path=f_path,
            line_no=line_no,
            closing_pr=close_pr,
        )

        action_logger(request.authuser,
                      'user_commented_pull_request:%s' % pull_request_id,
                      c.db_repo, request.ip_addr)

        if status:
            ChangesetStatusModel().set_status(
                c.db_repo.repo_id,
                status,
                request.authuser.user_id,
                comment,
                pull_request=pull_request_id
            )

        if close_pr:
            PullRequestModel().close_pull_request(pull_request_id)
            action_logger(request.authuser,
                          'user_closed_pull_request:%s' % pull_request_id,
                          c.db_repo, request.ip_addr)

        Session().commit()

        if not request.environ.get('HTTP_X_PARTIAL_XHR'):
            raise HTTPFound(location=pull_request.url())

        data = {
           'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
        }
        if comment is not None:
            c.comment = comment
            data.update(comment.get_dict())
            data.update({'rendered_text':
                         render('changeset/changeset_comment_block.html')})

        return data