blob: e3006b6366d343a659d09f21251ed6cf81588abe [file] [log] [blame]
// Copyright (C) 2013 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.googlesource.gerrit.plugins.github.git;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.GroupDescription;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.NameKey;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.util.ManualRequestContext;
import com.google.gerrit.server.util.OneOffRequestContext;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.googlesource.gerrit.plugins.github.GitHubConfig;
import com.googlesource.gerrit.plugins.github.GitHubURL;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CreateProjectStep extends ImportStep {
private static final Logger LOG = LoggerFactory.getLogger(CreateProjectStep.class);
private static final String CODE_REVIEW_REFS = "refs/for/refs/*";
private static final String TAGS_REFS = "refs/tags/*";
private static final String CODE_REVIEW_LABEL = "Code-Review";
private static final String VERIFIED_LABEL = "Verified";
private final OneOffRequestContext context;
private final String organisation;
private final String repository;
private MetaDataUpdate.User metaDataUpdateFactory;
private String description;
private GroupBackend groupBackend;
private String username;
private ProjectConfig projectConfig;
private ProjectCache projectCache;
private GitHubConfig config;
public interface Factory {
CreateProjectStep create(
@Assisted("organisation") String organisation,
@Assisted("name") String repository,
@Assisted("description") String description,
@Assisted("username") String username);
}
@Inject
public CreateProjectStep(
@GitHubURL String gitHubUrl,
MetaDataUpdate.User metaDataUpdateFactory,
GroupBackend groupBackend,
ProjectCache projectCache,
GitHubRepository.Factory ghRepoFactory,
GitHubConfig gitHubConfig,
OneOffRequestContext context,
@Assisted("organisation") String organisation,
@Assisted("name") String repository,
@Assisted("description") String description,
@Assisted("username") String username) {
super(gitHubUrl, organisation, repository, ghRepoFactory);
LOG.debug("Gerrit CreateProject " + organisation + "/" + repository);
this.organisation = organisation;
this.repository = repository;
this.description = description;
this.metaDataUpdateFactory = metaDataUpdateFactory;
this.groupBackend = groupBackend;
this.projectCache = projectCache;
this.username = username;
this.config = gitHubConfig;
this.context = context;
}
private void setProjectPermissions() {
addPermissions(AccessSection.ALL, Permission.OWNER);
addPermissions(
CODE_REVIEW_REFS,
Permission.READ,
Permission.PUSH,
Permission.REMOVE_REVIEWER,
Permission.SUBMIT,
Permission.REBASE);
PermissionRule reviewRange = new PermissionRule(getMyGroup());
reviewRange.setMin(new Integer(-2));
reviewRange.setMax(new Integer(+2));
addPermission(CODE_REVIEW_REFS, Permission.LABEL + CODE_REVIEW_LABEL, reviewRange);
PermissionRule verifiedRange = new PermissionRule(getMyGroup());
verifiedRange.setMin(new Integer(-1));
verifiedRange.setMax(new Integer(+1));
addPermission(CODE_REVIEW_REFS, Permission.LABEL + VERIFIED_LABEL, verifiedRange);
addPermissions(AccessSection.HEADS, Permission.READ, Permission.CREATE, Permission.PUSH_MERGE);
PermissionRule forcePush = new PermissionRule(getMyGroup());
forcePush.setForce(Boolean.TRUE);
addPermission(AccessSection.HEADS, Permission.PUSH, forcePush);
addPermissions(TAGS_REFS, Permission.PUSH);
PermissionRule removeTag = new PermissionRule(getMyGroup());
removeTag.setForce(Boolean.TRUE);
addPermission(TAGS_REFS, Permission.PUSH, removeTag);
}
private void addPermissions(String refSpec, String... permissions) {
AccessSection accessSection = projectConfig.getAccessSection(refSpec, true);
for (String permission : permissions) {
String[] permParts = permission.split("=");
String action = permParts[0];
PermissionRule rule;
if (permParts.length > 1) {
rule = PermissionRule.fromString(permParts[1], true);
rule.setGroup(getMyGroup());
} else {
rule = new PermissionRule(getMyGroup());
}
accessSection.getPermission(action, true).add(rule);
}
}
private void addPermission(String refSpec, String action, PermissionRule rule) {
projectConfig.getAccessSection(refSpec, true).getPermission(action, true).add(rule);
}
private GroupReference getMyGroup() {
GroupDescription.Basic g = groupBackend.get(AccountGroup.UUID.parse("user:" + username));
return projectConfig.resolve(GroupReference.forGroup(g));
}
private NameKey getProjectNameKey() {
return Project.NameKey.parse(organisation + "/" + repository);
}
@Override
public void doImport(ProgressMonitor progress) throws Exception {
MetaDataUpdate md = null;
try (ManualRequestContext requestContext = context.openAs(config.importAccountId)) {
md = metaDataUpdateFactory.create(getProjectNameKey());
projectConfig = ProjectConfig.read(md);
progress.beginTask("Configure Gerrit project", 2);
setProjectSettings();
progress.update(1);
setProjectPermissions();
progress.update(1);
md.setMessage("Imported from " + getSourceUri());
projectConfig.commit(md);
projectCache.onCreateProject(getProjectNameKey());
} finally {
if (md != null) {
md.close();
}
progress.endTask();
}
}
private void setProjectSettings() {
Project project = projectConfig.getProject();
project.setParentName(config.getBaseProject(getRepository().isPrivate()));
project.setDescription(description);
project.setSubmitType(SubmitType.MERGE_IF_NECESSARY);
project.setBooleanConfig(
BooleanProjectConfig.USE_CONTRIBUTOR_AGREEMENTS, InheritableBoolean.INHERIT);
project.setBooleanConfig(BooleanProjectConfig.USE_SIGNED_OFF_BY, InheritableBoolean.INHERIT);
project.setBooleanConfig(BooleanProjectConfig.USE_CONTENT_MERGE, InheritableBoolean.INHERIT);
project.setBooleanConfig(BooleanProjectConfig.REQUIRE_CHANGE_ID, InheritableBoolean.INHERIT);
}
@Override
public boolean rollback() {
return false;
}
}