diff --git a/cli/src/main/groovy/org/craftercms/cli/commands/marketplace/CopyPlugin.groovy b/cli/src/main/groovy/org/craftercms/cli/commands/marketplace/CopyPlugin.groovy index 9caff0810..a701f19c5 100644 --- a/cli/src/main/groovy/org/craftercms/cli/commands/marketplace/CopyPlugin.groovy +++ b/cli/src/main/groovy/org/craftercms/cli/commands/marketplace/CopyPlugin.groovy @@ -35,14 +35,13 @@ class CopyPlugin extends AbstractCommand { def run(client) { def body = [ - siteId: siteOptions.siteId, path : path ] if (parameters) { body.parameters = parameters } - def path = '/studio/api/2/marketplace/copy' + def path = "/studio/api/2/marketplace/${siteOptions.siteId}/copy" def result = client.post(path, body) if (result) { println "Copy plugin response" diff --git a/cli/src/main/groovy/org/craftercms/cli/commands/site/AddRemote.groovy b/cli/src/main/groovy/org/craftercms/cli/commands/site/AddRemote.groovy index 7eb77c510..aebe7b313 100644 --- a/cli/src/main/groovy/org/craftercms/cli/commands/site/AddRemote.groovy +++ b/cli/src/main/groovy/org/craftercms/cli/commands/site/AddRemote.groovy @@ -38,7 +38,6 @@ class AddRemote extends AbstractCommand { def run(client) { def params = [ - siteId : siteOptions.siteId, remoteName : remoteName, remoteUrl : remoteUrl, authenticationType: authAware.authType @@ -57,7 +56,7 @@ class AddRemote extends AbstractCommand { params.remotePrivateKey = authAware.privateKey.text.trim() } - def path = '/studio/api/2/repository/add_remote.json' + def path = "/studio/api/2/repository/${siteOptions.siteId}/add_remote.json" def result = client.post(path, params) if (result) { println result.response.message diff --git a/cli/src/main/groovy/org/craftercms/cli/commands/site/ListRemotes.groovy b/cli/src/main/groovy/org/craftercms/cli/commands/site/ListRemotes.groovy index c0564bac2..0733fd62f 100644 --- a/cli/src/main/groovy/org/craftercms/cli/commands/site/ListRemotes.groovy +++ b/cli/src/main/groovy/org/craftercms/cli/commands/site/ListRemotes.groovy @@ -27,9 +27,8 @@ class ListRemotes extends AbstractCommand { SiteOptions siteOptions def run(client) { - def path = '/studio/api/2/repository/list_remotes.json' - def query = [siteId: siteOptions.siteId] - def result = client.get(path, query) + def path = "/studio/api/2/repository/${siteOptions.siteId}/list_remotes.json" + def result = client.get(path) if (!result) { return } diff --git a/cli/src/main/groovy/org/craftercms/cli/commands/site/SyncFrom.groovy b/cli/src/main/groovy/org/craftercms/cli/commands/site/SyncFrom.groovy index aa92cc00b..a39b7be3b 100644 --- a/cli/src/main/groovy/org/craftercms/cli/commands/site/SyncFrom.groovy +++ b/cli/src/main/groovy/org/craftercms/cli/commands/site/SyncFrom.groovy @@ -27,7 +27,6 @@ class SyncFrom extends AbstractSyncCommand { def run(client) { def params = [ - siteId : siteOptions.siteId, remoteName : remoteOptions.remoteName, remoteBranch: remoteOptions.remoteBranch ] @@ -35,7 +34,7 @@ class SyncFrom extends AbstractSyncCommand { params.mergeStrategy = mergeStrategy } - def path = '/studio/api/2/repository/pull_from_remote.json' + def path = "/studio/api/2/repository/${siteOptions.siteId}/pull_from_remote.json" def result = client.post(path, params) if (result) { println result.response.message diff --git a/cli/src/main/groovy/org/craftercms/cli/commands/site/SyncTo.groovy b/cli/src/main/groovy/org/craftercms/cli/commands/site/SyncTo.groovy index 27a81db58..ff5e6a180 100644 --- a/cli/src/main/groovy/org/craftercms/cli/commands/site/SyncTo.groovy +++ b/cli/src/main/groovy/org/craftercms/cli/commands/site/SyncTo.groovy @@ -27,7 +27,6 @@ class SyncTo extends AbstractSyncCommand { def run(client) { def params = [ - siteId : siteOptions.siteId, remoteName : remoteOptions.remoteName, remoteBranch: remoteOptions.remoteBranch ] @@ -35,7 +34,7 @@ class SyncTo extends AbstractSyncCommand { params.force = force } - def path = '/studio/api/2/repository/push_to_remote.json' + def path = "/studio/api/2/repository/${siteOptions.siteId}/push_to_remote.json" def result = client.post(path, params) if (result) { println result.response.message diff --git a/deployer/src/main/java/org/craftercms/deployer/impl/upgrade/operations/ReplaceProcessorUpgradeOperation.java b/deployer/src/main/java/org/craftercms/deployer/impl/upgrade/operations/ReplaceProcessorUpgradeOperation.java index 2f6e542e5..d1e53f29a 100644 --- a/deployer/src/main/java/org/craftercms/deployer/impl/upgrade/operations/ReplaceProcessorUpgradeOperation.java +++ b/deployer/src/main/java/org/craftercms/deployer/impl/upgrade/operations/ReplaceProcessorUpgradeOperation.java @@ -42,6 +42,7 @@ public class ReplaceProcessorUpgradeOperation extends AbstractProcessorUpgradeOp protected String newProcessorName; protected List deleteProperties; + protected Map properties; @Override @SuppressWarnings("rawtypes,unchecked") @@ -59,6 +60,18 @@ protected void doInit(HierarchicalConfiguration config) throws ConfigurationExce newProcessorName = getRequiredStringProperty(config, CONFIG_KEY_NEW_PROCESSOR); deleteProperties = config.getList(String.class, CONFIG_KEY_DELETE_PROPERTIES, Collections.emptyList()); + + properties = new HashMap<>(); + if (config.containsKey(CONFIG_KEY_PROPERTIES)) { + HierarchicalConfiguration propertyConfig = config.configurationAt(CONFIG_KEY_PROPERTIES); + if (propertyConfig != null) { + Iterator it = propertyConfig.getKeys(); + while (it.hasNext()) { + String key = it.next(); + properties.put(key, propertyConfig.getString(key)); + } + } + } } protected boolean matchesAllConditions(Map processorObj) { @@ -81,6 +94,7 @@ protected void doExecuteInternal(Target target, Map targetConfig for (Map processorObj : pipelineObj) { if (matchesAllConditions(processorObj)) { processorObj.put(PROCESSOR_NAME_CONFIG_KEY, newProcessorName); + properties.forEach(processorObj::put); deleteProperties.forEach(processorObj::remove); } } diff --git a/deployer/src/main/resources/templates/targets/authoring-target-template.yaml b/deployer/src/main/resources/templates/targets/authoring-target-template.yaml index f8a083e81..f12e17383 100644 --- a/deployer/src/main/resources/templates/targets/authoring-target-template.yaml +++ b/deployer/src/main/resources/templates/targets/authoring-target-template.yaml @@ -20,5 +20,5 @@ target: - processorName: httpMethodCallProcessor includeFiles: [ "^/?config/studio/scripts/classes/.*$" ] method: GET - url: ${target.studioUrl}/api/2/plugin/script/reload.json?siteId=${target.siteName}&token=${target.studioManagementToken} + url: ${target.studioUrl}/api/2/plugin/${target.siteName}/script/reload.json?token=${target.studioManagementToken} - processorName: fileOutputProcessor diff --git a/deployer/src/main/resources/upgrade/pipelines.yaml b/deployer/src/main/resources/upgrade/pipelines.yaml index 1e6e22a5f..2eb46eaaa 100644 --- a/deployer/src/main/resources/upgrade/pipelines.yaml +++ b/deployer/src/main/resources/upgrade/pipelines.yaml @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. +# Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 as published by @@ -97,7 +97,7 @@ pipelines: value: ${target.engineUrl}/api/1/site/context/rebuild.json?crafterSite=${target.siteName}&token=${target.engineManagementToken} - property: jumpTo value: fileOutputProcessor - + # Upgrade entrypoint - currentVersion: 2.6 nextVersion: 4.1.3-t @@ -114,3 +114,13 @@ pipelines: - type: replaceProcessorUpgrader processor: authoringElasticsearchIndexingProcessor newProcessor: authoringSearchIndexingProcessor + - currentVersion: 4.1.3.0 + nextVersion: 5.0.0.0 + operations: + - type: replaceProcessorUpgrader + processor: httpMethodCallProcessor + newProcessor: httpMethodCallProcessor + conditions: + - url: '.*/api/2/plugin/script/reload.json.*' + properties: + - url: ${target.studioUrl}/api/2/plugin/${target.siteName}/script/reload.json?token=${target.studioManagementToken} diff --git a/studio/src/main/api/studio-api.yaml b/studio/src/main/api/studio-api.yaml index 46ba50d77..1ffd77407 100644 --- a/studio/src/main/api/studio-api.yaml +++ b/studio/src/main/api/studio-api.yaml @@ -849,7 +849,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/users/{id}/sites/{site}/roles: + /api/2/users/{id}/sites/{siteId}/roles: get: tags: - users @@ -865,7 +865,7 @@ paths: required: true schema: type: string - - name: site + - name: siteId in: path description: The site ID required: true @@ -1076,7 +1076,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/users/me/sites/{site}/roles: + /api/2/users/me/sites/{siteId}/roles: get: tags: - users @@ -1086,7 +1086,7 @@ paths: Required Permission: "LOGGED_IN" operationId: getCurrentUserSiteRoles parameters: - - name: site + - name: siteId in: path description: The site ID required: true @@ -1111,7 +1111,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/users/me/sites/{site}/permissions: + /api/2/users/me/sites/{siteId}/permissions: get: tags: - users @@ -1121,7 +1121,7 @@ paths: Required Permission: "LOGGED_IN" operationId: getCurrentUserSitePermissions parameters: - - name: site + - name: siteId in: path description: The site ID required: true @@ -1148,7 +1148,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/users/me/sites/{site}/has_permissions: + /api/2/users/me/sites/{siteId}/has_permissions: post: tags: - users @@ -1158,7 +1158,7 @@ paths: Required Permission: "LOGGED_IN" operationId: hasCurrentUserSitePermissions parameters: - - name: site + - name: siteId in: path description: The site ID required: true @@ -1577,7 +1577,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/aws/s3/list: + /api/2/aws/{siteId}/s3/list: get: tags: - aws @@ -1588,7 +1588,7 @@ paths: Required Permission: "s3_read" parameters: - name: siteId - in: query + in: path description: The site ID required: true schema: @@ -1638,12 +1638,19 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/aws/s3/upload: + /api/2/aws/{siteId}/s3/upload: post: tags: - aws summary: Upload a file to an S3 bucket operationId: uploadItem + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string description: | Module: Studio
Required Permission: "s3_write" @@ -1654,9 +1661,6 @@ paths: schema: type: object properties: - siteId: - type: string - description: The site ID profileId: type: string description: The profile ID @@ -1671,7 +1675,6 @@ paths: format: binary description: The content of the file to upload required: - - siteId - profileId - filename - file @@ -1694,12 +1697,19 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/aws/mediaconvert/upload: + /api/2/aws/{siteId}/mediaconvert/upload: post: tags: - aws summary: Upload a file to an S3 bucket and trigger a MediaConvert job operationId: uploadVideo + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string description: | Module: Studio
Required Permission: "s3_write" @@ -1710,9 +1720,6 @@ paths: schema: type: object properties: - siteId: - type: string - description: The site ID inputProfileId: type: string description: The MediaConvert profile ID @@ -1724,7 +1731,6 @@ paths: format: binary description: The content of the file to upload required: - - siteId - inputProfileId - outputProfileId - file @@ -1749,7 +1755,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/webdav/list: + /api/2/webdav/{siteId}/list: get: tags: - webdav @@ -1760,7 +1766,7 @@ paths: operationId: listItemsWebdav parameters: - name: siteId - in: query + in: path description: The site ID required: true schema: @@ -1804,7 +1810,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/webdav/upload: + /api/2/webdav/{siteId}/upload: post: tags: - webdav @@ -1813,6 +1819,13 @@ paths: Module: Studio
Required Permission: "webdav_write" operationId: uploadItemWebdav + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: required: true content: @@ -1820,9 +1833,6 @@ paths: schema: type: object properties: - siteId: - type: string - description: The site ID profileId: type: string description: The profile ID @@ -1834,7 +1844,6 @@ paths: format: binary description: The content of the file to upload required: - - siteId - profileId - file responses: @@ -2408,7 +2417,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/search/search: + /api/2/search/{siteId}/search: post: tags: - search @@ -2417,7 +2426,7 @@ paths: operationId: search parameters: - name: siteId - in: query + in: path description: The site ID required: true schema: @@ -2822,7 +2831,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/repository/add_remote: + /api/2/repository/{siteId}/add_remote: post: tags: - repository @@ -2831,6 +2840,13 @@ paths: Module: Studio
Required permission "add_remote" operationId: addRemoteRepository + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: Remote repository entity required: true @@ -2859,7 +2875,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/repository/pull_from_remote: + /api/2/repository/{siteId}/pull_from_remote: post: tags: - repository @@ -2868,6 +2884,13 @@ paths: Module: Studio
Required permission "pull_from_remote" operationId: pullFromRemoteRepository + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: pull from remote repository request body required: true @@ -2876,9 +2899,6 @@ paths: schema: type: object properties: - siteId: - type: string - description: Site ID remoteName: type: string description: Remote repository name to pull from @@ -2890,7 +2910,6 @@ paths: format: theirs, ours, none description: Merge strategy to use when pulling content from remote repository required: - - siteId - remoteName - remoteBranch responses: @@ -2927,7 +2946,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/repository/push_to_remote: + /api/2/repository/{siteId}/push_to_remote: post: tags: - repository @@ -2936,6 +2955,13 @@ paths: Module: Studio
Required permission "push_to_remote" operationId: pushToRemoteRepository + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: push to remote repository request body required: true @@ -2944,9 +2970,6 @@ paths: schema: type: object properties: - siteId: - type: string - description: Site ID remoteName: type: string description: Remote repository name to push to @@ -2957,7 +2980,6 @@ paths: type: boolean description: Indicates whether to force push to remote or not required: - - siteId - remoteName - remoteBranch responses: @@ -2981,7 +3003,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/repository/remove_remote: + /api/2/repository/{siteId}/remove_remote: post: tags: - repository @@ -2990,6 +3012,13 @@ paths: Module: Studio
Required permission "remove_remote" operationId: removeRemoteRepository + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: remove remote repository request body required: true @@ -2998,14 +3027,10 @@ paths: schema: type: object properties: - siteId: - type: string - description: Site ID remoteName: type: string description: Remote repository name of remote to be removed required: - - siteId - remoteName responses: '200': @@ -3026,7 +3051,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/repository/list_remotes: + /api/2/repository/{siteId}/list_remotes: get: tags: - repository @@ -3037,7 +3062,7 @@ paths: operationId: listRemoteRepositories parameters: - name: siteId - in: query + in: path description: Site ID required: true schema: @@ -3065,7 +3090,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/repository/status: + /api/2/repository/{siteId}/status: get: tags: - repository @@ -3076,7 +3101,7 @@ paths: operationId: repositoryStatus parameters: - name: siteId - in: query + in: path description: Site ID required: true schema: @@ -3102,7 +3127,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/repository/resolve_conflict: + /api/2/repository/{siteId}/resolve_conflict: post: tags: - repository @@ -3111,6 +3136,13 @@ paths: Module: Studio
Required permission "resolve_conflict" operationId: resolveConflict + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: resolve conflict request body required: true @@ -3119,9 +3151,6 @@ paths: schema: type: object properties: - siteId: - type: string - description: site ID path: type: string description: Conflicted file path @@ -3129,7 +3158,6 @@ paths: type: string description: resolution mechanism to use (ours, theirs) required: - - siteId - path - resolution responses: @@ -3153,7 +3181,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/repository/diff_conflicted_file: + /api/2/repository/{siteId}/diff_conflicted_file: get: tags: - repository @@ -3164,7 +3192,7 @@ paths: operationId: diffConflictedFile parameters: - name: siteId - in: query + in: path description: Site ID required: true schema: @@ -3207,7 +3235,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/repository/commit_resolution: + /api/2/repository/{siteId}/commit_resolution: post: tags: - repository @@ -3216,6 +3244,13 @@ paths: Module: Studio
Required permission "commit_resolution" operationId: commitResolution + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: Commit resolution request body required: true @@ -3224,14 +3259,10 @@ paths: schema: type: object properties: - siteId: - type: string - description: site ID commitMessage: type: string description: Commit message required: - - siteId - commitMessage responses: '200': @@ -3254,7 +3285,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/repository/cancel_failed_pull: + /api/2/repository/{siteId}/cancel_failed_pull: post: tags: - repository @@ -3263,19 +3294,13 @@ paths: Module: Studio
Required permission "cancel_failed_pull" operationId: cancelFailedPull - requestBody: - description: cancel failed pull request body - required: true - content: - application/json: - schema: - type: object - properties: - siteId: - type: string - description: site ID - required: - - siteId + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string responses: '200': description: OK @@ -3470,7 +3495,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/configuration/get_configuration: + /api/2/configuration/{siteId}/get_configuration: get: tags: - configuration @@ -3481,7 +3506,7 @@ paths: operationId: getConfiguration parameters: - name: siteId - in: query + in: path description: Site ID required: true schema: @@ -3528,7 +3553,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/configuration/write_configuration: + /api/2/configuration/{siteId}/write_configuration: post: tags: - configuration @@ -3537,6 +3562,13 @@ paths: Module: Studio
Required permission "write_configuration" operationId: writeConfiguration + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: write configuration request body required: true @@ -3545,9 +3577,6 @@ paths: schema: type: object properties: - siteId: - type: string - description: site ID module: type: string description: Module name (e.g. studio, engine) @@ -3561,7 +3590,6 @@ paths: type: string description: configuration file content required: - - siteId - module - path - content @@ -3586,7 +3614,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/configuration/clear_cache: + /api/2/configuration/{siteId}/clear_cache: get: tags: - configuration @@ -3597,7 +3625,7 @@ paths: operationId: clearConfigurationCache parameters: - name: siteId - in: query + in: path description: Site ID required: true schema: @@ -3614,7 +3642,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/configuration/get_configuration_history: + /api/2/configuration/{siteId}/get_configuration_history: get: tags: - configuration @@ -3625,7 +3653,7 @@ paths: operationId: getConfigurationHistory parameters: - name: siteId - in: query + in: path description: Site ID required: true schema: @@ -3682,7 +3710,7 @@ paths: # operationId: getTranslationConfig # parameters: # - name: siteId - # in: query + # in: path # description: site ID # required: true # schema: @@ -4000,7 +4028,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/plugin/file: + /api/2/plugin/{siteId}/file: # Override the server to change the prefix servers: - url: http://localhost:8080/studio/1 @@ -4014,7 +4042,7 @@ paths: operationId: getPluginFile parameters: - name: siteId - in: query + in: path description: The site ID required: true schema: @@ -4072,7 +4100,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/plugin/get_configuration: + /api/2/plugin/{siteId}/get_configuration: get: tags: - plugin @@ -4083,7 +4111,7 @@ paths: operationId: getPluginConfiguration parameters: - name: siteId - in: query + in: path description: The id of the site required: true schema: @@ -4116,7 +4144,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/plugin/write_configuration: + /api/2/plugin/{siteId}/write_configuration: post: tags: - plugin @@ -4125,6 +4153,13 @@ paths: Module: Studio
Required permission "write_configuration" and "site member" operationId: writePluginConfiguration + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: write configuration request body required: true @@ -4133,9 +4168,6 @@ paths: schema: type: object properties: - siteId: - type: string - description: The id of the site pluginId: type: string description: The id of the plugin @@ -4143,7 +4175,6 @@ paths: type: string description: configuration file content required: - - siteId - pluginId - content responses: @@ -4165,7 +4196,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/plugin/script/reload: + /api/2/plugin/{siteId}/script/reload: get: tags: - plugin @@ -4174,7 +4205,7 @@ paths: operationId: reloadClasses parameters: - name: siteId - in: query + in: path description: Site ID required: true schema: @@ -4204,7 +4235,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/list_quick_create_content: + /api/2/content/{siteId}/list_quick_create_content: get: tags: - content @@ -4215,7 +4246,7 @@ paths: operationId: quickCreateContent parameters: - name: siteId - in: query + in: path description: Site ID required: true schema: @@ -4243,7 +4274,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/get_delete_package: + /api/2/content/{siteId}/get_delete_package: post: tags: - content @@ -4252,22 +4283,25 @@ paths: Module: Studio
Required permission "content_read" operationId: getDeletePackage + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: content: application/json: schema: type: object properties: - siteId: - description: Site ID - type: string paths: description: Content paths to get a delete package for type: array items: type: string required: - - siteId - paths responses: '200': @@ -4299,7 +4333,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/delete: + /api/2/content/{siteId}/delete: post: tags: - content @@ -4308,6 +4342,13 @@ paths: Module: Studio
Required permission "content_delete" operationId: contentDelete + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: parameters for delete content required: true @@ -4316,9 +4357,6 @@ paths: schema: type: object properties: - siteId: - type: string - description: site identifier items: type: array description: path(s) of content item(s) @@ -4332,7 +4370,6 @@ paths: type: string description: deletion comment by the user performing the delete required: - - siteId - items responses: '200': @@ -4357,7 +4394,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/rename: + /api/2/content/{siteId}/rename: post: tags: - content @@ -4366,6 +4403,13 @@ paths: Module: Studio
Required permission "content_write" operationId: contentRename + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: parameters for rename content required: true @@ -4374,9 +4418,6 @@ paths: schema: type: object properties: - siteId: - type: string - description: site identifier path: type: string description: full path to the item to rename @@ -4384,7 +4425,6 @@ paths: type: string description: new item name (just the name, no path) required: - - siteId - path - name responses: @@ -4870,7 +4910,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/exists: + /api/2/content/{siteId}/exists: get: tags: - content @@ -4881,7 +4921,7 @@ paths: operationId: contentExists parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -4915,7 +4955,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/item_by_path: + /api/2/content/{siteId}/item_by_path: get: tags: - content @@ -4926,7 +4966,7 @@ paths: operationId: getDetailedItemByPath parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -4966,7 +5006,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/sandbox_items_by_path: + /api/2/content/{siteId}/sandbox_items_by_path: post: tags: - content @@ -4975,6 +5015,13 @@ paths: Module: Studio
Required permission "get_children" and "site member" operationId: getContentItemsByPath + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: required: true content: @@ -4982,9 +5029,6 @@ paths: schema: type: object properties: - siteId: - description: Site ID - type: string paths: description: item paths to get type: array @@ -4994,7 +5038,6 @@ paths: description: when set to true, return an item instead of a folder if the path can match either type: boolean required: - - siteId - paths responses: '200': @@ -5025,7 +5068,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/descriptor: + /api/2/content/{siteId}/descriptor: get: tags: - content @@ -5034,7 +5077,7 @@ paths: operationId: getDescriptor parameters: - name: siteId - in: query + in: path description: The site ID required: true schema: @@ -5125,7 +5168,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/duplicate: + /api/2/content/{siteId}/duplicate: post: tags: - content @@ -5134,6 +5177,13 @@ paths: Module: Studio
Required permission "Write" operationId: duplicateItem + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: required: true content: @@ -5141,14 +5191,10 @@ paths: schema: type: object properties: - siteId: - type: string - description: The id of the site path: type: string description: The path of the item to duplicate required: - - siteId - path responses: '200': @@ -5174,7 +5220,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/item_lock_by_path: + /api/2/content/{siteId}/item_lock_by_path: post: tags: - content @@ -5183,6 +5229,13 @@ paths: Module: Studio
Required permission "content_write" operationId: itemLockByPath + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: required: true content: @@ -5190,14 +5243,10 @@ paths: schema: type: object properties: - siteId: - type: string - description: The id of the site path: type: string description: Path of item to lock required: - - siteId - path responses: '200': @@ -5225,7 +5274,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/item_unlock_by_path: + /api/2/content/{siteId}/item_unlock_by_path: post: tags: - content @@ -5234,6 +5283,13 @@ paths: Module: Studio
Required permission "item_unlock" or lock owner operationId: itemUnlockByPath + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: required: true content: @@ -5241,14 +5297,10 @@ paths: schema: type: object properties: - siteId: - type: string - description: The id of the site path: type: string description: The path of the item to unlock required: - - siteId - path responses: '200': @@ -5274,7 +5326,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/get_content_by_commit_id: + /api/2/content/{siteId}/get_content_by_commit_id: get: tags: - content @@ -5285,7 +5337,7 @@ paths: operationId: getContentByCommitId parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -5326,7 +5378,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/content/item_history: + /api/2/content/{siteId}/item_history: get: tags: - content @@ -5337,7 +5389,7 @@ paths: operationId: getItemHistory parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -5790,7 +5842,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/marketplace/installed: + /api/2/marketplace/{siteId}/installed: get: tags: - marketplace @@ -5801,7 +5853,7 @@ paths: operationId: getInstalledPlugins parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -5829,7 +5881,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/marketplace/install: + /api/2/marketplace/{siteId}/install: post: tags: - marketplace @@ -5838,6 +5890,13 @@ paths: Module: Studio
Required permission "install_plugins" operationId: installPlugin + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: required: true content: @@ -5845,9 +5904,6 @@ paths: schema: type: object properties: - siteId: - description: The id of the site - type: string pluginId: description: The id of the plugin type: string @@ -5859,7 +5915,6 @@ paths: additionalProperties: type: string required: - - siteId - pluginId - pluginVersion responses: @@ -5883,7 +5938,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/marketplace/copy: + /api/2/marketplace/{siteId}/copy: post: tags: - marketplace @@ -5892,6 +5947,13 @@ paths: Module: Studio
Required permission "install_plugins" operationId: copyPlugin + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: required: true content: @@ -5899,9 +5961,6 @@ paths: schema: type: object properties: - siteId: - description: The id of the site - type: string path: description: The path of the local plugin source folder type: string @@ -5911,7 +5970,6 @@ paths: additionalProperties: type: string required: - - siteId - path responses: '200': @@ -5932,7 +5990,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/marketplace/remove: + /api/2/marketplace/{siteId}/remove: post: tags: - marketplace @@ -5941,6 +5999,13 @@ paths: Module: Studio
Required permission "remove_plugins" operationId: removePlugin + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: required: true content: @@ -5948,16 +6013,12 @@ paths: schema: type: object properties: - siteId: - description: The id of the site - type: string pluginId: description: The id of the plugin type: string force: description: Indicates if the plugin should be removed even if there are dependant items required: - - siteId - pluginId responses: '200': @@ -5982,7 +6043,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/marketplace/usage: + /api/2/marketplace/{siteId}/usage: get: tags: - marketplace @@ -5993,11 +6054,11 @@ paths: operationId: pluginUsage parameters: - name: siteId - description: The id of the site + in: path + description: Site ID + required: true schema: type: string - required: true - in: query - name: pluginId description: The id of the plugin schema: @@ -6622,7 +6683,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/publish/available_targets: + /api/2/publish/{siteId}/available_targets: get: tags: - publishing @@ -6633,7 +6694,7 @@ paths: operationId: getAvailablePublishingTargets parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -6672,7 +6733,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/publish/has_initial_publish: + /api/2/publish/{siteId}/has_initial_publish: get: tags: - publishing @@ -6683,7 +6744,7 @@ paths: operationId: hasInitialPublish parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -6737,8 +6798,7 @@ paths: type: boolean description: true to enable, false to disable required: - - siteId - - enabled + - enable responses: '200': description: OK @@ -6969,7 +7029,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/dashboard/activity: + /api/2/dashboard/{siteId}/activity: get: tags: - dashboard @@ -6980,7 +7040,7 @@ paths: operationId: getDashboardActivities parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -7064,7 +7124,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/dashboard/activity/me: + /api/2/dashboard/{siteId}/activity/me: get: tags: - dashboard @@ -7075,7 +7135,7 @@ paths: operationId: getDashboardMyActivities parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -7151,7 +7211,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/dashboard/content/unpublished: + /api/2/dashboard/{siteId}/content/unpublished: get: tags: - dashboard @@ -7162,7 +7222,7 @@ paths: operationId: getDashboardContentUnpublished parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -7226,7 +7286,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/dashboard/publishing/stats: + /api/2/dashboard/{siteId}/publishing/stats: get: tags: - dashboard @@ -7237,7 +7297,7 @@ paths: operationId: getDashboardPublishingStats parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -7272,7 +7332,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/dashboard/content/expiring: + /api/2/dashboard/{siteId}/content/expiring: get: tags: - dashboard @@ -7283,7 +7343,7 @@ paths: operationId: getDashboardContentExpiring parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -7350,7 +7410,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/dashboard/content/expired: + /api/2/dashboard/{siteId}/content/expired: get: tags: - dashboard @@ -7361,7 +7421,7 @@ paths: operationId: getDashboardContentExpired parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -7425,7 +7485,7 @@ paths: # operationId: getItemsForTranslation # parameters: # - name: siteId - # in: query + # in: path # description: site ID # required: true # schema: @@ -7621,7 +7681,7 @@ paths: # operationId: getTranslationTargetLocales # parameters: # - name: siteId - # in: query + # in: path # description: site ID # required: true # schema: @@ -7768,7 +7828,7 @@ paths: # '500': # $ref: '#/components/responses/InternalServerError' - /api/2/workflow/item_states: + /api/2/workflow/{siteId}/item_states: get: tags: - workflow @@ -7779,7 +7839,7 @@ paths: operationId: getItemStates parameters: - name: siteId - in: query + in: path description: site ID required: true schema: @@ -7852,6 +7912,13 @@ paths: Module: Studio
Required permission "set_item_states" operationId: setItemStates + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: List of items to set workflow state(s) required: true @@ -7860,9 +7927,6 @@ paths: schema: type: object properties: - siteId: - type: string - description: site ID items: type: array description: path(s) of item(s) @@ -7887,7 +7951,6 @@ paths: type: boolean description: true if item is to be set as modified, otherwise false required: - - siteId - items responses: '200': @@ -7908,7 +7971,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/workflow/update_item_states_by_query: + /api/2/workflow/{siteId}/update_item_states_by_query: post: tags: - workflow @@ -7917,6 +7980,13 @@ paths: Module: Studio
Required permission "set_item_states" operationId: updateItemStates + parameters: + - name: siteId + in: path + description: Site ID + required: true + schema: + type: string requestBody: description: List of items to set workflow state(s) required: true @@ -7928,9 +7998,6 @@ paths: query: type: object properties: - siteId: - type: string - description: site ID path: type: string description: path regex of item(s) @@ -7938,8 +8005,6 @@ paths: type: integer format: int64 description: state bitmap mask to filter by state - required: - - siteId update: type: object properties: @@ -7983,7 +8048,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/workflow/{site}/affected_packages: + /api/2/workflow/{siteId}/affected_packages: get: tags: - workflow @@ -7993,7 +8058,7 @@ paths: Required permission "publish_get_queue" operationId: getWorkflowAffectedPackages parameters: - - name: site + - name: siteId in: path description: site ID required: true @@ -8037,7 +8102,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/workflow/{site}/approve: + /api/2/workflow/{siteId}/approve: post: tags: - workflow @@ -8047,7 +8112,7 @@ paths: Required permission "publish_review" operationId: workflowApprove parameters: - - name: site + - name: siteId in: path description: site ID required: true @@ -8101,7 +8166,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/workflow/{site}/reject: + /api/2/workflow/{siteId}/reject: post: tags: - workflow @@ -8111,7 +8176,7 @@ paths: Required permission "publish_review" operationId: workflowReject parameters: - - name: site + - name: siteId in: path description: site ID required: true @@ -8158,7 +8223,7 @@ paths: '500': $ref: '#/components/responses/InternalServerError' - /api/2/workflow/{site}/cancel: + /api/2/workflow/{siteId}/cancel: post: tags: - workflow @@ -8168,7 +8233,7 @@ paths: Required permission "publish_cancel" operationId: cancelPublishPackages parameters: - - name: site + - name: siteId in: path description: site ID required: true @@ -9706,9 +9771,6 @@ components: RemoteRepository: type: object properties: - siteId: - type: string - description: site identifier remoteName: type: string description: remote repository name @@ -9743,7 +9805,6 @@ components: type: string description: private key to access required: - - siteId - remoteName - remoteUrl - authenticationType diff --git a/studio/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepository.java b/studio/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepository.java index 4b6f3e23d..0159e5260 100644 --- a/studio/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepository.java +++ b/studio/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepository.java @@ -21,7 +21,6 @@ import jakarta.validation.constraints.Size; import org.craftercms.commons.git.utils.AuthenticationType; import org.craftercms.commons.jackson.CaseInsensitiveEnumDeserializer; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import org.craftercms.commons.validation.annotations.param.ValidateNoTagsParam; import java.io.Serializable; @@ -31,8 +30,6 @@ public class RemoteRepository implements Serializable { private static final long serialVersionUID = -5031083831374591061L; private long id; - @ValidSiteId - private String siteId; @Size(max = 50) private String remoteName; @Size(max = 2000) @@ -58,14 +55,6 @@ public void setId(long id) { this.id = id; } - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getRemoteName() { return remoteName; } diff --git a/studio/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepositoryDAO.java b/studio/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepositoryDAO.java index e0330d011..de8d9c14e 100644 --- a/studio/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepositoryDAO.java +++ b/studio/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepositoryDAO.java @@ -21,6 +21,7 @@ import java.util.Map; import static org.craftercms.studio.api.v2.dal.QueryParameterNames.REPOSITORY; +import static org.craftercms.studio.api.v2.dal.QueryParameterNames.SITE_ID; public interface RemoteRepositoryDAO { @@ -29,9 +30,10 @@ public interface RemoteRepositoryDAO { /** * Inserts a new remote repository. * + * @param siteId the site ID * @param repository the remote repository to insert */ - void insertRemoteRepository(@Param(REPOSITORY) RemoteRepository repository); + void insertRemoteRepository(@Param(SITE_ID) String siteId, @Param(REPOSITORY) RemoteRepository repository); void deleteRemoteRepository(Map params); } diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/ConfigurationController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/ConfigurationController.java index 30cdbe95f..b5a136ea4 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/ConfigurationController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/ConfigurationController.java @@ -51,6 +51,7 @@ import org.craftercms.studio.model.rest.WriteConfigurationRequest; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -72,7 +73,7 @@ public ConfigurationController(ConfigurationService configurationService, Studio } @GetMapping(value = CLEAR_CACHE, produces = APPLICATION_JSON_VALUE) - public Result clearCache(@ValidSiteId @RequestParam String siteId) { + public Result clearCache(@ValidSiteId @PathVariable String siteId) { configurationService.invalidateConfiguration(siteId); var result = new Result(); result.setResponse(OK); @@ -81,7 +82,7 @@ public Result clearCache(@ValidSiteId @RequestParam String siteId) { @GetMapping(value = GET_CONFIGURATION, produces = APPLICATION_JSON_VALUE) @LogExecutionTime - public ResultOne getConfiguration(@ValidSiteId @RequestParam(name = "siteId", required = true) String siteId, + public ResultOne getConfiguration(@ValidSiteId @PathVariable String siteId, @EsapiValidatedParam(type = ALPHANUMERIC) @RequestParam(name = "module", required = true) String module, @ValidConfigurationPath @RequestParam(name = "path", required = true) String path, @EsapiValidatedParam(type = ALPHANUMERIC) @RequestParam(name = "environment", required = false) String environment) @@ -100,10 +101,10 @@ public ResultOne getConfiguration(@ValidSiteId @RequestParam(name = "sit } @PostMapping(value = WRITE_CONFIGURATION, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result writeConfiguration(@Validated @RequestBody WriteConfigurationRequest wcRequest) + public Result writeConfiguration(@ValidSiteId @PathVariable String siteId, + @Validated @RequestBody WriteConfigurationRequest wcRequest) throws ServiceLayerException, UserNotFoundException, AuthenticationException { InputStream is = IOUtils.toInputStream(wcRequest.getContent(), UTF_8); - String siteId = wcRequest.getSiteId(); if (CS.equals(siteId, studioConfiguration.getProperty(CONFIGURATION_GLOBAL_SYSTEM_SITE))) { configurationService.writeGlobalConfiguration(wcRequest.getPath(), is); } else { @@ -116,7 +117,7 @@ public Result writeConfiguration(@Validated @RequestBody WriteConfigurationReque } @GetMapping(value = GET_CONFIGURATION_HISTORY, produces = APPLICATION_JSON_VALUE) - public ResultOne getConfigurationHistory(@ValidSiteId @RequestParam(name = "siteId", required = true) String siteId, + public ResultOne getConfigurationHistory(@ValidSiteId @PathVariable String siteId, @EsapiValidatedParam(type = ALPHANUMERIC) @RequestParam(name = "module", required = true) String module, @ValidConfigurationPath @RequestParam(name = "path", required = true) String path, @EsapiValidatedParam(type = ALPHANUMERIC) @RequestParam(name = "environment", required = false) String environment) @@ -130,7 +131,7 @@ public ResultOne getConfigurationHistory(@ValidSiteId @Req } @GetMapping(value = TRANSLATION, produces = APPLICATION_JSON_VALUE) - public ResultOne getTranslationConfiguration(@ValidSiteId @RequestParam String siteId) throws ServiceLayerException { + public ResultOne getTranslationConfiguration(@ValidSiteId @PathVariable String siteId) throws ServiceLayerException { ResultOne result = new ResultOne<>(); result.setEntity(RESULT_KEY_CONFIG, configurationService.getTranslationConfiguration(siteId)); result.setResponse(OK); diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/ContentController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/ContentController.java index 9aa7d0329..d7e0689ec 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/ContentController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/ContentController.java @@ -103,8 +103,8 @@ public ContentController(ContentService contentService, DependencyService depend this.contentTypeService = contentTypeService; } - @GetMapping(value = EXISTS, produces = APPLICATION_JSON_VALUE) - public ResultOne contentExists(@NotEmpty @ValidSiteId @RequestParam String siteId, + @GetMapping(value = SITE_ID + EXISTS, produces = APPLICATION_JSON_VALUE) + public ResultOne contentExists(@NotEmpty @ValidSiteId @PathVariable String siteId, @ValidExistingContentPath @ValidateSecurePathParam @RequestParam String path) throws SiteNotFoundException { var result = new ResultOne(); @@ -113,8 +113,8 @@ public ResultOne contentExists(@NotEmpty @ValidSiteId @RequestParam Str return result; } - @GetMapping(value = LIST_QUICK_CREATE_CONTENT, produces = APPLICATION_JSON_VALUE) - public ResultList listQuickCreateContent(@NotBlank @ValidSiteId @RequestParam(name = "siteId") String siteId) + @GetMapping(value = SITE_ID + LIST_QUICK_CREATE_CONTENT, produces = APPLICATION_JSON_VALUE) + public ResultList listQuickCreateContent(@NotBlank @ValidSiteId @PathVariable String siteId) throws ServiceLayerException { List items = contentTypeService.getQuickCreatableContentTypes(siteId); ResultList result = new ResultList<>(); @@ -123,10 +123,11 @@ public ResultList listQuickCreateContent(@NotBlank @ValidSiteId return result; } - @PostMapping(value = GET_DELETE_PACKAGE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne>> getDeletePackage(@RequestBody @Valid GetDeletePackageRequestBody request) throws SiteNotFoundException { - List childItems = contentService.getChildItems(request.getSiteId(), request.getPaths()); - Collection dependentItems = dependencyService.getDependentPaths(request.getSiteId(), request.getPaths()); + @PostMapping(value = SITE_ID + GET_DELETE_PACKAGE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) + public ResultOne>> getDeletePackage(@ValidSiteId @PathVariable String siteId, + @RequestBody @Valid GetDeletePackageRequestBody request) throws SiteNotFoundException { + List childItems = contentService.getChildItems(siteId, request.getPaths()); + Collection dependentItems = dependencyService.getDependentPaths(siteId, request.getPaths()); ResultOne>> result = new ResultOne<>(); result.setResponse(OK); Map> items = new HashMap<>(); @@ -136,10 +137,10 @@ public ResultOne>> getDeletePackage(@RequestBo return result; } - @PostMapping(value = DELETE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result delete(@RequestBody @Validated DeleteRequestBody deleteRequestBody) + @PostMapping(value = SITE_ID + DELETE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) + public Result delete(@ValidSiteId @PathVariable String siteId, @RequestBody @Validated DeleteRequestBody deleteRequestBody) throws UserNotFoundException, ServiceLayerException, AuthenticationException { - UnwrappedResult result = UnwrappedResult.of(contentService.deleteContent(deleteRequestBody.getSiteId(), + UnwrappedResult result = UnwrappedResult.of(contentService.deleteContent(siteId, deleteRequestBody.getItems(), deleteRequestBody.getTitle(), deleteRequestBody.getComment())); result.setResponse(OK); @@ -158,8 +159,8 @@ public Result getChildrenByPaths(@PathVariable @ValidSiteId String siteId, @Vali return result; } - @GetMapping(value = GET_DESCRIPTOR, produces = APPLICATION_JSON_VALUE) - public ResultOne getDescriptor(@NotEmpty @ValidSiteId @RequestParam String siteId, + @GetMapping(value = SITE_ID + GET_DESCRIPTOR, produces = APPLICATION_JSON_VALUE) + public ResultOne getDescriptor(@NotEmpty @ValidSiteId @PathVariable String siteId, @ValidExistingContentPath @ValidateSecurePathParam @RequestParam String path, @RequestParam(required = false, defaultValue = "false") boolean flatten) throws ContentNotFoundException, SiteNotFoundException { @@ -182,19 +183,18 @@ public ResultList pasteItems(@ValidSiteId @PathVariable String siteId, return result; } - @PostMapping(value = DUPLICATE_ITEM, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE) - public ResultOne duplicateItem(@Valid @RequestBody DuplicateRequest request) throws Exception { + @PostMapping(value = SITE_ID + DUPLICATE_ITEM, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE) + public ResultOne duplicateItem(@ValidSiteId @PathVariable String siteId, @Valid @RequestBody DuplicateRequest request) throws Exception { var result = new ResultOne(); result.setResponse(OK); result.setEntity(RESULT_KEY_ITEM, - clipboardService.duplicateItem(request.getSiteId(), request.getPath())); + clipboardService.duplicateItem(siteId, request.getPath())); return result; } - @GetMapping(value = ITEM_BY_PATH, produces = APPLICATION_JSON_VALUE) - public ResultOne getItemByPath(@ValidSiteId - @RequestParam(value = REQUEST_PARAM_SITEID) String siteId, + @GetMapping(value = SITE_ID + ITEM_BY_PATH, produces = APPLICATION_JSON_VALUE) + public ResultOne getItemByPath(@ValidSiteId @PathVariable String siteId, @ValidExistingContentPath @RequestParam(value = REQUEST_PARAM_PATH) String path, @RequestParam(value = REQUEST_PARAM_PREFER_CONTENT, required = false, @@ -207,10 +207,10 @@ public ResultOne getItemByPath(@ValidSiteId return result; } - @PostMapping(value = SANDBOX_ITEMS_BY_PATH, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE) - public GetContentItemsByPathResult getSandboxItemsByPath(@RequestBody @Valid GetSandboxItemsByPathRequestBody request) + @PostMapping(value = SITE_ID + SANDBOX_ITEMS_BY_PATH, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE) + public GetContentItemsByPathResult getSandboxItemsByPath(@ValidSiteId @PathVariable String siteId, + @RequestBody @Valid GetSandboxItemsByPathRequestBody request) throws ServiceLayerException, UserNotFoundException { - String siteId = request.getSiteId(); Collection missing = Collections.emptyList(); List paths = request.getPaths(); boolean preferContent = request.isPreferContent(); @@ -232,27 +232,27 @@ public GetContentItemsByPathResult getSandboxItemsByPath(@RequestBody @Valid Get return result; } - @PostMapping(value = ITEM_LOCK_BY_PATH, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result itemLockByPath(@RequestBody @Valid LockItemByPathRequest request) + @PostMapping(value = SITE_ID + ITEM_LOCK_BY_PATH, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) + public Result itemLockByPath(@ValidSiteId @PathVariable String siteId, @RequestBody @Valid LockItemByPathRequest request) throws UserNotFoundException, ServiceLayerException { - contentService.lockContent(request.getSiteId(), request.getPath()); + contentService.lockContent(siteId, request.getPath()); Result result = new Result(); result.setResponse(OK); return result; } - @PostMapping(value = ITEM_UNLOCK_BY_PATH, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result itemUnlockByPath(@RequestBody @Valid UnlockItemByPathRequest request) + @PostMapping(value = SITE_ID + ITEM_UNLOCK_BY_PATH, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) + public Result itemUnlockByPath(@ValidSiteId @PathVariable String siteId, @RequestBody @Valid UnlockItemByPathRequest request) throws ContentNotFoundException, SiteNotFoundException, RepositoryException { - contentService.unlockContent(request.getSiteId(), request.getPath()); + contentService.unlockContent(siteId, request.getPath()); Result result = new Result(); result.setResponse(OK); return result; } @Valid - @GetMapping(GET_CONTENT_BY_COMMIT_ID) - public ResponseEntity getContentByCommitId(@ValidSiteId @RequestParam(value = REQUEST_PARAM_SITEID) String siteId, + @GetMapping(SITE_ID + GET_CONTENT_BY_COMMIT_ID) + public ResponseEntity getContentByCommitId(@ValidSiteId @PathVariable String siteId, @ValidExistingContentPath @RequestParam(value = REQUEST_PARAM_PATH) String path, @NotBlank @EsapiValidatedParam(type = ALPHANUMERIC) @RequestParam(value = REQUEST_PARAM_COMMIT_ID) String commitId) throws ServiceLayerException, UserNotFoundException { @@ -300,10 +300,10 @@ private ResponseEntity writeContent(final String siteId, .body(result); } - @PostMapping(value = RENAME, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result rename(@Valid @RequestBody RenameRequestBody renameRequestBody) + @PostMapping(value = SITE_ID + RENAME, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) + public Result rename(@ValidSiteId @PathVariable String siteId, @Valid @RequestBody RenameRequestBody renameRequestBody) throws AuthenticationException, UserNotFoundException, ServiceLayerException, ValidationException { - contentService.renameContent(renameRequestBody.getSiteId(), renameRequestBody.getPath(), renameRequestBody.getName()); + contentService.renameContent(siteId, renameRequestBody.getPath(), renameRequestBody.getName()); var result = new Result(); result.setResponse(OK); return result; @@ -329,8 +329,8 @@ public Result moveAndUpdate(@ValidSiteId @PathVariable String siteId, @Valid @Re return result; } - @GetMapping(value = ITEM_HISTORY, produces = APPLICATION_JSON_VALUE) - public ResultList getHistory(@ValidSiteId @RequestParam(value = REQUEST_PARAM_SITEID) String siteId, + @GetMapping(value = SITE_ID + ITEM_HISTORY, produces = APPLICATION_JSON_VALUE) + public ResultList getHistory(@ValidSiteId @PathVariable String siteId, @ValidExistingContentPath @RequestParam(value = REQUEST_PARAM_PATH) String path) throws ServiceLayerException { ResultList result = new ResultList<>(); result.setResponse(OK); diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/DashboardController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/DashboardController.java index 2efd7ee4f..e92c761e9 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/DashboardController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/DashboardController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2024 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -36,6 +36,7 @@ import org.springframework.format.annotation.DateTimeFormat; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -53,7 +54,7 @@ @Validated @RestController -@RequestMapping(API_2 + DASHBOARD) +@RequestMapping(API_2 + DASHBOARD + SITE_ID) public class DashboardController { private final DashboardService dashboardService; @@ -66,7 +67,7 @@ public DashboardController(final DashboardService dashboardService) { @Valid @GetMapping(value = ACTIVITY, produces = APPLICATION_JSON_VALUE) public PaginatedResultList getActivitiesForUsers( - @ValidSiteId @RequestParam(value = REQUEST_PARAM_SITEID) String siteId, + @ValidSiteId @PathVariable String siteId, @RequestParam(value = REQUEST_PARAM_USERNAMES, required = false) List<@NotBlank @EsapiValidatedParam(type = USERNAME) String> usernames, @RequestParam(value = REQUEST_PARAM_DATE_FROM, required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime dateFrom, @@ -91,7 +92,7 @@ public PaginatedResultList getActivitiesForUsers( @Valid @GetMapping(value = ACTIVITY + ME, produces = APPLICATION_JSON_VALUE) public PaginatedResultList getMyActivities( - @ValidSiteId @RequestParam(value = REQUEST_PARAM_SITEID) String siteId, + @ValidSiteId @PathVariable String siteId, @RequestParam(value = REQUEST_PARAM_DATE_FROM, required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime dateFrom, @RequestParam(value = REQUEST_PARAM_DATE_TO, required = false) @@ -115,7 +116,7 @@ public PaginatedResultList getMyActivities( @Valid @GetMapping(value = CONTENT + UNPUBLISHED, produces = APPLICATION_JSON_VALUE) - public PaginatedResultList getContentUnpublished(@ValidSiteId @RequestParam(value = REQUEST_PARAM_SITEID) String siteId, + public PaginatedResultList getContentUnpublished(@ValidSiteId @PathVariable String siteId, @PositiveOrZero @RequestParam(value = REQUEST_PARAM_OFFSET, required = false, defaultValue = "0") int offset, @PositiveOrZero @RequestParam(value = REQUEST_PARAM_LIMIT, required = false, defaultValue = "10") int limit, @RequestParam(value = REQUEST_PARAM_SORT, required = false, defaultValue = "dateModified desc") @@ -137,7 +138,7 @@ public PaginatedResultList getContentUnpublished(@ValidSiteId @Requ @Valid @GetMapping(value = CONTENT + EXPIRING, produces = APPLICATION_JSON_VALUE) public PaginatedResultList getContentExpiring( - @ValidSiteId @RequestParam(value = REQUEST_PARAM_SITEID) String siteId, + @ValidSiteId @PathVariable String siteId, @RequestParam(value = REQUEST_PARAM_DATE_FROM) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime dateFrom, @RequestParam(value = REQUEST_PARAM_DATE_TO) @@ -160,7 +161,7 @@ public PaginatedResultList getContentExpiring( @Valid @GetMapping(value = CONTENT + EXPIRED, produces = APPLICATION_JSON_VALUE) public PaginatedResultList getContentExpired( - @ValidSiteId @RequestParam(value = REQUEST_PARAM_SITEID) String siteId, + @ValidSiteId @PathVariable String siteId, @PositiveOrZero @RequestParam(value = REQUEST_PARAM_OFFSET, required = false, defaultValue = "0") int offset, @PositiveOrZero @RequestParam(value = REQUEST_PARAM_LIMIT, required = false, defaultValue = "10") int limit) throws AuthenticationException, ServiceLayerException, UserNotFoundException { @@ -178,7 +179,7 @@ public PaginatedResultList getContentExpired( @Valid @GetMapping(value = PUBLISHING + STATS, produces = APPLICATION_JSON_VALUE) public ResultOne getPublishingStats( - @ValidSiteId @RequestParam(value = REQUEST_PARAM_SITEID) String siteId, + @ValidSiteId @PathVariable String siteId, @RequestParam(value = REQUEST_PARAM_DAYS) int days) throws SiteNotFoundException { var publishingStats = dashboardService.getPublishingStats(siteId, days); var result = new ResultOne(); diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/DependencyController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/DependencyController.java index dfb9034f7..d6168dad5 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/DependencyController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/DependencyController.java @@ -52,10 +52,10 @@ public DependencyController(final DependencyService dependencyService) { } @PostMapping(value = PATH_PARAM_SITE + PUBLISH_DEPENDENCIES, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne>> getPublishDependencies(@PathVariable @ValidSiteId String site, + public ResultOne>> getPublishDependencies(@PathVariable @ValidSiteId String siteId, @RequestBody @Valid GetPublishDependenciesRequestBody request) throws SiteNotFoundException { - Collection softDeps = dependencyService.getSoftDependencies(site, request.getPaths()); - Collection hardDeps = dependencyService.getHardDependencies(site, request.getPaths()); + Collection softDeps = dependencyService.getSoftDependencies(siteId, request.getPaths()); + Collection hardDeps = dependencyService.getHardDependencies(siteId, request.getPaths()); softDeps.removeAll(hardDeps); @@ -69,10 +69,10 @@ public ResultOne>> getPublishDependencies(@Pat } @PostMapping(value = PATH_PARAM_SITE + DEPENDENT_ITEMS, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne> getDependentItems(@PathVariable @ValidSiteId String site, + public ResultOne> getDependentItems(@PathVariable @ValidSiteId String siteId, @RequestBody @Valid GetDependentsRequestBody request) throws ServiceLayerException { - Collection items = dependencyService.getDependentItems(site, request.getPath()); + Collection items = dependencyService.getDependentItems(siteId, request.getPath()); var result = new ResultOne>(); result.setResponse(OK); result.setEntity(RESULT_KEY_ITEMS, items); @@ -80,10 +80,10 @@ public ResultOne> getDependentItems(@PathVariable @ValidSi } @PostMapping(value = PATH_PARAM_SITE + DEPENDENCIES, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne> getDependencies(@PathVariable @ValidSiteId String site, + public ResultOne> getDependencies(@PathVariable @ValidSiteId String siteId, @RequestBody @Valid GetDependenciesRequestBody request) throws ServiceLayerException { - Collection items = dependencyService.getDependencies(site, request.getPath()); + Collection items = dependencyService.getDependencies(siteId, request.getPath()); var result = new ResultOne>(); result.setResponse(OK); result.setEntity(RESULT_KEY_ITEMS, items); diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/MarketplaceController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/MarketplaceController.java index aee9fad91..c0241afc1 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/MarketplaceController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/MarketplaceController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -86,17 +86,17 @@ public PaginatedResultList> searchPlugins(@RequestParam(requ return result; } - @GetMapping(value = "/installed", produces = APPLICATION_JSON_VALUE) - public ResultList getInstalledPlugins(@RequestParam @ValidSiteId String siteId) throws MarketplaceException { + @GetMapping(value = "/{siteId}/installed", produces = APPLICATION_JSON_VALUE) + public ResultList getInstalledPlugins(@PathVariable @ValidSiteId String siteId) throws MarketplaceException { ResultList result = new ResultList<>(); result.setResponse(ApiResponse.OK); result.setEntities(RESULT_KEY_PLUGINS, marketplaceService.getInstalledPlugins(siteId)); return result; } - @PostMapping(value = "/install", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result installPlugin(@Valid @RequestBody InstallPluginRequest request) throws MarketplaceException { - marketplaceService.installPlugin(request.getSiteId(), request.getPluginId(), request.getPluginVersion(), + @PostMapping(value = "/{siteId}/install", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) + public Result installPlugin(@PathVariable @ValidSiteId String siteId, @Valid @RequestBody InstallPluginRequest request) throws MarketplaceException { + marketplaceService.installPlugin(siteId, request.getPluginId(), request.getPluginVersion(), request.getParameters()); Result result = new Result(); @@ -104,8 +104,8 @@ public Result installPlugin(@Valid @RequestBody InstallPluginRequest request) th return result; } - @GetMapping(value = "/usage", produces = APPLICATION_JSON_VALUE) - public ResultList getDependantItems(@RequestParam @ValidSiteId String siteId, @RequestParam String pluginId) + @GetMapping(value = "/{siteId}/usage", produces = APPLICATION_JSON_VALUE) + public ResultList getDependantItems(@PathVariable @ValidSiteId String siteId, @RequestParam String pluginId) throws ServiceLayerException { ResultList result = new ResultList<>(); result.setResponse(ApiResponse.OK); @@ -113,9 +113,9 @@ public ResultList getDependantItems(@RequestParam @ValidSiteId String si return result; } - @PostMapping(value = "/remove", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result removePlugin(@Valid @RequestBody RemovePluginRequest request) throws ServiceLayerException { - marketplaceService.removePlugin(request.getSiteId(), request.getPluginId(), request.isForce()); + @PostMapping(value = "/{siteId}/remove", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) + public Result removePlugin(@PathVariable @ValidSiteId String siteId, @Valid @RequestBody RemovePluginRequest request) throws ServiceLayerException { + marketplaceService.removePlugin(siteId, request.getPluginId(), request.isForce()); Result result = new Result(); result.setResponse(ApiResponse.OK); @@ -125,23 +125,11 @@ public Result removePlugin(@Valid @RequestBody RemovePluginRequest request) thro @JsonIgnoreProperties(ignoreUnknown = true) protected static class RemovePluginRequest { - @NotEmpty - @ValidSiteId - protected String siteId; - @NotEmpty protected String pluginId; protected boolean force; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getPluginId() { return pluginId; } @@ -160,9 +148,9 @@ public void setForce(boolean force) { } - @PostMapping(value = "copy", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result copyPlugin(@Valid @RequestBody CopyPluginRequest request) throws MarketplaceException { - marketplaceService.copyPlugin(request.getSiteId(), request.getPath(), request.getParameters()); + @PostMapping(value = "/{siteId}/copy", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) + public Result copyPlugin(@PathVariable @ValidSiteId String siteId, @Valid @RequestBody CopyPluginRequest request) throws MarketplaceException { + marketplaceService.copyPlugin(siteId, request.getPath(), request.getParameters()); Result result = new Result(); result.setResponse(ApiResponse.OK); @@ -172,24 +160,12 @@ public Result copyPlugin(@Valid @RequestBody CopyPluginRequest request) throws M @JsonIgnoreProperties(ignoreUnknown = true) protected static class CopyPluginRequest { - @NotEmpty - @ValidSiteId - protected String siteId; - @NotEmpty @ValidExistingContentPath protected String path; protected Map parameters = new HashMap<>(); - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getPath() { return path; } diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/PluginController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/PluginController.java index 1c8d96b4a..93bbdc731 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/PluginController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/PluginController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -22,7 +22,6 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.Size; import org.craftercms.commons.exceptions.InvalidManagementTokenException; import org.craftercms.commons.validation.annotations.param.ValidSiteId; import org.craftercms.studio.api.v1.exception.ServiceLayerException; @@ -71,8 +70,8 @@ public PluginController(StudioConfiguration studioConfiguration, this.marketplaceService = marketplaceService; } - @GetMapping(value = "/get_configuration", produces = APPLICATION_JSON_VALUE) - public ResultOne getPluginConfiguration(@ValidSiteId String siteId, String pluginId) throws ServiceLayerException { + @GetMapping(value = "/{siteId}/get_configuration", produces = APPLICATION_JSON_VALUE) + public ResultOne getPluginConfiguration(@ValidSiteId @PathVariable String siteId, String pluginId) throws ServiceLayerException { String content = marketplaceService.getPluginConfigurationAsString(siteId, pluginId); ResultOne result = new ResultOne<>(); @@ -81,10 +80,10 @@ public ResultOne getPluginConfiguration(@ValidSiteId String siteId, Stri return result; } - @PostMapping(value = "/write_configuration", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result writeConfiguration(@Valid @RequestBody WriteConfigurationRequest request) + @PostMapping(value = "/{siteId}/write_configuration", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) + public Result writeConfiguration(@ValidSiteId @PathVariable String siteId, @Valid @RequestBody WriteConfigurationRequest request) throws UserNotFoundException, ServiceLayerException, AuthenticationException { - marketplaceService.writePluginConfiguration(request.getSiteId(), request.getPluginId(), request.getContent()); + marketplaceService.writePluginConfiguration(siteId, request.getPluginId(), request.getContent()); Result result = new Result(); result.setResponse(OK); @@ -94,8 +93,8 @@ public Result writeConfiguration(@Valid @RequestBody WriteConfigurationRequest r /** * Reloads the groovy classes for the given site */ - @GetMapping(value = "/script/reload", produces = APPLICATION_JSON_VALUE) - public Result reloadClasses(@ValidSiteId @RequestParam String siteId, @RequestParam String token) + @GetMapping(value = "/{siteId}/script/reload", produces = APPLICATION_JSON_VALUE) + public Result reloadClasses(@ValidSiteId @PathVariable String siteId, @RequestParam String token) throws InvalidParametersException, InvalidManagementTokenException { validateToken(token); @@ -110,12 +109,12 @@ public Result reloadClasses(@ValidSiteId @RequestParam String siteId, @RequestPa /** * Executes a rest script for the given site */ - @RequestMapping(value = "/script/**") - public ResultOne runScript(@ValidSiteId @RequestParam String siteId, HttpServletRequest request, HttpServletResponse response) + @RequestMapping(value = "/{siteId}/script/**") + public ResultOne runScript(@ValidSiteId @PathVariable String siteId, HttpServletRequest request, HttpServletResponse response) throws ResourceException, ScriptException, ConfigurationException { // No better way to do this for now, later can be replaced by "/script/{*scriptUrl}" var scriptUrl = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); - scriptUrl = removeStart(removeExtension(scriptUrl), "/api/2/plugin/script"); + scriptUrl = removeStart(removeExtension(scriptUrl), "/api/2/plugin/" + siteId + "/script"); // Add the binding with the right values // Execute the script @@ -137,25 +136,12 @@ public ResultOne runScript(@ValidSiteId @RequestParam String siteId, Htt public static class WriteConfigurationRequest { - @NotEmpty - @Size(max = 50) - @ValidSiteId - private String siteId; - @NotEmpty private String pluginId; @NotEmpty private String content; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getPluginId() { return pluginId; } diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/PublishController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/PublishController.java index d45bddeb8..b803cfd9a 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/PublishController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/PublishController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2024 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -79,7 +79,7 @@ public PublishController(final PublishService publishService, final SitesService } @GetMapping(value = PATH_PARAM_SITE + PACKAGES, produces = APPLICATION_JSON_VALUE) - public PaginatedResultList getPublishPackages(@ValidSiteId @PathVariable String site, + public PaginatedResultList getPublishPackages(@ValidSiteId @PathVariable String siteId, @EsapiValidatedParam(type = ALPHANUMERIC) @Size(max = 20) @Pattern(regexp = ALPHANUMERIC_LOWERCASE_PATTERN) @RequestParam(name = REQUEST_PARAM_TARGET, required = false) @@ -100,10 +100,10 @@ public PaginatedResultList getPublishPackages(@ValidSiteId @Path @RequestParam(name = REQUEST_PARAM_LIMIT, required = false, defaultValue = "10") @PositiveOrZero int limit) throws ServiceLayerException, UserNotFoundException { - long total = publishService.getPublishPackagesCount(site, target, states, approvalStates, submitter, reviewer, isScheduled); + long total = publishService.getPublishPackagesCount(siteId, target, states, approvalStates, submitter, reviewer, isScheduled); Collection packages = new ArrayList<>(); if (total > 0) { - packages = publishService.getPublishPackages(site, target, states, approvalStates, submitter, reviewer, isScheduled, sort, offset, limit); + packages = publishService.getPublishPackages(siteId, target, states, approvalStates, submitter, reviewer, isScheduled, sort, offset, limit); } PaginatedResultList result = new PaginatedResultList<>(); @@ -116,21 +116,21 @@ public PaginatedResultList getPublishPackages(@ValidSiteId @Path } @GetMapping(value = PATH_PARAM_SITE + PACKAGE + PATH_PARAM_PACKAGE, produces = APPLICATION_JSON_VALUE) - public GetPackageResult getPublishPackage(@PathVariable @ValidSiteId String site, + public GetPackageResult getPublishPackage(@PathVariable @ValidSiteId String siteId, @PathVariable @Positive long packageId) throws ServiceLayerException, UserNotFoundException { - PublishPackage publishPackage = publishService.getPackage(site, packageId); - TaskProgress progress = sitesService.getPublishingTaskProgress(site, packageId); + PublishPackage publishPackage = publishService.getPackage(siteId, packageId); + TaskProgress progress = sitesService.getPublishingTaskProgress(siteId, packageId); GetPackageResult result = new GetPackageResult(progress, publishPackage); result.setResponse(OK); return result; } @PostMapping(value = PATH_PARAM_SITE + PACKAGE + PATH_PARAM_PACKAGE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result updatePublishPackage(@PathVariable @ValidSiteId String site, + public Result updatePublishPackage(@PathVariable @ValidSiteId String siteId, @PathVariable @Positive long packageId, @Validated @RequestBody UpdatePackageRequest request) throws InvalidPackageStateException, SiteNotFoundException, AuthenticationException { - publishService.updatePublishPackage(site, packageId, request.getSchedule(), request.isUpdateSchedule(), + publishService.updatePublishPackage(siteId, packageId, request.getSchedule(), request.isUpdateSchedule(), request.getComment(), request.getTitle(), request.isRequestApproval()); Result result = new Result(); result.setResponse(OK); @@ -138,7 +138,7 @@ public Result updatePublishPackage(@PathVariable @ValidSiteId String site, } @GetMapping(value = PATH_PARAM_SITE + PACKAGE + PATH_PARAM_PACKAGE + ITEMS, produces = APPLICATION_JSON_VALUE) - public PaginatedResultList getPublishPackageItems(@PathVariable @ValidSiteId String site, + public PaginatedResultList getPublishPackageItems(@PathVariable @ValidSiteId String siteId, @PathVariable @Positive long packageId, @RequestParam(name = REQUEST_PARAM_PATH, required = false) String path, @RequestParam(name = REQUEST_PARAM_SYSTEM_TYPE, required = false) List systemTypes, @@ -149,9 +149,9 @@ public PaginatedResultList getPublishPackageItems(@Path defaultValue = "10") @PositiveOrZero int limit) throws PublishPackageNotFoundException, SiteNotFoundException { Collection items = emptyList(); - int totalItemCount = publishService.getPublishPackageItemCount(site, packageId, path, systemTypes, internalName); + int totalItemCount = publishService.getPublishPackageItemCount(siteId, packageId, path, systemTypes, internalName); if (totalItemCount > 0) { - items = publishService.getPublishPackageItems(site, packageId, path, systemTypes, internalName, offset, limit); + items = publishService.getPublishPackageItems(siteId, packageId, path, systemTypes, internalName, offset, limit); } PaginatedResultList result = new PaginatedResultList<>(); result.setEntities(RESULT_KEY_ITEMS, items); @@ -163,9 +163,9 @@ public PaginatedResultList getPublishPackageItems(@Path } @GetMapping(value = PATH_PARAM_SITE + STATUS, produces = APPLICATION_JSON_VALUE) - public ResultOne getPublishingStatus(@PathVariable @ValidSiteId String site) + public ResultOne getPublishingStatus(@PathVariable @ValidSiteId String siteId) throws SiteNotFoundException, RepositoryException { - PublishStatus status = sitesService.getPublishingStatus(site); + PublishStatus status = sitesService.getPublishingStatus(siteId); ResultOne result = new ResultOne<>(); result.setEntity(RESULT_KEY_PUBLISH_STATUS, status); result.setResponse(OK); @@ -173,7 +173,7 @@ public ResultOne getPublishingStatus(@PathVariable @ValidSiteId S } @GetMapping(value = AVAILABLE_TARGETS, produces = APPLICATION_JSON_VALUE) - public AvailablePublishingTargets getAvailablePublishingTargets(@ValidSiteId @RequestParam(name = REQUEST_PARAM_SITEID) String siteId) + public AvailablePublishingTargets getAvailablePublishingTargets(@ValidSiteId @PathVariable String siteId) throws SiteNotFoundException, RepositoryException { var availableTargets = publishService.getAvailablePublishingTargets(siteId); var published = publishService.isSitePublished(siteId); @@ -186,7 +186,7 @@ public AvailablePublishingTargets getAvailablePublishingTargets(@ValidSiteId @Re @Valid @GetMapping(value = HAS_INITIAL_PUBLISH, produces = APPLICATION_JSON_VALUE) - public ResultOne hasInitialPublish(@ValidSiteId @RequestParam(name = REQUEST_PARAM_SITEID) String siteId) + public ResultOne hasInitialPublish(@ValidSiteId @PathVariable String siteId) throws SiteNotFoundException, RepositoryException { var published = publishService.isSitePublished(siteId); ResultOne result = new ResultOne<>(); @@ -196,10 +196,10 @@ public ResultOne hasInitialPublish(@ValidSiteId @RequestParam(name = RE } @PostMapping(value = PATH_PARAM_SITE + CALCULATE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne calculatePublishPackage(@PathVariable @NotEmpty @ValidSiteId String site, + public ResultOne calculatePublishPackage(@PathVariable @NotEmpty @ValidSiteId String siteId, @Validated @RequestBody CalculatePublishPackageRequest request) throws ServiceLayerException, IOException { - CalculatedPublishPackageResult calculatedPackage = publishService.calculatePublishPackage(site, + CalculatedPublishPackageResult calculatedPackage = publishService.calculatePublishPackage(siteId, request.getPublishingTarget(), request.getPaths(), request.getCommitIds()); ResultOne result = new ResultOne<>(); @@ -209,11 +209,11 @@ public ResultOne calculatePublishPackage(@PathVa } @PostMapping(value = PATH_PARAM_SITE + PACKAGE + PATH_PARAM_PACKAGE + RECALCULATE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne recalculate(@PathVariable @NotEmpty @ValidSiteId String site, + public ResultOne recalculate(@PathVariable @NotEmpty @ValidSiteId String siteId, @PathVariable @Positive long packageId, @Valid @RequestBody RecalculatePublishPackageRequest request) throws ServiceLayerException, IOException { - CalculatedPublishPackageResult calculatedPackage = publishService.recalculatePublishPackage(site, + CalculatedPublishPackageResult calculatedPackage = publishService.recalculatePublishPackage(siteId, packageId, request.getPublishingTarget()); ResultOne result = new ResultOne<>(); @@ -223,8 +223,8 @@ public ResultOne recalculate(@PathVariable @NotE } @PostMapping(value = PATH_PARAM_SITE + ENABLE_PUBLISHER, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result enablePublisher(@PathVariable @NotEmpty @ValidSiteId String site, @RequestBody EnablePublisherRequest request) { - sitesService.enablePublishing(site, request.isEnable()); + public Result enablePublisher(@PathVariable @NotEmpty @ValidSiteId String siteId, @RequestBody EnablePublisherRequest request) { + sitesService.enablePublishing(siteId, request.isEnable()); Result result = new Result(); result.setResponse(OK); return result; @@ -232,10 +232,10 @@ public Result enablePublisher(@PathVariable @NotEmpty @ValidSiteId String site, @ResponseStatus(HttpStatus.CREATED) @PostMapping(value = PATH_PARAM_SITE + PACKAGE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne publish(@PathVariable @NotEmpty @ValidSiteId String site, + public ResultOne publish(@PathVariable @NotEmpty @ValidSiteId String siteId, @Validated @RequestBody PublishPackageRequest request) throws ServiceLayerException, UserNotFoundException, AuthenticationException { - long packageId = submitPublishPackage(site, request); + long packageId = submitPublishPackage(siteId, request); ResultOne result = new ResultOne<>(); result.setResponse(CREATED); diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/RepositoryManagementController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/RepositoryManagementController.java index f324ab22b..6cf0b909f 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/RepositoryManagementController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/RepositoryManagementController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -43,7 +43,6 @@ import static org.craftercms.studio.api.v1.constant.StudioConstants.FILE_SEPARATOR; import static org.craftercms.studio.controller.rest.v2.RequestConstants.REQUEST_PARAM_PATH; -import static org.craftercms.studio.controller.rest.v2.RequestConstants.REQUEST_PARAM_SITEID; import static org.craftercms.studio.controller.rest.v2.RequestMappingConstants.*; import static org.craftercms.studio.controller.rest.v2.ResultConstants.*; import static org.craftercms.studio.model.rest.ApiResponse.*; @@ -63,16 +62,17 @@ public RepositoryManagementController(final RepositoryManagementService reposito @ResponseStatus(HttpStatus.CREATED) @PostMapping(value = ADD_REMOTE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result addRemote(HttpServletResponse response, @Valid @RequestBody RemoteRepository remoteRepository) + public Result addRemote(HttpServletResponse response, @ValidSiteId @PathVariable String siteId, + @Valid @RequestBody RemoteRepository remoteRepository) throws ServiceLayerException, InvalidRemoteUrlException { Result result = new Result(); - repositoryManagementService.addRemote(remoteRepository.getSiteId(), remoteRepository); + repositoryManagementService.addRemote(siteId, remoteRepository); result.setResponse(CREATED); return result; } @GetMapping(value = LIST_REMOTES, produces = APPLICATION_JSON_VALUE) - public ResultList listRemotes(@ValidSiteId @RequestParam(name = "siteId") String siteId) + public ResultList listRemotes(@ValidSiteId @PathVariable String siteId) throws ServiceLayerException { List remotes = repositoryManagementService.listRemotes(siteId); @@ -83,10 +83,11 @@ public ResultList listRemotes(@ValidSiteId @RequestParam(n } @PostMapping(value = PULL_FROM_REMOTE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne pullFromRemote(@Valid @RequestBody PullFromRemoteRequest pullFromRemoteRequest) + public ResultOne pullFromRemote(@ValidSiteId @PathVariable String siteId, + @Valid @RequestBody PullFromRemoteRequest pullFromRemoteRequest) throws InvalidRemoteUrlException, ServiceLayerException, InvalidRemoteRepositoryCredentialsException, RemoteRepositoryNotFoundException { - MergeResult mergeResult = repositoryManagementService.pullFromRemote(pullFromRemoteRequest.getSiteId(), + MergeResult mergeResult = repositoryManagementService.pullFromRemote(siteId, pullFromRemoteRequest.getRemoteName(), pullFromRemoteRequest.getRemoteBranch(), pullFromRemoteRequest.getMergeStrategy()); @@ -97,10 +98,11 @@ public ResultOne pullFromRemote(@Valid @RequestBody PullFromRemoteR } @PostMapping(value = PUSH_TO_REMOTE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result pushToRemote(HttpServletResponse response, @Valid @RequestBody PushToRemoteRequest pushToRemoteRequest) + public Result pushToRemote(HttpServletResponse response, @ValidSiteId @PathVariable String siteId, + @Valid @RequestBody PushToRemoteRequest pushToRemoteRequest) throws InvalidRemoteUrlException, ServiceLayerException, InvalidRemoteRepositoryCredentialsException, RemoteRepositoryNotFoundException { - boolean res = repositoryManagementService.pushToRemote(pushToRemoteRequest.getSiteId(), + boolean res = repositoryManagementService.pushToRemote(siteId, pushToRemoteRequest.getRemoteName(), pushToRemoteRequest.getRemoteBranch(), pushToRemoteRequest.isForce()); @@ -115,9 +117,10 @@ public Result pushToRemote(HttpServletResponse response, @Valid @RequestBody Pus } @PostMapping(value = REMOVE_REMOTE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result removeRemote(HttpServletResponse response, @Valid @RequestBody RemoveRemoteRequest removeRemoteRequest) + public Result removeRemote(HttpServletResponse response, @ValidSiteId @PathVariable String siteId, + @Valid @RequestBody RemoveRemoteRequest removeRemoteRequest) throws SiteNotFoundException, RemoteNotRemovableException { - boolean res = repositoryManagementService.removeRemote(removeRemoteRequest.getSiteId(), + boolean res = repositoryManagementService.removeRemote(siteId, removeRemoteRequest.getRemoteName()); Result result = new Result(); @@ -130,8 +133,8 @@ public Result removeRemote(HttpServletResponse response, @Valid @RequestBody Rem return result; } - @GetMapping(value = STATUS, produces = APPLICATION_JSON_VALUE) - public ResultOne getRepositoryStatus(@ValidSiteId @RequestParam(value = REQUEST_PARAM_SITEID) String siteId) + @GetMapping(value = SITE_ID + STATUS, produces = APPLICATION_JSON_VALUE) + public ResultOne getRepositoryStatus(@ValidSiteId @PathVariable String siteId) throws ServiceLayerException { RepositoryStatus status = repositoryManagementService.getRepositoryStatus(siteId); ResultOne result = new ResultOne<>(); @@ -141,13 +144,14 @@ public ResultOne getRepositoryStatus(@ValidSiteId @RequestPara } @PostMapping(value = RESOLVE_CONFLICT, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne resolveConflict(@Valid @RequestBody ResolveConflictRequest resolveConflictRequest) + public ResultOne resolveConflict(@ValidSiteId @PathVariable String siteId, + @Valid @RequestBody ResolveConflictRequest resolveConflictRequest) throws ServiceLayerException { String path = resolveConflictRequest.getPath(); if (!path.startsWith(FILE_SEPARATOR)) { path = FILE_SEPARATOR + path; } - RepositoryStatus status = repositoryManagementService.resolveConflict(resolveConflictRequest.getSiteId(), + RepositoryStatus status = repositoryManagementService.resolveConflict(siteId, path, resolveConflictRequest.getResolution()); ResultOne result = new ResultOne<>(); result.setResponse(OK); @@ -156,7 +160,7 @@ public ResultOne resolveConflict(@Valid @RequestBody ResolveCo } @GetMapping(value = DIFF_CONFLICTED_FILE, produces = APPLICATION_JSON_VALUE) - public ResultOne getDiffForConflictedFile(@ValidSiteId @RequestParam(value = REQUEST_PARAM_SITEID) String siteId, + public ResultOne getDiffForConflictedFile(@ValidSiteId @PathVariable String siteId, @ValidExistingContentPath @RequestParam(value = REQUEST_PARAM_PATH) String path) throws ServiceLayerException { String diffPath = path; @@ -171,9 +175,10 @@ public ResultOne getDiffForConflictedFile(@ValidSiteId @Requ } @PostMapping(value = COMMIT_RESOLUTION, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne commitConflictResolution(@Valid @RequestBody CommitResolutionRequest commitResolutionRequest) + public ResultOne commitConflictResolution(@ValidSiteId @PathVariable String siteId, + @Valid @RequestBody CommitResolutionRequest commitResolutionRequest) throws ServiceLayerException { - RepositoryStatus status = repositoryManagementService.commitResolution(commitResolutionRequest.getSiteId(), + RepositoryStatus status = repositoryManagementService.commitResolution(siteId, commitResolutionRequest.getCommitMessage()); ResultOne result = new ResultOne<>(); result.setEntity(RESULT_KEY_REPOSITORY_STATUS, status); @@ -181,10 +186,10 @@ public ResultOne commitConflictResolution(@Valid @RequestBody return result; } - @PostMapping(value = CANCEL_FAILED_PULL, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne cancelFailedPull(@Valid @RequestBody CancelFailedPullRequest cancelFailedPullRequest) + @PostMapping(value = CANCEL_FAILED_PULL, produces = APPLICATION_JSON_VALUE) + public ResultOne cancelFailedPull(@ValidSiteId @PathVariable String siteId) throws ServiceLayerException { - RepositoryStatus status = repositoryManagementService.cancelFailedPull(cancelFailedPullRequest.getSiteId()); + RepositoryStatus status = repositoryManagementService.cancelFailedPull(siteId); ResultOne result = new ResultOne<>(); result.setEntity(RESULT_KEY_REPOSITORY_STATUS, status); result.setResponse(OK); diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/RequestMappingConstants.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/RequestMappingConstants.java index 3e11053dc..b21951710 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/RequestMappingConstants.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/RequestMappingConstants.java @@ -85,7 +85,7 @@ public final class RequestMappingConstants { public static final String ENABLE = "/enable"; public static final String DISABLE = "/disable"; public static final String SITES = "/sites"; - public static final String PATH_PARAM_SITE = "/{site}"; + public static final String PATH_PARAM_SITE = SITE_ID; public static final String ROLES = "/roles"; public static final String ME = "/me"; public static final String LOGOUT_SSO_URL = "/logout/sso/url"; @@ -103,16 +103,16 @@ public final class RequestMappingConstants { * Repository Management controller **/ public static final String REPOSITORY = "/repository"; - public static final String ADD_REMOTE = "/add_remote"; - public static final String LIST_REMOTES = "/list_remotes"; - public static final String PULL_FROM_REMOTE = "/pull_from_remote"; - public static final String PUSH_TO_REMOTE = "/push_to_remote"; - public static final String REMOVE_REMOTE = "/remove_remote"; + public static final String ADD_REMOTE = SITE_ID + "/add_remote"; + public static final String LIST_REMOTES = SITE_ID + "/list_remotes"; + public static final String PULL_FROM_REMOTE = SITE_ID + "/pull_from_remote"; + public static final String PUSH_TO_REMOTE = SITE_ID + "/push_to_remote"; + public static final String REMOVE_REMOTE = SITE_ID + "/remove_remote"; public static final String STATUS = "/status"; - public static final String RESOLVE_CONFLICT = "/resolve_conflict"; - public static final String DIFF_CONFLICTED_FILE = "/diff_conflicted_file"; - public static final String COMMIT_RESOLUTION = "/commit_resolution"; - public static final String CANCEL_FAILED_PULL = "/cancel_failed_pull"; + public static final String RESOLVE_CONFLICT = SITE_ID + "/resolve_conflict"; + public static final String DIFF_CONFLICTED_FILE = SITE_ID + "/diff_conflicted_file"; + public static final String COMMIT_RESOLUTION = SITE_ID + "/commit_resolution"; + public static final String CANCEL_FAILED_PULL = SITE_ID + "/cancel_failed_pull"; public static final String UNLOCK = "/unlock"; public static final String CORRUPTED = "/corrupted"; public static final String REPAIR = "/repair"; @@ -129,8 +129,8 @@ public final class RequestMappingConstants { public static final String PACKAGES = "/packages"; public static final String PACKAGE = "/package"; public static final String CANCEL = "/cancel"; - public static final String AVAILABLE_TARGETS = "/available_targets"; - public static final String HAS_INITIAL_PUBLISH = "/has_initial_publish"; + public static final String AVAILABLE_TARGETS = SITE_ID + "/available_targets"; + public static final String HAS_INITIAL_PUBLISH = SITE_ID + "/has_initial_publish"; public static final String ENABLE_PUBLISHER = "/enable"; public static final String PATH_PARAM_PACKAGE = "/{packageId}"; public static final String ITEMS = "/items"; @@ -149,8 +149,8 @@ public final class RequestMappingConstants { * Workflow Controller */ public static final String WORKFLOW = "/workflow"; - public static final String ITEM_STATES = "/item_states"; - public static final String UPDATE_ITEM_STATES_BY_QUERY = "/update_item_states_by_query"; + public static final String ITEM_STATES = SITE_ID + "/item_states"; + public static final String UPDATE_ITEM_STATES_BY_QUERY = SITE_ID + "/update_item_states_by_query"; public static final String AFFECTED_PACKAGES = "/affected_packages"; public static final String REJECT = "/reject"; public static final String APPROVE = "/approve"; @@ -170,11 +170,11 @@ public final class RequestMappingConstants { * Configuration Controller */ public static final String CONFIGURATION = "/configuration"; - public static final String CLEAR_CACHE = "/clear_cache"; - public static final String GET_CONFIGURATION = "/get_configuration"; - public static final String WRITE_CONFIGURATION = "/write_configuration"; - public static final String GET_CONFIGURATION_HISTORY = "/get_configuration_history"; - public static final String TRANSLATION = "/translation"; + public static final String CLEAR_CACHE = SITE_ID + "/clear_cache"; + public static final String GET_CONFIGURATION = SITE_ID + "/get_configuration"; + public static final String WRITE_CONFIGURATION = SITE_ID + "/write_configuration"; + public static final String GET_CONFIGURATION_HISTORY = SITE_ID + "/get_configuration_history"; + public static final String TRANSLATION = SITE_ID + "/translation"; public static final String CONTENT_TYPES = "/content_types"; public static final String USAGE = "/usage"; public static final String PREVIEW_IMAGE = "/preview_image"; diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/SearchController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/SearchController.java index b1d7761f9..8a7ff4abb 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/SearchController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/SearchController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -54,8 +54,8 @@ public SearchController(final SearchService searchService) { this.searchService = searchService; } - @PostMapping(value = "/search", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne search(@ValidSiteId @RequestParam String siteId, @Valid @RequestBody SearchParams params) + @PostMapping(value = "/{siteId}/search", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) + public ResultOne search(@ValidSiteId @PathVariable String siteId, @Valid @RequestBody SearchParams params) throws AuthenticationException, ServiceLayerException { SearchResult searchResult = searchService.search(siteId, params); diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/UsersController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/UsersController.java index 11a437b34..0cb20ac36 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/UsersController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/UsersController.java @@ -285,12 +285,12 @@ public PaginatedResultList getUserSites( * Get user roles for a site API * * @param userId User identifier - * @param site The site ID + * @param siteId The site ID * @return Response containing list of roles */ @GetMapping(value = PATH_PARAM_ID + SITES + PATH_PARAM_SITE + ROLES, produces = APPLICATION_JSON_VALUE) public ResultList getUserSiteRoles(@NotNull @PathVariable(REQUEST_PARAM_ID) String userId, - @NotNull @ValidSiteId @PathVariable(REQUEST_PARAM_SITE) String site) + @NotNull @ValidSiteId @PathVariable(REQUEST_PARAM_SITEID) String siteId) throws ServiceLayerException, UserNotFoundException, ValidationException { int uId = -1; String username = StringUtils.EMPTY; @@ -301,7 +301,7 @@ public ResultList getUserSiteRoles(@NotNull @PathVariable(REQUEST_PARAM_ username = userId; } - List roles = userService.getUserSiteRoles(uId, username, site) + List roles = userService.getUserSiteRoles(uId, username, siteId) .stream() .map(NormalizedRole::toString) .toList(); @@ -357,9 +357,9 @@ public PaginatedResultList getCurrentUserSites( * @return Response containing current authenticated user roles */ @GetMapping(value = ME + SITES + PATH_PARAM_SITE + ROLES, produces = APPLICATION_JSON_VALUE) - public ResultList getCurrentUserSiteRoles(@NotBlank @ValidSiteId @PathVariable(REQUEST_PARAM_SITE) String site) + public ResultList getCurrentUserSiteRoles(@NotBlank @ValidSiteId @PathVariable(REQUEST_PARAM_SITEID) String siteId) throws AuthenticationException, ServiceLayerException, UserNotFoundException { - List roles = userService.getCurrentUserSiteRoles(site); + List roles = userService.getCurrentUserSiteRoles(siteId); ResultList result = new ResultList<>(); result.setResponse(OK); @@ -493,9 +493,9 @@ public ResultOne> deleteUserProperties( * @return Response containing current authenticated user permissions */ @GetMapping(value = ME + SITES + PATH_PARAM_SITE + PERMISSIONS, produces = APPLICATION_JSON_VALUE) - public ResultList getCurrentUserSitePermissions(@ValidSiteId @PathVariable(REQUEST_PARAM_SITE) String site) + public ResultList getCurrentUserSitePermissions(@ValidSiteId @PathVariable(REQUEST_PARAM_SITEID) String siteId) throws ServiceLayerException, UserNotFoundException, ExecutionException { - List permissions = userService.getCurrentUserSitePermissions(site).stream().sorted().toList(); + List permissions = userService.getCurrentUserSitePermissions(siteId).stream().sorted().toList(); ResultList result = new ResultList<>(); result.setResponse(OK); result.setEntities(RESULT_KEY_PERMISSIONS, permissions); @@ -509,11 +509,11 @@ public ResultList getCurrentUserSitePermissions(@ValidSiteId @PathVariab */ @PostMapping(value = ME + SITES + PATH_PARAM_SITE + HAS_PERMISSIONS, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResultOne> checkCurrentUserHasSitePermissions(@ValidSiteId @PathVariable(REQUEST_PARAM_SITE) String site, + public ResultOne> checkCurrentUserHasSitePermissions(@ValidSiteId @PathVariable(REQUEST_PARAM_SITEID) String siteId, @Valid @RequestBody HasPermissionsRequest permissionsRequest) throws ServiceLayerException, UserNotFoundException, ExecutionException { Map hasPermissions = - userService.hasCurrentUserSitePermissions(site, permissionsRequest.getPermissions()); + userService.hasCurrentUserSitePermissions(siteId, permissionsRequest.getPermissions()); ResultOne> result = new ResultOne<>(); result.setResponse(OK); diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/WebdavController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/WebdavController.java index 853e954dd..f24893e61 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/WebdavController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/WebdavController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -65,7 +65,7 @@ */ @Validated @RestController -@RequestMapping("/api/2/webdav") +@RequestMapping("/api/2/webdav/{siteId}") public class WebdavController { /** @@ -92,7 +92,7 @@ public WebdavController(final WebDavService webDavService) { */ @GetMapping(value = "list", produces = APPLICATION_JSON_VALUE) public ResultList listItems( - @NotBlank @ValidSiteId @RequestParam(REQUEST_PARAM_SITEID) String siteId, + @NotBlank @ValidSiteId @PathVariable String siteId, @NotBlank @RequestParam(REQUEST_PARAM_PROFILE_ID) String profileId, @ValidExistingContentPath @RequestParam(value = REQUEST_PARAM_PATH, required = false, defaultValue = StringUtils.EMPTY) String path, @RequestParam(value = REQUEST_PARAM_TYPE, required = false, defaultValue = StringUtils.EMPTY) String type) @@ -116,7 +116,7 @@ public ResultList listItems( * @throws ConfigurationProfileNotFoundException if the profile is not found */ @PostMapping(value = "/upload", produces = APPLICATION_JSON_VALUE) - public ResultOne uploadItem(HttpServletRequest request) throws IOException, WebDavException, + public ResultOne uploadItem(@ValidSiteId @PathVariable String siteId, HttpServletRequest request) throws IOException, WebDavException, InvalidParametersException, SiteNotFoundException, ConfigurationProfileNotFoundException, ValidationException { if (!JakartaServletFileUpload.isMultipartContent(request)) { throw new InvalidParametersException("The request is not multipart"); @@ -125,7 +125,6 @@ public ResultOne uploadItem(HttpServletRequest request) throws IOExc try { JakartaServletFileUpload upload = new JakartaServletFileUpload(); FileItemInputIterator iterator = upload.getItemIterator(request); - String siteId = null; String profileId = null; String path = null; if (!iterator.hasNext()) { @@ -137,9 +136,6 @@ public ResultOne uploadItem(HttpServletRequest request) throws IOExc try (InputStream stream = item.getInputStream()) { if (item.isFormField()) { switch (name) { - case REQUEST_PARAM_SITEID: - siteId = Streams.asString(stream); - break; case REQUEST_PARAM_PROFILE_ID: profileId = Streams.asString(stream); break; diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/WorkflowController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/WorkflowController.java index 8eb53b69d..86ca3d949 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/WorkflowController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/WorkflowController.java @@ -71,7 +71,7 @@ public WorkflowController(final WorkflowService workflowService, final PublishSe } @GetMapping(value = ITEM_STATES, produces = APPLICATION_JSON_VALUE) - public PaginatedResultList getItemStates(@NotBlank @ValidSiteId @RequestParam(name = REQUEST_PARAM_SITEID) String siteId, + public PaginatedResultList getItemStates(@NotBlank @ValidSiteId @PathVariable String siteId, @RequestParam(name = REQUEST_PARAM_PATH, required = false) String path, @RequestParam(name = REQUEST_PARAM_STATES, required = false) Long states, @PositiveOrZero @RequestParam(value = REQUEST_PARAM_OFFSET, required = false, defaultValue = "0") @@ -108,10 +108,11 @@ private boolean isPathRegexValid(String pathRegex) { } @PostMapping(value = ITEM_STATES, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE) - public Result updateItemStates(@Valid @RequestBody ItemStatesPostRequestBody requestBody) + public Result updateItemStates(@ValidSiteId @PathVariable String siteId, + @Valid @RequestBody ItemStatesPostRequestBody requestBody) throws SiteNotFoundException { ItemStatesUpdate update = requestBody.getUpdate(); - workflowService.updateItemStates(requestBody.getSiteId(), requestBody.getItems(), + workflowService.updateItemStates(siteId, requestBody.getItems(), update.isClearSystemProcessing(), update.isClearUserLocked(), update.getLive(), update.getStaged(), update.getNew(), update.getModified()); @@ -121,7 +122,8 @@ public Result updateItemStates(@Valid @RequestBody ItemStatesPostRequestBody req } @PostMapping(value = UPDATE_ITEM_STATES_BY_QUERY, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE) - public Result updateItemStatesByQuery(@Valid @RequestBody UpdateItemStatesByQueryRequestBody requestBody) + public Result updateItemStatesByQuery(@ValidSiteId @PathVariable String siteId, + @Valid @RequestBody UpdateItemStatesByQueryRequestBody requestBody) throws SiteNotFoundException, InvalidParametersException { UpdateItemStatesByQueryRequestBody.Query query = requestBody.getQuery(); ItemStatesUpdate update = requestBody.getUpdate(); @@ -129,7 +131,7 @@ public Result updateItemStatesByQuery(@Valid @RequestBody UpdateItemStatesByQuer if (!isPathRegexValid(resolvedPathRegex)) { throw new InvalidParametersException("Parameter 'path' is not valid regular expression."); } - workflowService.updateItemStatesByQuery(query.getSiteId(), resolvedPathRegex, + workflowService.updateItemStatesByQuery(siteId, resolvedPathRegex, query.getStates(), update.isClearSystemProcessing(), update.isClearUserLocked(), update.getLive(), update.getStaged(), update.getNew(), update.getModified()); @@ -140,10 +142,10 @@ public Result updateItemStatesByQuery(@Valid @RequestBody UpdateItemStatesByQuer } @GetMapping(value = PATH_PARAM_SITE + AFFECTED_PACKAGES, produces = APPLICATION_JSON_VALUE) - public ResultList getWorkflowAffectedPackages(@ValidSiteId @PathVariable String site, + public ResultList getWorkflowAffectedPackages(@ValidSiteId @PathVariable String siteId, @ValidExistingContentPath @RequestParam(REQUEST_PARAM_PATH) String path, @RequestParam(value = REQUEST_PARAM_INCLUDE_CHILDREN, required = false) boolean includeChildren) throws ServiceLayerException { - Collection affectedPackages = emptyIfNull(publishService.getActivePackagesForItems(site, List.of(path), includeChildren)); + Collection affectedPackages = emptyIfNull(publishService.getActivePackagesForItems(siteId, List.of(path), includeChildren)); ResultList result = new ResultList<>(); result.setEntities(RESULT_KEY_PACKAGES, affectedPackages); result.setResponse(OK); @@ -151,10 +153,10 @@ public ResultList getWorkflowAffectedPackages(@ValidSiteId @Path } @PostMapping(value = PATH_PARAM_SITE + APPROVE, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result approve(@Valid @PathVariable @NotEmpty @ValidSiteId String site, + public Result approve(@Valid @PathVariable @NotEmpty @ValidSiteId String siteId, @Valid @RequestBody ApproveRequestBody request) throws UserNotFoundException, ServiceLayerException, AuthenticationException { - workflowService.approvePackages(site, request.getPackageIds(), + workflowService.approvePackages(siteId, request.getPackageIds(), request.getSchedule(), request.isUpdateSchedule(), request.getComment()); Result result = new Result(); @@ -163,10 +165,10 @@ public Result approve(@Valid @PathVariable @NotEmpty @ValidSiteId String site, } @PostMapping(value = PATH_PARAM_SITE + REJECT, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result reject(@Valid @PathVariable @NotEmpty @ValidSiteId String site, + public Result reject(@Valid @PathVariable @NotEmpty @ValidSiteId String siteId, @Valid @RequestBody ReviewPackageRequestBody rejectRequestBody) throws ServiceLayerException, AuthenticationException { - workflowService.rejectPackages(site, rejectRequestBody.getPackageIds(), + workflowService.rejectPackages(siteId, rejectRequestBody.getPackageIds(), rejectRequestBody.getComment()); Result result = new Result(); result.setResponse(OK); @@ -174,10 +176,10 @@ public Result reject(@Valid @PathVariable @NotEmpty @ValidSiteId String site, } @PostMapping(value = PATH_PARAM_SITE + CANCEL, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public Result cancel(@Valid @PathVariable @NotEmpty @ValidSiteId String site, + public Result cancel(@Valid @PathVariable @NotEmpty @ValidSiteId String siteId, @Valid @RequestBody ReviewPackageRequestBody cancelPackageRequest) throws ServiceLayerException, AuthenticationException { - workflowService.cancelPackages(site, cancelPackageRequest.getPackageIds(), cancelPackageRequest.getComment()); + workflowService.cancelPackages(siteId, cancelPackageRequest.getPackageIds(), cancelPackageRequest.getComment()); Result result = new Result(); result.setResponse(OK); return result; diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsMediaConvertController.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsMediaConvertController.java index 4c8d2d073..af033fc23 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsMediaConvertController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsMediaConvertController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -36,6 +36,7 @@ import org.craftercms.studio.model.rest.ResultOne; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.Validator; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -46,7 +47,6 @@ import java.io.InputStream; import static org.craftercms.commons.validation.annotations.param.EsapiValidationType.*; -import static org.craftercms.studio.controller.rest.v2.RequestConstants.REQUEST_PARAM_SITEID; import static org.craftercms.studio.controller.rest.v2.RequestConstants.REQUEST_PARAM_SITE_ID; import static org.craftercms.studio.controller.rest.v2.ResultConstants.RESULT_KEY_ITEM; import static org.craftercms.studio.controller.rest.ValidationUtils.validateValue; @@ -59,7 +59,7 @@ * @since 3.1.1 */ @RestController -@RequestMapping("/api/2/aws/mediaconvert") +@RequestMapping("/api/2/aws/{siteId}/mediaconvert") public class AwsMediaConvertController { public static final String INPUT_PROFILE_PARAM = "inputProfileId"; @@ -80,7 +80,7 @@ public class AwsMediaConvertController { * @throws ConfigurationProfileNotFoundException if the profile is not found */ @PostMapping(value = "/upload", produces = APPLICATION_JSON_VALUE) - public ResultOne uploadVideo(HttpServletRequest request) + public ResultOne uploadVideo(@PathVariable String siteId, HttpServletRequest request) throws IOException, AwsException, InvalidParametersException, ConfigurationProfileNotFoundException, SiteNotFoundException, ValidationException { if (!JakartaServletFileUpload.isMultipartContent(request)) { throw new InvalidParametersException("The request is not multipart"); @@ -89,7 +89,6 @@ public ResultOne uploadVideo(HttpServletRequest request) try { JakartaServletFileUpload upload = new JakartaServletFileUpload(); FileItemInputIterator iterator = upload.getItemIterator(request); - String siteId = null; String inputProfileId = null; String outputProfileId = null; while (iterator.hasNext()) { @@ -98,9 +97,6 @@ public ResultOne uploadVideo(HttpServletRequest request) try (InputStream stream = item.getInputStream()) { if (item.isFormField()) { switch (name) { - case REQUEST_PARAM_SITEID: - siteId = Streams.asString(stream); - break; case INPUT_PROFILE_PARAM: inputProfileId = Streams.asString(stream); break; diff --git a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsS3Controller.java b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsS3Controller.java index 10d31d394..af0f8105d 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsS3Controller.java +++ b/studio/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsS3Controller.java @@ -66,7 +66,7 @@ */ @Validated @RestController -@RequestMapping("/api/2/aws/s3") +@RequestMapping("/api/2/aws/{siteId}/s3") public class AwsS3Controller { protected final AwsS3Service s3Service; @@ -91,7 +91,7 @@ public AwsS3Controller(AwsS3Service s3Service) { */ @GetMapping(value = "/list", produces = APPLICATION_JSON_VALUE) public ResultList listItems( - @ValidSiteId @RequestParam(REQUEST_PARAM_SITEID) String siteId, + @ValidSiteId @PathVariable String siteId, @ValidateNoTagsParam @RequestParam(REQUEST_PARAM_PROFILE_ID) String profileId, @ValidExistingContentPath @RequestParam(value = REQUEST_PARAM_PATH, required = false, defaultValue = StringUtils.EMPTY) String path, @ValidateNoTagsParam @RequestParam(value = REQUEST_PARAM_TYPE, required = false, defaultValue = StringUtils.EMPTY) String type, @@ -117,7 +117,7 @@ public ResultList listItems( * @throws ConfigurationProfileNotFoundException if the profile is not found */ @PostMapping(value = "/upload", produces = APPLICATION_JSON_VALUE) - public ResultOne uploadItem(HttpServletRequest request) throws IOException, InvalidParametersException, + public ResultOne uploadItem(@ValidSiteId @PathVariable String siteId, HttpServletRequest request) throws IOException, InvalidParametersException, AwsException, SiteNotFoundException, ConfigurationProfileNotFoundException, ValidationException { if (!JakartaServletFileUpload.isMultipartContent(request)) { throw new InvalidParametersException("The request is not multipart"); @@ -126,7 +126,6 @@ public ResultOne uploadItem(HttpServletRequest request) throws IOExcepti try { JakartaServletFileUpload upload = new JakartaServletFileUpload(); FileItemInputIterator iterator = upload.getItemIterator(request); - String siteId = null; String profileId = null; String path = null; String filename = null; @@ -136,9 +135,6 @@ public ResultOne uploadItem(HttpServletRequest request) throws IOExcepti try (InputStream stream = item.getInputStream()) { if (item.isFormField()) { switch (name) { - case REQUEST_PARAM_SITEID: - siteId = Streams.asString(stream); - break; case REQUEST_PARAM_PROFILE_ID: profileId = Streams.asString(stream); break; diff --git a/studio/src/main/java/org/craftercms/studio/controller/web/v1/PluginController.java b/studio/src/main/java/org/craftercms/studio/controller/web/v1/PluginController.java index eff11c9a4..dce15318c 100644 --- a/studio/src/main/java/org/craftercms/studio/controller/web/v1/PluginController.java +++ b/studio/src/main/java/org/craftercms/studio/controller/web/v1/PluginController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -27,6 +27,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -59,8 +60,8 @@ public PluginController(ConfigurationService configurationService) { * Returns a single file for a given plugin */ @Valid - @GetMapping("/file") - public ResponseEntity getPluginFile(@ValidSiteId @RequestParam String siteId, + @GetMapping("/{siteId}/file") + public ResponseEntity getPluginFile(@ValidSiteId @PathVariable String siteId, @ValidExistingContentPath @ValidateSecurePathParam @RequestParam String type, @ValidExistingContentPath @ValidateSecurePathParam @RequestParam String name, @ValidExistingContentPath @ValidateSecurePathParam @RequestParam(required = false) String filename, diff --git a/studio/src/main/java/org/craftercms/studio/impl/v2/repository/GitContentRepositoryImpl.java b/studio/src/main/java/org/craftercms/studio/impl/v2/repository/GitContentRepositoryImpl.java index 0b3144f2c..39df9e1f5 100644 --- a/studio/src/main/java/org/craftercms/studio/impl/v2/repository/GitContentRepositoryImpl.java +++ b/studio/src/main/java/org/craftercms/studio/impl/v2/repository/GitContentRepositoryImpl.java @@ -645,7 +645,6 @@ private void insertRemoteToDb(String siteId, String remoteName, String remoteUrl String remoteToken, String remotePrivateKey) throws CryptoException { logger.debug("Insert git remote '{}' in site '{}' into the database", remoteName, siteId); RemoteRepository remote = new RemoteRepository(); - remote.setSiteId(siteId); remote.setRemoteName(remoteName); remote.setRemoteUrl(remoteUrl); remote.setAuthenticationType(authenticationType); @@ -674,7 +673,7 @@ private void insertRemoteToDb(String siteId, String remoteName, String remoteUrl } // Insert site remote record into database - retryingDatabaseOperationFacade.retry(() -> remoteRepositoryDAO.insertRemoteRepository(remote)); + retryingDatabaseOperationFacade.retry(() -> remoteRepositoryDAO.insertRemoteRepository(siteId, remote)); } @Override diff --git a/studio/src/main/java/org/craftercms/studio/impl/v2/service/repository/internal/RepositoryManagementServiceInternalImpl.java b/studio/src/main/java/org/craftercms/studio/impl/v2/service/repository/internal/RepositoryManagementServiceInternalImpl.java index ceca3b711..044bec1fd 100644 --- a/studio/src/main/java/org/craftercms/studio/impl/v2/service/repository/internal/RepositoryManagementServiceInternalImpl.java +++ b/studio/src/main/java/org/craftercms/studio/impl/v2/service/repository/internal/RepositoryManagementServiceInternalImpl.java @@ -228,7 +228,6 @@ private void insertRemoteToDb(String siteId, RemoteRepository remoteRepository) // TODO: SJ: Avoid using string literals logger.debug("Insert the remote repository '{}' from site '{}' into the database", remoteRepository.getRemoteName(), siteId); - remoteRepository.setSiteId(siteId); if (isNotEmpty(remoteRepository.getRemotePassword())) { logger.trace("Encrypt the password before inserting into the database for site '{}'", siteId); String hashedPassword = encryptor.encrypt(remoteRepository.getRemotePassword()); @@ -246,7 +245,7 @@ private void insertRemoteToDb(String siteId, RemoteRepository remoteRepository) } logger.debug("Insert the site remote record into database for site '{}'", siteId); - retryingDatabaseOperationFacade.retry(() -> remoteRepositoryDao.insertRemoteRepository(remoteRepository)); + retryingDatabaseOperationFacade.retry(() -> remoteRepositoryDao.insertRemoteRepository(siteId, remoteRepository)); } @Override diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/CancelFailedPullRequest.java b/studio/src/main/java/org/craftercms/studio/model/rest/CancelFailedPullRequest.java deleted file mode 100644 index 636ee6e2c..000000000 --- a/studio/src/main/java/org/craftercms/studio/model/rest/CancelFailedPullRequest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.model.rest; - -import org.craftercms.commons.validation.annotations.param.ValidSiteId; - -import jakarta.validation.constraints.NotEmpty; - -public class CancelFailedPullRequest { - - @NotEmpty - @ValidSiteId - private String siteId; - - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } -} diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/CommitResolutionRequest.java b/studio/src/main/java/org/craftercms/studio/model/rest/CommitResolutionRequest.java index 0485cdd79..4c8e2d178 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/CommitResolutionRequest.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/CommitResolutionRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,25 +16,10 @@ package org.craftercms.studio.model.rest; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; - -import jakarta.validation.constraints.NotEmpty; - public class CommitResolutionRequest { - @NotEmpty - @ValidSiteId - private String siteId; private String commitMessage; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getCommitMessage() { return commitMessage; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/PullFromRemoteRequest.java b/studio/src/main/java/org/craftercms/studio/model/rest/PullFromRemoteRequest.java index 3dcb91e90..ca72b0dad 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/PullFromRemoteRequest.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/PullFromRemoteRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -17,7 +17,6 @@ package org.craftercms.studio.model.rest; import org.apache.commons.lang3.StringUtils; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.Size; @@ -30,10 +29,6 @@ public enum MergeStrategy { none } - @NotEmpty - @ValidSiteId - private String siteId; - @NotEmpty @Size(max = 50) private String remoteName; @@ -43,14 +38,6 @@ public enum MergeStrategy { private MergeStrategy mergeStrategy = MergeStrategy.none; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getRemoteName() { return remoteName; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/PushToRemoteRequest.java b/studio/src/main/java/org/craftercms/studio/model/rest/PushToRemoteRequest.java index 1c9edafe9..5d6c30903 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/PushToRemoteRequest.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/PushToRemoteRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,16 +16,11 @@ package org.craftercms.studio.model.rest; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; - import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.Size; public class PushToRemoteRequest { - @NotEmpty - @ValidSiteId - private String siteId; @NotEmpty @Size(max = 50) private String remoteName; @@ -33,14 +28,6 @@ public class PushToRemoteRequest { private String remoteBranch; private boolean force; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getRemoteName() { return remoteName; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/RemoveRemoteRequest.java b/studio/src/main/java/org/craftercms/studio/model/rest/RemoveRemoteRequest.java index cc91ae15f..dad2335ae 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/RemoveRemoteRequest.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/RemoveRemoteRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,27 +16,14 @@ package org.craftercms.studio.model.rest; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; - import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.Size; public class RemoveRemoteRequest { - @NotEmpty - @ValidSiteId - private String siteId; @NotEmpty @Size(max = 50) private String remoteName; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getRemoteName() { return remoteName; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/ResolveConflictRequest.java b/studio/src/main/java/org/craftercms/studio/model/rest/ResolveConflictRequest.java index 45fdc01aa..e07aace84 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/ResolveConflictRequest.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/ResolveConflictRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -19,28 +19,16 @@ import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import org.craftercms.commons.validation.annotations.param.ValidExistingContentPath; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import org.craftercms.studio.api.v2.service.repository.ConflictResolution; public class ResolveConflictRequest { - @NotEmpty - @ValidSiteId - private String siteId; @NotEmpty @ValidExistingContentPath private String path; @NotNull private ConflictResolution resolution; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getPath() { return path; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/WriteConfigurationRequest.java b/studio/src/main/java/org/craftercms/studio/model/rest/WriteConfigurationRequest.java index 48d17e216..d532579b8 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/WriteConfigurationRequest.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/WriteConfigurationRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2024 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -18,7 +18,6 @@ import org.craftercms.commons.validation.annotations.param.EsapiValidatedParam; import org.craftercms.commons.validation.annotations.param.ValidConfigurationPath; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import org.craftercms.studio.model.validation.annotations.ConfigurableMax; import static org.craftercms.commons.validation.annotations.param.EsapiValidationType.ALPHANUMERIC; @@ -26,8 +25,6 @@ public class WriteConfigurationRequest { - @ValidSiteId - private String siteId; @EsapiValidatedParam(type = ALPHANUMERIC) private String module; @ValidConfigurationPath @@ -37,14 +34,6 @@ public class WriteConfigurationRequest { @ConfigurableMax(CONFIGURATION_MAX_CONFIGURATION_LENGTH) private String content; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getModule() { return module; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/clipboard/DuplicateRequest.java b/studio/src/main/java/org/craftercms/studio/model/rest/clipboard/DuplicateRequest.java index b99a4238f..80f95a431 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/clipboard/DuplicateRequest.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/clipboard/DuplicateRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,7 +16,6 @@ package org.craftercms.studio.model.rest.clipboard; import org.craftercms.commons.validation.annotations.param.ValidExistingContentPath; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import jakarta.validation.constraints.NotEmpty; @@ -28,13 +27,6 @@ */ public class DuplicateRequest { - /** - * The id of the site - */ - @NotEmpty - @ValidSiteId - protected String siteId; - /** * The path of the item */ @@ -42,14 +34,6 @@ public class DuplicateRequest { @ValidExistingContentPath protected String path; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getPath() { return path; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/content/DeleteRequestBody.java b/studio/src/main/java/org/craftercms/studio/model/rest/content/DeleteRequestBody.java index 4e7f7ca4c..7e15ec116 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/content/DeleteRequestBody.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/content/DeleteRequestBody.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -18,14 +18,11 @@ import java.util.Set; -import org.craftercms.commons.validation.annotations.param.EsapiValidatedParam; -import static org.craftercms.commons.validation.annotations.param.EsapiValidationType.SITE_ID; import org.craftercms.commons.validation.annotations.param.ValidExistingContentPath; import org.craftercms.commons.validation.annotations.param.ValidateSecurePathParam; import static org.craftercms.studio.api.v2.service.publish.PublishService.PACKAGE_COMMENT_MAX_LENGTH; import static org.craftercms.studio.api.v2.service.publish.PublishService.PACKAGE_TITLE_MAX_LENGTH; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.Size; @@ -34,9 +31,6 @@ */ public class DeleteRequestBody { - @NotBlank - @EsapiValidatedParam(type = SITE_ID) - private String siteId; @NotEmpty private Set<@NotEmpty @ValidExistingContentPath @ValidateSecurePathParam String> items; @@ -47,14 +41,6 @@ public class DeleteRequestBody { @Size(max = PACKAGE_COMMENT_MAX_LENGTH) private String comment; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public Set getItems() { return items; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/content/GetDeletePackageRequestBody.java b/studio/src/main/java/org/craftercms/studio/model/rest/content/GetDeletePackageRequestBody.java index 7c0c5f926..5ccb9290d 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/content/GetDeletePackageRequestBody.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/content/GetDeletePackageRequestBody.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -19,31 +19,17 @@ import java.util.List; import org.craftercms.commons.validation.annotations.param.ValidExistingContentPath; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; @JsonIgnoreProperties public class GetDeletePackageRequestBody { - @NotBlank - @ValidSiteId - private String siteId; - @NotEmpty private List<@NotEmpty @ValidExistingContentPath String> paths; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public List getPaths() { return paths; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/content/GetSandboxItemsByPathRequestBody.java b/studio/src/main/java/org/craftercms/studio/model/rest/content/GetSandboxItemsByPathRequestBody.java index e040cc125..99ed0bf93 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/content/GetSandboxItemsByPathRequestBody.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/content/GetSandboxItemsByPathRequestBody.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -17,7 +17,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.craftercms.commons.validation.annotations.param.ValidExistingContentPath; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import jakarta.validation.constraints.NotEmpty; @@ -32,21 +31,10 @@ @JsonIgnoreProperties public class GetSandboxItemsByPathRequestBody { - @NotEmpty - @ValidSiteId - private String siteId; @NotEmpty private List<@ValidExistingContentPath @NotEmpty String> paths; private boolean preferContent; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public List getPaths() { return paths; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/content/LockItemByPathRequest.java b/studio/src/main/java/org/craftercms/studio/model/rest/content/LockItemByPathRequest.java index 5d35717ce..cf57c41f1 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/content/LockItemByPathRequest.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/content/LockItemByPathRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -17,27 +17,15 @@ package org.craftercms.studio.model.rest.content; import org.craftercms.commons.validation.annotations.param.ValidExistingContentPath; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import jakarta.validation.constraints.NotEmpty; public class LockItemByPathRequest { - @NotEmpty - @ValidSiteId - private String siteId; @NotEmpty @ValidExistingContentPath private String path; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getPath() { return path; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/content/RenameRequestBody.java b/studio/src/main/java/org/craftercms/studio/model/rest/content/RenameRequestBody.java index 36338b9f0..386f47ea5 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/content/RenameRequestBody.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/content/RenameRequestBody.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -18,15 +18,11 @@ import org.craftercms.commons.validation.annotations.param.ValidExistingContentPath; import org.craftercms.commons.validation.annotations.param.ValidNewContentPath; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import jakarta.validation.constraints.NotEmpty; public class RenameRequestBody { - @NotEmpty - @ValidSiteId - private String siteId; @NotEmpty @ValidExistingContentPath private String path; @@ -34,14 +30,6 @@ public class RenameRequestBody { @ValidNewContentPath private String name; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getPath() { return path; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/content/UnlockItemByPathRequest.java b/studio/src/main/java/org/craftercms/studio/model/rest/content/UnlockItemByPathRequest.java index d84e82f4a..d42a858b6 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/content/UnlockItemByPathRequest.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/content/UnlockItemByPathRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -17,27 +17,15 @@ package org.craftercms.studio.model.rest.content; import org.craftercms.commons.validation.annotations.param.ValidExistingContentPath; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import jakarta.validation.constraints.NotEmpty; public class UnlockItemByPathRequest { - @NotEmpty - @ValidSiteId - private String siteId; @NotEmpty @ValidExistingContentPath private String path; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getPath() { return path; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/marketplace/InstallPluginRequest.java b/studio/src/main/java/org/craftercms/studio/model/rest/marketplace/InstallPluginRequest.java index 6e2586a79..8c640839a 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/marketplace/InstallPluginRequest.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/marketplace/InstallPluginRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -18,7 +18,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.craftercms.commons.plugin.model.Version; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; @@ -36,10 +35,6 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class InstallPluginRequest { - @NotBlank - @ValidSiteId - private String siteId; - @NotBlank private String pluginId; @@ -49,14 +44,6 @@ public class InstallPluginRequest { private Map parameters = Collections.emptyMap(); - public String getSiteId() { - return siteId; - } - - public void setSiteId(final String siteId) { - this.siteId = siteId; - } - public String getPluginId() { return pluginId; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/workflow/ItemStatesPostRequestBody.java b/studio/src/main/java/org/craftercms/studio/model/rest/workflow/ItemStatesPostRequestBody.java index f41dfa5bd..d2bd20a20 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/workflow/ItemStatesPostRequestBody.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/workflow/ItemStatesPostRequestBody.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -18,7 +18,6 @@ import com.fasterxml.jackson.annotation.JsonUnwrapped; import org.craftercms.commons.validation.annotations.param.ValidExistingContentPath; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; @@ -28,9 +27,6 @@ public class ItemStatesPostRequestBody { - @NotEmpty - @ValidSiteId - private String siteId; @NotEmpty private List<@NotBlank @ValidExistingContentPath String> items; @@ -38,14 +34,6 @@ public class ItemStatesPostRequestBody { @JsonUnwrapped private ItemStatesUpdate update; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public List getItems() { return items; } diff --git a/studio/src/main/java/org/craftercms/studio/model/rest/workflow/UpdateItemStatesByQueryRequestBody.java b/studio/src/main/java/org/craftercms/studio/model/rest/workflow/UpdateItemStatesByQueryRequestBody.java index 66d66b095..a3319f9fd 100644 --- a/studio/src/main/java/org/craftercms/studio/model/rest/workflow/UpdateItemStatesByQueryRequestBody.java +++ b/studio/src/main/java/org/craftercms/studio/model/rest/workflow/UpdateItemStatesByQueryRequestBody.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,10 +16,7 @@ package org.craftercms.studio.model.rest.workflow; -import org.craftercms.commons.validation.annotations.param.ValidSiteId; - import jakarta.validation.Valid; -import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import org.craftercms.commons.validation.annotations.param.ValidateNoTagsParam; import org.craftercms.commons.validation.annotations.param.ValidateSecurePathParam; @@ -50,10 +47,6 @@ public void setUpdate(ItemStatesUpdate update) { } public static class Query { - @NotEmpty - @ValidSiteId - private String siteId; - /** * Content path regex */ @@ -63,14 +56,6 @@ public static class Query { private Long states; - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - public String getPath() { return path; } diff --git a/studio/src/main/resources/crafter/studio/studio-config.yaml b/studio/src/main/resources/crafter/studio/studio-config.yaml index f7610cef9..7fd5f1037 100644 --- a/studio/src/main/resources/crafter/studio/studio-config.yaml +++ b/studio/src/main/resources/crafter/studio/studio-config.yaml @@ -349,7 +349,7 @@ studio.security.sessionTimeout: 480 studio.security.inactivityTimeout: 30 # Comma separated list of URLs that should not be tracked as user activity studio.security.activity.excludeUrls: > - /api/2/publish/status.*,/api/2/content/children_by_path.*,/api/2/content/sandbox_items_by_path.* + /api/2/publish/.+/status.*,/api/2/content/.+/children.*,/api/2/content/.+/sandbox_items_by_path.* # Configuration for the user activity cache studio.security.activity.cache.config: initialCapacity=25,maximumSize=100 @@ -359,7 +359,7 @@ studio.security.publicUrls: > /api/2/system/available_languages.*, /api/2/monitoring/.+,/api/2/users/forgot_password.*,/api/2/users/set_password.*,/static-assets/.+, /api/2/users/validate_token.*,/api/2/users/forgot_password.*, - /api/2/plugin/script/reload.* + /api/2/plugin/.+/script/reload.* # Salt for encrypting studio.security.cipher.salt: DgGN9xhq3GOn6zxg # Key for encrypting diff --git a/studio/src/main/resources/org/craftercms/studio/api/v2/dal/repository/RemoteRepositoryDAO.xml b/studio/src/main/resources/org/craftercms/studio/api/v2/dal/repository/RemoteRepositoryDAO.xml index a8724f37d..f8bcbb529 100644 --- a/studio/src/main/resources/org/craftercms/studio/api/v2/dal/repository/RemoteRepositoryDAO.xml +++ b/studio/src/main/resources/org/craftercms/studio/api/v2/dal/repository/RemoteRepositoryDAO.xml @@ -21,7 +21,6 @@ - @@ -38,10 +37,10 @@ AND remote_name = #{remoteName} limit 0, 1 - + INSERT INTO remote_repository (site_id, remote_name, remote_url, authentication_type, remote_username, remote_password, remote_token, remote_private_key) - VALUES (#{repository.siteId}, #{repository.remoteName}, #{repository.remoteUrl}, #{repository.authenticationType}, #{repository.remoteUsername}, + VALUES (#{siteId}, #{repository.remoteName}, #{repository.remoteUrl}, #{repository.authenticationType}, #{repository.remoteUsername}, #{repository.remotePassword}, #{repository.remoteToken}, #{repository.remotePrivateKey})