Skip to content

Commit

Permalink
feat(auth):
Browse files Browse the repository at this point in the history
Converge namespace permission related interfaces into the same;
Full trace name change ClusterRole to NamespaceInClusterRole likes.
  • Loading branch information
BlackBear2003 committed Jan 1, 2025
1 parent 7aad74b commit 0dc0292
Show file tree
Hide file tree
Showing 25 changed files with 237 additions and 244 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,54 +48,75 @@ public PermissionValidator(
this.systemRoleManagerService = systemRoleManagerService;
}

public boolean hasModifyNamespacePermission(String appId, String namespaceName) {
private boolean hasModifyNamespacePermission(String appId, String namespaceName) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.MODIFY_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName));
}

public boolean hasModifyNamespacePermission(String appId, String namespaceName, String env) {
return hasModifyNamespacePermission(appId, namespaceName) ||
rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.MODIFY_NAMESPACE, RoleUtils.buildNamespaceTargetId(appId, namespaceName, env));
private boolean hasModifyNamespacePermission(String appId, String namespaceName, String env) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.MODIFY_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName, env));
}

public boolean hasModifyClusterPermission(String appId, String env, String clusterName) {
private boolean hasModifyNamespaceInClusterPermission(String appId, String env, String clusterName) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.MODIFY_CLUSTER,
PermissionType.MODIFY_NAMESPACE_IN_CLUSTER,
RoleUtils.buildClusterTargetId(appId, env, clusterName));
}

public boolean hasReleaseNamespacePermission(String appId, String namespaceName) {
public boolean hasModifyNamespacePermission(String appId, String env, String clusterName, String namespaceName) {
if (hasModifyNamespacePermission(appId, namespaceName)) {
return true;
}
if (hasModifyNamespacePermission(appId, namespaceName, env)) {
return true;
}
if (hasModifyNamespaceInClusterPermission(appId, env, clusterName)) {
return true;
}
return false;
}

private boolean hasReleaseNamespacePermission(String appId, String namespaceName) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.RELEASE_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName));
}

public boolean hasReleaseNamespacePermission(String appId, String namespaceName, String env) {
return hasReleaseNamespacePermission(appId, namespaceName) ||
rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.RELEASE_NAMESPACE, RoleUtils.buildNamespaceTargetId(appId, namespaceName, env));
private boolean hasReleaseNamespacePermission(String appId, String namespaceName, String env) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.RELEASE_NAMESPACE,
RoleUtils.buildNamespaceTargetId(appId, namespaceName, env));
}

public boolean hasReleaseClusterPermission(String appId, String env, String clusterName) {
private boolean hasReleaseNamespaceInClusterPermission(String appId, String env, String clusterName) {
return rolePermissionService.userHasPermission(userInfoHolder.getUser().getUserId(),
PermissionType.RELEASE_CLUSTER,
PermissionType.RELEASE_NAMESPACE_IN_CLUSTER,
RoleUtils.buildClusterTargetId(appId, env, clusterName));
}

public boolean hasDeleteNamespacePermission(String appId) {
return hasAssignRolePermission(appId) || isSuperAdmin();
public boolean hasReleaseNamespacePermission(String appId, String env, String clusterName, String namespaceName) {
if (hasReleaseNamespacePermission(appId, namespaceName)) {
return true;
}
if (hasReleaseNamespacePermission(appId, namespaceName, env)) {
return true;
}
if (hasReleaseNamespaceInClusterPermission(appId, env, clusterName)) {
return true;
}
return false;
}

public boolean hasOperateNamespacePermission(String appId, String namespaceName) {
return hasModifyNamespacePermission(appId, namespaceName) || hasReleaseNamespacePermission(appId, namespaceName);
public boolean hasDeleteNamespacePermission(String appId) {
return hasAssignRolePermission(appId) || isSuperAdmin();
}

public boolean hasOperateNamespacePermission(String appId, String namespaceName, String env) {
return hasOperateNamespacePermission(appId, namespaceName) ||
hasModifyNamespacePermission(appId, namespaceName, env) ||
hasReleaseNamespacePermission(appId, namespaceName, env);
public boolean hasOperateNamespacePermission(String appId, String env, String clusterName, String namespaceName) {
return hasModifyNamespacePermission(appId, env, clusterName, namespaceName)
|| hasReleaseNamespacePermission(appId, env, clusterName, namespaceName);
}

public boolean hasAssignRolePermission(String appId) {
Expand Down Expand Up @@ -136,7 +157,8 @@ public boolean isSuperAdmin() {
return rolePermissionService.isSuperAdmin(userInfoHolder.getUser().getUserId());
}

public boolean shouldHideConfigToCurrentUser(String appId, String env, String namespaceName) {
public boolean shouldHideConfigToCurrentUser(String appId, String env, String clusterName,
String namespaceName) {
// 1. check whether the current environment enables member only function
if (!portalConfig.isConfigViewMemberOnly(env)) {
return false;
Expand All @@ -149,7 +171,7 @@ public boolean shouldHideConfigToCurrentUser(String appId, String env, String na
}

// 3. check app admin and operate permissions
return !isAppAdmin(appId) && !hasOperateNamespacePermission(appId, namespaceName, env);
return !isAppAdmin(appId) && !hasOperateNamespacePermission(appId, env, clusterName, namespaceName);
}

public boolean hasCreateApplicationPermission() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,8 @@ public interface PermissionType {

String RELEASE_NAMESPACE = "ReleaseNamespace";

/**
* cluster level permission
*/

String MODIFY_CLUSTER = "ModifyCluster";
String MODIFY_NAMESPACE_IN_CLUSTER = "ModifyNamespaceInCluster";

String RELEASE_CLUSTER = "ReleaseCluster";
String RELEASE_NAMESPACE_IN_CLUSTER = "ReleaseNamespaceInCluster";

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ public class RoleType {

public static final String RELEASE_NAMESPACE = "ReleaseNamespace";

public static final String MODIFY_CLUSTER = "ModifyCluster";
public static final String MODIFY_NAMESPACE_IN_CLUSTER = "ModifyNamespaceInCluster";

public static final String RELEASE_CLUSTER = "ReleaseCluster";
public static final String RELEASE_NAMESPACE_IN_CLUSTER = "ReleaseNamespaceInCluster";

public static boolean isValidRoleType(String roleType) {
return MASTER.equals(roleType) || MODIFY_NAMESPACE.equals(roleType) || RELEASE_NAMESPACE.equals(
roleType) || MODIFY_CLUSTER.equals(roleType) || RELEASE_CLUSTER.equals(roleType);
roleType) || MODIFY_NAMESPACE_IN_CLUSTER.equals(roleType) || RELEASE_NAMESPACE_IN_CLUSTER.equals(roleType);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ public List<App> findAppsByOwner(@RequestParam("owner") String owner, Pageable p
public App create(@Valid @RequestBody AppModel appModel) {

App app = transformToApp(appModel);

return appService.createAppAndAddRolePermission(app, appModel.getAdmins());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public List<CommitDTO> find(@PathVariable String appId, @PathVariable String env
@RequestParam(required = false) String key,
@Valid @PositiveOrZero(message = "page should be positive or 0") @RequestParam(defaultValue = "0") int page,
@Valid @Positive(message = "size should be positive number") @RequestParam(defaultValue = "10") int size) {
if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) {
if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceName)) {
return Collections.emptyList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public ConfigsExportController(
* application.json
* </pre>
*/
@PreAuthorize(value = "!@permissionValidator.shouldHideConfigToCurrentUser(#appId, #env, #namespaceName)")
@PreAuthorize(value = "!@permissionValidator.shouldHideConfigToCurrentUser(#appId, #env, #clusterName, #namespaceName)")
@GetMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items/export")
public void exportItems(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ public ConfigsImportController(
* etc.
* @throws IOException
*/
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)"
+ "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)")
@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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ public ItemController(final ItemService configService, final UserInfoHolder user
this.namespaceService = namespaceService;
}

@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)"
+ "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)")
@PutMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items", consumes = {
"application/json"})
public void modifyItemsByText(@PathVariable String appId, @PathVariable String env,
Expand All @@ -88,8 +87,7 @@ public void modifyItemsByText(@PathVariable String appId, @PathVariable String e
configService.updateConfigItemByText(model);
}

@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)"
+ "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)")
@PostMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item")
public ItemDTO createItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
Expand All @@ -108,8 +106,7 @@ public ItemDTO createItem(@PathVariable String appId, @PathVariable String env,
return configService.createItem(appId, Env.valueOf(env), clusterName, namespaceName, item);
}

@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env) "
+ "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)")
@PutMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item")
public void updateItem(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
Expand All @@ -123,8 +120,7 @@ public void updateItem(@PathVariable String appId, @PathVariable String env,
}


@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env) "
+ "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)")
@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,
Expand All @@ -146,7 +142,7 @@ public List<ItemDTO> findItems(@PathVariable String appId, @PathVariable String
@PathVariable String clusterName, @PathVariable String namespaceName,
@RequestParam(defaultValue = "lineNum") String orderBy) {

if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, namespaceName)) {
if (permissionValidator.shouldHideConfigToCurrentUser(appId, env, clusterName, namespaceName)) {
return Collections.emptyList();
}

Expand Down Expand Up @@ -187,9 +183,10 @@ public List<ItemDiffs> diff(@RequestBody NamespaceSyncModel model) {
}

if (permissionValidator
.shouldHideConfigToCurrentUser(namespace.getAppId(), namespace.getEnv().getName(), namespace.getNamespaceName())) {
.shouldHideConfigToCurrentUser(namespace.getAppId(), namespace.getEnv().getName(),
namespace.getClusterName(), namespace.getNamespaceName())) {
diff.setDiffs(new ItemChangeSets());
diff.setExtInfo("You are not this project's administrator, nor you have edit or release permission for the namespace in environment: " + namespace.getEnv());
diff.setExtInfo("You are not this project's administrator, nor you have edit or release permission for the namespace:" + namespace);
}
}

Expand All @@ -200,31 +197,30 @@ public List<ItemDiffs> diff(@RequestBody NamespaceSyncModel model) {
public ResponseEntity<Void> update(@PathVariable String appId, @PathVariable String namespaceName,
@RequestBody NamespaceSyncModel model) {
checkModel(!model.isInvalid() && model.syncToNamespacesValid(appId, namespaceName));
boolean hasPermission = permissionValidator.hasModifyNamespacePermission(appId, namespaceName);
Env envNoPermission = null;
// if uses has ModifyNamespace permission then he has permission
if (!hasPermission) {
// else check if user has every env's ModifyNamespace permission
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())
|| permissionValidator.hasModifyClusterPermission(namespaceIdentifier.getAppId(), namespaceIdentifier.getEnv().toString(), namespaceIdentifier.getClusterName());
if (!hasPermission) {
envNoPermission = namespaceIdentifier.getEnv();
break;
}
NamespaceIdentifier noPermissionNamespace = null;
// check if user has every namespace's ModifyNamespace permission
boolean hasPermission = true;
for (NamespaceIdentifier namespaceIdentifier : model.getSyncToNamespaces()) {
// once user has not one of the namespace's ModifyNamespace permission, then break the loop
hasPermission = permissionValidator.hasModifyNamespacePermission(
namespaceIdentifier.getAppId(),
namespaceIdentifier.getEnv().getName(),
namespaceIdentifier.getClusterName(),
namespaceIdentifier.getNamespaceName()
);
if (!hasPermission) {
noPermissionNamespace = namespaceIdentifier;
break;
}
}
if (hasPermission) {
configService.syncItems(model.getSyncToNamespaces(), model.getSyncItems());
return ResponseEntity.status(HttpStatus.OK).build();
}
throw new AccessDeniedException(String.format("You don't have the permission to modify environment: %s", envNoPermission));
throw new AccessDeniedException(String.format("You don't have the permission to modify namespace: %s", noPermissionNamespace));
}

@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)"
+ "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)")
@PostMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/syntax-check", consumes = {
"application/json"})
public ResponseEntity<Void> syntaxCheckText(@PathVariable String appId, @PathVariable String env,
Expand All @@ -235,8 +231,7 @@ public ResponseEntity<Void> syntaxCheckText(@PathVariable String appId, @PathVar
return ResponseEntity.ok().build();
}

@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName, #env)"
+ "or @permissionValidator.hasModifyClusterPermission(#appId, #env, #clusterName)")
@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)")
@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) {
Expand Down
Loading

0 comments on commit 0dc0292

Please sign in to comment.