Line data Source code
1 : // Copyright (C) 2016 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.restapi.change; 16 : 17 : import static com.google.gerrit.server.project.ProjectCache.illegalState; 18 : 19 : import com.google.gerrit.extensions.client.ReviewerState; 20 : import com.google.gerrit.extensions.common.AccountVisibility; 21 : import com.google.gerrit.extensions.common.SuggestedReviewerInfo; 22 : import com.google.gerrit.extensions.restapi.AuthException; 23 : import com.google.gerrit.extensions.restapi.BadRequestException; 24 : import com.google.gerrit.extensions.restapi.Response; 25 : import com.google.gerrit.extensions.restapi.RestReadView; 26 : import com.google.gerrit.server.CurrentUser; 27 : import com.google.gerrit.server.change.ChangeResource; 28 : import com.google.gerrit.server.config.GerritServerConfig; 29 : import com.google.gerrit.server.permissions.PermissionBackend; 30 : import com.google.gerrit.server.permissions.PermissionBackendException; 31 : import com.google.gerrit.server.permissions.RefPermission; 32 : import com.google.gerrit.server.project.ProjectCache; 33 : import com.google.gerrit.server.restapi.change.ReviewersUtil.VisibilityControl; 34 : import com.google.inject.Inject; 35 : import com.google.inject.Provider; 36 : import java.io.IOException; 37 : import java.util.List; 38 : import org.eclipse.jgit.errors.ConfigInvalidException; 39 : import org.eclipse.jgit.lib.Config; 40 : import org.kohsuke.args4j.Option; 41 : 42 : public class SuggestChangeReviewers extends SuggestReviewers 43 : implements RestReadView<ChangeResource> { 44 : 45 : private final PermissionBackend permissionBackend; 46 : private final Provider<CurrentUser> self; 47 : private final ProjectCache projectCache; 48 : 49 : private boolean excludeGroups; 50 91 : private ReviewerState reviewerState = ReviewerState.REVIEWER; 51 : 52 : @Option( 53 : name = "--exclude-groups", 54 : aliases = {"-e"}, 55 : usage = "exclude groups from query") 56 : public SuggestChangeReviewers setExcludeGroups(boolean excludeGroups) { 57 1 : this.excludeGroups = excludeGroups; 58 1 : return this; 59 : } 60 : 61 : @Option( 62 : name = "--reviewer-state", 63 : usage = 64 : "The type of reviewers that should be suggested" 65 : + " (can be 'REVIEWER' or 'CC', default is 'REVIEWER')") 66 : public SuggestChangeReviewers setReviewerState(ReviewerState reviewerState) { 67 1 : this.reviewerState = reviewerState; 68 1 : return this; 69 : } 70 : 71 : @Inject 72 : SuggestChangeReviewers( 73 : AccountVisibility av, 74 : PermissionBackend permissionBackend, 75 : Provider<CurrentUser> self, 76 : @GerritServerConfig Config cfg, 77 : ReviewersUtil reviewersUtil, 78 : ProjectCache projectCache) { 79 91 : super(av, cfg, reviewersUtil); 80 91 : this.permissionBackend = permissionBackend; 81 91 : this.self = self; 82 91 : this.projectCache = projectCache; 83 91 : } 84 : 85 : @Override 86 : public Response<List<SuggestedReviewerInfo>> apply(ChangeResource rsrc) 87 : throws AuthException, BadRequestException, IOException, ConfigInvalidException, 88 : PermissionBackendException { 89 2 : if (!self.get().isIdentifiedUser()) { 90 0 : throw new AuthException("Authentication required"); 91 : } 92 2 : if (reviewerState.equals(ReviewerState.REMOVED)) { 93 0 : throw new BadRequestException( 94 0 : String.format("Unsupported reviewer state: %s", ReviewerState.REMOVED)); 95 : } 96 : 97 2 : return Response.ok( 98 2 : reviewersUtil.suggestReviewers( 99 : reviewerState, 100 2 : rsrc.getNotes(), 101 : this, 102 2 : projectCache.get(rsrc.getProject()).orElseThrow(illegalState(rsrc.getProject())), 103 2 : getVisibility(rsrc), 104 : excludeGroups)); 105 : } 106 : 107 : private VisibilityControl getVisibility(ChangeResource rsrc) { 108 : 109 2 : return account -> { 110 : // Use the destination reference, not the change, as private changes deny anyone who is not 111 : // already a reviewer. 112 1 : return permissionBackend 113 1 : .absentUser(account) 114 1 : .ref(rsrc.getChange().getDest()) 115 1 : .testOrFalse(RefPermission.READ); 116 : }; 117 : } 118 : }