Merge branch 'stable-2.14' into stable-2.15
* stable-2.14:
Update mockito to 2.23.4
Always pass ALLOW_INSECURE to MoreFiles.deleteRecursively
ArchiveRepositoryRemoverTest: Refactor assertions on repo content
Format external_plugin_deps.bzl with buildifier
Upgrade bazlets to latest stable-2.14 to build with 2.14.17 API
Upgrade bazlets to latest stable-2.14 to build with 2.14.16 API
Change-Id: Ie45390df44f13bf66234cf8b41f3e51eb405701d
diff --git a/WORKSPACE b/WORKSPACE
index ce2b64b..7442807 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
load("//:bazlets.bzl", "load_bazlets")
load_bazlets(
- commit = "714a32382ebd02919007d3514513af4395768d80",
+ commit = "6d3fd710ea4ca44805bb8c858d72b53bd3a500f3",
#local_path = "/home/<user>/projects/bazlets",
)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteAction.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteAction.java
index 459d819..040f7e4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteAction.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteAction.java
@@ -16,6 +16,7 @@
import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.project.ProjectResource;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -36,7 +37,8 @@
DeleteLog deleteLog,
DeletePreconditions preConditions,
Configuration cfg,
- HideProject hideProject) {
+ HideProject hideProject,
+ NotesMigration migration) {
super(
dbHandler,
fsHandler,
@@ -45,7 +47,8 @@
deleteLog,
preConditions,
cfg,
- hideProject);
+ hideProject,
+ migration);
this.protectedProjects = protectedProjects;
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java
index 47ef932..5543961 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java
@@ -19,6 +19,7 @@
import static java.util.stream.Collectors.joining;
import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.api.access.PluginPermission;
import com.google.gerrit.extensions.common.ProjectInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
@@ -26,10 +27,13 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MergeOpRepoManager;
+import com.google.gerrit.server.git.SubmoduleException;
import com.google.gerrit.server.git.SubmoduleOp;
+import com.google.gerrit.server.permissions.GlobalPermission;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ListChildProjects;
import com.google.gerrit.server.project.ProjectResource;
import com.google.gerrit.server.query.change.ChangeData;
@@ -59,6 +63,7 @@
private final SubmoduleOp.Factory subOpFactory;
private final Provider<CurrentUser> userProvider;
private final ProtectedProjects protectedProjects;
+ private final PermissionBackend permissionBackend;
@Inject
public DeletePreconditions(
@@ -70,7 +75,8 @@
GitRepositoryManager repoManager,
SubmoduleOp.Factory subOpFactory,
Provider<CurrentUser> userProvider,
- ProtectedProjects protectedProjects) {
+ ProtectedProjects protectedProjects,
+ PermissionBackend permissionBackend) {
this.config = config;
this.listChildProjectsProvider = listChildProjectsProvider;
this.mergeOpProvider = mergeOpProvider;
@@ -80,6 +86,7 @@
this.subOpFactory = subOpFactory;
this.userProvider = userProvider;
this.protectedProjects = protectedProjects;
+ this.permissionBackend = permissionBackend;
}
void assertDeletePermission(ProjectResource rsrc) throws AuthException {
@@ -88,11 +95,12 @@
}
}
- boolean canDelete(ProjectResource rsrc) {
- CapabilityControl ctl = userProvider.get().getCapabilities();
- return ctl.canAdministrateServer()
- || ctl.canPerform(pluginName + "-" + DELETE_PROJECT)
- || (ctl.canPerform(pluginName + "-" + DELETE_OWN_PROJECT) && rsrc.getControl().isOwner());
+ protected boolean canDelete(ProjectResource rsrc) {
+ PermissionBackend.WithUser userPermission = permissionBackend.user(userProvider);
+ return userPermission.testOrFalse(GlobalPermission.ADMINISTRATE_SERVER)
+ || userPermission.testOrFalse(new PluginPermission(pluginName, DELETE_PROJECT))
+ || (userPermission.testOrFalse(new PluginPermission(pluginName, DELETE_OWN_PROJECT))
+ && rsrc.getControl().isOwner());
}
void assertCanBeDeleted(ProjectResource rsrc, Input input) throws ResourceConflictException {
@@ -125,11 +133,16 @@
}
private void assertHasNoChildProjects(ProjectResource rsrc) throws CannotDeleteProjectException {
- List<ProjectInfo> children = listChildProjectsProvider.get().apply(rsrc);
- if (!children.isEmpty()) {
+ try {
+ List<ProjectInfo> children = listChildProjectsProvider.get().apply(rsrc);
+ if (!children.isEmpty()) {
+ throw new CannotDeleteProjectException(
+ "Cannot delete project because it has children: "
+ + children.stream().map(info -> info.name).collect(joining(",")));
+ }
+ } catch (PermissionBackendException e) {
throw new CannotDeleteProjectException(
- "Cannot delete project because it has children: "
- + children.stream().map(info -> info.name).collect(joining(",")));
+ String.format("Unable to verify if '%s' has children projects.", rsrc.getName()));
}
}
@@ -150,7 +163,7 @@
} catch (RepositoryNotFoundException e) {
// we're trying to delete the repository,
// so this exception should not stop us
- } catch (IOException e) {
+ } catch (IOException | SubmoduleException e) {
throw new CannotDeleteProjectException("Project is subscribed by other projects.");
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProject.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProject.java
index 5d83c80..58844eb 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProject.java
@@ -22,6 +22,7 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.project.ProjectResource;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -50,6 +51,7 @@
private final DeleteLog deleteLog;
private final Configuration cfg;
private final HideProject hideProject;
+ private NotesMigration migration;
@Inject
DeleteProject(
@@ -60,7 +62,8 @@
DeleteLog deleteLog,
DeletePreconditions preConditions,
Configuration cfg,
- HideProject hideProject) {
+ HideProject hideProject,
+ NotesMigration migration) {
this.dbHandler = dbHandler;
this.fsHandler = fsHandler;
this.cacheHandler = cacheHandler;
@@ -69,6 +72,7 @@
this.preConditions = preConditions;
this.cfg = cfg;
this.hideProject = hideProject;
+ this.migration = migration;
}
@Override
@@ -89,7 +93,9 @@
Exception ex = null;
try {
if (!preserve || !cfg.projectOnPreserveHidden()) {
- dbHandler.delete(project);
+ if (!migration.disableChangeReviewDb()) {
+ dbHandler.delete(project);
+ }
try {
fsHandler.delete(project, preserve);
} catch (RepositoryNotFoundException e) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java
index 397a65c..8b60ae3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java
@@ -24,6 +24,7 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
+import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.CreateProject;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectResource;
@@ -88,7 +89,8 @@
} catch (BadRequestException
| UnprocessableEntityException
| ResourceNotFoundException
- | ConfigInvalidException e) {
+ | ConfigInvalidException
+ | PermissionBackendException e) {
throw new ResourceConflictException(
String.format("Failed to create project %s", projectName));
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/projectconfig/ProjectConfigDeleteHandler.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/projectconfig/ProjectConfigDeleteHandler.java
new file mode 100644
index 0000000..9906c6c
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/projectconfig/ProjectConfigDeleteHandler.java
@@ -0,0 +1,59 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.deleteproject.projectconfig;
+
+import static java.util.stream.Collectors.joining;
+
+import com.google.gerrit.extensions.common.ProjectInfo;
+import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.ListChildProjects;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.googlesource.gerrit.plugins.deleteproject.CannotDeleteProjectException;
+import com.googlesource.gerrit.plugins.deleteproject.ProtectedProjects;
+import java.util.List;
+
+public class ProjectConfigDeleteHandler {
+
+ private final ProtectedProjects protectedProjects;
+ private final Provider<ListChildProjects> listChildProjectsProvider;
+
+ @Inject
+ public ProjectConfigDeleteHandler(
+ ProtectedProjects protectedProjects, Provider<ListChildProjects> listChildProjectsProvider) {
+ this.protectedProjects = protectedProjects;
+ this.listChildProjectsProvider = listChildProjectsProvider;
+ }
+
+ public void assertCanDelete(ProjectResource rsrc) throws CannotDeleteProjectException {
+ protectedProjects.assertIsNotProtected(rsrc);
+ assertHasNoChildProjects(rsrc);
+ }
+
+ private void assertHasNoChildProjects(ProjectResource rsrc) throws CannotDeleteProjectException {
+ try {
+ List<ProjectInfo> children = listChildProjectsProvider.get().apply(rsrc);
+ if (!children.isEmpty()) {
+ throw new CannotDeleteProjectException(
+ "Cannot delete project because it has children: "
+ + children.stream().map(info -> info.name).collect(joining(",")));
+ }
+ } catch (PermissionBackendException e) {
+ throw new CannotDeleteProjectException(
+ "Cannot delete project because of failure in permission backend.");
+ }
+ }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditionsTest.java b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditionsTest.java
index 125041a..b02763d 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditionsTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditionsTest.java
@@ -23,15 +23,17 @@
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
+import com.google.gerrit.extensions.api.access.PluginPermission;
import com.google.gerrit.extensions.common.ProjectInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MergeOpRepoManager;
import com.google.gerrit.server.git.SubmoduleOp;
+import com.google.gerrit.server.permissions.GlobalPermission;
+import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ListChildProjects;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectResource;
@@ -50,9 +52,6 @@
@RunWith(MockitoJUnitRunner.class)
public class DeletePreconditionsTest {
private static final String PLUGIN_NAME = "delete-project";
- private static final String DELETE_OWN_PROJECT_PERMISSION =
- PLUGIN_NAME + "-" + DELETE_OWN_PROJECT;
- private static final String DELETE_PROJECT_PERMISSION = PLUGIN_NAME + "-" + DELETE_PROJECT;
private static final Project.NameKey PROJECT_NAMEKEY = new Project.NameKey("test-project");
@Mock private Configuration config;
@@ -63,10 +62,9 @@
@Mock private SubmoduleOp.Factory subOpFactory;
@Mock private Provider<CurrentUser> userProvider;
@Mock private ProtectedProjects protectedProjects;
-
@Mock private ProjectControl control;
- @Mock private CapabilityControl ctl;
- @Mock private CurrentUser user;
+ @Mock private PermissionBackend permissionBackend;
+ @Mock private PermissionBackend.WithUser userPermission;
@Rule public ExpectedException expectedException = ExpectedException.none();
@@ -86,44 +84,37 @@
repoManager,
subOpFactory,
userProvider,
- protectedProjects);
+ protectedProjects,
+ permissionBackend);
}
@Test
public void testUserCanDeleteIfAdmin() {
- when(ctl.canAdministrateServer()).thenReturn(true);
- when(userProvider.get()).thenReturn(user);
- when(user.getCapabilities()).thenReturn(ctl);
+ when(permissionBackend.user(userProvider)).thenReturn(userPermission);
+ when(userPermission.testOrFalse(GlobalPermission.ADMINISTRATE_SERVER)).thenReturn(true);
assertThat(preConditions.canDelete(rsrc)).isTrue();
}
@Test
public void testUserCanDeleteIfHasDeletePermission() {
- when(ctl.canAdministrateServer()).thenReturn(false);
- when(ctl.canPerform(DELETE_PROJECT_PERMISSION)).thenReturn(true);
- when(userProvider.get()).thenReturn(user);
- when(user.getCapabilities()).thenReturn(ctl);
+ when(permissionBackend.user(userProvider)).thenReturn(userPermission);
+ when(userPermission.testOrFalse(new PluginPermission(PLUGIN_NAME, DELETE_PROJECT)))
+ .thenReturn(true);
assertThat(preConditions.canDelete(rsrc)).isTrue();
}
@Test
public void testUserCanDeleteIfIsOwnerAndHasDeleteOwnPermission() {
- when(ctl.canAdministrateServer()).thenReturn(false);
- when(ctl.canPerform(DELETE_PROJECT_PERMISSION)).thenReturn(false);
- when(ctl.canPerform(DELETE_OWN_PROJECT_PERMISSION)).thenReturn(true);
- when(userProvider.get()).thenReturn(user);
- when(user.getCapabilities()).thenReturn(ctl);
+ when(permissionBackend.user(userProvider)).thenReturn(userPermission);
+ when(userPermission.testOrFalse(new PluginPermission(PLUGIN_NAME, DELETE_OWN_PROJECT)))
+ .thenReturn(true);
when(control.isOwner()).thenReturn(true);
assertThat(preConditions.canDelete(rsrc)).isTrue();
}
@Test
public void testUserCannotDelete() throws Exception {
- when(ctl.canAdministrateServer()).thenReturn(false);
- when(ctl.canPerform(DELETE_PROJECT_PERMISSION)).thenReturn(false);
- when(ctl.canPerform(DELETE_OWN_PROJECT_PERMISSION)).thenReturn(false);
- when(userProvider.get()).thenReturn(user);
- when(user.getCapabilities()).thenReturn(ctl);
+ when(permissionBackend.user(userProvider)).thenReturn(userPermission);
expectedException.expect(AuthException.class);
expectedException.expectMessage("not allowed to delete project");
preConditions.assertDeletePermission(rsrc);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java
index af3ff0d..a68edf8 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java
@@ -20,7 +20,6 @@
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import com.google.common.base.Joiner;
-import com.google.common.base.MoreObjects;
import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
@@ -94,7 +93,7 @@
@Test
@UseLocalDisk
public void testHttpDeleteProjectWithWatches() throws Exception {
- watch(project.get(), null);
+ watch(project.get());
RestResponse r = httpDeleteProjectHelper(true);
r.assertNoContent();
assertThat(projectDir.exists()).isFalse();
@@ -211,8 +210,8 @@
@UseLocalDisk
@GerritConfig(name = "plugin.delete-project.allowDeletionOfReposWithTags", value = "false")
public void testDeleteProjWithTags() throws Exception {
- grant(Permission.CREATE, project, "refs/tags/*", false, REGISTERED_USERS);
- pushTagOldCommitNotForce(Status.OK);
+ grant(project, "refs/tags/*", Permission.CREATE, false, REGISTERED_USERS);
+ pushTagOldCommitNotForce();
String cmd = createDeleteCommand(project.get());
adminSshSession.exec(cmd);
@@ -295,19 +294,18 @@
.join(PLUGIN, "delete", "--yes-really-delete", cmd, Joiner.on(" ").join(params));
}
- private String pushTagOldCommitNotForce(Status expectedStatus) throws Exception {
+ private void pushTagOldCommitNotForce() throws Exception {
testRepo = cloneProject(project, user);
commitBuilder().ident(user.getIdent()).message("subject (" + System.nanoTime() + ")").create();
- String tagName = MoreObjects.firstNonNull(null, "v1_" + System.nanoTime());
+ String tagName = "v1_" + System.nanoTime();
- grant(Permission.SUBMIT, project, "refs/for/refs/heads/master", false, REGISTERED_USERS);
+ grant(project, "refs/for/refs/heads/master", Permission.SUBMIT, false, REGISTERED_USERS);
pushHead(testRepo, "refs/for/master%submit");
String tagRef = RefNames.REFS_TAGS + tagName;
PushResult r = pushHead(testRepo, tagRef, false, false);
RemoteRefUpdate refUpdate = r.getRemoteUpdate(tagRef);
- assertThat(refUpdate.getStatus()).named("LIGHTWEIGHT").isEqualTo(expectedStatus);
- return tagName;
+ assertThat(refUpdate.getStatus()).named("LIGHTWEIGHT").isEqualTo(Status.OK);
}
private boolean isEmpty(Path dir) throws IOException {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/fs/ArchiveRepositoryRemoverTest.java b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/fs/ArchiveRepositoryRemoverTest.java
index bd976ab..64634b9 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/fs/ArchiveRepositoryRemoverTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/fs/ArchiveRepositoryRemoverTest.java
@@ -28,7 +28,6 @@
import com.google.common.base.Joiner;
import com.google.gerrit.server.git.WorkQueue;
-import com.google.gerrit.server.git.WorkQueue.Executor;
import com.google.inject.Provider;
import com.googlesource.gerrit.plugins.deleteproject.Configuration;
import com.googlesource.gerrit.plugins.deleteproject.TimeMachine;
@@ -38,6 +37,7 @@
import java.nio.file.Path;
import java.time.Instant;
import java.util.List;
+import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.StreamSupport;
@@ -59,7 +59,7 @@
private static final int NUMBER_OF_REPOS = 10;
private static final String PLUGIN_NAME = "delete-project";
- @Mock private Executor executorMock;
+ @Mock private ScheduledExecutorService executorMock;
@Mock private ScheduledFuture<?> scheduledFutureMock;
@Mock private WorkQueue workQueueMock;
@Mock private Provider<RepositoryCleanupTask> cleanupTaskProviderMock;