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.schema; 16 : 17 : import static com.google.gerrit.server.project.ProjectConfig.ACCESS; 18 : import static java.util.stream.Collectors.toList; 19 : 20 : import com.google.common.annotations.VisibleForTesting; 21 : import com.google.gerrit.entities.PermissionRule; 22 : import com.google.gerrit.entities.RefNames; 23 : import com.google.gerrit.exceptions.StorageException; 24 : import com.google.gerrit.server.config.AllProjectsConfigProvider; 25 : import com.google.gerrit.server.config.AllProjectsName; 26 : import com.google.gerrit.server.git.meta.MetaDataUpdate; 27 : import com.google.gerrit.server.git.meta.VersionedMetaData; 28 : import com.google.gerrit.server.project.ProjectConfig; 29 : import com.google.inject.Inject; 30 : import java.io.IOException; 31 : import java.util.Arrays; 32 : import java.util.List; 33 : import java.util.Optional; 34 : import java.util.Set; 35 : import org.eclipse.jgit.errors.ConfigInvalidException; 36 : import org.eclipse.jgit.lib.CommitBuilder; 37 : import org.eclipse.jgit.lib.Config; 38 : import org.eclipse.jgit.lib.PersonIdent; 39 : import org.eclipse.jgit.lib.StoredConfig; 40 : 41 : public class ProjectConfigSchemaUpdate extends VersionedMetaData { 42 : public static class Factory { 43 : private final AllProjectsName allProjectsName; 44 : private final AllProjectsConfigProvider allProjectsConfigProvider; 45 : 46 : @Inject 47 1 : Factory(AllProjectsName allProjectsName, AllProjectsConfigProvider allProjectsConfigProvider) { 48 1 : this.allProjectsName = allProjectsName; 49 1 : this.allProjectsConfigProvider = allProjectsConfigProvider; 50 1 : } 51 : 52 : ProjectConfigSchemaUpdate read(MetaDataUpdate update) 53 : throws IOException, ConfigInvalidException { 54 1 : ProjectConfigSchemaUpdate r = 55 1 : new ProjectConfigSchemaUpdate(update, allProjectsConfigProvider.get(allProjectsName)); 56 1 : r.load(update); 57 1 : return r; 58 : } 59 : } 60 : 61 : private final MetaDataUpdate update; 62 : private final Optional<StoredConfig> baseConfig; 63 : private Config config; 64 : private boolean updated; 65 : 66 1 : private ProjectConfigSchemaUpdate(MetaDataUpdate update, Optional<StoredConfig> baseConfig) { 67 1 : this.update = update; 68 1 : this.baseConfig = baseConfig; 69 1 : } 70 : 71 : @Override 72 : protected String getRefName() { 73 1 : return RefNames.REFS_CONFIG; 74 : } 75 : 76 : @Override 77 : protected void onLoad() throws IOException, ConfigInvalidException { 78 1 : if (baseConfig.isPresent()) { 79 1 : baseConfig.get().load(); 80 : } 81 1 : config = readConfig(ProjectConfig.PROJECT_CONFIG, baseConfig); 82 1 : } 83 : 84 : @VisibleForTesting 85 : Config getConfig() { 86 1 : return config; 87 : } 88 : 89 : public void removeForceFromPermission(String name) { 90 0 : for (String subsection : config.getSubsections(ACCESS)) { 91 0 : Set<String> names = config.getNames(ACCESS, subsection); 92 0 : if (names.contains(name)) { 93 0 : List<String> values = 94 0 : Arrays.stream(config.getStringList(ACCESS, subsection, name)) 95 0 : .map( 96 : r -> { 97 0 : PermissionRule rule = PermissionRule.fromString(r, false); 98 0 : if (rule.getForce()) { 99 0 : rule = rule.toBuilder().setForce(false).build(); 100 0 : updated = true; 101 : } 102 0 : return rule.asString(false); 103 : }) 104 0 : .collect(toList()); 105 0 : config.setStringList(ACCESS, subsection, name, values); 106 : } 107 0 : } 108 0 : } 109 : 110 : @Override 111 : protected boolean onSave(CommitBuilder commit) throws IOException, ConfigInvalidException { 112 0 : saveConfig(ProjectConfig.PROJECT_CONFIG, config); 113 0 : return true; 114 : } 115 : 116 : public void save(PersonIdent personIdent, String commitMessage) { 117 0 : if (!updated) { 118 0 : return; 119 : } 120 : 121 0 : update.getCommitBuilder().setAuthor(personIdent); 122 0 : update.getCommitBuilder().setCommitter(personIdent); 123 0 : update.setMessage(commitMessage); 124 : try { 125 0 : commit(update); 126 0 : } catch (IOException e) { 127 0 : throw new StorageException(e); 128 0 : } 129 0 : } 130 : 131 : public boolean isUpdated() { 132 0 : return updated; 133 : } 134 : }