From 26bf55aa5d0bed71fa720e3a61648e29afd4f395 Mon Sep 17 00:00:00 2001 From: Will Ezell Date: Fri, 27 Feb 2026 09:58:54 -0500 Subject: [PATCH 1/4] debt(dwr): replacing PermissionAjax with rest endpoint ref: #34797 --- .../permission/AssetPermissionHelper.java | 53 +++- .../system/permission/PermissionResource.java | 145 +++++++++++ .../permission/PermissionableObjectView.java | 70 +++++ ...esponseEntityPermissionableObjectView.java | 14 + .../business/PermissionableObjectDWR.java | 5 + .../dotmarketing/business/ajax/HostAjax.java | 5 + .../dotmarketing/business/ajax/InodeAjax.java | 5 + .../business/ajax/PermissionAjax.java | 5 + .../categories/ajax/CategoryAjax.java | 5 + .../com/liferay/portal/util/PortalUtil.java | 5 +- dotCMS/src/main/webapp/WEB-INF/dwr.xml | 22 +- .../main/webapp/WEB-INF/openapi/openapi.yaml | 106 ++++++++ .../src/main/webapp/html/common/top_inc.jsp | 2 - .../legacy-custom-field.jsp | 2 - .../webapp/html/ng-contentlet-selector.jsp | 2 - .../ext/browser/view_browser_js_inc.jsp | 7 +- .../ext/calendar/view_calendar_main_inc.jsp | 1 - .../ext/categories/view_categories.jsp | 244 ++++++++++++------ .../ext/categories/view_categories_dialog.jsp | 2 - .../common/edit_permissions_tab_js_inc.jsp | 215 ++++++++++++++- .../edit_permissions_tab_js_inc_ajax.jsp | 206 ++++++++++++++- .../ext/contentlet/field/edit_field_js.jsp | 1 - .../ext/contentlet/view_contentlets.jsp | 1 - .../contentlet/view_contentlets_js_inc.jsp | 7 +- .../ext/contentlet/view_contentlets_popup.jsp | 8 +- .../ext/files/upload_multiple_js_inc.jsp | 1 - .../ext/fileupload/upload_multiple_js_inc.jsp | 1 - .../ext/hostadmin/view_hosts_js_inc.jsp | 153 +++++------ 28 files changed, 1100 insertions(+), 193 deletions(-) create mode 100644 dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/PermissionableObjectView.java create mode 100644 dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/ResponseEntityPermissionableObjectView.java diff --git a/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/AssetPermissionHelper.java b/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/AssetPermissionHelper.java index f1f39f21f0a2..498ccafbc796 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/AssetPermissionHelper.java +++ b/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/AssetPermissionHelper.java @@ -256,9 +256,13 @@ public List buildRolePermissions(final Permissionable asset, // Build individual permissions set final Set individual = convertPermissionsToTypeSet(individualPermissions); - // Build inheritable permissions map (only for parent permissionables) + // Build inheritable permissions map. + // Always include when there are inheritable-type permissions, even for + // non-parent permissionables. The DWR compatibility layer in the JSP needs + // these to merge into the "individual" bucket (matching legacy DWR behavior + // where getPermissions() forced all types to "individual"). final Map> inheritable; - if (isParentPermissionable && !inheritablePermissions.isEmpty()) { + if (!inheritablePermissions.isEmpty()) { inheritable = buildInheritablePermissionMap(inheritablePermissions); } else { inheritable = null; @@ -990,6 +994,51 @@ private UpdateRolePermissionsView buildRolePermissionUpdateResponse(final Permis .build(); } + /** + * Builds a PermissionableObjectView for the given asset. + * Returns metadata needed by the permissions tab UI to determine which + * permission options to display. + * + *

Replaces the legacy {@code PermissionAjax.getAsset()} DWR method. + * + * @param assetId Asset identifier (inode or identifier) + * @param user Requesting user + * @return PermissionableObjectView containing asset metadata + * @throws DotDataException If there's an error accessing data + * @throws DotSecurityException If security validation fails + */ + public PermissionableObjectView getPermissionableObjectView(final String assetId, + final User user) + throws DotDataException, DotSecurityException { + + final Permissionable asset = resolveAsset(assetId); + if (asset == null) { + throw new NotFoundInDbException(String.format("Asset not found: %s", assetId)); + } + + final boolean isFolder = asset instanceof Folder; + final boolean isHost = asset instanceof Host + || (asset instanceof Contentlet + && ((Contentlet) asset).isHost()); + final boolean isContentType = asset instanceof com.dotcms.contenttype.model.type.ContentType + || asset instanceof com.dotmarketing.portlets.structure.model.Structure; + final boolean isParentPermissionable = asset.isParentPermissionable(); + final boolean canEditPermissions = permissionAPI.doesUserHavePermission( + asset, PermissionAPI.PERMISSION_EDIT_PERMISSIONS, user, false); + + final String type = asset.getClass().getName(); + + return new PermissionableObjectView( + asset.getPermissionId(), + type, + isFolder, + isHost, + isContentType, + isParentPermissionable, + canEditPermissions + ); + } + /** * Builds asset view with permissions filtered to a specific role. * diff --git a/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/PermissionResource.java b/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/PermissionResource.java index 8e8aa4c42cb0..eb169db7c127 100644 --- a/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/PermissionResource.java +++ b/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/PermissionResource.java @@ -4,6 +4,7 @@ import com.dotcms.rest.InitDataObject; import com.dotcms.rest.Pagination; import com.dotcms.rest.ResponseEntityPaginatedDataView; +import com.dotcms.rest.ResponseEntityStringView; import com.dotcms.rest.ResponseEntityView; import com.dotcms.rest.WebResource; import com.dotcms.rest.annotation.NoCache; @@ -1142,4 +1143,148 @@ public ResponseEntityUpdateRolePermissionsView updateRolePermissions( return new ResponseEntityUpdateRolePermissionsView(result); } + + /** + * Breaks permission inheritance for a specific asset, making it have its own + * individual permissions (copied from parent). This is used when an asset is + * currently inheriting permissions and the user wants to customize them. + * + * @param request HTTP servlet request + * @param response HTTP servlet response + * @param assetId Asset identifier (inode or identifier) + * @return ResponseEntityStringView with success message + * @throws DotDataException If there's an error accessing permission data + * @throws DotSecurityException If security validation fails + */ + @Operation( + summary = "Break permission inheritance", + description = "Breaks permission inheritance for a specific asset, giving it individual " + + "permissions copied from its parent. After this operation, the asset's permissions " + + "can be modified independently of the parent." + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "Inheritance broken successfully", + content = @Content(mediaType = "application/json", + schema = @Schema(implementation = ResponseEntityStringView.class))), + @ApiResponse(responseCode = "401", + description = "Unauthorized - authentication required", + content = @Content(mediaType = "application/json")), + @ApiResponse(responseCode = "403", + description = "Forbidden - user lacks EDIT_PERMISSIONS on asset", + content = @Content(mediaType = "application/json")), + @ApiResponse(responseCode = "404", + description = "Asset not found", + content = @Content(mediaType = "application/json")) + }) + @PUT + @Path("/{assetId}/_individualpermission") + @JSONP + @NoCache + @Produces({MediaType.APPLICATION_JSON}) + public ResponseEntityStringView permissionIndividually( + final @Context HttpServletRequest request, + final @Context HttpServletResponse response, + @Parameter(description = "Asset identifier (inode or identifier)", required = true) + final @PathParam("assetId") String assetId) + throws DotDataException, DotSecurityException { + + Logger.debug(this, () -> String.format( + "permissionIndividually called - assetId: %s", assetId)); + + final User user = new WebResource.InitBuilder(webResource) + .requiredBackendUser(true) + .requiredFrontendUser(false) + .requestAndResponse(request, response) + .rejectWhenNoUser(true) + .init() + .getUser(); + + if (!UtilMethods.isSet(assetId)) { + throw new BadRequestException("Asset ID is required"); + } + + final Permissionable asset = assetPermissionHelper.resolveAsset(assetId); + if (asset == null) { + throw new NotFoundInDbException(String.format("Asset not found: %s", assetId)); + } + + final PermissionAPI permissionAPI = APILocator.getPermissionAPI(); + if (!permissionAPI.doesUserHavePermission(asset, PermissionAPI.PERMISSION_EDIT_PERMISSIONS, user)) { + throw new DotSecurityException("User does not have permission to edit permissions on this asset"); + } + + final Permissionable parentPermissionable = permissionAPI.findParentPermissionable(asset); + if (parentPermissionable != null) { + permissionAPI.permissionIndividually(parentPermissionable, asset, user); + } + + Logger.info(this, () -> String.format( + "Successfully broke permission inheritance for asset: %s", assetId)); + + return new ResponseEntityStringView("Permission inheritance broken successfully"); + } + + /** + * Retrieves metadata about a permissionable asset, including type information + * and permission flags. Used by the permissions tab UI to determine which + * permission options to display. + * + * @param request HTTP servlet request + * @param response HTTP servlet response + * @param assetId Asset identifier (inode or identifier) + * @return ResponseEntityPermissionableObjectView containing asset metadata + * @throws DotDataException If there's an error accessing data + * @throws DotSecurityException If security validation fails + */ + @Operation( + summary = "Get permissionable asset metadata", + description = "Retrieves metadata about a permissionable asset including its type, " + + "whether it is a folder/host/content type, and whether the current user " + + "has permission to edit its permissions." + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "Asset metadata retrieved successfully", + content = @Content(mediaType = "application/json", + schema = @Schema(implementation = ResponseEntityPermissionableObjectView.class))), + @ApiResponse(responseCode = "401", + description = "Unauthorized - authentication required", + content = @Content(mediaType = "application/json")), + @ApiResponse(responseCode = "404", + description = "Asset not found", + content = @Content(mediaType = "application/json")) + }) + @GET + @Path("/{assetId}/_permissionable") + @JSONP + @NoCache + @Produces({MediaType.APPLICATION_JSON}) + public ResponseEntityPermissionableObjectView getPermissionableObject( + final @Context HttpServletRequest request, + final @Context HttpServletResponse response, + @Parameter(description = "Asset identifier (inode or identifier)", required = true) + final @PathParam("assetId") String assetId) + throws DotDataException, DotSecurityException { + + Logger.debug(this, () -> String.format( + "getPermissionableObject called - assetId: %s", assetId)); + + final User user = new WebResource.InitBuilder(webResource) + .requiredBackendUser(true) + .requiredFrontendUser(false) + .requestAndResponse(request, response) + .rejectWhenNoUser(true) + .init() + .getUser(); + + if (!UtilMethods.isSet(assetId)) { + throw new BadRequestException("Asset ID is required"); + } + + final PermissionableObjectView view = assetPermissionHelper.getPermissionableObjectView( + assetId, user); + + return new ResponseEntityPermissionableObjectView(view); + } } diff --git a/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/PermissionableObjectView.java b/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/PermissionableObjectView.java new file mode 100644 index 000000000000..eb02e718031f --- /dev/null +++ b/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/PermissionableObjectView.java @@ -0,0 +1,70 @@ +package com.dotcms.rest.api.v1.system.permission; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * View object representing metadata about a permissionable asset. + * Used by the permissions tab to determine UI rendering (e.g., which + * permission checkboxes to show, whether to show folder/host-specific options). + * + *

Replaces the legacy {@code PermissionableObjectDWR} used by DWR. + */ +public class PermissionableObjectView { + + private final String id; + private final String type; + private final boolean isFolder; + private final boolean isHost; + private final boolean isContentType; + private final boolean isParentPermissionable; + private final boolean doesUserHavePermissionsToEdit; + + public PermissionableObjectView(final String id, + final String type, + final boolean isFolder, + final boolean isHost, + final boolean isContentType, + final boolean isParentPermissionable, + final boolean doesUserHavePermissionsToEdit) { + this.id = id; + this.type = type; + this.isFolder = isFolder; + this.isHost = isHost; + this.isContentType = isContentType; + this.isParentPermissionable = isParentPermissionable; + this.doesUserHavePermissionsToEdit = doesUserHavePermissionsToEdit; + } + + public String getId() { + return id; + } + + public String getType() { + return type; + } + + @JsonProperty("isFolder") + public boolean isFolder() { + return isFolder; + } + + @JsonProperty("isHost") + public boolean isHost() { + return isHost; + } + + @JsonProperty("isContentType") + public boolean isContentType() { + return isContentType; + } + + @JsonProperty("isParentPermissionable") + public boolean isParentPermissionable() { + return isParentPermissionable; + } + + @JsonProperty("doesUserHavePermissionsToEdit") + public boolean isDoesUserHavePermissionsToEdit() { + return doesUserHavePermissionsToEdit; + } +} diff --git a/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/ResponseEntityPermissionableObjectView.java b/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/ResponseEntityPermissionableObjectView.java new file mode 100644 index 000000000000..fc9fc56f1e36 --- /dev/null +++ b/dotCMS/src/main/java/com/dotcms/rest/api/v1/system/permission/ResponseEntityPermissionableObjectView.java @@ -0,0 +1,14 @@ +package com.dotcms.rest.api.v1.system.permission; + +import com.dotcms.rest.ResponseEntityView; + +/** + * Typed ResponseEntityView for PermissionableObjectView. + * Used for accurate Swagger schema documentation. + */ +public class ResponseEntityPermissionableObjectView extends ResponseEntityView { + + public ResponseEntityPermissionableObjectView(final PermissionableObjectView entity) { + super(entity); + } +} diff --git a/dotCMS/src/main/java/com/dotmarketing/business/PermissionableObjectDWR.java b/dotCMS/src/main/java/com/dotmarketing/business/PermissionableObjectDWR.java index ab8914007616..ebdcdce8ed9c 100644 --- a/dotCMS/src/main/java/com/dotmarketing/business/PermissionableObjectDWR.java +++ b/dotCMS/src/main/java/com/dotmarketing/business/PermissionableObjectDWR.java @@ -1,5 +1,10 @@ package com.dotmarketing.business; +/** + * @deprecated This DWR bean is deprecated and will be removed in a future release. + * Use {@link com.dotcms.rest.api.v1.system.permission.PermissionableObjectView} instead. + */ +@Deprecated(forRemoval = true) public class PermissionableObjectDWR { private String id; diff --git a/dotCMS/src/main/java/com/dotmarketing/business/ajax/HostAjax.java b/dotCMS/src/main/java/com/dotmarketing/business/ajax/HostAjax.java index 37d52d25eb1d..f9bcc8fe33dd 100644 --- a/dotCMS/src/main/java/com/dotmarketing/business/ajax/HostAjax.java +++ b/dotCMS/src/main/java/com/dotmarketing/business/ajax/HostAjax.java @@ -47,6 +47,11 @@ * @version 1.0 * @since Mar 22, 2012 */ +/** + * @deprecated This DWR class is deprecated and will be removed in a future release. + * Use the JAX-RS REST API at {@code /api/v1/site/} instead. + */ +@Deprecated(forRemoval = true) public class HostAjax { private final HostAPI hostAPI = APILocator.getHostAPI(); diff --git a/dotCMS/src/main/java/com/dotmarketing/business/ajax/InodeAjax.java b/dotCMS/src/main/java/com/dotmarketing/business/ajax/InodeAjax.java index 5a3b665bac35..09973d93df47 100644 --- a/dotCMS/src/main/java/com/dotmarketing/business/ajax/InodeAjax.java +++ b/dotCMS/src/main/java/com/dotmarketing/business/ajax/InodeAjax.java @@ -7,6 +7,11 @@ import com.dotmarketing.util.InodeUtils; import com.dotmarketing.util.Logger; +/** + * @deprecated This DWR class is deprecated and will be removed in a future release. + * No JSP callers remain. DWR entry removed from dwr.xml. + */ +@Deprecated(forRemoval = true) public class InodeAjax { public int compareInodes(String inodeStr1,String inodeStr2){ diff --git a/dotCMS/src/main/java/com/dotmarketing/business/ajax/PermissionAjax.java b/dotCMS/src/main/java/com/dotmarketing/business/ajax/PermissionAjax.java index 690cb0a62346..cb38f7fa38ed 100644 --- a/dotCMS/src/main/java/com/dotmarketing/business/ajax/PermissionAjax.java +++ b/dotCMS/src/main/java/com/dotmarketing/business/ajax/PermissionAjax.java @@ -64,6 +64,11 @@ * @author davidtorresv * */ +/** + * @deprecated This DWR class is deprecated and will be removed in a future release. + * Use the JAX-RS REST API at {@code /api/v1/permissions/} instead. + */ +@Deprecated(forRemoval = true) public class PermissionAjax { private final ContentletAPI contentletAPI = APILocator.getContentletAPI(); diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/ajax/CategoryAjax.java b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/ajax/CategoryAjax.java index e047a9173948..9e7d889518f5 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/ajax/CategoryAjax.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/ajax/CategoryAjax.java @@ -37,6 +37,11 @@ /** * @author David */ +/** + * @deprecated This DWR class is deprecated and will be removed in a future release. + * Use the JAX-RS REST API at {@code /api/v1/categories/} instead. + */ +@Deprecated(forRemoval = true) public class CategoryAjax { private CategoryAPI categoryAPI = APILocator.getCategoryAPI(); diff --git a/dotCMS/src/main/java/com/liferay/portal/util/PortalUtil.java b/dotCMS/src/main/java/com/liferay/portal/util/PortalUtil.java index fa9ee5f77c07..68be0598f6ac 100644 --- a/dotCMS/src/main/java/com/liferay/portal/util/PortalUtil.java +++ b/dotCMS/src/main/java/com/liferay/portal/util/PortalUtil.java @@ -427,7 +427,10 @@ public static User getUserFromAuthHeader(HttpServletRequest req) { return null; } - String tok = req.getHeader("Authorization").replace("Bearer ", "").trim(); + String tok = req.getHeader("Authorization") + .replace("Bearer ", "") + .replace("bearer ", "") + .trim(); return Try.of(() -> JsonWebTokenFactory.getInstance().getJsonWebTokenService().parseToken(tok).getActiveUser() .orElse(null)).getOrNull(); diff --git a/dotCMS/src/main/webapp/WEB-INF/dwr.xml b/dotCMS/src/main/webapp/WEB-INF/dwr.xml index d85feac1d805..7b2b4a07e955 100644 --- a/dotCMS/src/main/webapp/WEB-INF/dwr.xml +++ b/dotCMS/src/main/webapp/WEB-INF/dwr.xml @@ -10,9 +10,7 @@ - - - + @@ -34,15 +32,9 @@ - - - - - - - - - + + + @@ -102,10 +94,6 @@ - - - + diff --git a/dotCMS/src/main/webapp/WEB-INF/openapi/openapi.yaml b/dotCMS/src/main/webapp/WEB-INF/openapi/openapi.yaml index 5b04a806fed2..daf3a0f5cb66 100644 --- a/dotCMS/src/main/webapp/WEB-INF/openapi/openapi.yaml +++ b/dotCMS/src/main/webapp/WEB-INF/openapi/openapi.yaml @@ -11125,6 +11125,72 @@ paths: summary: Update asset permissions tags: - Permissions + /v1/permissions/{assetId}/_individualpermission: + put: + description: "Breaks permission inheritance for a specific asset, giving it\ + \ individual permissions copied from its parent. After this operation, the\ + \ asset's permissions can be modified independently of the parent." + operationId: permissionIndividually + parameters: + - description: Asset identifier (inode or identifier) + in: path + name: assetId + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/ResponseEntityStringView" + description: Inheritance broken successfully + "401": + content: + application/json: {} + description: Unauthorized - authentication required + "403": + content: + application/json: {} + description: Forbidden - user lacks EDIT_PERMISSIONS on asset + "404": + content: + application/json: {} + description: Asset not found + summary: Break permission inheritance + tags: + - Permissions + /v1/permissions/{assetId}/_permissionable: + get: + description: "Retrieves metadata about a permissionable asset including its\ + \ type, whether it is a folder/host/content type, and whether the current\ + \ user has permission to edit its permissions." + operationId: getPermissionableObject + parameters: + - description: Asset identifier (inode or identifier) + in: path + name: assetId + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/ResponseEntityPermissionableObjectView" + description: Asset metadata retrieved successfully + "401": + content: + application/json: {} + description: Unauthorized - authentication required + "404": + content: + application/json: {} + description: Asset not found + summary: Get permissionable asset metadata + tags: + - Permissions /v1/permissions/{assetId}/_reset: put: description: "Removes all individual permissions from an asset, making it inherit\ @@ -24490,6 +24556,23 @@ components: type: string permissionType: type: string + PermissionableObjectView: + type: object + properties: + doesUserHavePermissionsToEdit: + type: boolean + id: + type: string + isContentType: + type: boolean + isFolder: + type: boolean + isHost: + type: boolean + isParentPermissionable: + type: boolean + type: + type: string Persona: type: object properties: @@ -26159,6 +26242,29 @@ components: type: array items: type: string + ResponseEntityPermissionableObjectView: + type: object + properties: + entity: + $ref: "#/components/schemas/PermissionableObjectView" + errors: + type: array + items: + $ref: "#/components/schemas/ErrorEntity" + i18nMessagesMap: + type: object + additionalProperties: + type: string + messages: + type: array + items: + $ref: "#/components/schemas/MessageEntity" + pagination: + $ref: "#/components/schemas/Pagination" + permissions: + type: array + items: + type: string ResponseEntityPermissionsByTypeView: type: object properties: diff --git a/dotCMS/src/main/webapp/html/common/top_inc.jsp b/dotCMS/src/main/webapp/html/common/top_inc.jsp index 91337189a700..17a55d9b4283 100644 --- a/dotCMS/src/main/webapp/html/common/top_inc.jsp +++ b/dotCMS/src/main/webapp/html/common/top_inc.jsp @@ -106,12 +106,10 @@ THIS FILE AND ITS INCLUDES - - - - <% // Cache busting for development - use timestamp String cacheBuster = String.valueOf(System.currentTimeMillis()); diff --git a/dotCMS/src/main/webapp/html/ng-contentlet-selector.jsp b/dotCMS/src/main/webapp/html/ng-contentlet-selector.jsp index fba147d8d001..5c1f8c22e63a 100644 --- a/dotCMS/src/main/webapp/html/ng-contentlet-selector.jsp +++ b/dotCMS/src/main/webapp/html/ng-contentlet-selector.jsp @@ -248,8 +248,6 @@ - - - @@ -1149,7 +1147,10 @@ Structure defaultFileAssetStructure = CacheLocator.getContentTypeCache().getStru function setAsDefaultHost(objId,referer) { if (confirm('<%= UtilMethods.escapeSingleQuotes(LanguageUtil.get(pageContext, "Are-you-sure-you-want-to-set-this-host-as-the-default-host")) %>')) { - HostAjax.makeDefault(objId, setAsDefaultHostCallback); + fetch('/api/v1/site/' + objId + '/_makedefault', {method: 'PUT', cache: 'no-cache'}) + .then(function(r) { return r.json(); }) + .then(function() { setAsDefaultHostCallback(); }) + .catch(function(error) { console.error('Error setting default host:', error); }); } } diff --git a/dotCMS/src/main/webapp/html/portlet/ext/calendar/view_calendar_main_inc.jsp b/dotCMS/src/main/webapp/html/portlet/ext/calendar/view_calendar_main_inc.jsp index 9dbe741da6fa..77bed310ebc0 100644 --- a/dotCMS/src/main/webapp/html/portlet/ext/calendar/view_calendar_main_inc.jsp +++ b/dotCMS/src/main/webapp/html/portlet/ext/calendar/view_calendar_main_inc.jsp @@ -38,7 +38,6 @@ <%@page import="com.dotmarketing.business.PermissionAPI"%> - diff --git a/dotCMS/src/main/webapp/html/portlet/ext/categories/view_categories.jsp b/dotCMS/src/main/webapp/html/portlet/ext/categories/view_categories.jsp index 191f001235ae..bf2daa8a494d 100644 --- a/dotCMS/src/main/webapp/html/portlet/ext/categories/view_categories.jsp +++ b/dotCMS/src/main/webapp/html/portlet/ext/categories/view_categories.jsp @@ -58,7 +58,6 @@ } - - +