Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.dotmarketing.portlets.contentlet.business.HostAPI;
import com.dotmarketing.portlets.folders.business.FolderAPI;
import com.dotmarketing.portlets.folders.model.Folder;
import com.dotmarketing.util.InodeUtils;
import com.dotmarketing.util.Logger;
import com.dotmarketing.util.UtilMethods;
import com.liferay.portal.model.User;
Expand Down Expand Up @@ -102,7 +103,7 @@ private Map folderToMap (final Folder folder) {
*/
public Folder loadFolderByURI(String siteName, User user, String uri) throws DotDataException, DotSecurityException {
Host host = hostAPI.findByName(siteName,user,true);
Folder ret = null;
Folder ret;
if(uri.equals("/")){
ret = folderAPI.findSystemFolder();
}else{
Expand Down Expand Up @@ -208,7 +209,7 @@ public List<FolderSearchResultView> findSubFoldersPathByParentPath(final String

/**
* Will find the subfolders living directly under the host passed.
* If pathToSearch is sent is gonna filter the path of the subfolder by it.
* If pathToSearch is sent is going to filter the path of the subfolder by it.
*/
private List<FolderSearchResultView> findSubfoldersUnderHost(final String siteId,
final String pathToSearch, final User user)
Expand Down Expand Up @@ -237,7 +238,7 @@ private List<FolderSearchResultView> findSubfoldersUnderHost(final String siteId
}

/**
* Will find the subfolders living directly under the host passed and the last valid folder (spliting the pathToSearch by the last '/').
* Will find the subfolders living directly under the host passed and the last valid folder (splitting the pathToSearch by the last '/').
* And filter the results by what is left after the last '/'.
*/
private List<FolderSearchResultView> findSubfoldersUnderFolder(final String siteId,
Expand Down Expand Up @@ -272,4 +273,12 @@ private List<FolderSearchResultView> findSubfoldersUnderFolder(final String site
return subFolders;
}

/**
* Check if the folder is valid and has an inode.
* @param folder folder to check
* @return true if the folder exists in the database or if the folder is not null
*/
public boolean isValidFolder(final Folder folder) {
return UtilMethods.isSet(folder) && InodeUtils.isSet(folder.getInode());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@
import com.dotmarketing.util.UtilMethods;
import com.liferay.portal.model.User;
import com.liferay.util.StringPool;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import javax.servlet.http.HttpSession;
import javax.ws.rs.DELETE;
import javax.ws.rs.PUT;
import org.glassfish.jersey.server.JSONP;
Expand All @@ -35,7 +39,6 @@
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
Expand Down Expand Up @@ -69,20 +72,46 @@ public FolderResource(final WebResource webResource,

/**
* Delete one or more path for a site
* @param httpServletRequest
* @param httpServletResponse
* @param paths
* @param siteName
* @param httpServletRequest The current instance of the {@link HttpServletRequest}.
* @param httpServletResponse The current instance of the {@link HttpServletResponse}.
* @param paths paths to delete
* @param siteName site name
* @return List of folders deleted
* @throws DotSecurityException
* @throws DotDataException
* @throws IllegalArgumentException if the site name is not found
* @throws DoesNotExistException if the folder does not exist
* @throws DotSecurityException if the user does not have permission to delete the folder
* @throws DotDataException if there is an error deleting the folder
*/
@DELETE
@Path("/{siteName}")
@JSONP
@NoCache
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_JSON, "application/javascript"})
@Operation(
summary = "Delete one or more path for a site",
description = "Delete one or more path for a site if they exist"
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Folders deleted successfully",
content = @Content(mediaType = "application/json",
examples = @ExampleObject(value = "{\n"
+ " \"entity\": [\n"
+ " \"/folder-1/folder-2/target-folder\"\n"
+ " ],\n"
+ " \"errors\": [],\n"
+ " \"i18nMessagesMap\": {},\n"
+ " \"messages\": [],\n"
+ " \"pagination\": null,\n"
+ " \"permissions\": []\n"
+ "}"
)
)
),
@ApiResponse(responseCode = "401", description = "Unauthorized access"),
@ApiResponse(responseCode = "404", description = "Folders not found"),
@ApiResponse(responseCode = "403", description = "Insufficient permissions to delete folders")
})
public final Response deleteFolders(@Context final HttpServletRequest httpServletRequest,
@Context final HttpServletResponse httpServletResponse,
final List<String> paths,
Expand All @@ -100,23 +129,21 @@ public final Response deleteFolders(@Context final HttpServletRequest httpServle
final List<String> deletedFolders = new ArrayList<>();

final Host host = APILocator.getHostAPI().findByName(siteName, user, true);
if(!UtilMethods.isSet(host)) {

throw new IllegalArgumentException(String.format(" Couldn't find any host with name `%s` ",siteName));
if (!UtilMethods.isSet(host)) {
throw new IllegalArgumentException(
String.format(" Couldn't find any host with name `%s` ", siteName));
}

Logger.debug(this, ()-> "Deleting the folders: " + paths);
Logger.debug(this, () -> "Deleting the folders: " + paths);

for (final String path : paths) {

final Folder folder = folderHelper.loadFolderByURI(host.getIdentifier(), user, path);
if (null != folder) {

Logger.debug(this, ()-> "Deleting the folder: " + path);
folderHelper.deleteFolder (folder, user);
if (folderHelper.isValidFolder(folder)) {
Logger.debug(this, () -> "Deleting the folder: " + path);
folderHelper.deleteFolder(folder, user);
deletedFolders.add(path);
} else {

Logger.error(this, "The folder does not exists: " + path);
throw new DoesNotExistException("The folder does not exists: " + path);
}
Expand Down
23 changes: 19 additions & 4 deletions dotCMS/src/main/webapp/WEB-INF/openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8617,6 +8617,7 @@ paths:
- Folders
/v1/folder/{siteName}:
delete:
description: Delete one or more path for a site if they exist
operationId: deleteFolders
parameters:
- in: path
Expand All @@ -8632,11 +8633,25 @@ paths:
items:
type: string
responses:
default:
"200":
content:
application/javascript: {}
application/json: {}
description: default response
application/json:
example:
entity:
- /folder-1/folder-2/target-folder
errors: []
i18nMessagesMap: {}
messages: []
pagination: null
permissions: []
description: Folders deleted successfully
"401":
description: Unauthorized access
"403":
description: Insufficient permissions to delete folders
"404":
description: Folders not found
summary: Delete one or more path for a site
tags:
- Folders
/v1/forgotpassword:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,63 @@
}
]
},
{
"name": "deleteFolder",
"item": [
{
"name": "deleteNonExistedFolder",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Response status code is 404\", function () {",
" pm.expect(pm.response.code).to.equal(404);",
"});",
"",
"pm.test(\"Response should contain a message field\", function () {",
" const responseData = pm.response.json();",
" ",
" pm.expect(responseData).to.be.an('object');",
" pm.expect(responseData).to.have.property('message');",
"});",
""
],
"type": "text/javascript",
"packages": {},
"requests": {}
}
}
],
"request": {
"method": "DELETE",
"header": [],
"body": {
"mode": "raw",
"raw": "[\"/folder-1/folder-2/target-folder\"]",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{serverURL}}/api/v1/folder/default",
"host": [
"{{serverURL}}"
],
"path": [
"api",
"v1",
"folder",
"default"
]
}
},
"response": []
}
]
},
{
"name": "Get Folder Success",
"event": [
Expand Down
38 changes: 36 additions & 2 deletions test-karate/src/test/java/graphql/ftm/deleteFolder.feature
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
Feature: Delete a Folder
Scenario: Delete a folder on the given path if exists
Scenario: Delete an existing folder
# Create a folder
* def assetPath = '//default' + path + '/'
* def createRequest =
"""
{
"assetPath": "#(assetPath)",
"data": {
"title": "application/containers/banner",
"showOnMenu": false,
"sortOrder": 1,
"defaultAssetType": "FileAsset"
}
}
"""

Given url baseUrl + '/api/v1/assets/folders'
And headers commonHeaders
And request createRequest
When method POST
Then status 200
* def errors = call extractErrors response
* match errors == []

# Delete an existing folder (previously created)
Given url baseUrl + '/api/v1/folder/default'
And headers commonHeaders
And request
Expand All @@ -9,4 +33,14 @@ Feature: Delete a Folder
When method DELETE
Then status 200
* def errors = call extractErrors response
* match errors == []
* match errors == []

Scenario: Try to delete a non-existing folder
* def nonExistingFolder = '/does-not-exist-folder'

Given url baseUrl + '/api/v1/folder/default'
And headers commonHeaders
And request ["#(nonExistingFolder)"]
When method DELETE
Then status 404
* match response.message == 'The folder does not exists: ' + nonExistingFolder
Loading