ACLs for superproject subscriptions

This allows submodules of the superproject subscription feature to specify
fine grained, who is allowed to subscribe to it. See
Documentation/user-submodules.txt for the changed
handling of subscriptions.

The current tests were kept closely as-is, just enabling the subscription
feature. New tests have been written to test for the denial of superproject
subscriptions.

As of this change the superproject subscription table which was an
approximate cache for the subscriptions is dropped, and the superproject
subscription is performed as
 * parse the submodule ACL for potential superprojects
 * check the .gitmodules file in all potential superprojects for a real
   subscription
 * perform the superproject update if the supscription is valid

The cache worked semi-reliable (e.g. 2015-04-28 Submodule Subscriptions:
Remove subscriptions by deleting .gitmodules,
I1eaf452d5499397644e8eea3707a1352af89126d), so drop the cache and trade in
correctness over performance.

Bug: Issue 3311
Change-Id: Id74dc5a34a50b336a22005c96b79f3c4688a36ec
Signed-off-by: Stefan Beller <sbeller@google.com>
This commit is contained in:
Stefan Beller
2016-03-21 12:14:58 -07:00
parent 8cc252ef0c
commit c62f9fe511
23 changed files with 723 additions and 359 deletions

View File

@@ -22,15 +22,12 @@ import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.SubmoduleSubscription;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.DeleteBranches.Input;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@@ -69,7 +66,6 @@ class DeleteBranches implements RestModifyView<ProjectResource, Input> {
private final Provider<IdentifiedUser> identifiedUser;
private final GitRepositoryManager repoManager;
private final Provider<ReviewDb> dbProvider;
private final Provider<InternalChangeQuery> queryProvider;
private final GitReferenceUpdated referenceUpdated;
private final ChangeHooks hooks;
@@ -77,13 +73,11 @@ class DeleteBranches implements RestModifyView<ProjectResource, Input> {
@Inject
DeleteBranches(Provider<IdentifiedUser> identifiedUser,
GitRepositoryManager repoManager,
Provider<ReviewDb> dbProvider,
Provider<InternalChangeQuery> queryProvider,
GitReferenceUpdated referenceUpdated,
ChangeHooks hooks) {
this.identifiedUser = identifiedUser;
this.repoManager = repoManager;
this.dbProvider = dbProvider;
this.queryProvider = queryProvider;
this.referenceUpdated = referenceUpdated;
this.hooks = hooks;
@@ -167,15 +161,11 @@ class DeleteBranches implements RestModifyView<ProjectResource, Input> {
errorMessages.append("\n");
}
private void postDeletion(ProjectResource project, ReceiveCommand cmd)
throws OrmException {
private void postDeletion(ProjectResource project, ReceiveCommand cmd) {
referenceUpdated.fire(project.getNameKey(), cmd);
Branch.NameKey branchKey =
new Branch.NameKey(project.getNameKey(), cmd.getRefName());
hooks.doRefUpdatedHook(branchKey, cmd.getOldId(), cmd.getNewId(),
identifiedUser.get().getAccount());
ResultSet<SubmoduleSubscription> submoduleSubscriptions =
dbProvider.get().submoduleSubscriptions().bySuperProject(branchKey);
dbProvider.get().submoduleSubscriptions().delete(submoduleSubscriptions);
}
}