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:
Dave Borowitz
2017-08-07 16:57:41 +00:00
committed by Gerrit Code Review
13 changed files with 139 additions and 127 deletions

View File

@@ -23,6 +23,7 @@ import com.google.gerrit.extensions.api.projects.CommentLinkInfo;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.extensions.registration.DynamicMap;
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.rules.PrologModule;
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.PatchListCacheImpl;
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.ProjectCacheImpl;
import com.google.gerrit.server.project.ProjectState;
@@ -115,6 +117,8 @@ public class BatchProgramModule extends FactoryModule {
.in(SINGLETON);
bind(new TypeLiteral<DynamicMap<ChangeQueryProcessor.ChangeAttributeFactory>>() {})
.toInstance(DynamicMap.<ChangeQueryProcessor.ChangeAttributeFactory>emptyMap());
bind(new TypeLiteral<DynamicMap<RestView<CommitResource>>>() {})
.toInstance(DynamicMap.<RestView<CommitResource>>emptyMap());
bind(String.class)
.annotatedWith(CanonicalWebUrl.class)
.toProvider(CanonicalWebUrlProvider.class);

View File

@@ -56,9 +56,11 @@ import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.RefPermission;
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.ProjectControl;
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.update.BatchUpdate;
import com.google.gerrit.server.update.RetryHelper;
@@ -100,6 +102,7 @@ public class CreateChange
private final PermissionBackend permissionBackend;
private final Provider<CurrentUser> user;
private final ProjectsCollection projectsCollection;
private final CommitsCollection commits;
private final ChangeInserter.Factory changeInserterFactory;
private final ChangeJson.Factory jsonFactory;
private final ChangeFinder changeFinder;
@@ -121,6 +124,7 @@ public class CreateChange
PermissionBackend permissionBackend,
Provider<CurrentUser> user,
ProjectsCollection projectsCollection,
CommitsCollection commits,
ChangeInserter.Factory changeInserterFactory,
ChangeJson.Factory json,
ChangeFinder changeFinder,
@@ -139,6 +143,7 @@ public class CreateChange
this.permissionBackend = permissionBackend;
this.user = user;
this.projectsCollection = projectsCollection;
this.commits = commits;
this.changeInserterFactory = changeInserterFactory;
this.jsonFactory = json;
this.changeFinder = changeFinder;
@@ -311,12 +316,13 @@ public class CreateChange
throw new BadRequestException("merge.source must be non-empty");
}
ProjectState state = projectControl.getProjectState();
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);
}
MergeUtil mergeUtil = mergeUtilFactory.create(projectControl.getProjectState());
MergeUtil mergeUtil = mergeUtilFactory.create(state);
// default merge strategy from project settings
String mergeStrategy =
MoreObjects.firstNonNull(

View File

@@ -43,8 +43,10 @@ import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.PermissionBackendException;
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.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.RetryHelper;
import com.google.gerrit.server.update.RetryingRestModifyView;
@@ -69,9 +71,9 @@ import org.eclipse.jgit.util.ChangeIdUtil;
@Singleton
public class CreateMergePatchSet
extends RetryingRestModifyView<ChangeResource, MergePatchSetInput, Response<ChangeInfo>> {
private final Provider<ReviewDb> db;
private final GitRepositoryManager gitManager;
private final CommitsCollection commits;
private final TimeZone serverTimeZone;
private final Provider<CurrentUser> user;
private final ChangeJson.Factory jsonFactory;
@@ -83,6 +85,7 @@ public class CreateMergePatchSet
CreateMergePatchSet(
Provider<ReviewDb> db,
GitRepositoryManager gitManager,
CommitsCollection commits,
@GerritPersonIdent PersonIdent myIdent,
Provider<CurrentUser> user,
ChangeJson.Factory json,
@@ -93,6 +96,7 @@ public class CreateMergePatchSet
super(retryHelper);
this.db = db;
this.gitManager = gitManager;
this.commits = commits;
this.serverTimeZone = myIdent.getTimeZone();
this.user = user;
this.jsonFactory = json;
@@ -116,6 +120,7 @@ public class CreateMergePatchSet
ChangeControl ctl = rsrc.getControl();
PatchSet ps = psUtil.current(db.get(), ctl.getNotes());
ProjectControl projectControl = ctl.getProjectControl();
ProjectState state = projectControl.getProjectState();
Change change = ctl.getChange();
Project.NameKey project = change.getProject();
Branch.NameKey dest = change.getDest();
@@ -125,7 +130,7 @@ public class CreateMergePatchSet
RevWalk rw = new RevWalk(reader)) {
RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, merge.source);
if (!projectControl.canReadCommit(db.get(), git, sourceCommit)) {
if (!commits.canRead(state, git, sourceCommit)) {
throw new ResourceNotFoundException(
"cannot find source commit: " + merge.source + " to merge.");
}

View File

@@ -19,13 +19,11 @@ import com.google.gerrit.extensions.common.MergeableInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
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.git.GitRepositoryManager;
import com.google.gerrit.server.git.InMemoryInserter;
import com.google.gerrit.server.git.MergeUtil;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import org.eclipse.jgit.lib.Config;
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. */
public class CheckMergeability implements RestReadView<BranchResource> {
private String source;
private String strategy;
private SubmitType submitType;
private final Provider<ReviewDb> db;
@Option(
name = "--source",
@@ -68,14 +64,15 @@ public class CheckMergeability implements RestReadView<BranchResource> {
}
private final GitRepositoryManager gitManager;
private final CommitsCollection commits;
@Inject
CheckMergeability(
GitRepositoryManager gitManager, @GerritServerConfig Config cfg, Provider<ReviewDb> db) {
GitRepositoryManager gitManager, CommitsCollection commits, @GerritServerConfig Config cfg) {
this.gitManager = gitManager;
this.commits = commits;
this.strategy = MergeUtil.getMergeStrategy(cfg).getName();
this.submitType = cfg.getEnum("project", null, "submitType", SubmitType.MERGE_IF_NECESSARY);
this.db = db;
}
@Override
@@ -102,7 +99,7 @@ public class CheckMergeability implements RestReadView<BranchResource> {
RevCommit targetCommit = rw.parseCommit(destRef.getObjectId());
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);
}

View File

@@ -19,33 +19,48 @@ import com.google.gerrit.extensions.restapi.ChildCollection;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
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.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.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class CommitsCollection implements ChildCollection<ProjectResource, CommitResource> {
private static final Logger log = LoggerFactory.getLogger(CommitsCollection.class);
private final DynamicMap<RestView<CommitResource>> views;
private final GitRepositoryManager repoManager;
private final Provider<ReviewDb> db;
private final VisibleRefFilter.Factory refFilter;
private final Provider<InternalChangeQuery> queryProvider;
@Inject
public CommitsCollection(
DynamicMap<RestView<CommitResource>> views,
GitRepositoryManager repoManager,
Provider<ReviewDb> db) {
VisibleRefFilter.Factory refFilter,
Provider<InternalChangeQuery> queryProvider) {
this.views = views;
this.repoManager = repoManager;
this.db = db;
this.refFilter = refFilter;
this.queryProvider = queryProvider;
}
@Override
@@ -67,7 +82,7 @@ public class CommitsCollection implements ChildCollection<ProjectResource, Commi
RevWalk rw = new RevWalk(repo)) {
RevCommit commit = rw.parseCommit(objectId);
rw.parseBody(commit);
if (!parent.getControl().canReadCommit(db.get(), repo, commit)) {
if (!canRead(parent.getProjectState(), repo, commit)) {
throw new ResourceNotFoundException(id);
}
for (int i = 0; i < commit.getParentCount(); i++) {
@@ -83,4 +98,37 @@ public class CommitsCollection implements ChildCollection<ProjectResource, Commi
public DynamicMap<RestView<CommitResource>> 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;
}
}
}

View File

@@ -17,10 +17,8 @@ package com.google.gerrit.server.project;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
@@ -34,13 +32,13 @@ import org.eclipse.jgit.revwalk.RevWalk;
@Singleton
public class GetHead implements RestReadView<ProjectResource> {
private GitRepositoryManager repoManager;
private Provider<ReviewDb> db;
private final GitRepositoryManager repoManager;
private final CommitsCollection commits;
@Inject
GetHead(GitRepositoryManager repoManager, Provider<ReviewDb> db) {
GetHead(GitRepositoryManager repoManager, CommitsCollection commits) {
this.repoManager = repoManager;
this.db = db;
this.commits = commits;
}
@Override
@@ -59,7 +57,7 @@ public class GetHead implements RestReadView<ProjectResource> {
} else if (head.getObjectId() != null) {
try (RevWalk rw = new RevWalk(repo)) {
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();
}
throw new AuthException("not allowed to see HEAD");

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.server.project;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.gerrit.common.Nullable;
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.IdentifiedUser;
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.GitReceivePackGroups;
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.notedb.ChangeNotes;
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.ProjectPermission;
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.Provider;
@@ -71,10 +69,11 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -132,16 +131,14 @@ public class ProjectControl {
private final Set<AccountGroup.UUID> uploadGroups;
private final Set<AccountGroup.UUID> receiveGroups;
private final String canonicalWebUrl;
private final PermissionBackend.WithUser perm;
private final CurrentUser user;
private final ProjectState state;
private final CommitsCollection commits;
private final ChangeControl.Factory changeControlFactory;
private final PermissionCollection.Factory permissionFilter;
private final VisibleRefFilter.Factory refFilter;
private final Collection<ContributorAgreement> contributorAgreements;
private final Provider<InternalChangeQuery> queryProvider;
private final Metrics metrics;
private List<SectionMatcher> allSections;
@@ -156,22 +153,20 @@ public class ProjectControl {
@GitReceivePackGroups Set<AccountGroup.UUID> receiveGroups,
ProjectCache pc,
PermissionCollection.Factory permissionFilter,
CommitsCollection commits,
ChangeControl.Factory changeControlFactory,
VisibleRefFilter.Factory refFilter,
Provider<InternalChangeQuery> queryProvider,
@CanonicalWebUrl @Nullable String canonicalWebUrl,
PermissionBackend permissionBackend,
@Assisted CurrentUser who,
@Assisted ProjectState ps,
Metrics metrics) {
this.changeControlFactory = changeControlFactory;
this.refFilter = refFilter;
this.uploadGroups = uploadGroups;
this.receiveGroups = receiveGroups;
this.permissionFilter = permissionFilter;
this.commits = commits;
this.contributorAgreements = pc.getAllProjects().getConfig().getContributorAgreements();
this.canonicalWebUrl = canonicalWebUrl;
this.queryProvider = queryProvider;
this.metrics = metrics;
this.perm = permissionBackend.user(who);
user = who;
@@ -483,50 +478,26 @@ public class ProjectControl {
return false;
}
/** @return whether a commit is visible to user. */
public boolean canReadCommit(ReviewDb db, Repository repo, RevCommit commit) {
// Look for changes associated with the commit.
boolean isReachableFromHeadsOrTags(Repository repo, RevCommit commit) {
try {
List<ChangeData> changes =
queryProvider.get().byProjectCommit(getProject().getNameKey(), commit);
for (ChangeData change : changes) {
if (controlFor(db, change.change()).isVisible(db)) {
return true;
RefDatabase refdb = repo.getRefDatabase();
Collection<Ref> heads = refdb.getRefs(Constants.R_HEADS).values();
Collection<Ref> tags = refdb.getRefs(Constants.R_TAGS).values();
Map<String, Ref> refs = Maps.newHashMapWithExpectedSize(heads.size() + tags.size());
for (Ref r : Iterables.concat(heads, tags)) {
refs.put(r.getName(), r);
}
}
} catch (OrmException e) {
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());
return commits.isReachableFrom(state, repo, commit, refs);
} catch (IOException e) {
String msg =
log.error(
String.format(
"Cannot verify permissions to commit object %s in repository %s",
commit.name(), getProject().getNameKey());
log.error(msg, e);
commit.name(), getProject().getNameKey()),
e);
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() {
return new ForProjectImpl();
}

View File

@@ -45,9 +45,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
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
// of whether they are pushing any new objects along with the create.
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
// 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
@@ -357,21 +355,6 @@ public class RefControl {
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.
*

View File

@@ -55,19 +55,19 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/** Unit tests for {@link ProjectControl}. */
public class ProjectControlTest {
/** Unit tests for {@link CommitsCollection}. */
public class CommitsCollectionTest {
@Inject private AccountManager accountManager;
@Inject private IdentifiedUser.GenericFactory userFactory;
@Inject private InMemoryDatabase schemaFactory;
@Inject private InMemoryRepositoryManager repoManager;
@Inject private ProjectControl.GenericFactory projectControlFactory;
@Inject private SchemaCreator schemaCreator;
@Inject private ThreadLocalRequestContext requestContext;
@Inject protected ProjectCache projectCache;
@Inject protected MetaDataUpdate.Server metaDataUpdateFactory;
@Inject protected AllProjectsName allProjects;
@Inject protected GroupCache groupCache;
@Inject private CommitsCollection commits;
private LifecycleManager lifecycle;
private ReviewDb db;
@@ -135,11 +135,11 @@ public class ProjectControlTest {
public void canReadCommitWhenAllRefsVisible() throws Exception {
allow(project, READ, REGISTERED_USERS, "refs/*");
ObjectId id = repo.branch("master").commit().create();
ProjectControl pc = newProjectControl();
ProjectState state = readProjectState();
RevWalk rw = repo.getRevWalk();
Repository r = repo.getRepository();
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id)));
assertTrue(commits.canRead(state, r, rw.parseCommit(id)));
}
@Test
@@ -150,12 +150,12 @@ public class ProjectControlTest {
ObjectId id1 = repo.branch("branch1").commit().create();
ObjectId id2 = repo.branch("branch2").commit().create();
ProjectControl pc = newProjectControl();
ProjectState state = readProjectState();
RevWalk rw = repo.getRevWalk();
Repository r = repo.getRepository();
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id1)));
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id2)));
assertTrue(commits.canRead(state, r, rw.parseCommit(id1)));
assertTrue(commits.canRead(state, r, rw.parseCommit(id2)));
}
@Test
@@ -166,12 +166,12 @@ public class ProjectControlTest {
ObjectId id1 = repo.branch("branch1").commit().create();
ObjectId id2 = repo.branch("branch2").commit().create();
ProjectControl pc = newProjectControl();
ProjectState state = readProjectState();
RevWalk rw = repo.getRevWalk();
Repository r = repo.getRepository();
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id1)));
assertFalse(pc.canReadCommit(db, r, rw.parseCommit(id2)));
assertTrue(commits.canRead(state, r, rw.parseCommit(id1)));
assertFalse(commits.canRead(state, r, rw.parseCommit(id2)));
}
@Test
@@ -185,11 +185,11 @@ public class ProjectControlTest {
RevCommit parent2 = repo.commit().create();
repo.branch("branch2").commit().parent(parent2).create();
ProjectControl pc = newProjectControl();
ProjectState state = readProjectState();
RevWalk rw = repo.getRevWalk();
Repository r = repo.getRepository();
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(parent1)));
assertFalse(pc.canReadCommit(db, r, rw.parseCommit(parent2)));
assertTrue(commits.canRead(state, r, rw.parseCommit(parent1)));
assertFalse(commits.canRead(state, r, rw.parseCommit(parent2)));
}
@Test
@@ -199,16 +199,16 @@ public class ProjectControlTest {
RevCommit parent1 = repo.commit().create();
ObjectId id1 = repo.branch("branch1").commit().parent(parent1).create();
ProjectControl pc = newProjectControl();
ProjectState state = readProjectState();
RevWalk rw = repo.getRevWalk();
Repository r = repo.getRepository();
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(parent1)));
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id1)));
assertTrue(commits.canRead(state, r, rw.parseCommit(parent1)));
assertTrue(commits.canRead(state, r, rw.parseCommit(id1)));
repo.branch("branch1").update(parent1);
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(parent1)));
assertFalse(pc.canReadCommit(db, r, rw.parseCommit(id1)));
assertTrue(commits.canRead(state, r, rw.parseCommit(parent1)));
assertFalse(commits.canRead(state, r, rw.parseCommit(id1)));
}
@Test
@@ -218,20 +218,20 @@ public class ProjectControlTest {
RevCommit parent1 = repo.commit().create();
ObjectId id1 = repo.branch("branch1").commit().parent(parent1).create();
ProjectControl pc = newProjectControl();
ProjectState state = readProjectState();
RevWalk rw = repo.getRevWalk();
Repository r = repo.getRepository();
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(parent1)));
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(id1)));
assertTrue(commits.canRead(state, r, rw.parseCommit(parent1)));
assertTrue(commits.canRead(state, r, rw.parseCommit(id1)));
repo.branch("branch1").update(parent1);
assertTrue(pc.canReadCommit(db, r, rw.parseCommit(parent1)));
assertFalse(pc.canReadCommit(db, r, rw.parseCommit(id1)));
assertTrue(commits.canRead(state, r, rw.parseCommit(parent1)));
assertFalse(commits.canRead(state, r, rw.parseCommit(id1)));
}
private ProjectControl newProjectControl() throws Exception {
return projectControlFactory.controlFor(project.getName(), user);
private ProjectState readProjectState() throws Exception {
return projectCache.get(project.getName());
}
protected void allow(ProjectConfig project, String permission, AccountGroup.UUID id, String ref)

View File

@@ -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.ProjectPermission;
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.util.RequestContext;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
@@ -212,7 +211,6 @@ public class RefControlTest {
@Inject private SingleVersionListener singleVersionListener;
@Inject private InMemoryDatabase schemaFactory;
@Inject private ThreadLocalRequestContext requestContext;
@Inject private Provider<InternalChangeQuery> queryProvider;
@Inject private ProjectControl.Metrics metrics;
@Before
@@ -899,17 +897,14 @@ public class RefControlTest {
}
private ProjectControl user(ProjectConfig local, String name, AccountGroup.UUID... memberOf) {
String canonicalWebUrl = "http://localhost";
return new ProjectControl(
Collections.<AccountGroup.UUID>emptySet(),
Collections.<AccountGroup.UUID>emptySet(),
projectCache,
sectionSorter,
null, // commitsCollection
changeControlFactory,
null, // refFilter
queryProvider,
canonicalWebUrl,
"http://localhost", // canonicalWebUrl
permissionBackend,
new MockUser(name, memberOf),
newProjectState(local),

View File

@@ -20,6 +20,7 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.sshd.SshScope.Context;
import com.google.inject.Inject;
import java.io.IOException;
@@ -45,6 +46,8 @@ public abstract class AbstractGitCommand extends BaseCommand {
@Inject private IdentifiedUser.GenericFactory userFactory;
protected Repository repo;
protected ProjectState state;
protected Project.NameKey projectName;
protected Project project;
@Override
@@ -86,10 +89,12 @@ public abstract class AbstractGitCommand extends BaseCommand {
}
private void service() throws IOException, PermissionBackendException, Failure {
project = projectControl.getProjectState().getProject();
state = projectControl.getProjectState();
project = state.getProject();
projectName = project.getNameKey();
try {
repo = repoManager.openRepository(project.getNameKey());
repo = repoManager.openRepository(projectName);
} catch (RepositoryNotFoundException e) {
throw new Failure(1, "fatal: '" + project.getName() + "': not a git archive", e);
}

View File

@@ -18,13 +18,13 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableMap;
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.change.AllowedFormats;
import com.google.gerrit.server.change.ArchiveFormat;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
import com.google.gerrit.server.project.CommitsCollection;
import com.google.gerrit.sshd.AbstractGitCommand;
import com.google.inject.Inject;
import java.io.IOException;
@@ -121,9 +121,9 @@ public class UploadArchive extends AbstractGitCommand {
}
@Inject private PermissionBackend permissionBackend;
@Inject private CommitsCollection commits;
@Inject private IdentifiedUser user;
@Inject private AllowedFormats allowedFormats;
@Inject private ReviewDb db;
private Options options = new Options();
/**
@@ -244,13 +244,13 @@ public class UploadArchive extends AbstractGitCommand {
private boolean canRead(ObjectId revId) throws IOException, PermissionBackendException {
try {
permissionBackend.user(user).project(project.getNameKey()).check(ProjectPermission.READ);
permissionBackend.user(user).project(projectName).check(ProjectPermission.READ);
return true;
} catch (AuthException e) {
// Check reachability of the specific revision.
try (RevWalk rw = new RevWalk(repo)) {
RevCommit commit = rw.parseCommit(revId);
return projectControl.canReadCommit(db, repo, commit);
return commits.canRead(state, repo, commit);
}
}
}