Merge branch 'stable-2.14' into stable-2.15
* stable-2.14:
Bump required bazel version to 1.0.0rc2
Upgrade bazlets to latest stable-2.14
Change-Id: I50790acf74d4832a8994b72e4b0768177fc5d960
diff --git a/BUILD b/BUILD
index 7052c49..9b65e8f 100644
--- a/BUILD
+++ b/BUILD
@@ -21,7 +21,7 @@
)
junit_tests(
- name = "delete_project_tests",
+ name = "delete-project_tests",
srcs = glob(["src/test/java/**/*.java"]),
tags = ["delete-project"],
deps = [":delete-project__plugin_test_deps"],
diff --git a/WORKSPACE b/WORKSPACE
index ac35f01..7cf9250 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
load("//:bazlets.bzl", "load_bazlets")
load_bazlets(
- commit = "bec81c8319e560d2a92ba0fe35d40d021ffd7708",
+ commit = "1aa9482d30e8873e6d3e1e75dc307a43aae0482e",
#local_path = "/home/<user>/projects/bazlets",
)
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 7e04095..ef666ef 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -3,8 +3,8 @@
def external_plugin_deps():
maven_jar(
name = "mockito",
- artifact = "org.mockito:mockito-core:2.27.0",
- sha1 = "835fc3283b481f4758b8ef464cd560c649c08b00",
+ artifact = "org.mockito:mockito-core:2.28.2",
+ sha1 = "91110215a8cb9b77a46e045ee758f77d79167cc0",
deps = [
"@byte-buddy//jar",
"@byte-buddy-agent//jar",
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/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;