Mercurial > kallithea
changeset 6525:bcc67f909d9f
pullrequests: pass around reviewer User objects, not IDs
This moves reviewer user validation into the controller and eliminates
the UserInvalidException.
author | Søren Løvborg <sorenl@unity3d.com> |
---|---|
date | Mon, 27 Feb 2017 15:38:20 +0100 |
parents | d32a2218b525 |
children | 33a44dd50a87 |
files | kallithea/controllers/pullrequests.py kallithea/lib/exceptions.py kallithea/model/pull_request.py |
diffstat | 3 files changed, 53 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/kallithea/controllers/pullrequests.py Mon Feb 27 15:44:49 2017 +0100 +++ b/kallithea/controllers/pullrequests.py Mon Feb 27 15:38:20 2017 +0100 @@ -42,7 +42,6 @@ from kallithea.lib.base import BaseRepoController, render, jsonify from kallithea.lib.compat import json, OrderedDict from kallithea.lib.diffs import LimitedDiffContainer -from kallithea.lib.exceptions import UserInvalidException from kallithea.lib.page import Page from kallithea.lib.utils import action_logger from kallithea.lib.vcs.exceptions import EmptyRepositoryError, ChangesetDoesNotExistError @@ -65,6 +64,20 @@ log = logging.getLogger(__name__) +def _get_reviewer(user_id): + """Look up user by ID and validate it as a potential reviewer.""" + try: + user = User.get(int(user_id)) + except ValueError: + user = None + + if user is None or user.is_default_user: + h.flash(_('Invalid reviewer "%s" specified') % user_id, category='error') + raise HTTPBadRequest() + + return user + + class PullrequestsController(BaseRepoController): def _get_repo_refs(self, repo, rev=None, branch=None, branch_rev=None): @@ -363,7 +376,7 @@ # requested destination and have the exact ancestor other_ref = '%s:%s:%s' % (other_ref_type, other_ref_name, ancestor_rev) - reviewer_ids = [] + reviewers = [] title = _form['pullrequest_title'] if not title: @@ -377,13 +390,10 @@ created_by = User.get(request.authuser.user_id) pull_request = PullRequestModel().create( created_by, org_repo, org_ref, other_repo, other_ref, revisions, - title, description, reviewer_ids) + title, description, reviewers) Session().commit() h.flash(_('Successfully opened new pull request'), category='success') - except UserInvalidException as u: - h.flash(_('Invalid reviewer "%s" specified') % u, category='error') - raise HTTPBadRequest() except Exception: h.flash(_('Error occurred while creating pull request'), category='error') @@ -392,7 +402,7 @@ raise HTTPFound(location=pull_request.url()) - def create_new_iteration(self, old_pull_request, new_rev, title, description, reviewer_ids): + def create_new_iteration(self, old_pull_request, new_rev, title, description, reviewers): org_repo = old_pull_request.org_repo org_ref_type, org_ref_name, org_rev = old_pull_request.org_ref.split(':') new_org_rev = self._get_ref_rev(org_repo, 'rev', new_rev) @@ -478,10 +488,7 @@ created_by = User.get(request.authuser.user_id) pull_request = PullRequestModel().create( created_by, org_repo, new_org_ref, other_repo, new_other_ref, revisions, - title, description, reviewer_ids) - except UserInvalidException as u: - h.flash(_('Invalid reviewer "%s" specified') % u, category='error') - raise HTTPBadRequest() + title, description, reviewers) except Exception: h.flash(_('Error occurred while creating pull request'), category='error') @@ -518,12 +525,14 @@ raise HTTPForbidden() _form = PullRequestPostForm()().to_python(request.POST) - reviewer_ids = set(int(s) for s in _form['review_members']) - org_reviewer_ids = set(int(s) for s in _form['org_review_members']) - current_reviewer_ids = set(prr.user_id for prr in pull_request.reviewers) - other_added = [User.get(u) for u in current_reviewer_ids - org_reviewer_ids] - other_removed = [User.get(u) for u in org_reviewer_ids - current_reviewer_ids] + 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)), @@ -538,22 +547,20 @@ _form['updaterev'], _form['pullrequest_title'], _form['pullrequest_desc'], - reviewer_ids) + 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) - add_reviewer_ids = reviewer_ids - org_reviewer_ids - current_reviewer_ids - remove_reviewer_ids = (org_reviewer_ids - reviewer_ids) & current_reviewer_ids - try: - PullRequestModel().mention_from_description(user, pull_request, old_description) - PullRequestModel().add_reviewers(user, pull_request, add_reviewer_ids) - PullRequestModel().remove_reviewers(user, pull_request, remove_reviewer_ids) - except UserInvalidException as u: - h.flash(_('Invalid reviewer "%s" specified') % u, category='error') - raise HTTPBadRequest() + + 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')
--- a/kallithea/lib/exceptions.py Mon Feb 27 15:44:49 2017 +0100 +++ b/kallithea/lib/exceptions.py Mon Feb 27 15:38:20 2017 +0100 @@ -99,10 +99,6 @@ pass -class UserInvalidException(Exception): - pass - - class RepositoryCreationError(Exception): pass
--- a/kallithea/model/pull_request.py Mon Feb 27 15:44:49 2017 +0100 +++ b/kallithea/model/pull_request.py Mon Feb 27 15:38:20 2017 +0100 @@ -34,9 +34,8 @@ from kallithea.model.meta import Session from kallithea.lib import helpers as h -from kallithea.lib.exceptions import UserInvalidException from kallithea.model.db import PullRequest, PullRequestReviewer, Notification, \ - ChangesetStatus, User + ChangesetStatus from kallithea.model.notification import NotificationModel from kallithea.lib.utils2 import extract_mentioned_users, safe_unicode @@ -44,21 +43,18 @@ log = logging.getLogger(__name__) -class PullRequestModel(object): +def _assert_valid_reviewers(seq): + """Sanity check: elements are actual User objects, and not the default user.""" + assert not any(user.is_default_user for user in seq) - def _get_valid_reviewers(self, seq): - """ Generate User objects from a sequence of user IDs, usernames or - User objects. Raises UserInvalidException if the DEFAULT user is - specified, or if a given ID or username does not match any user. - """ - for user_spec in seq: - user = User.guess_instance(user_spec) - if user is None or user.is_default_user: - raise UserInvalidException(user_spec) - yield user + +class PullRequestModel(object): def create(self, created_by, org_repo, org_ref, other_repo, other_ref, revisions, title, description, reviewers): + reviewers = set(reviewers) + _assert_valid_reviewers(reviewers) + pr = PullRequest() pr.org_repo = org_repo pr.org_ref = org_ref @@ -90,7 +86,6 @@ pull_request=pr, ) - reviewers = set(self._get_valid_reviewers(reviewers)) mention_recipients = extract_mentioned_users(description) self.add_reviewers(created_by, pr, reviewers, mention_recipients) @@ -99,9 +94,14 @@ def add_reviewers(self, user, pr, reviewers, mention_recipients=None): """Add reviewer and send notification to them. """ - reviewer_users = set(self._get_valid_reviewers(reviewers)) + reviewers = set(reviewers) + _assert_valid_reviewers(reviewers) + if mention_recipients is not None: + mention_recipients = set(mention_recipients) - reviewers + _assert_valid_reviewers(mention_recipients) + #members - for reviewer in reviewer_users: + for reviewer in reviewers: prr = PullRequestReviewer(reviewer, pr) Session().add(prr) @@ -151,16 +151,12 @@ type_=Notification.TYPE_PULL_REQUEST, email_kwargs=email_kwargs) - mention_recipient_users = set() if mention_recipients: - mention_recipient_users = set(self._get_valid_reviewers(mention_recipients)) - mention_recipient_users.difference_update(reviewers) - if mention_recipient_users: email_kwargs['is_mention'] = True subject = _('[Mention]') + ' ' + subject # FIXME: this subject is wrong and unused! NotificationModel().create(created_by=user, subject=subject, body=body, - recipients=mention_recipient_users, + recipients=mention_recipients, type_=Notification.TYPE_PULL_REQUEST, email_kwargs=email_kwargs) @@ -171,12 +167,12 @@ log.debug("Mentioning %s", mention_recipients) self.add_reviewers(user, pr, set(), mention_recipients) - def remove_reviewers(self, user, pull_request, reviewer_ids): - """Remove users in the given user_id list from being reviewers of the PR.""" + def remove_reviewers(self, user, pull_request, reviewers): + """Remove specified users from being reviewers of the PR.""" PullRequestReviewer.query() \ .filter_by(pull_request=pull_request) \ - .filter(PullRequestReviewer.user_id.in_(reviewer_ids)) \ + .filter(PullRequestReviewer.user_id.in_(r.user_id for r in reviewers)) \ .delete(synchronize_session='fetch') # the default of 'evaluate' is not available def delete(self, pull_request):