diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsImportController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsImportController.java index 88ecfba5a69..0e6a6226e4d 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsImportController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ConfigsImportController.java @@ -61,7 +61,8 @@ public ConfigsImportController( * etc. * @throws IOException */ - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)" + + "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)") @PostMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items/import") public void importConfigFile(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ItemController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ItemController.java index 0a4521d0539..17012265fd3 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ItemController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ItemController.java @@ -73,7 +73,8 @@ public ItemController(final ItemService configService, final UserInfoHolder user this.namespaceService = namespaceService; } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)" + + "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)") @PutMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items", consumes = { "application/json"}) public void modifyItemsByText(@PathVariable String appId, @PathVariable String env, @@ -122,7 +123,8 @@ public void updateItem(@PathVariable String appId, @PathVariable String env, } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env) ") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env) " + + "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)") @DeleteMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}") public void deleteItem(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, @@ -206,7 +208,8 @@ public ResponseEntity update(@PathVariable String appId, @PathVariable Str hasPermission = true; for (NamespaceIdentifier namespaceIdentifier : model.getSyncToNamespaces()) { // once user has not one of the env's ModifyNamespace permission, then break the loop - hasPermission &= permissionValidator.hasModifyNamespacePermission(namespaceIdentifier.getAppId(), namespaceIdentifier.getNamespaceName(), namespaceIdentifier.getEnv().toString()); + hasPermission &= permissionValidator.hasModifyNamespacePermission(namespaceIdentifier.getAppId(), namespaceIdentifier.getNamespaceName(), namespaceIdentifier.getEnv().toString()) + || permissionValidator.hasModifyClusterPermission(namespaceIdentifier.getAppId(), namespaceIdentifier.getEnv().toString(), namespaceIdentifier.getClusterName()); if (!hasPermission) { envNoPermission = namespaceIdentifier.getEnv(); break; @@ -220,7 +223,8 @@ public ResponseEntity update(@PathVariable String appId, @PathVariable Str throw new AccessDeniedException(String.format("You don't have the permission to modify environment: %s", envNoPermission)); } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)" + + "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/syntax-check", consumes = { "application/json"}) public ResponseEntity syntaxCheckText(@PathVariable String appId, @PathVariable String env, @@ -231,7 +235,8 @@ public ResponseEntity syntaxCheckText(@PathVariable String appId, @PathVar return ResponseEntity.ok().build(); } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)" + + "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)") @PutMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/revoke-items") public void revokeItems(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName) { diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java index 8daa6b68a87..cdfa3cb08f8 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java @@ -78,7 +78,8 @@ public NamespaceBO findBranch(@PathVariable String appId, return namespaceBO; } - @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)" + + "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches") @ApolloAuditLog(type = OpType.CREATE, name = "NamespaceBranch.create") public NamespaceDTO createBranch(@PathVariable String appId, @@ -97,9 +98,12 @@ public void deleteBranch(@PathVariable String appId, @PathVariable String namespaceName, @PathVariable String branchName) { - boolean canDelete = permissionValidator.hasReleaseNamespacePermission(appId, namespaceName, env) || - (permissionValidator.hasModifyNamespacePermission(appId, namespaceName, env) && - releaseService.loadLatestRelease(appId, Env.valueOf(env), branchName, namespaceName) == null); + boolean hasModifyPermission = permissionValidator.hasModifyNamespacePermission(appId, namespaceName, env) + || permissionValidator.hasModifyClusterPermission(appId, env, clusterName); + boolean hasReleasePermission = permissionValidator.hasReleaseNamespacePermission(appId, namespaceName, env) + || permissionValidator.hasReleaseClusterPermission(appId, env, clusterName); + boolean canDelete = hasReleasePermission + || (hasModifyPermission && releaseService.loadLatestRelease(appId, Env.valueOf(env), branchName, namespaceName) == null); if (!canDelete) { @@ -115,7 +119,8 @@ public void deleteBranch(@PathVariable String appId, - @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)" + + "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/merge") @ApolloAuditLog(type = OpType.UPDATE, name = "NamespaceBranch.merge") public ReleaseDTO merge(@PathVariable String appId, @PathVariable String env, diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseController.java index 06e303f18fe..2b441ff8a59 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseController.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/ReleaseController.java @@ -69,7 +69,8 @@ public ReleaseController( this.userInfoHolder = userInfoHolder; } - @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)" + + "or @permissionValidator.hasReleaseClusterPermission(#appId, #env, #clusterName)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/releases") public ReleaseDTO createRelease(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @@ -98,7 +99,8 @@ public ReleaseDTO createRelease(@PathVariable String appId, return createdRelease; } - @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)") + @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName, #env)" + + "or @permissionValidator.hasReleaseClusterPermission(#appId, #env, #clusterName)") @PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/releases") public ReleaseDTO createGrayRelease(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @@ -187,7 +189,13 @@ public void rollback(@PathVariable String env, throw NotFoundException.releaseNotFound(releaseId); } - if (!permissionValidator.hasReleaseNamespacePermission(release.getAppId(), release.getNamespaceName(), env)) { + boolean releaseNamespacePermission = permissionValidator.hasReleaseNamespacePermission(release.getAppId(), + release.getNamespaceName(), env); + boolean releaseClusterPermission = permissionValidator.hasReleaseClusterPermission(release.getAppId(), env, + release.getClusterName()); + + // if neither no permission + if (!releaseClusterPermission && !releaseNamespacePermission) { throw new AccessDeniedException("Access is denied"); } diff --git a/apollo-portal/src/main/resources/static/config.html b/apollo-portal/src/main/resources/static/config.html index 3d7be59a972..ae0153363e2 100644 --- a/apollo-portal/src/main/resources/static/config.html +++ b/apollo-portal/src/main/resources/static/config.html @@ -199,7 +199,8 @@
+ href="{{ '/cluster/role.html' | prefixPath }}?#/appid={{pageContext.appId}}&env={{pageContext.env}}&clusterName={{pageContext.clusterName}}" + ng-show="hasAssignUserPermission"> {{'Component.Cluster.Grant' | translate }} diff --git a/apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js b/apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js index ea811ce34a7..e04809fb7ac 100644 --- a/apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js +++ b/apollo-portal/src/main/resources/static/scripts/directive/namespace-panel-directive.js @@ -277,21 +277,34 @@ function directive($window, $translate, toastr, AppUtil, EventManager, Permissio ) .then(function (result) { //branch has same permission - namespace.hasModifyPermission = result.hasPermission; + namespace.hasModifyPermission = namespace.hasModifyPermission || result.hasPermission; if (namespace.branch) { - namespace.branch.hasModifyPermission = result.hasPermission; + namespace.branch.hasModifyPermission = namespace.branch.hasModifyPermission || result.hasPermission; } }); } else { //branch has same permission - namespace.hasModifyPermission = result.hasPermission; + namespace.hasModifyPermission = namespace.hasModifyPermission || result.hasPermission; if (namespace.branch) { - namespace.branch.hasModifyPermission = result.hasPermission; + namespace.branch.hasModifyPermission = namespace.branch.hasModifyPermission || result.hasPermission; } } }); + PermissionService.has_modify_cluster_permission( + scope.appId, + scope.env, + scope.cluster + ).then(function (result) { + if (result.hasPermission) { + namespace.hasModifyPermission = namespace.hasModifyPermission || result.hasPermission; + if (namespace.branch) { + namespace.branch.hasModifyPermission = namespace.branch.hasModifyPermission || result.hasPermission; + } + } + }); + PermissionService.has_release_namespace_permission( scope.appId, namespace.baseInfo.namespaceName) @@ -304,20 +317,34 @@ function directive($window, $translate, toastr, AppUtil, EventManager, Permissio ) .then(function (result) { //branch has same permission - namespace.hasReleasePermission = result.hasPermission; + namespace.hasReleasePermission |= result.hasPermission; if (namespace.branch) { - namespace.branch.hasReleasePermission = result.hasPermission; + namespace.branch.hasReleasePermission |= result.hasPermission; } }); } else { //branch has same permission - namespace.hasReleasePermission = result.hasPermission; + namespace.hasReleasePermission |= result.hasPermission; if (namespace.branch) { - namespace.branch.hasReleasePermission = result.hasPermission; + namespace.branch.hasReleasePermission |= result.hasPermission; } } }); + + PermissionService.has_release_cluster_permission( + scope.appId, + scope.env, + scope.cluster + ).then(function (result) { + if (result.hasPermission) { + namespace.hasReleasePermission |= result.hasPermission; + if (namespace.branch) { + namespace.branch.hasReleasePermission |= result.hasPermission; + } + } + }); + } function initLinkedNamespace(namespace) {