Add REST endpoint to delete uploaded images Change-Id: I77d5bfac51d036e6a642c34d54368c14edfebf22 Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/DeleteImage.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/DeleteImage.java new file mode 100644 index 0000000..ff9cfb5 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/DeleteImage.java
@@ -0,0 +1,88 @@ +// 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.imagare; + +import com.google.gerrit.extensions.restapi.AuthException; +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.server.git.GitRepositoryManager; +import com.google.inject.Inject; + +import com.googlesource.gerrit.plugins.imagare.DeleteImage.Input; + +import org.eclipse.jgit.errors.RepositoryNotFoundException; +import org.eclipse.jgit.lib.RefUpdate; +import org.eclipse.jgit.lib.Repository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +public class DeleteImage implements RestModifyView<ImageResource, Input> { + private static final Logger log = LoggerFactory.getLogger(DeleteImage.class); + + public static class Input { + } + + private final GitRepositoryManager repoManager; + + @Inject + public DeleteImage(GitRepositoryManager repoManager) { + this.repoManager = repoManager; + } + + @Override + public Response<?> apply(ImageResource rsrc, Input input) + throws AuthException, ResourceConflictException, + RepositoryNotFoundException, IOException { + if (!rsrc.getControl().canDelete()) { + throw new AuthException("not allowed to delete image"); + } + + Repository r = repoManager.openRepository(rsrc.getProject()); + try { + RefUpdate.Result result; + RefUpdate u; + try { + u = r.updateRef(rsrc.getRef()); + u.setForceUpdate(true); + result = u.delete(); + } catch (IOException e) { + log.error("Cannot delete " + rsrc.getRef(), e); + throw e; + } + + switch (result) { + case NEW: + case NO_CHANGE: + case FAST_FORWARD: + case FORCED: + break; + + case REJECTED_CURRENT_BRANCH: + log.warn("Cannot delete " + rsrc.getRef() + ": " + result.name()); + throw new ResourceConflictException("cannot delete current branch"); + + default: + log.error("Cannot delete " + rsrc.getRef() + ": " + result.name()); + throw new ResourceConflictException("cannot delete branch: " + result.name()); + } + } finally { + r.close(); + } + return Response.none(); + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/ImageResource.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/ImageResource.java index a3388f2..b76f013 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/imagare/ImageResource.java +++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/ImageResource.java
@@ -16,10 +16,29 @@ import com.google.gerrit.extensions.restapi.RestResource; import com.google.gerrit.extensions.restapi.RestView; +import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.server.project.RefControl; import com.google.inject.TypeLiteral; public class ImageResource implements RestResource { public static final TypeLiteral<RestView<ImageResource>> IMAGE_KIND = new TypeLiteral<RestView<ImageResource>>() {}; + private final RefControl refControl; + + ImageResource(RefControl refControl) { + this.refControl = refControl; + } + + public RefControl getControl() { + return refControl; + } + + public Project.NameKey getProject() { + return refControl.getProjectControl().getProject().getNameKey(); + } + + public String getRef() { + return refControl.getRefName(); + } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/ImagesCollection.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/ImagesCollection.java index dbe0a63..33e2ab6 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/imagare/ImagesCollection.java +++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/ImagesCollection.java
@@ -21,7 +21,9 @@ import com.google.gerrit.extensions.restapi.ResourceNotFoundException; import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gerrit.extensions.restapi.RestView; +import com.google.gerrit.reviewdb.client.Branch; import com.google.gerrit.server.project.ProjectResource; +import com.google.gerrit.server.project.RefControl; import com.google.inject.Inject; import com.google.inject.Provider; @@ -46,7 +48,14 @@ @Override public ImageResource parse(ProjectResource parent, IdString id) throws ResourceNotFoundException { - throw new ResourceNotFoundException(id); + RefControl refControl = + parent.getControl().controlForRef( + new Branch.NameKey(parent.getNameKey(), id.get())); + if (refControl.canRead()) { + return new ImageResource(refControl); + } else { + throw new ResourceNotFoundException(id); + } } @Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/imagare/Module.java b/src/main/java/com/googlesource/gerrit/plugins/imagare/Module.java index 5ab84bf..8388c97 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/imagare/Module.java +++ b/src/main/java/com/googlesource/gerrit/plugins/imagare/Module.java
@@ -36,6 +36,7 @@ DynamicMap.mapOf(binder(), IMAGE_KIND); bind(ImagesCollection.class); child(PROJECT_KIND, "images").to(ImagesCollection.class); + delete(IMAGE_KIND).to(DeleteImage.class); get(CONFIG_KIND, "config").to(GetConfig.class); put(CONFIG_KIND, "config").to(PutConfig.class); get(ACCOUNT_KIND, "preference").to(GetPreference.class);
diff --git a/src/main/resources/Documentation/rest-api-projects.md b/src/main/resources/Documentation/rest-api-projects.md index 30033e7..ca76941 100644 --- a/src/main/resources/Documentation/rest-api-projects.md +++ b/src/main/resources/Documentation/rest-api-projects.md
@@ -39,6 +39,35 @@ HTTP/1.1 201 Created ``` +### <a id="delete-image"> Delete Image +_DELETE /project/[\{project-name\}](../../../Documentation/rest-api-projects.html#project-name)/@PLUGIN@~images/[\{image-ref\}](#image-ref)_ + +Deletes an image. + +Caller must have the +[Force Push](../../../Documentation/access-control.html#category_push) +access right on the `refs/images/*` namespace of the project. + +#### Request + +``` + DELETE /config/server/@PLUGIN@~images/refs%2Fimages%2Fec%2F3b946dcbcc5dfae0e127656168ab6dc55bbda8 HTTP/1.0 +``` + +#### Response + +``` + HTTP/1.1 204 No Content +``` + +<a id="ids">IDs +--------------- + +### <a id="image-ref"></a>Image Ref + +The `refs/images/` ref, must be URL encoded. +E.g. `refs%2Fimages%2Fec%2F3b946dcbcc5dfae0e127656168ab6dc55bbda8`. + <a id="json-entities">JSON Entities -----------------------------------