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.account; 16 : 17 : import com.google.common.flogger.FluentLogger; 18 : import com.google.gerrit.entities.AccountGroup; 19 : import com.google.gerrit.entities.ContributorAgreement; 20 : import com.google.gerrit.entities.PermissionRule; 21 : import com.google.gerrit.entities.PermissionRule.Action; 22 : import com.google.gerrit.extensions.common.AgreementInfo; 23 : import com.google.gerrit.extensions.restapi.AuthException; 24 : import com.google.gerrit.extensions.restapi.MethodNotAllowedException; 25 : import com.google.gerrit.extensions.restapi.Response; 26 : import com.google.gerrit.extensions.restapi.RestApiException; 27 : import com.google.gerrit.extensions.restapi.RestReadView; 28 : import com.google.gerrit.server.CurrentUser; 29 : import com.google.gerrit.server.IdentifiedUser; 30 : import com.google.gerrit.server.account.AccountResource; 31 : import com.google.gerrit.server.config.GerritServerConfig; 32 : import com.google.gerrit.server.permissions.GlobalPermission; 33 : import com.google.gerrit.server.permissions.PermissionBackend; 34 : import com.google.gerrit.server.permissions.PermissionBackendException; 35 : import com.google.gerrit.server.project.ProjectCache; 36 : import com.google.gerrit.server.restapi.config.AgreementJson; 37 : import com.google.inject.Inject; 38 : import com.google.inject.Provider; 39 : import com.google.inject.Singleton; 40 : import java.util.ArrayList; 41 : import java.util.Collection; 42 : import java.util.List; 43 : import org.eclipse.jgit.lib.Config; 44 : 45 : /** 46 : * REST endpoint to get all contributor agreements that have been signed by an account. 47 : * 48 : * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/agreements} requests. 49 : * 50 : * <p>Contributor agreements are only available if contributor agreements have been enabled in 51 : * {@code gerrit.config} (see {@code auth.contributorAgreements}). 52 : */ 53 : @Singleton 54 : public class GetAgreements implements RestReadView<AccountResource> { 55 148 : private static final FluentLogger logger = FluentLogger.forEnclosingClass(); 56 : 57 : private final Provider<CurrentUser> self; 58 : private final ProjectCache projectCache; 59 : private final AgreementJson agreementJson; 60 : private final boolean agreementsEnabled; 61 : private final PermissionBackend permissionBackend; 62 : 63 : @Inject 64 : GetAgreements( 65 : Provider<CurrentUser> self, 66 : ProjectCache projectCache, 67 : AgreementJson agreementJson, 68 : PermissionBackend permissionBackend, 69 148 : @GerritServerConfig Config config) { 70 148 : this.self = self; 71 148 : this.projectCache = projectCache; 72 148 : this.agreementJson = agreementJson; 73 148 : this.agreementsEnabled = config.getBoolean("auth", "contributorAgreements", false); 74 148 : this.permissionBackend = permissionBackend; 75 148 : } 76 : 77 : @Override 78 : public Response<List<AgreementInfo>> apply(AccountResource resource) 79 : throws RestApiException, PermissionBackendException { 80 1 : if (!agreementsEnabled) { 81 1 : throw new MethodNotAllowedException("contributor agreements disabled"); 82 : } 83 : 84 1 : if (!self.get().isIdentifiedUser()) { 85 0 : throw new AuthException("not allowed to get contributor agreements"); 86 : } 87 : 88 1 : IdentifiedUser user = self.get().asIdentifiedUser(); 89 1 : if (user != resource.getUser()) { 90 1 : if (!permissionBackend.user(user).test(GlobalPermission.ADMINISTRATE_SERVER)) { 91 1 : throw new AuthException("not allowed to get contributor agreements"); 92 : } 93 : } 94 : 95 1 : List<AgreementInfo> results = new ArrayList<>(); 96 1 : Collection<ContributorAgreement> cas = 97 1 : projectCache.getAllProjects().getConfig().getContributorAgreements().values(); 98 1 : for (ContributorAgreement ca : cas) { 99 1 : List<AccountGroup.UUID> groupIds = new ArrayList<>(); 100 1 : for (PermissionRule rule : ca.getAccepted()) { 101 1 : if ((rule.getAction() == Action.ALLOW) && (rule.getGroup() != null)) { 102 1 : if (rule.getGroup().getUUID() != null) { 103 1 : groupIds.add(rule.getGroup().getUUID()); 104 : } else { 105 0 : logger.atWarning().log( 106 : "group \"%s\" does not exist, referenced in CLA \"%s\"", 107 0 : rule.getGroup().getName(), ca.getName()); 108 : } 109 : } 110 1 : } 111 : 112 1 : if (user.getEffectiveGroups().containsAnyOf(groupIds)) { 113 1 : results.add(agreementJson.format(ca)); 114 : } 115 1 : } 116 1 : return Response.ok(results); 117 : } 118 : }