Merge "Consolidate reachable commit in CommitsCollection"
* submodules: * Update plugins/replication from branch 'master' - Migrate calls to ChangeControl#isVisible to PermissionBackend Change-Id: I740e70aa799b5cc5e74ed86054876d1baa753373
This commit is contained in:
@@ -23,6 +23,7 @@ import com.google.gerrit.extensions.api.projects.CommentLinkInfo;
|
|||||||
import com.google.gerrit.extensions.config.FactoryModule;
|
import com.google.gerrit.extensions.config.FactoryModule;
|
||||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||||
|
import com.google.gerrit.extensions.restapi.RestView;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.rules.PrologModule;
|
import com.google.gerrit.rules.PrologModule;
|
||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
@@ -63,6 +64,7 @@ import com.google.gerrit.server.notedb.NoteDbModule;
|
|||||||
import com.google.gerrit.server.patch.DiffExecutorModule;
|
import com.google.gerrit.server.patch.DiffExecutorModule;
|
||||||
import com.google.gerrit.server.patch.PatchListCacheImpl;
|
import com.google.gerrit.server.patch.PatchListCacheImpl;
|
||||||
import com.google.gerrit.server.project.CommentLinkProvider;
|
import com.google.gerrit.server.project.CommentLinkProvider;
|
||||||
|
import com.google.gerrit.server.project.CommitResource;
|
||||||
import com.google.gerrit.server.project.DefaultPermissionBackendModule;
|
import com.google.gerrit.server.project.DefaultPermissionBackendModule;
|
||||||
import com.google.gerrit.server.project.ProjectCacheImpl;
|
import com.google.gerrit.server.project.ProjectCacheImpl;
|
||||||
import com.google.gerrit.server.project.ProjectState;
|
import com.google.gerrit.server.project.ProjectState;
|
||||||
@@ -115,6 +117,8 @@ public class BatchProgramModule extends FactoryModule {
|
|||||||
.in(SINGLETON);
|
.in(SINGLETON);
|
||||||
bind(new TypeLiteral<DynamicMap<ChangeQueryProcessor.ChangeAttributeFactory>>() {})
|
bind(new TypeLiteral<DynamicMap<ChangeQueryProcessor.ChangeAttributeFactory>>() {})
|
||||||
.toInstance(DynamicMap.<ChangeQueryProcessor.ChangeAttributeFactory>emptyMap());
|
.toInstance(DynamicMap.<ChangeQueryProcessor.ChangeAttributeFactory>emptyMap());
|
||||||
|
bind(new TypeLiteral<DynamicMap<RestView<CommitResource>>>() {})
|
||||||
|
.toInstance(DynamicMap.<RestView<CommitResource>>emptyMap());
|
||||||
bind(String.class)
|
bind(String.class)
|
||||||
.annotatedWith(CanonicalWebUrl.class)
|
.annotatedWith(CanonicalWebUrl.class)
|
||||||
.toProvider(CanonicalWebUrlProvider.class);
|
.toProvider(CanonicalWebUrlProvider.class);
|
||||||
|
@@ -56,9 +56,11 @@ import com.google.gerrit.server.permissions.PermissionBackend;
|
|||||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||||
import com.google.gerrit.server.permissions.RefPermission;
|
import com.google.gerrit.server.permissions.RefPermission;
|
||||||
import com.google.gerrit.server.project.ChangeControl;
|
import com.google.gerrit.server.project.ChangeControl;
|
||||||
|
import com.google.gerrit.server.project.CommitsCollection;
|
||||||
import com.google.gerrit.server.project.InvalidChangeOperationException;
|
import com.google.gerrit.server.project.InvalidChangeOperationException;
|
||||||
import com.google.gerrit.server.project.ProjectControl;
|
import com.google.gerrit.server.project.ProjectControl;
|
||||||
import com.google.gerrit.server.project.ProjectResource;
|
import com.google.gerrit.server.project.ProjectResource;
|
||||||
|
import com.google.gerrit.server.project.ProjectState;
|
||||||
import com.google.gerrit.server.project.ProjectsCollection;
|
import com.google.gerrit.server.project.ProjectsCollection;
|
||||||
import com.google.gerrit.server.update.BatchUpdate;
|
import com.google.gerrit.server.update.BatchUpdate;
|
||||||
import com.google.gerrit.server.update.RetryHelper;
|
import com.google.gerrit.server.update.RetryHelper;
|
||||||
@@ -100,6 +102,7 @@ public class CreateChange
|
|||||||
private final PermissionBackend permissionBackend;
|
private final PermissionBackend permissionBackend;
|
||||||
private final Provider<CurrentUser> user;
|
private final Provider<CurrentUser> user;
|
||||||
private final ProjectsCollection projectsCollection;
|
private final ProjectsCollection projectsCollection;
|
||||||
|
private final CommitsCollection commits;
|
||||||
private final ChangeInserter.Factory changeInserterFactory;
|
private final ChangeInserter.Factory changeInserterFactory;
|
||||||
private final ChangeJson.Factory jsonFactory;
|
private final ChangeJson.Factory jsonFactory;
|
||||||
private final ChangeFinder changeFinder;
|
private final ChangeFinder changeFinder;
|
||||||
@@ -121,6 +124,7 @@ public class CreateChange
|
|||||||
PermissionBackend permissionBackend,
|
PermissionBackend permissionBackend,
|
||||||
Provider<CurrentUser> user,
|
Provider<CurrentUser> user,
|
||||||
ProjectsCollection projectsCollection,
|
ProjectsCollection projectsCollection,
|
||||||
|
CommitsCollection commits,
|
||||||
ChangeInserter.Factory changeInserterFactory,
|
ChangeInserter.Factory changeInserterFactory,
|
||||||
ChangeJson.Factory json,
|
ChangeJson.Factory json,
|
||||||
ChangeFinder changeFinder,
|
ChangeFinder changeFinder,
|
||||||
@@ -139,6 +143,7 @@ public class CreateChange
|
|||||||
this.permissionBackend = permissionBackend;
|
this.permissionBackend = permissionBackend;
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.projectsCollection = projectsCollection;
|
this.projectsCollection = projectsCollection;
|
||||||
|
this.commits = commits;
|
||||||
this.changeInserterFactory = changeInserterFactory;
|
this.changeInserterFactory = changeInserterFactory;
|
||||||
this.jsonFactory = json;
|
this.jsonFactory = json;
|
||||||
this.changeFinder = changeFinder;
|
this.changeFinder = changeFinder;
|
||||||
@@ -311,12 +316,13 @@ public class CreateChange
|
|||||||
throw new BadRequestException("merge.source must be non-empty");
|
throw new BadRequestException("merge.source must be non-empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProjectState state = projectControl.getProjectState();
|
||||||
RevCommit sourceCommit = MergeUtil.resolveCommit(repo, rw, merge.source);
|
RevCommit sourceCommit = MergeUtil.resolveCommit(repo, rw, merge.source);
|
||||||
if (!projectControl.canReadCommit(db.get(), repo, sourceCommit)) {
|
if (!commits.canRead(state, repo, sourceCommit)) {
|
||||||
throw new BadRequestException("do not have read permission for: " + merge.source);
|
throw new BadRequestException("do not have read permission for: " + merge.source);
|
||||||
}
|
}
|
||||||
|
|
||||||
MergeUtil mergeUtil = mergeUtilFactory.create(projectControl.getProjectState());
|
MergeUtil mergeUtil = mergeUtilFactory.create(state);
|
||||||
// default merge strategy from project settings
|
// default merge strategy from project settings
|
||||||
String mergeStrategy =
|
String mergeStrategy =
|
||||||
MoreObjects.firstNonNull(
|
MoreObjects.firstNonNull(
|
||||||
|
@@ -43,8 +43,10 @@ import com.google.gerrit.server.git.MergeUtil;
|
|||||||
import com.google.gerrit.server.permissions.ChangePermission;
|
import com.google.gerrit.server.permissions.ChangePermission;
|
||||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||||
import com.google.gerrit.server.project.ChangeControl;
|
import com.google.gerrit.server.project.ChangeControl;
|
||||||
|
import com.google.gerrit.server.project.CommitsCollection;
|
||||||
import com.google.gerrit.server.project.InvalidChangeOperationException;
|
import com.google.gerrit.server.project.InvalidChangeOperationException;
|
||||||
import com.google.gerrit.server.project.ProjectControl;
|
import com.google.gerrit.server.project.ProjectControl;
|
||||||
|
import com.google.gerrit.server.project.ProjectState;
|
||||||
import com.google.gerrit.server.update.BatchUpdate;
|
import com.google.gerrit.server.update.BatchUpdate;
|
||||||
import com.google.gerrit.server.update.RetryHelper;
|
import com.google.gerrit.server.update.RetryHelper;
|
||||||
import com.google.gerrit.server.update.RetryingRestModifyView;
|
import com.google.gerrit.server.update.RetryingRestModifyView;
|
||||||
@@ -69,9 +71,9 @@ import org.eclipse.jgit.util.ChangeIdUtil;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class CreateMergePatchSet
|
public class CreateMergePatchSet
|
||||||
extends RetryingRestModifyView<ChangeResource, MergePatchSetInput, Response<ChangeInfo>> {
|
extends RetryingRestModifyView<ChangeResource, MergePatchSetInput, Response<ChangeInfo>> {
|
||||||
|
|
||||||
private final Provider<ReviewDb> db;
|
private final Provider<ReviewDb> db;
|
||||||
private final GitRepositoryManager gitManager;
|
private final GitRepositoryManager gitManager;
|
||||||
|
private final CommitsCollection commits;
|
||||||
private final TimeZone serverTimeZone;
|
private final TimeZone serverTimeZone;
|
||||||
private final Provider<CurrentUser> user;
|
private final Provider<CurrentUser> user;
|
||||||
private final ChangeJson.Factory jsonFactory;
|
private final ChangeJson.Factory jsonFactory;
|
||||||
@@ -83,6 +85,7 @@ public class CreateMergePatchSet
|
|||||||
CreateMergePatchSet(
|
CreateMergePatchSet(
|
||||||
Provider<ReviewDb> db,
|
Provider<ReviewDb> db,
|
||||||
GitRepositoryManager gitManager,
|
GitRepositoryManager gitManager,
|
||||||
|
CommitsCollection commits,
|
||||||
@GerritPersonIdent PersonIdent myIdent,
|
@GerritPersonIdent PersonIdent myIdent,
|
||||||
Provider<CurrentUser> user,
|
Provider<CurrentUser> user,
|
||||||
ChangeJson.Factory json,
|
ChangeJson.Factory json,
|
||||||
@@ -93,6 +96,7 @@ public class CreateMergePatchSet
|
|||||||
super(retryHelper);
|
super(retryHelper);
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.gitManager = gitManager;
|
this.gitManager = gitManager;
|
||||||
|
this.commits = commits;
|
||||||
this.serverTimeZone = myIdent.getTimeZone();
|
this.serverTimeZone = myIdent.getTimeZone();
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.jsonFactory = json;
|
this.jsonFactory = json;
|
||||||
@@ -116,6 +120,7 @@ public class CreateMergePatchSet
|
|||||||
ChangeControl ctl = rsrc.getControl();
|
ChangeControl ctl = rsrc.getControl();
|
||||||
PatchSet ps = psUtil.current(db.get(), ctl.getNotes());
|
PatchSet ps = psUtil.current(db.get(), ctl.getNotes());
|
||||||
ProjectControl projectControl = ctl.getProjectControl();
|
ProjectControl projectControl = ctl.getProjectControl();
|
||||||
|
ProjectState state = projectControl.getProjectState();
|
||||||
Change change = ctl.getChange();
|
Change change = ctl.getChange();
|
||||||
Project.NameKey project = change.getProject();
|
Project.NameKey project = change.getProject();
|
||||||
Branch.NameKey dest = change.getDest();
|
Branch.NameKey dest = change.getDest();
|
||||||
@@ -125,7 +130,7 @@ public class CreateMergePatchSet
|
|||||||
RevWalk rw = new RevWalk(reader)) {
|
RevWalk rw = new RevWalk(reader)) {
|
||||||
|
|
||||||
RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, merge.source);
|
RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, merge.source);
|
||||||
if (!projectControl.canReadCommit(db.get(), git, sourceCommit)) {
|
if (!commits.canRead(state, git, sourceCommit)) {
|
||||||
throw new ResourceNotFoundException(
|
throw new ResourceNotFoundException(
|
||||||
"cannot find source commit: " + merge.source + " to merge.");
|
"cannot find source commit: " + merge.source + " to merge.");
|
||||||
}
|
}
|
||||||
|
@@ -19,13 +19,11 @@ import com.google.gerrit.extensions.common.MergeableInfo;
|
|||||||
import com.google.gerrit.extensions.restapi.BadRequestException;
|
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
|
||||||
import com.google.gerrit.server.config.GerritServerConfig;
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
import com.google.gerrit.server.git.InMemoryInserter;
|
import com.google.gerrit.server.git.InMemoryInserter;
|
||||||
import com.google.gerrit.server.git.MergeUtil;
|
import com.google.gerrit.server.git.MergeUtil;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.eclipse.jgit.lib.Config;
|
import org.eclipse.jgit.lib.Config;
|
||||||
import org.eclipse.jgit.lib.ObjectInserter;
|
import org.eclipse.jgit.lib.ObjectInserter;
|
||||||
@@ -39,11 +37,9 @@ import org.kohsuke.args4j.Option;
|
|||||||
|
|
||||||
/** Check the mergeability at current branch for a git object references expression. */
|
/** Check the mergeability at current branch for a git object references expression. */
|
||||||
public class CheckMergeability implements RestReadView<BranchResource> {
|
public class CheckMergeability implements RestReadView<BranchResource> {
|
||||||
|
|
||||||
private String source;
|
private String source;
|
||||||
private String strategy;
|
private String strategy;
|
||||||
private SubmitType submitType;
|
private SubmitType submitType;
|
||||||
private final Provider<ReviewDb> db;
|
|
||||||
|
|
||||||
@Option(
|
@Option(
|
||||||
name = "--source",
|
name = "--source",
|
||||||
@@ -68,14 +64,15 @@ public class CheckMergeability implements RestReadView<BranchResource> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final GitRepositoryManager gitManager;
|
private final GitRepositoryManager gitManager;
|
||||||
|
private final CommitsCollection commits;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CheckMergeability(
|
CheckMergeability(
|
||||||
GitRepositoryManager gitManager, @GerritServerConfig Config cfg, Provider<ReviewDb> db) {
|
GitRepositoryManager gitManager, CommitsCollection commits, @GerritServerConfig Config cfg) {
|
||||||
this.gitManager = gitManager;
|
this.gitManager = gitManager;
|
||||||
|
this.commits = commits;
|
||||||
this.strategy = MergeUtil.getMergeStrategy(cfg).getName();
|
this.strategy = MergeUtil.getMergeStrategy(cfg).getName();
|
||||||
this.submitType = cfg.getEnum("project", null, "submitType", SubmitType.MERGE_IF_NECESSARY);
|
this.submitType = cfg.getEnum("project", null, "submitType", SubmitType.MERGE_IF_NECESSARY);
|
||||||
this.db = db;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -102,7 +99,7 @@ public class CheckMergeability implements RestReadView<BranchResource> {
|
|||||||
RevCommit targetCommit = rw.parseCommit(destRef.getObjectId());
|
RevCommit targetCommit = rw.parseCommit(destRef.getObjectId());
|
||||||
RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, source);
|
RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, source);
|
||||||
|
|
||||||
if (!resource.getControl().canReadCommit(db.get(), git, sourceCommit)) {
|
if (!commits.canRead(resource.getProjectState(), git, sourceCommit)) {
|
||||||
throw new BadRequestException("do not have read permission for: " + source);
|
throw new BadRequestException("do not have read permission for: " + source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,33 +19,48 @@ import com.google.gerrit.extensions.restapi.ChildCollection;
|
|||||||
import com.google.gerrit.extensions.restapi.IdString;
|
import com.google.gerrit.extensions.restapi.IdString;
|
||||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||||
import com.google.gerrit.extensions.restapi.RestView;
|
import com.google.gerrit.extensions.restapi.RestView;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
|
import com.google.gerrit.server.change.IncludedInResolver;
|
||||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
|
import com.google.gerrit.server.git.VisibleRefFilter;
|
||||||
|
import com.google.gerrit.server.query.change.ChangeData;
|
||||||
|
import com.google.gerrit.server.query.change.InternalChangeQuery;
|
||||||
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||||
import org.eclipse.jgit.errors.MissingObjectException;
|
import org.eclipse.jgit.errors.MissingObjectException;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
|
import org.eclipse.jgit.lib.Ref;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
import org.eclipse.jgit.revwalk.RevWalk;
|
import org.eclipse.jgit.revwalk.RevWalk;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CommitsCollection implements ChildCollection<ProjectResource, CommitResource> {
|
public class CommitsCollection implements ChildCollection<ProjectResource, CommitResource> {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CommitsCollection.class);
|
||||||
|
|
||||||
private final DynamicMap<RestView<CommitResource>> views;
|
private final DynamicMap<RestView<CommitResource>> views;
|
||||||
private final GitRepositoryManager repoManager;
|
private final GitRepositoryManager repoManager;
|
||||||
private final Provider<ReviewDb> db;
|
private final VisibleRefFilter.Factory refFilter;
|
||||||
|
private final Provider<InternalChangeQuery> queryProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CommitsCollection(
|
public CommitsCollection(
|
||||||
DynamicMap<RestView<CommitResource>> views,
|
DynamicMap<RestView<CommitResource>> views,
|
||||||
GitRepositoryManager repoManager,
|
GitRepositoryManager repoManager,
|
||||||
Provider<ReviewDb> db) {
|
VisibleRefFilter.Factory refFilter,
|
||||||
|
Provider<InternalChangeQuery> queryProvider) {
|
||||||
this.views = views;
|
this.views = views;
|
||||||
this.repoManager = repoManager;
|
this.repoManager = repoManager;
|
||||||
this.db = db;
|
this.refFilter = refFilter;
|
||||||
|
this.queryProvider = queryProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -67,7 +82,7 @@ public class CommitsCollection implements ChildCollection<ProjectResource, Commi
|
|||||||
RevWalk rw = new RevWalk(repo)) {
|
RevWalk rw = new RevWalk(repo)) {
|
||||||
RevCommit commit = rw.parseCommit(objectId);
|
RevCommit commit = rw.parseCommit(objectId);
|
||||||
rw.parseBody(commit);
|
rw.parseBody(commit);
|
||||||
if (!parent.getControl().canReadCommit(db.get(), repo, commit)) {
|
if (!canRead(parent.getProjectState(), repo, commit)) {
|
||||||
throw new ResourceNotFoundException(id);
|
throw new ResourceNotFoundException(id);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < commit.getParentCount(); i++) {
|
for (int i = 0; i < commit.getParentCount(); i++) {
|
||||||
@@ -83,4 +98,37 @@ public class CommitsCollection implements ChildCollection<ProjectResource, Commi
|
|||||||
public DynamicMap<RestView<CommitResource>> views() {
|
public DynamicMap<RestView<CommitResource>> views() {
|
||||||
return views;
|
return views;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return true if {@code commit} is visible to the caller. */
|
||||||
|
public boolean canRead(ProjectState state, Repository repo, RevCommit commit) {
|
||||||
|
Project.NameKey project = state.getProject().getNameKey();
|
||||||
|
|
||||||
|
// Look for changes associated with the commit.
|
||||||
|
try {
|
||||||
|
List<ChangeData> changes =
|
||||||
|
queryProvider.get().enforceVisibility(true).byProjectCommit(project, commit);
|
||||||
|
if (!changes.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (OrmException e) {
|
||||||
|
log.error("Cannot look up change for commit " + commit.name() + " in " + project, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isReachableFrom(state, repo, commit, repo.getAllRefs());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReachableFrom(
|
||||||
|
ProjectState state, Repository repo, RevCommit commit, Map<String, Ref> refs) {
|
||||||
|
try (RevWalk rw = new RevWalk(repo)) {
|
||||||
|
refs = refFilter.create(state, repo).filter(refs, true);
|
||||||
|
return IncludedInResolver.includedInAny(repo, rw, commit, refs.values());
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(
|
||||||
|
String.format(
|
||||||
|
"Cannot verify permissions to commit object %s in repository %s",
|
||||||
|
commit.name(), state.getProject().getNameKey()),
|
||||||
|
e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,10 +17,8 @@ package com.google.gerrit.server.project;
|
|||||||
import com.google.gerrit.extensions.restapi.AuthException;
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
|
||||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||||
@@ -34,13 +32,13 @@ import org.eclipse.jgit.revwalk.RevWalk;
|
|||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class GetHead implements RestReadView<ProjectResource> {
|
public class GetHead implements RestReadView<ProjectResource> {
|
||||||
private GitRepositoryManager repoManager;
|
private final GitRepositoryManager repoManager;
|
||||||
private Provider<ReviewDb> db;
|
private final CommitsCollection commits;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GetHead(GitRepositoryManager repoManager, Provider<ReviewDb> db) {
|
GetHead(GitRepositoryManager repoManager, CommitsCollection commits) {
|
||||||
this.repoManager = repoManager;
|
this.repoManager = repoManager;
|
||||||
this.db = db;
|
this.commits = commits;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,7 +57,7 @@ public class GetHead implements RestReadView<ProjectResource> {
|
|||||||
} else if (head.getObjectId() != null) {
|
} else if (head.getObjectId() != null) {
|
||||||
try (RevWalk rw = new RevWalk(repo)) {
|
try (RevWalk rw = new RevWalk(repo)) {
|
||||||
RevCommit commit = rw.parseCommit(head.getObjectId());
|
RevCommit commit = rw.parseCommit(head.getObjectId());
|
||||||
if (rsrc.getControl().canReadCommit(db.get(), repo, commit)) {
|
if (commits.canRead(rsrc.getProjectState(), repo, commit)) {
|
||||||
return head.getObjectId().name();
|
return head.getObjectId().name();
|
||||||
}
|
}
|
||||||
throw new AuthException("not allowed to see HEAD");
|
throw new AuthException("not allowed to see HEAD");
|
||||||
|
@@ -16,6 +16,7 @@ package com.google.gerrit.server.project;
|
|||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.gerrit.common.Nullable;
|
import com.google.gerrit.common.Nullable;
|
||||||
import com.google.gerrit.common.PageLinks;
|
import com.google.gerrit.common.PageLinks;
|
||||||
@@ -39,11 +40,9 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
|
|||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.account.GroupMembership;
|
import com.google.gerrit.server.account.GroupMembership;
|
||||||
import com.google.gerrit.server.change.IncludedInResolver;
|
|
||||||
import com.google.gerrit.server.config.CanonicalWebUrl;
|
import com.google.gerrit.server.config.CanonicalWebUrl;
|
||||||
import com.google.gerrit.server.config.GitReceivePackGroups;
|
import com.google.gerrit.server.config.GitReceivePackGroups;
|
||||||
import com.google.gerrit.server.config.GitUploadPackGroups;
|
import com.google.gerrit.server.config.GitUploadPackGroups;
|
||||||
import com.google.gerrit.server.git.VisibleRefFilter;
|
|
||||||
import com.google.gerrit.server.group.SystemGroupBackend;
|
import com.google.gerrit.server.group.SystemGroupBackend;
|
||||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||||
import com.google.gerrit.server.permissions.FailedPermissionBackend;
|
import com.google.gerrit.server.permissions.FailedPermissionBackend;
|
||||||
@@ -55,7 +54,6 @@ import com.google.gerrit.server.permissions.PermissionBackend.ForRef;
|
|||||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||||
import com.google.gerrit.server.permissions.ProjectPermission;
|
import com.google.gerrit.server.permissions.ProjectPermission;
|
||||||
import com.google.gerrit.server.query.change.ChangeData;
|
import com.google.gerrit.server.query.change.ChangeData;
|
||||||
import com.google.gerrit.server.query.change.InternalChangeQuery;
|
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
@@ -71,10 +69,11 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.eclipse.jgit.lib.Constants;
|
||||||
import org.eclipse.jgit.lib.Ref;
|
import org.eclipse.jgit.lib.Ref;
|
||||||
|
import org.eclipse.jgit.lib.RefDatabase;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
import org.eclipse.jgit.revwalk.RevWalk;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -132,16 +131,14 @@ public class ProjectControl {
|
|||||||
|
|
||||||
private final Set<AccountGroup.UUID> uploadGroups;
|
private final Set<AccountGroup.UUID> uploadGroups;
|
||||||
private final Set<AccountGroup.UUID> receiveGroups;
|
private final Set<AccountGroup.UUID> receiveGroups;
|
||||||
|
|
||||||
private final String canonicalWebUrl;
|
private final String canonicalWebUrl;
|
||||||
private final PermissionBackend.WithUser perm;
|
private final PermissionBackend.WithUser perm;
|
||||||
private final CurrentUser user;
|
private final CurrentUser user;
|
||||||
private final ProjectState state;
|
private final ProjectState state;
|
||||||
|
private final CommitsCollection commits;
|
||||||
private final ChangeControl.Factory changeControlFactory;
|
private final ChangeControl.Factory changeControlFactory;
|
||||||
private final PermissionCollection.Factory permissionFilter;
|
private final PermissionCollection.Factory permissionFilter;
|
||||||
private final VisibleRefFilter.Factory refFilter;
|
|
||||||
private final Collection<ContributorAgreement> contributorAgreements;
|
private final Collection<ContributorAgreement> contributorAgreements;
|
||||||
private final Provider<InternalChangeQuery> queryProvider;
|
|
||||||
private final Metrics metrics;
|
private final Metrics metrics;
|
||||||
|
|
||||||
private List<SectionMatcher> allSections;
|
private List<SectionMatcher> allSections;
|
||||||
@@ -156,22 +153,20 @@ public class ProjectControl {
|
|||||||
@GitReceivePackGroups Set<AccountGroup.UUID> receiveGroups,
|
@GitReceivePackGroups Set<AccountGroup.UUID> receiveGroups,
|
||||||
ProjectCache pc,
|
ProjectCache pc,
|
||||||
PermissionCollection.Factory permissionFilter,
|
PermissionCollection.Factory permissionFilter,
|
||||||
|
CommitsCollection commits,
|
||||||
ChangeControl.Factory changeControlFactory,
|
ChangeControl.Factory changeControlFactory,
|
||||||
VisibleRefFilter.Factory refFilter,
|
|
||||||
Provider<InternalChangeQuery> queryProvider,
|
|
||||||
@CanonicalWebUrl @Nullable String canonicalWebUrl,
|
@CanonicalWebUrl @Nullable String canonicalWebUrl,
|
||||||
PermissionBackend permissionBackend,
|
PermissionBackend permissionBackend,
|
||||||
@Assisted CurrentUser who,
|
@Assisted CurrentUser who,
|
||||||
@Assisted ProjectState ps,
|
@Assisted ProjectState ps,
|
||||||
Metrics metrics) {
|
Metrics metrics) {
|
||||||
this.changeControlFactory = changeControlFactory;
|
this.changeControlFactory = changeControlFactory;
|
||||||
this.refFilter = refFilter;
|
|
||||||
this.uploadGroups = uploadGroups;
|
this.uploadGroups = uploadGroups;
|
||||||
this.receiveGroups = receiveGroups;
|
this.receiveGroups = receiveGroups;
|
||||||
this.permissionFilter = permissionFilter;
|
this.permissionFilter = permissionFilter;
|
||||||
|
this.commits = commits;
|
||||||
this.contributorAgreements = pc.getAllProjects().getConfig().getContributorAgreements();
|
this.contributorAgreements = pc.getAllProjects().getConfig().getContributorAgreements();
|
||||||
this.canonicalWebUrl = canonicalWebUrl;
|
this.canonicalWebUrl = canonicalWebUrl;
|
||||||
this.queryProvider = queryProvider;
|
|
||||||
this.metrics = metrics;
|
this.metrics = metrics;
|
||||||
this.perm = permissionBackend.user(who);
|
this.perm = permissionBackend.user(who);
|
||||||
user = who;
|
user = who;
|
||||||
@@ -483,50 +478,26 @@ public class ProjectControl {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return whether a commit is visible to user. */
|
boolean isReachableFromHeadsOrTags(Repository repo, RevCommit commit) {
|
||||||
public boolean canReadCommit(ReviewDb db, Repository repo, RevCommit commit) {
|
|
||||||
// Look for changes associated with the commit.
|
|
||||||
try {
|
try {
|
||||||
List<ChangeData> changes =
|
RefDatabase refdb = repo.getRefDatabase();
|
||||||
queryProvider.get().byProjectCommit(getProject().getNameKey(), commit);
|
Collection<Ref> heads = refdb.getRefs(Constants.R_HEADS).values();
|
||||||
for (ChangeData change : changes) {
|
Collection<Ref> tags = refdb.getRefs(Constants.R_TAGS).values();
|
||||||
if (controlFor(db, change.change()).isVisible(db)) {
|
Map<String, Ref> refs = Maps.newHashMapWithExpectedSize(heads.size() + tags.size());
|
||||||
return true;
|
for (Ref r : Iterables.concat(heads, tags)) {
|
||||||
}
|
refs.put(r.getName(), r);
|
||||||
}
|
}
|
||||||
} catch (OrmException e) {
|
return commits.isReachableFrom(state, repo, commit, refs);
|
||||||
log.error(
|
|
||||||
"Cannot look up change for commit " + commit.name() + " in " + getProject().getName(), e);
|
|
||||||
}
|
|
||||||
// Scan all visible refs.
|
|
||||||
return canReadCommitFromVisibleRef(repo, commit);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean canReadCommitFromVisibleRef(Repository repo, RevCommit commit) {
|
|
||||||
try (RevWalk rw = new RevWalk(repo)) {
|
|
||||||
return isMergedIntoVisibleRef(repo, rw, commit, repo.getAllRefs().values());
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
String msg =
|
log.error(
|
||||||
String.format(
|
String.format(
|
||||||
"Cannot verify permissions to commit object %s in repository %s",
|
"Cannot verify permissions to commit object %s in repository %s",
|
||||||
commit.name(), getProject().getNameKey());
|
commit.name(), getProject().getNameKey()),
|
||||||
log.error(msg, e);
|
e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isMergedIntoVisibleRef(
|
|
||||||
Repository repo, RevWalk rw, RevCommit commit, Collection<Ref> unfilteredRefs)
|
|
||||||
throws IOException {
|
|
||||||
VisibleRefFilter filter = refFilter.create(state, repo);
|
|
||||||
Map<String, Ref> m = Maps.newHashMapWithExpectedSize(unfilteredRefs.size());
|
|
||||||
for (Ref r : unfilteredRefs) {
|
|
||||||
m.put(r.getName(), r);
|
|
||||||
}
|
|
||||||
Map<String, Ref> refs = filter.filter(m, true);
|
|
||||||
return IncludedInResolver.includedInAny(repo, rw, commit, refs.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
ForProject asForProject() {
|
ForProject asForProject() {
|
||||||
return new ForProjectImpl();
|
return new ForProjectImpl();
|
||||||
}
|
}
|
||||||
|
@@ -45,9 +45,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.eclipse.jgit.lib.Constants;
|
|
||||||
import org.eclipse.jgit.lib.PersonIdent;
|
import org.eclipse.jgit.lib.PersonIdent;
|
||||||
import org.eclipse.jgit.lib.Ref;
|
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
import org.eclipse.jgit.revwalk.RevObject;
|
import org.eclipse.jgit.revwalk.RevObject;
|
||||||
@@ -347,7 +345,7 @@ public class RefControl {
|
|||||||
// If the user has push permissions, they can create the ref regardless
|
// If the user has push permissions, they can create the ref regardless
|
||||||
// of whether they are pushing any new objects along with the create.
|
// of whether they are pushing any new objects along with the create.
|
||||||
return null;
|
return null;
|
||||||
} else if (isMergedIntoBranchOrTag(repo, commit)) {
|
} else if (projectControl.isReachableFromHeadsOrTags(repo, commit)) {
|
||||||
// If the user has no push permissions, check whether the object is
|
// If the user has no push permissions, check whether the object is
|
||||||
// merged into a branch or tag readable by this user. If so, they are
|
// merged into a branch or tag readable by this user. If so, they are
|
||||||
// not effectively "pushing" more objects, so they can create the ref
|
// not effectively "pushing" more objects, so they can create the ref
|
||||||
@@ -357,21 +355,6 @@ public class RefControl {
|
|||||||
return userId + " lacks permission " + Permission.PUSH + " for creating new commit object";
|
return userId + " lacks permission " + Permission.PUSH + " for creating new commit object";
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isMergedIntoBranchOrTag(Repository repo, RevCommit commit) {
|
|
||||||
try (RevWalk rw = new RevWalk(repo)) {
|
|
||||||
List<Ref> refs = new ArrayList<>(repo.getRefDatabase().getRefs(Constants.R_HEADS).values());
|
|
||||||
refs.addAll(repo.getRefDatabase().getRefs(Constants.R_TAGS).values());
|
|
||||||
return projectControl.isMergedIntoVisibleRef(repo, rw, commit, refs);
|
|
||||||
} catch (IOException e) {
|
|
||||||
String msg =
|
|
||||||
String.format(
|
|
||||||
"Cannot verify permissions to commit object %s in repository %s",
|
|
||||||
commit.name(), projectControl.getProject().getNameKey());
|
|
||||||
log.error(msg, e);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the user can delete the Git ref controlled by this object.
|
* Determines whether the user can delete the Git ref controlled by this object.
|
||||||
*
|
*
|
||||||
|
@@ -55,19 +55,19 @@ import org.junit.After;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/** Unit tests for {@link ProjectControl}. */
|
/** Unit tests for {@link CommitsCollection}. */
|
||||||
public class ProjectControlTest {
|
public class CommitsCollectionTest {
|
||||||
@Inject private AccountManager accountManager;
|
@Inject private AccountManager accountManager;
|
||||||
@Inject private IdentifiedUser.GenericFactory userFactory;
|
@Inject private IdentifiedUser.GenericFactory userFactory;
|
||||||
@Inject private InMemoryDatabase schemaFactory;
|
@Inject private InMemoryDatabase schemaFactory;
|
||||||
@Inject private InMemoryRepositoryManager repoManager;
|
@Inject private InMemoryRepositoryManager repoManager;
|
||||||
@Inject private ProjectControl.GenericFactory projectControlFactory;
|
|
||||||
@Inject private SchemaCreator schemaCreator;
|
@Inject private SchemaCreator schemaCreator;
|
||||||
@Inject private ThreadLocalRequestContext requestContext;
|
@Inject private ThreadLocalRequestContext requestContext;
|
||||||
@Inject protected ProjectCache projectCache;
|
@Inject protected ProjectCache projectCache;
|
||||||
@Inject protected MetaDataUpdate.Server metaDataUpdateFactory;
|
@Inject protected MetaDataUpdate.Server metaDataUpdateFactory;
|
||||||
@Inject protected AllProjectsName allProjects;
|
@Inject protected AllProjectsName allProjects;
|
||||||
@Inject protected GroupCache groupCache;
|
@Inject protected GroupCache groupCache;
|
||||||
|
@Inject private CommitsCollection commits;
|
||||||
|
|
||||||
private LifecycleManager lifecycle;
|
private LifecycleManager lifecycle;
|
||||||
private ReviewDb db;
|
private ReviewDb db;
|
||||||
@@ -135,11 +135,11 @@ public class ProjectControlTest {
|
|||||||
public void canReadCommitWhenAllRefsVisible() throws Exception {
|
public void canReadCommitWhenAllRefsVisible() throws Exception {
|
||||||
allow(project, READ, REGISTERED_USERS, "refs/*");
|
allow(project, READ, REGISTERED_USERS, "refs/*");
|
||||||
ObjectId id = repo.branch("master").commit().create();
|
ObjectId id = repo.branch("master").commit().create();
|
||||||
ProjectControl pc = newProjectControl();
|
ProjectState state = readProjectState();
|
||||||
RevWalk rw = repo.getRevWalk();
|
RevWalk rw = repo.getRevWalk();
|
||||||
Repository r = repo.getRepository();
|
Repository r = repo.getRepository();
|
||||||
|
|
||||||
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id)));
|
assertTrue(commits.canRead(state, r, rw.parseCommit(id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -150,12 +150,12 @@ public class ProjectControlTest {
|
|||||||
ObjectId id1 = repo.branch("branch1").commit().create();
|
ObjectId id1 = repo.branch("branch1").commit().create();
|
||||||
ObjectId id2 = repo.branch("branch2").commit().create();
|
ObjectId id2 = repo.branch("branch2").commit().create();
|
||||||
|
|
||||||
ProjectControl pc = newProjectControl();
|
ProjectState state = readProjectState();
|
||||||
RevWalk rw = repo.getRevWalk();
|
RevWalk rw = repo.getRevWalk();
|
||||||
Repository r = repo.getRepository();
|
Repository r = repo.getRepository();
|
||||||
|
|
||||||
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id1)));
|
assertTrue(commits.canRead(state, r, rw.parseCommit(id1)));
|
||||||
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id2)));
|
assertTrue(commits.canRead(state, r, rw.parseCommit(id2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -166,12 +166,12 @@ public class ProjectControlTest {
|
|||||||
ObjectId id1 = repo.branch("branch1").commit().create();
|
ObjectId id1 = repo.branch("branch1").commit().create();
|
||||||
ObjectId id2 = repo.branch("branch2").commit().create();
|
ObjectId id2 = repo.branch("branch2").commit().create();
|
||||||
|
|
||||||
ProjectControl pc = newProjectControl();
|
ProjectState state = readProjectState();
|
||||||
RevWalk rw = repo.getRevWalk();
|
RevWalk rw = repo.getRevWalk();
|
||||||
Repository r = repo.getRepository();
|
Repository r = repo.getRepository();
|
||||||
|
|
||||||
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id1)));
|
assertTrue(commits.canRead(state, r, rw.parseCommit(id1)));
|
||||||
assertFalse(pc.canReadCommit(db, r, rw.parseCommit(id2)));
|
assertFalse(commits.canRead(state, r, rw.parseCommit(id2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -185,11 +185,11 @@ public class ProjectControlTest {
|
|||||||
RevCommit parent2 = repo.commit().create();
|
RevCommit parent2 = repo.commit().create();
|
||||||
repo.branch("branch2").commit().parent(parent2).create();
|
repo.branch("branch2").commit().parent(parent2).create();
|
||||||
|
|
||||||
ProjectControl pc = newProjectControl();
|
ProjectState state = readProjectState();
|
||||||
RevWalk rw = repo.getRevWalk();
|
RevWalk rw = repo.getRevWalk();
|
||||||
Repository r = repo.getRepository();
|
Repository r = repo.getRepository();
|
||||||
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(parent1)));
|
assertTrue(commits.canRead(state, r, rw.parseCommit(parent1)));
|
||||||
assertFalse(pc.canReadCommit(db, r, rw.parseCommit(parent2)));
|
assertFalse(commits.canRead(state, r, rw.parseCommit(parent2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -199,16 +199,16 @@ public class ProjectControlTest {
|
|||||||
RevCommit parent1 = repo.commit().create();
|
RevCommit parent1 = repo.commit().create();
|
||||||
ObjectId id1 = repo.branch("branch1").commit().parent(parent1).create();
|
ObjectId id1 = repo.branch("branch1").commit().parent(parent1).create();
|
||||||
|
|
||||||
ProjectControl pc = newProjectControl();
|
ProjectState state = readProjectState();
|
||||||
RevWalk rw = repo.getRevWalk();
|
RevWalk rw = repo.getRevWalk();
|
||||||
Repository r = repo.getRepository();
|
Repository r = repo.getRepository();
|
||||||
|
|
||||||
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(parent1)));
|
assertTrue(commits.canRead(state, r, rw.parseCommit(parent1)));
|
||||||
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id1)));
|
assertTrue(commits.canRead(state, r, rw.parseCommit(id1)));
|
||||||
|
|
||||||
repo.branch("branch1").update(parent1);
|
repo.branch("branch1").update(parent1);
|
||||||
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(parent1)));
|
assertTrue(commits.canRead(state, r, rw.parseCommit(parent1)));
|
||||||
assertFalse(pc.canReadCommit(db, r, rw.parseCommit(id1)));
|
assertFalse(commits.canRead(state, r, rw.parseCommit(id1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -218,20 +218,20 @@ public class ProjectControlTest {
|
|||||||
RevCommit parent1 = repo.commit().create();
|
RevCommit parent1 = repo.commit().create();
|
||||||
ObjectId id1 = repo.branch("branch1").commit().parent(parent1).create();
|
ObjectId id1 = repo.branch("branch1").commit().parent(parent1).create();
|
||||||
|
|
||||||
ProjectControl pc = newProjectControl();
|
ProjectState state = readProjectState();
|
||||||
RevWalk rw = repo.getRevWalk();
|
RevWalk rw = repo.getRevWalk();
|
||||||
Repository r = repo.getRepository();
|
Repository r = repo.getRepository();
|
||||||
|
|
||||||
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(parent1)));
|
assertTrue(commits.canRead(state, r, rw.parseCommit(parent1)));
|
||||||
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id1)));
|
assertTrue(commits.canRead(state, r, rw.parseCommit(id1)));
|
||||||
|
|
||||||
repo.branch("branch1").update(parent1);
|
repo.branch("branch1").update(parent1);
|
||||||
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(parent1)));
|
assertTrue(commits.canRead(state, r, rw.parseCommit(parent1)));
|
||||||
assertFalse(pc.canReadCommit(db, r, rw.parseCommit(id1)));
|
assertFalse(commits.canRead(state, r, rw.parseCommit(id1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProjectControl newProjectControl() throws Exception {
|
private ProjectState readProjectState() throws Exception {
|
||||||
return projectControlFactory.controlFor(project.getName(), user);
|
return projectCache.get(project.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void allow(ProjectConfig project, String permission, AccountGroup.UUID id, String ref)
|
protected void allow(ProjectConfig project, String permission, AccountGroup.UUID id, String ref)
|
@@ -60,7 +60,6 @@ import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener;
|
|||||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||||
import com.google.gerrit.server.permissions.ProjectPermission;
|
import com.google.gerrit.server.permissions.ProjectPermission;
|
||||||
import com.google.gerrit.server.permissions.RefPermission;
|
import com.google.gerrit.server.permissions.RefPermission;
|
||||||
import com.google.gerrit.server.query.change.InternalChangeQuery;
|
|
||||||
import com.google.gerrit.server.schema.SchemaCreator;
|
import com.google.gerrit.server.schema.SchemaCreator;
|
||||||
import com.google.gerrit.server.util.RequestContext;
|
import com.google.gerrit.server.util.RequestContext;
|
||||||
import com.google.gerrit.server.util.ThreadLocalRequestContext;
|
import com.google.gerrit.server.util.ThreadLocalRequestContext;
|
||||||
@@ -212,7 +211,6 @@ public class RefControlTest {
|
|||||||
@Inject private SingleVersionListener singleVersionListener;
|
@Inject private SingleVersionListener singleVersionListener;
|
||||||
@Inject private InMemoryDatabase schemaFactory;
|
@Inject private InMemoryDatabase schemaFactory;
|
||||||
@Inject private ThreadLocalRequestContext requestContext;
|
@Inject private ThreadLocalRequestContext requestContext;
|
||||||
@Inject private Provider<InternalChangeQuery> queryProvider;
|
|
||||||
@Inject private ProjectControl.Metrics metrics;
|
@Inject private ProjectControl.Metrics metrics;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -899,17 +897,14 @@ public class RefControlTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ProjectControl user(ProjectConfig local, String name, AccountGroup.UUID... memberOf) {
|
private ProjectControl user(ProjectConfig local, String name, AccountGroup.UUID... memberOf) {
|
||||||
String canonicalWebUrl = "http://localhost";
|
|
||||||
|
|
||||||
return new ProjectControl(
|
return new ProjectControl(
|
||||||
Collections.<AccountGroup.UUID>emptySet(),
|
Collections.<AccountGroup.UUID>emptySet(),
|
||||||
Collections.<AccountGroup.UUID>emptySet(),
|
Collections.<AccountGroup.UUID>emptySet(),
|
||||||
projectCache,
|
projectCache,
|
||||||
sectionSorter,
|
sectionSorter,
|
||||||
|
null, // commitsCollection
|
||||||
changeControlFactory,
|
changeControlFactory,
|
||||||
null, // refFilter
|
"http://localhost", // canonicalWebUrl
|
||||||
queryProvider,
|
|
||||||
canonicalWebUrl,
|
|
||||||
permissionBackend,
|
permissionBackend,
|
||||||
new MockUser(name, memberOf),
|
new MockUser(name, memberOf),
|
||||||
newProjectState(local),
|
newProjectState(local),
|
||||||
|
@@ -20,6 +20,7 @@ import com.google.gerrit.server.IdentifiedUser;
|
|||||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||||
import com.google.gerrit.server.project.ProjectControl;
|
import com.google.gerrit.server.project.ProjectControl;
|
||||||
|
import com.google.gerrit.server.project.ProjectState;
|
||||||
import com.google.gerrit.sshd.SshScope.Context;
|
import com.google.gerrit.sshd.SshScope.Context;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -45,6 +46,8 @@ public abstract class AbstractGitCommand extends BaseCommand {
|
|||||||
@Inject private IdentifiedUser.GenericFactory userFactory;
|
@Inject private IdentifiedUser.GenericFactory userFactory;
|
||||||
|
|
||||||
protected Repository repo;
|
protected Repository repo;
|
||||||
|
protected ProjectState state;
|
||||||
|
protected Project.NameKey projectName;
|
||||||
protected Project project;
|
protected Project project;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -86,10 +89,12 @@ public abstract class AbstractGitCommand extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void service() throws IOException, PermissionBackendException, Failure {
|
private void service() throws IOException, PermissionBackendException, Failure {
|
||||||
project = projectControl.getProjectState().getProject();
|
state = projectControl.getProjectState();
|
||||||
|
project = state.getProject();
|
||||||
|
projectName = project.getNameKey();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
repo = repoManager.openRepository(project.getNameKey());
|
repo = repoManager.openRepository(projectName);
|
||||||
} catch (RepositoryNotFoundException e) {
|
} catch (RepositoryNotFoundException e) {
|
||||||
throw new Failure(1, "fatal: '" + project.getName() + "': not a git archive", e);
|
throw new Failure(1, "fatal: '" + project.getName() + "': not a git archive", e);
|
||||||
}
|
}
|
||||||
|
@@ -18,13 +18,13 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.gerrit.extensions.restapi.AuthException;
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.change.AllowedFormats;
|
import com.google.gerrit.server.change.AllowedFormats;
|
||||||
import com.google.gerrit.server.change.ArchiveFormat;
|
import com.google.gerrit.server.change.ArchiveFormat;
|
||||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||||
import com.google.gerrit.server.permissions.ProjectPermission;
|
import com.google.gerrit.server.permissions.ProjectPermission;
|
||||||
|
import com.google.gerrit.server.project.CommitsCollection;
|
||||||
import com.google.gerrit.sshd.AbstractGitCommand;
|
import com.google.gerrit.sshd.AbstractGitCommand;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -121,9 +121,9 @@ public class UploadArchive extends AbstractGitCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject private PermissionBackend permissionBackend;
|
@Inject private PermissionBackend permissionBackend;
|
||||||
|
@Inject private CommitsCollection commits;
|
||||||
@Inject private IdentifiedUser user;
|
@Inject private IdentifiedUser user;
|
||||||
@Inject private AllowedFormats allowedFormats;
|
@Inject private AllowedFormats allowedFormats;
|
||||||
@Inject private ReviewDb db;
|
|
||||||
private Options options = new Options();
|
private Options options = new Options();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -244,13 +244,13 @@ public class UploadArchive extends AbstractGitCommand {
|
|||||||
|
|
||||||
private boolean canRead(ObjectId revId) throws IOException, PermissionBackendException {
|
private boolean canRead(ObjectId revId) throws IOException, PermissionBackendException {
|
||||||
try {
|
try {
|
||||||
permissionBackend.user(user).project(project.getNameKey()).check(ProjectPermission.READ);
|
permissionBackend.user(user).project(projectName).check(ProjectPermission.READ);
|
||||||
return true;
|
return true;
|
||||||
} catch (AuthException e) {
|
} catch (AuthException e) {
|
||||||
// Check reachability of the specific revision.
|
// Check reachability of the specific revision.
|
||||||
try (RevWalk rw = new RevWalk(repo)) {
|
try (RevWalk rw = new RevWalk(repo)) {
|
||||||
RevCommit commit = rw.parseCommit(revId);
|
RevCommit commit = rw.parseCommit(revId);
|
||||||
return projectControl.canReadCommit(db, repo, commit);
|
return commits.canRead(state, repo, commit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Submodule plugins/replication updated: fae5360380...0721b208ad
Reference in New Issue
Block a user