Merge "Allow to propose changes to access rights through code review"
This commit is contained in:
@@ -15,41 +15,26 @@
|
||||
package com.google.gerrit.httpd.rpc.project;
|
||||
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
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.common.data.ProjectAccess;
|
||||
import com.google.gerrit.common.errors.InvalidNameException;
|
||||
import com.google.gerrit.common.errors.NoSuchGroupException;
|
||||
import com.google.gerrit.httpd.rpc.Handler;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.account.GroupBackend;
|
||||
import com.google.gerrit.server.account.GroupBackends;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||
import com.google.gerrit.server.project.ProjectCache;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gerrit.server.project.RefControl;
|
||||
import com.google.gwtorm.server.OrmConcurrencyException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
class ChangeProjectAccess extends Handler<ProjectAccess> {
|
||||
class ChangeProjectAccess extends ProjectAccessHandler<ProjectAccess> {
|
||||
interface Factory {
|
||||
ChangeProjectAccess create(@Assisted Project.NameKey projectName,
|
||||
@Nullable @Assisted ObjectId base,
|
||||
@@ -58,15 +43,7 @@ class ChangeProjectAccess extends Handler<ProjectAccess> {
|
||||
}
|
||||
|
||||
private final ProjectAccessFactory.Factory projectAccessFactory;
|
||||
private final ProjectControl.Factory projectControlFactory;
|
||||
private final ProjectCache projectCache;
|
||||
private final GroupBackend groupBackend;
|
||||
private final MetaDataUpdate.User metaDataUpdateFactory;
|
||||
|
||||
private final Project.NameKey projectName;
|
||||
private final ObjectId base;
|
||||
private List<AccessSection> sectionList;
|
||||
private String message;
|
||||
|
||||
@Inject
|
||||
ChangeProjectAccess(final ProjectAccessFactory.Factory projectAccessFactory,
|
||||
@@ -78,132 +55,17 @@ class ChangeProjectAccess extends Handler<ProjectAccess> {
|
||||
@Nullable @Assisted final ObjectId base,
|
||||
@Assisted List<AccessSection> sectionList,
|
||||
@Nullable @Assisted String message) {
|
||||
super(projectControlFactory, groupBackend, metaDataUpdateFactory,
|
||||
projectName, base, sectionList, message, true);
|
||||
this.projectAccessFactory = projectAccessFactory;
|
||||
this.projectControlFactory = projectControlFactory;
|
||||
this.projectCache = projectCache;
|
||||
this.groupBackend = groupBackend;
|
||||
this.metaDataUpdateFactory = metaDataUpdateFactory;
|
||||
|
||||
this.projectName = projectName;
|
||||
this.base = base;
|
||||
this.sectionList = sectionList;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectAccess call() throws NoSuchProjectException, IOException,
|
||||
ConfigInvalidException, InvalidNameException, NoSuchGroupException,
|
||||
OrmConcurrencyException {
|
||||
final ProjectControl projectControl =
|
||||
projectControlFactory.controlFor(projectName);
|
||||
|
||||
final MetaDataUpdate md;
|
||||
try {
|
||||
md = metaDataUpdateFactory.create(projectName);
|
||||
} catch (RepositoryNotFoundException notFound) {
|
||||
throw new NoSuchProjectException(projectName);
|
||||
}
|
||||
try {
|
||||
ProjectConfig config = ProjectConfig.read(md, base);
|
||||
Set<String> toDelete = scanSectionNames(config);
|
||||
|
||||
for (AccessSection section : mergeSections(sectionList)) {
|
||||
String name = section.getName();
|
||||
|
||||
if (AccessSection.GLOBAL_CAPABILITIES.equals(name)) {
|
||||
if (!projectControl.isOwner()) {
|
||||
continue;
|
||||
}
|
||||
replace(config, toDelete, section);
|
||||
|
||||
} else if (AccessSection.isValid(name)) {
|
||||
if (!projectControl.controlForRef(name).isOwner()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RefControl.validateRefPattern(name);
|
||||
|
||||
replace(config, toDelete, section);
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : toDelete) {
|
||||
if (AccessSection.GLOBAL_CAPABILITIES.equals(name)) {
|
||||
if (projectControl.isOwner()) {
|
||||
config.remove(config.getAccessSection(name));
|
||||
}
|
||||
|
||||
} else if (projectControl.controlForRef(name).isOwner()) {
|
||||
config.remove(config.getAccessSection(name));
|
||||
}
|
||||
}
|
||||
|
||||
if (message != null && !message.isEmpty()) {
|
||||
if (!message.endsWith("\n")) {
|
||||
message += "\n";
|
||||
}
|
||||
md.setMessage(message);
|
||||
} else {
|
||||
md.setMessage("Modify access rules\n");
|
||||
}
|
||||
|
||||
if (config.commit(md)) {
|
||||
projectCache.evict(config.getProject());
|
||||
return projectAccessFactory.create(projectName).call();
|
||||
|
||||
} else {
|
||||
throw new OrmConcurrencyException("Cannot update " + projectName);
|
||||
}
|
||||
} finally {
|
||||
md.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void replace(ProjectConfig config, Set<String> toDelete,
|
||||
AccessSection section) throws NoSuchGroupException {
|
||||
for (Permission permission : section.getPermissions()) {
|
||||
for (PermissionRule rule : permission.getRules()) {
|
||||
lookupGroup(rule);
|
||||
}
|
||||
}
|
||||
config.replace(section);
|
||||
toDelete.remove(section.getName());
|
||||
}
|
||||
|
||||
private static List<AccessSection> mergeSections(List<AccessSection> src) {
|
||||
Map<String, AccessSection> map = new LinkedHashMap<String, AccessSection>();
|
||||
for (AccessSection section : src) {
|
||||
if (section.getPermissions().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AccessSection prior = map.get(section.getName());
|
||||
if (prior != null) {
|
||||
prior.mergeFrom(section);
|
||||
} else {
|
||||
map.put(section.getName(), section);
|
||||
}
|
||||
}
|
||||
return new ArrayList<AccessSection>(map.values());
|
||||
}
|
||||
|
||||
private static Set<String> scanSectionNames(ProjectConfig config) {
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (AccessSection section : config.getAccessSections()) {
|
||||
names.add(section.getName());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
private void lookupGroup(PermissionRule rule) throws NoSuchGroupException {
|
||||
GroupReference ref = rule.getGroup();
|
||||
if (ref.getUUID() == null) {
|
||||
final GroupReference group =
|
||||
GroupBackends.findBestSuggestion(groupBackend, ref.getName());
|
||||
if (group == null) {
|
||||
throw new NoSuchGroupException(ref.getName());
|
||||
}
|
||||
ref.setUUID(group.getUUID());
|
||||
}
|
||||
protected ProjectAccess updateProjectConfig(ProjectConfig config,
|
||||
MetaDataUpdate md) throws IOException, NoSuchProjectException, ConfigInvalidException {
|
||||
config.commit(md);
|
||||
projectCache.evict(config.getProject());
|
||||
return projectAccessFactory.create(projectName).call();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,10 +86,11 @@ class ChangeProjectSettings extends Handler<ProjectDetail> {
|
||||
config.getProject().copySettingsFrom(update);
|
||||
|
||||
md.setMessage("Modified project settings\n");
|
||||
if (config.commit(md)) {
|
||||
try {
|
||||
config.commit(md);
|
||||
mgr.setProjectDescription(projectName, update.getDescription());
|
||||
userCache.get().evict(config.getProject());
|
||||
} else {
|
||||
} catch (IOException e) {
|
||||
throw new OrmConcurrencyException("Cannot update " + projectName);
|
||||
}
|
||||
} catch (ConfigInvalidException err) {
|
||||
|
||||
@@ -96,10 +96,9 @@ class ProjectAccessFactory extends Handler<ProjectAccess> {
|
||||
|
||||
if (config.updateGroupNames(groupBackend)) {
|
||||
md.setMessage("Update group names\n");
|
||||
if (config.commit(md)) {
|
||||
projectCache.evict(config.getProject());
|
||||
pc = open();
|
||||
}
|
||||
config.commit(md);
|
||||
projectCache.evict(config.getProject());
|
||||
pc = open();
|
||||
} else if (config.getRevision() != null
|
||||
&& !config.getRevision().equals(
|
||||
pc.getProjectState().getConfig().getRevision())) {
|
||||
@@ -196,6 +195,8 @@ class ProjectAccessFactory extends Handler<ProjectAccess> {
|
||||
|
||||
detail.setLocal(local);
|
||||
detail.setOwnerOf(ownerOf);
|
||||
detail.setCanUpload(pc.isOwner()
|
||||
|| (metaConfigControl.isVisible() && metaConfigControl.canUpload()));
|
||||
detail.setConfigVisible(pc.isOwner() || metaConfigControl.isVisible());
|
||||
return detail;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
// Copyright (C) 2012 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.httpd.rpc.project;
|
||||
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
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.common.errors.InvalidNameException;
|
||||
import com.google.gerrit.common.errors.NoSuchGroupException;
|
||||
import com.google.gerrit.httpd.rpc.Handler;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.account.GroupBackend;
|
||||
import com.google.gerrit.server.account.GroupBackends;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gerrit.server.project.RefControl;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class ProjectAccessHandler<T> extends Handler<T> {
|
||||
|
||||
private final ProjectControl.Factory projectControlFactory;
|
||||
protected final GroupBackend groupBackend;
|
||||
private final MetaDataUpdate.User metaDataUpdateFactory;
|
||||
|
||||
protected final Project.NameKey projectName;
|
||||
protected final ObjectId base;
|
||||
private List<AccessSection> sectionList;
|
||||
protected String message;
|
||||
private boolean checkIfOwner;
|
||||
|
||||
protected ProjectAccessHandler(
|
||||
final ProjectControl.Factory projectControlFactory,
|
||||
final GroupBackend groupBackend,
|
||||
final MetaDataUpdate.User metaDataUpdateFactory,
|
||||
final Project.NameKey projectName, final ObjectId base,
|
||||
final List<AccessSection> sectionList, final String message,
|
||||
final boolean checkIfOwner) {
|
||||
this.projectControlFactory = projectControlFactory;
|
||||
this.groupBackend = groupBackend;
|
||||
this.metaDataUpdateFactory = metaDataUpdateFactory;
|
||||
|
||||
this.projectName = projectName;
|
||||
this.base = base;
|
||||
this.sectionList = sectionList;
|
||||
this.message = message;
|
||||
this.checkIfOwner = checkIfOwner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final T call() throws NoSuchProjectException, IOException,
|
||||
ConfigInvalidException, InvalidNameException, NoSuchGroupException,
|
||||
OrmException {
|
||||
final ProjectControl projectControl =
|
||||
projectControlFactory.controlFor(projectName);
|
||||
|
||||
final MetaDataUpdate md;
|
||||
try {
|
||||
md = metaDataUpdateFactory.create(projectName);
|
||||
} catch (RepositoryNotFoundException notFound) {
|
||||
throw new NoSuchProjectException(projectName);
|
||||
}
|
||||
try {
|
||||
ProjectConfig config = ProjectConfig.read(md, base);
|
||||
Set<String> toDelete = scanSectionNames(config);
|
||||
|
||||
for (AccessSection section : mergeSections(sectionList)) {
|
||||
String name = section.getName();
|
||||
|
||||
if (AccessSection.GLOBAL_CAPABILITIES.equals(name)) {
|
||||
if (checkIfOwner && !projectControl.isOwner()) {
|
||||
continue;
|
||||
}
|
||||
replace(config, toDelete, section);
|
||||
|
||||
} else if (AccessSection.isValid(name)) {
|
||||
if (checkIfOwner && !projectControl.controlForRef(name).isOwner()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RefControl.validateRefPattern(name);
|
||||
|
||||
replace(config, toDelete, section);
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : toDelete) {
|
||||
if (AccessSection.GLOBAL_CAPABILITIES.equals(name)) {
|
||||
if (!checkIfOwner || projectControl.isOwner()) {
|
||||
config.remove(config.getAccessSection(name));
|
||||
}
|
||||
|
||||
} else if (!checkIfOwner || projectControl.controlForRef(name).isOwner()) {
|
||||
config.remove(config.getAccessSection(name));
|
||||
}
|
||||
}
|
||||
|
||||
if (message != null && !message.isEmpty()) {
|
||||
if (!message.endsWith("\n")) {
|
||||
message += "\n";
|
||||
}
|
||||
md.setMessage(message);
|
||||
} else {
|
||||
md.setMessage("Modify access rules\n");
|
||||
}
|
||||
|
||||
return updateProjectConfig(config, md);
|
||||
} finally {
|
||||
md.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract T updateProjectConfig(ProjectConfig config,
|
||||
MetaDataUpdate md) throws IOException, NoSuchProjectException,
|
||||
ConfigInvalidException, OrmException;
|
||||
|
||||
private void replace(ProjectConfig config, Set<String> toDelete,
|
||||
AccessSection section) throws NoSuchGroupException {
|
||||
for (Permission permission : section.getPermissions()) {
|
||||
for (PermissionRule rule : permission.getRules()) {
|
||||
lookupGroup(rule);
|
||||
}
|
||||
}
|
||||
config.replace(section);
|
||||
toDelete.remove(section.getName());
|
||||
}
|
||||
|
||||
private static List<AccessSection> mergeSections(List<AccessSection> src) {
|
||||
Map<String, AccessSection> map = new LinkedHashMap<String, AccessSection>();
|
||||
for (AccessSection section : src) {
|
||||
if (section.getPermissions().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AccessSection prior = map.get(section.getName());
|
||||
if (prior != null) {
|
||||
prior.mergeFrom(section);
|
||||
} else {
|
||||
map.put(section.getName(), section);
|
||||
}
|
||||
}
|
||||
return new ArrayList<AccessSection>(map.values());
|
||||
}
|
||||
|
||||
private static Set<String> scanSectionNames(ProjectConfig config) {
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (AccessSection section : config.getAccessSections()) {
|
||||
names.add(section.getName());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
private void lookupGroup(PermissionRule rule) throws NoSuchGroupException {
|
||||
GroupReference ref = rule.getGroup();
|
||||
if (ref.getUUID() == null) {
|
||||
final GroupReference group =
|
||||
GroupBackends.findBestSuggestion(groupBackend, ref.getName());
|
||||
if (group == null) {
|
||||
throw new NoSuchGroupException(ref.getName());
|
||||
}
|
||||
ref.setUUID(group.getUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import com.google.gerrit.common.data.ProjectAccess;
|
||||
import com.google.gerrit.common.data.ProjectAdminService;
|
||||
import com.google.gerrit.common.data.ProjectDetail;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
||||
import com.google.gwtjsonrpc.common.VoidResult;
|
||||
@@ -33,6 +34,7 @@ import java.util.Set;
|
||||
class ProjectAdminServiceImpl implements ProjectAdminService {
|
||||
private final AddBranch.Factory addBranchFactory;
|
||||
private final ChangeProjectAccess.Factory changeProjectAccessFactory;
|
||||
private final ReviewProjectAccess.Factory reviewProjectAccessFactory;
|
||||
private final ChangeProjectSettings.Factory changeProjectSettingsFactory;
|
||||
private final DeleteBranches.Factory deleteBranchesFactory;
|
||||
private final ListBranches.Factory listBranchesFactory;
|
||||
@@ -44,6 +46,7 @@ class ProjectAdminServiceImpl implements ProjectAdminService {
|
||||
@Inject
|
||||
ProjectAdminServiceImpl(final AddBranch.Factory addBranchFactory,
|
||||
final ChangeProjectAccess.Factory changeProjectAccessFactory,
|
||||
final ReviewProjectAccess.Factory reviewProjectAccessFactory,
|
||||
final ChangeProjectSettings.Factory changeProjectSettingsFactory,
|
||||
final DeleteBranches.Factory deleteBranchesFactory,
|
||||
final ListBranches.Factory listBranchesFactory,
|
||||
@@ -53,6 +56,7 @@ class ProjectAdminServiceImpl implements ProjectAdminService {
|
||||
final CreateProjectHandler.Factory createNewProjectFactory) {
|
||||
this.addBranchFactory = addBranchFactory;
|
||||
this.changeProjectAccessFactory = changeProjectAccessFactory;
|
||||
this.reviewProjectAccessFactory = reviewProjectAccessFactory;
|
||||
this.changeProjectSettingsFactory = changeProjectSettingsFactory;
|
||||
this.deleteBranchesFactory = deleteBranchesFactory;
|
||||
this.listBranchesFactory = listBranchesFactory;
|
||||
@@ -98,6 +102,14 @@ class ProjectAdminServiceImpl implements ProjectAdminService {
|
||||
changeProjectAccessFactory.create(projectName, base, sections, msg).to(cb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reviewProjectAccess(Project.NameKey projectName,
|
||||
String baseRevision, String msg, List<AccessSection> sections,
|
||||
AsyncCallback<Change.Id> cb) {
|
||||
ObjectId base = ObjectId.fromString(baseRevision);
|
||||
reviewProjectAccessFactory.create(projectName, base, sections, msg).to(cb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void listBranches(final Project.NameKey projectName,
|
||||
final AsyncCallback<ListBranchesResult> callback) {
|
||||
|
||||
@@ -30,6 +30,7 @@ public class ProjectModule extends RpcServletModule {
|
||||
protected void configure() {
|
||||
factory(AddBranch.Factory.class);
|
||||
factory(ChangeProjectAccess.Factory.class);
|
||||
factory(ReviewProjectAccess.Factory.class);
|
||||
factory(CreateProjectHandler.Factory.class);
|
||||
factory(ChangeProjectSettings.Factory.class);
|
||||
factory(DeleteBranches.Factory.class);
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
// Copyright (C) 2012 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.httpd.rpc.project;
|
||||
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.client.PatchSetInfo;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.RevId;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.GroupBackend;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gerrit.server.patch.AddReviewer;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ReviewProjectAccess extends ProjectAccessHandler<Change.Id> {
|
||||
interface Factory {
|
||||
ReviewProjectAccess create(@Assisted Project.NameKey projectName,
|
||||
@Nullable @Assisted ObjectId base,
|
||||
@Assisted List<AccessSection> sectionList,
|
||||
@Nullable @Assisted String message);
|
||||
}
|
||||
|
||||
private final ReviewDb db;
|
||||
private final IdentifiedUser user;
|
||||
private final PatchSetInfoFactory patchSetInfoFactory;
|
||||
private final AddReviewer.Factory addReviewerFactory;
|
||||
|
||||
@Inject
|
||||
ReviewProjectAccess(final ProjectControl.Factory projectControlFactory,
|
||||
final GroupBackend groupBackend,
|
||||
final MetaDataUpdate.User metaDataUpdateFactory, final ReviewDb db,
|
||||
final IdentifiedUser user, final PatchSetInfoFactory patchSetInfoFactory,
|
||||
final AddReviewer.Factory addReviewerFactory,
|
||||
|
||||
@Assisted final Project.NameKey projectName,
|
||||
@Nullable @Assisted final ObjectId base,
|
||||
@Assisted List<AccessSection> sectionList,
|
||||
@Nullable @Assisted String message) {
|
||||
super(projectControlFactory, groupBackend, metaDataUpdateFactory,
|
||||
projectName, base, sectionList, message, false);
|
||||
this.db = db;
|
||||
this.user = user;
|
||||
this.patchSetInfoFactory = patchSetInfoFactory;
|
||||
this.addReviewerFactory = addReviewerFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Change.Id updateProjectConfig(ProjectConfig config, MetaDataUpdate md)
|
||||
throws IOException, NoSuchProjectException, ConfigInvalidException, OrmException {
|
||||
int nextChangeId = db.nextChangeId();
|
||||
PatchSet.Id patchSetId = new PatchSet.Id(new Change.Id(nextChangeId), 1);
|
||||
final PatchSet ps = new PatchSet(patchSetId);
|
||||
RevCommit commit = config.commitToNewRef(md, ps.getRefName());
|
||||
if (commit.getId().equals(base)) {
|
||||
return null;
|
||||
}
|
||||
Change.Key changeKey = new Change.Key("I" + commit.name());
|
||||
final Change change =
|
||||
new Change(changeKey, new Change.Id(nextChangeId), user.getAccountId(),
|
||||
new Branch.NameKey(config.getProject().getNameKey(),
|
||||
GitRepositoryManager.REF_CONFIG));
|
||||
change.nextPatchSetId();
|
||||
|
||||
ps.setCreatedOn(change.getCreatedOn());
|
||||
ps.setUploader(user.getAccountId());
|
||||
ps.setRevision(new RevId(commit.name()));
|
||||
|
||||
db.patchSets().insert(Collections.singleton(ps));
|
||||
|
||||
final PatchSetInfo info = patchSetInfoFactory.get(commit, ps.getId());
|
||||
change.setCurrentPatchSet(info);
|
||||
ChangeUtil.updated(change);
|
||||
|
||||
db.changes().insert(Collections.singleton(change));
|
||||
|
||||
addProjectOwnersAsReviewers(change.getId());
|
||||
|
||||
return change.getId();
|
||||
}
|
||||
|
||||
private void addProjectOwnersAsReviewers(final Change.Id changeId) {
|
||||
final String projectOwners =
|
||||
groupBackend.get(AccountGroup.PROJECT_OWNERS).getName();
|
||||
try {
|
||||
addReviewerFactory.create(changeId, Collections.singleton(projectOwners),
|
||||
false).call();
|
||||
} catch (Exception e) {
|
||||
// one of the owner groups is not visible to the user and this it why it
|
||||
// can't be added as reviewer
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user