blob: cd6da553273e10e37c12be73ea65335c334a3187 [file] [log] [blame]
// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.schema;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.common.data.PermissionRule.Action;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.project.RefPattern;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Optional;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
/** Make default Label-Code-Review permission on user branches exclusive. */
public class Schema_165 extends SchemaVersion {
private static final String COMMIT_MSG =
"Make default Label-Code-Review permission on user branches exclusive";
private final GitRepositoryManager repoManager;
private final AllUsersName allUsersName;
private final SystemGroupBackend systemGroupBackend;
private final PersonIdent serverUser;
@Inject
Schema_165(
Provider<Schema_164> prior,
GitRepositoryManager repoManager,
AllUsersName allUsersName,
SystemGroupBackend systemGroupBackend,
@GerritPersonIdent PersonIdent serverUser) {
super(prior);
this.repoManager = repoManager;
this.allUsersName = allUsersName;
this.systemGroupBackend = systemGroupBackend;
this.serverUser = serverUser;
}
@Override
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException {
try (Repository git = repoManager.openRepository(allUsersName);
MetaDataUpdate md = new MetaDataUpdate(GitReferenceUpdated.DISABLED, allUsersName, git)) {
ProjectConfig config = ProjectConfig.read(md);
Optional<Permission> permission = findDefaultPermission(config);
if (!permission.isPresent()) {
// the default permission was not found, hence it cannot be fixed
return;
}
permission.get().setExclusiveGroup(true);
md.getCommitBuilder().setAuthor(serverUser);
md.getCommitBuilder().setCommitter(serverUser);
md.setMessage(COMMIT_MSG);
config.commit(md);
} catch (IOException | ConfigInvalidException e) {
throw new OrmException(
"Failed to make default Label-Code-Review permission on user branches exclusive", e);
}
}
/**
* Searches for the default "Label-Code-Review" permission on the user branch and returns it if it
* was found. If it was not found (e.g. because it was removed or modified) {@link
* Optional#empty()} is returned.
*/
private Optional<Permission> findDefaultPermission(ProjectConfig config) {
AccessSection users =
config.getAccessSection(
RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}", false);
if (users == null) {
// default permission was removed
return Optional.empty();
}
Permission permission = users.getPermission(Permission.LABEL + "Code-Review", false);
return isDefaultPermissionUntouched(permission) ? Optional.of(permission) : Optional.empty();
}
/**
* Checks whether the given permission matches the default "Label-Code-Review" permission on the
* user branch that was initially setup by {@link AllUsersCreator}.
*/
private boolean isDefaultPermissionUntouched(Permission permission) {
if (permission == null) {
// default permission was removed
return false;
} else if (permission.getExclusiveGroup()) {
// default permission was modified
return false;
}
if (permission.getRules().size() != 1) {
// default permission was modified
return false;
}
PermissionRule rule = permission.getRule(systemGroupBackend.getGroup(REGISTERED_USERS));
if (rule == null) {
// default permission was removed
return false;
}
if (rule.getAction() != Action.ALLOW
|| rule.getForce()
|| rule.getMin() != -2
|| rule.getMax() != 2) {
// default permission was modified
return false;
}
return true;
}
}