From 095d7420433cd8e98b1880ae8b34735449c2bf26 Mon Sep 17 00:00:00 2001 From: s2042968 Date: Fri, 10 Jan 2025 15:30:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E6=9D=83=E9=99=90=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manage/aop/FilePermissionCheckAspect.java | 56 +++++++++++++++++++ .../software/manage/aop/PermissionAspect.java | 31 ---------- .../software/manage/aop/RoleCheckAspect.java | 29 ++++++++++ .../manage/common/GlobalExceptionHandler.java | 11 ++++ .../controller/EdFileInfoController.java | 8 +++ .../manage/controller/RoleController.java | 10 ++++ .../manage/controller/UserController.java | 11 ++++ .../manage/service/EdFileInfoService.java | 4 ++ .../manage/service/PermissionService.java | 1 + .../serviceimpl/EdFileInfoServiceImpl.java | 16 ++++++ .../serviceimpl/PermissionServiceImpl.java | 15 ++++- .../annotations/RequiredPermission.java | 10 ++-- .../common/annotations/RequiredRole.java | 12 ++++ .../exception/PermissionDeniedException.java | 21 +++++++ 14 files changed, 198 insertions(+), 37 deletions(-) create mode 100644 electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/FilePermissionCheckAspect.java delete mode 100644 electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/PermissionAspect.java create mode 100644 electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/RoleCheckAspect.java create mode 100644 electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/annotations/RequiredRole.java create mode 100644 electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/exception/PermissionDeniedException.java diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/FilePermissionCheckAspect.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/FilePermissionCheckAspect.java new file mode 100644 index 0000000..c5617a2 --- /dev/null +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/FilePermissionCheckAspect.java @@ -0,0 +1,56 @@ +package com.electromagnetic.industry.software.manage.aop; + +import com.electromagnetic.industry.software.common.annotations.RequiredPermission; +import com.electromagnetic.industry.software.common.enums.FilePermission; +import com.electromagnetic.industry.software.common.exception.PermissionDeniedException; +import com.electromagnetic.industry.software.common.util.UserThreadLocal; +import com.electromagnetic.industry.software.manage.pojo.req.UpdateFileInfoDTO; +import com.electromagnetic.industry.software.manage.service.EdFileInfoService; +import com.electromagnetic.industry.software.manage.service.PermissionService; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Map; + +@Aspect +@Component +public class FilePermissionCheckAspect { + + @Resource + PermissionService permissionService; + @Resource + EdFileInfoService edFileInfoService; + + @Around("@annotation(requiredPermission)") + public Object requirePermission(ProceedingJoinPoint joinPoint, RequiredPermission requiredPermission) throws Throwable{ + + // 获取方法参数 + Object[] args = joinPoint.getArgs(); + + if (args.length > 0) { + FilePermission filePermission = requiredPermission.value(); + String userId = UserThreadLocal.getUserId(); + String id = ""; + + if (args[0] instanceof String) { + String childId = args[0].toString(); + id = edFileInfoService.getCategoryId(childId); + } + + if (args[0] instanceof UpdateFileInfoDTO) { + UpdateFileInfoDTO updateFileInfoDTO = (UpdateFileInfoDTO) args[0]; + String childId = updateFileInfoDTO.getId(); + id = edFileInfoService.getCategoryId(childId); + } + + Map permissions = permissionService.getUserPermission(userId,id); + if (!permissions.get(filePermission.getCode()).equals(Boolean.TRUE)) { + throw new PermissionDeniedException("用户无权限执行此操作"); + } + } + return joinPoint.proceed(); + } +} diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/PermissionAspect.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/PermissionAspect.java deleted file mode 100644 index 4e8b773..0000000 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/PermissionAspect.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.electromagnetic.industry.software.manage.aop; - -import com.electromagnetic.industry.software.common.annotations.RequiredPermission; -import com.electromagnetic.industry.software.common.enums.FilePermission; -import com.electromagnetic.industry.software.common.util.UserThreadLocal; -import com.electromagnetic.industry.software.manage.service.PermissionService; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; -import org.springframework.stereotype.Component; - -import javax.annotation.Resource; -import java.util.Map; - -@Aspect -@Component -public class PermissionAspect { - - @Resource - PermissionService permissionService; - - @Before("@annotation(requiredPermission) && args(id)") - public void requirePermission(RequiredPermission requiredPermission, String id) { - - FilePermission filePermission = requiredPermission.value(); - String userId = UserThreadLocal.getUserId(); - Map permissions = permissionService.getUserPermission(userId,id); - if (!permissions.get(filePermission.getCode()).equals(Boolean.TRUE)) { - throw new SecurityException("用户无权限执行此操作"); - } - } -} diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/RoleCheckAspect.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/RoleCheckAspect.java new file mode 100644 index 0000000..64c3237 --- /dev/null +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/aop/RoleCheckAspect.java @@ -0,0 +1,29 @@ +package com.electromagnetic.industry.software.manage.aop; + +import com.electromagnetic.industry.software.common.annotations.RequiredRole; +import com.electromagnetic.industry.software.common.exception.PermissionDeniedException; +import com.electromagnetic.industry.software.common.util.UserThreadLocal; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + + +@Component +@Aspect +public class RoleCheckAspect { + + @Around("@annotation(requiredRole)") + public Object checkRole(ProceedingJoinPoint joinPoint, RequiredRole requiredRole) throws Throwable { + // 获取当前用户角色 + String currentRole = UserThreadLocal.getAdminType(); + + // 检查角色 + if (requiredRole.value().getValue().equals(currentRole)) { + return joinPoint.proceed(); // 用户角色匹配,执行方法 + } + + // 如果角色不匹配,抛出异常或返回无权限响应 + throw new PermissionDeniedException("用户无权限执行此操作"); + } +} diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/common/GlobalExceptionHandler.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/common/GlobalExceptionHandler.java index 7d102a9..f256a8f 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/common/GlobalExceptionHandler.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/common/GlobalExceptionHandler.java @@ -1,6 +1,7 @@ package com.electromagnetic.industry.software.manage.common; import com.electromagnetic.industry.software.common.exception.BizException; +import com.electromagnetic.industry.software.common.exception.PermissionDeniedException; import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; import com.electromagnetic.industry.software.common.util.ElectromagneticResultUtil; import lombok.extern.slf4j.Slf4j; @@ -10,6 +11,8 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; +import java.nio.file.AccessDeniedException; + @Slf4j @ControllerAdvice public class GlobalExceptionHandler { @@ -29,4 +32,12 @@ public class GlobalExceptionHandler { log.error(e.getMessage(), e); return ElectromagneticResultUtil.fail("-1", e.getMsg()); } + + @ExceptionHandler(PermissionDeniedException.class) + @ResponseStatus(HttpStatus.FORBIDDEN) + @ResponseBody + public ElectromagneticResult accessDeniedError(PermissionDeniedException e) { + log.error(e.getMessage(), e); + return ElectromagneticResultUtil.fail("-1", e.getMessage()); + } } \ No newline at end of file diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java index 86fd401..319d71a 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java @@ -1,5 +1,7 @@ package com.electromagnetic.industry.software.manage.controller; +import com.electromagnetic.industry.software.common.annotations.RequiredPermission; +import com.electromagnetic.industry.software.common.enums.FilePermission; import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; import com.electromagnetic.industry.software.manage.pojo.req.CreateFolderDTO; import com.electromagnetic.industry.software.manage.pojo.req.FileChunkDTO; @@ -32,6 +34,7 @@ public class EdFileInfoController { return edFileInfoService.createFolder(createFolderDTO); } + @RequiredPermission(value = FilePermission.DELETE) @RequestMapping("delete") public ElectromagneticResult delete(@RequestParam String id) { return edFileInfoService.delete(id); @@ -42,6 +45,7 @@ public class EdFileInfoController { return edFileInfoService.queryEdFileInfo(fileInfoQueryDTO); } + @RequiredPermission(value = FilePermission.UPLOAD) @RequestMapping("upload") public ElectromagneticResult upload(@RequestParam("parentId") String parentId, @RequestParam("file") MultipartFile file, @@ -49,16 +53,19 @@ public class EdFileInfoController { return edFileInfoService.upload(parentId, file, strategy); } + @RequiredPermission(value = FilePermission.DOWNLOAD) @RequestMapping("download") public ResponseEntity download(@RequestParam String id, HttpServletResponse response) { return edFileInfoService.download(id, response); } + @RequiredPermission(value = FilePermission.EDIT) @RequestMapping("updateFileInfo") public ElectromagneticResult updateFileInfo(@RequestBody UpdateFileInfoDTO updateFileInfoDTO) { return edFileInfoService.updateFileInfo(updateFileInfoDTO); } + @RequiredPermission(value = FilePermission.MOVE) @RequestMapping("moveFile") public ElectromagneticResult moveFile(@RequestParam("id") String id, @RequestParam("targetFolderId") String targetFolderId, @@ -66,6 +73,7 @@ public class EdFileInfoController { return edFileInfoService.moveFile(id, targetFolderId, strategy); } + @RequiredPermission(value = FilePermission.MOVE) @RequestMapping("copyFile") public ElectromagneticResult copyFile(@RequestParam("id") String id, @RequestParam("targetFolderId") String targetFolderId, diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/RoleController.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/RoleController.java index 99dd020..de951c8 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/RoleController.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/RoleController.java @@ -1,5 +1,7 @@ package com.electromagnetic.industry.software.manage.controller; +import com.electromagnetic.industry.software.common.annotations.RequiredRole; +import com.electromagnetic.industry.software.common.enums.AdminTypeEnum; import com.electromagnetic.industry.software.common.exception.BizException; import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; import com.electromagnetic.industry.software.common.util.ElectromagneticResultUtil; @@ -19,6 +21,7 @@ public class RoleController { private RoleService roleService; @ApiOperation(value = "新建角色", notes = "") + @RequiredRole(AdminTypeEnum.SECURITY) @RequestMapping(value = "/createRole", method = RequestMethod.POST) public ElectromagneticResult createRole(@RequestBody RoleDTO roleDTO) { try { @@ -30,6 +33,7 @@ public class RoleController { } @ApiOperation(value = "更新角色", notes = "") + @RequiredRole(AdminTypeEnum.SECURITY) @RequestMapping(value = "/updateRole", method = RequestMethod.POST) public ElectromagneticResult updateRole(@RequestBody RoleDTO roleDTO) { try { @@ -41,36 +45,42 @@ public class RoleController { } @ApiOperation(value = "删除角色", notes = "") + @RequiredRole(AdminTypeEnum.SECURITY) @GetMapping(value = "/deleteRole/{roleId}") public ElectromagneticResult deleteRole(@PathVariable("roleId") String roleId) { return ElectromagneticResultUtil.success(roleService.deleteRole(roleId)); } @ApiOperation(value = "查看角色", notes = "") + @RequiredRole(AdminTypeEnum.SECURITY) @GetMapping(value = "/getSingleRole/{roleId}") public ElectromagneticResult getRole(@PathVariable("roleId") String roleId) { return ElectromagneticResultUtil.success(roleService.getRole(roleId)); } @ApiOperation(value = "获取角色列表", notes = "") + @RequiredRole(AdminTypeEnum.SECURITY) @RequestMapping(value = "/list", method = RequestMethod.POST) public ElectromagneticResult getRoles(@RequestBody RolePageDTO rolePageDTO) { return ElectromagneticResultUtil.success(roleService.getRoles(rolePageDTO)); } @ApiOperation(value = "通过角色名查看角色权限", notes = "") + @RequiredRole(AdminTypeEnum.SECURITY) @GetMapping(value = "/getRoleByName") public ElectromagneticResult getRoleByName(@RequestParam("roleName") String roleName) { return ElectromagneticResultUtil.success(roleService.getRoleByName(roleName)); } @ApiOperation(value = "角色名列表", notes = "") + @RequiredRole(AdminTypeEnum.SECURITY) @GetMapping(value = "/getRoleNames") public ElectromagneticResult getRoleNames() { return ElectromagneticResultUtil.success(roleService.getAllRoleNames()); } @ApiOperation(value = "获得角色配置模版", notes = "") + @RequiredRole(AdminTypeEnum.SECURITY) @GetMapping(value = "/getRoleTemplate") public ElectromagneticResult getRoleTemplate() { return ElectromagneticResultUtil.success(roleService.getRoleTemplate()); diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/UserController.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/UserController.java index fef0f70..748fb6a 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/UserController.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/UserController.java @@ -1,5 +1,7 @@ package com.electromagnetic.industry.software.manage.controller; +import com.electromagnetic.industry.software.common.annotations.RequiredRole; +import com.electromagnetic.industry.software.common.enums.AdminTypeEnum; import com.electromagnetic.industry.software.common.enums.PublishEnum; import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; import com.electromagnetic.industry.software.common.util.ElectromagneticResultUtil; @@ -26,30 +28,35 @@ public class UserController { } @ApiOperation(value = "新增用户信息", notes = "") + @RequiredRole(AdminTypeEnum.SYSTEM) @PostMapping("/createUser") public ElectromagneticResult createUser(@RequestBody UserRequest userRequest) { return userService.createUser(userRequest); } @ApiOperation(value = "编辑用户信息", notes = "") + @RequiredRole(AdminTypeEnum.SYSTEM) @PutMapping("/updateUser") public ElectromagneticResult updateUser(@RequestBody UserModiRequest userModiRequest) { return userService.modifyUser(userModiRequest); } @ApiOperation(value = "发布用户信息", notes = "") + @RequiredRole(AdminTypeEnum.SYSTEM) @RequestMapping(value = "/publish", method = RequestMethod.POST) public ElectromagneticResult publishUser(@RequestBody UserPublishRequest userPublishRequest) { return userService.publishUser(userPublishRequest); } @ApiOperation(value = "获取单条用户信息", notes = "") + @RequiredRole(AdminTypeEnum.SYSTEM) @RequestMapping(value = "/getInfo", method = RequestMethod.GET) public ElectromagneticResult getSingleUser(GetSingleUserRequest getSingleUserRequest) { return userService.getSingleUser(getSingleUserRequest); } @ApiOperation(value = "查询用户信息", notes = "") + @RequiredRole(AdminTypeEnum.SYSTEM) @RequestMapping(value = "/list", method = RequestMethod.POST) public ElectromagneticResult searchUser(@RequestBody SearchUserRequest searchUserRequest) { return userService.searchUser(searchUserRequest); @@ -62,6 +69,7 @@ public class UserController { } @ApiOperation(value = "删除用户信息", notes = "") + @RequiredRole(AdminTypeEnum.SYSTEM) @PostMapping(value = "/deleteUser") public ElectromagneticResult deleteUser(@RequestBody UserDeleteRequest userDeleteRequest) { return userService.deleteUser(userDeleteRequest); @@ -74,6 +82,7 @@ public class UserController { } @ApiOperation(value = "人员绑定界面查询用户", notes = "") + @RequiredRole(AdminTypeEnum.SECURITY) @RequestMapping(value = "/bindRole/list", method = RequestMethod.POST) public ElectromagneticResult getPublishedUsers(@RequestBody SearchUserRequest searchUserRequest) { searchUserRequest.setIsPublished(PublishEnum.PUBLISHED.getCode().toString()); @@ -81,6 +90,7 @@ public class UserController { } @ApiOperation(value = "人员绑定", notes = "") + @RequiredRole(AdminTypeEnum.SECURITY) @RequestMapping(value = "/bindRoles", method = RequestMethod.POST) public ElectromagneticResult bindRoles(@RequestBody List list) { if (userService.bindRoles(list)) { @@ -91,6 +101,7 @@ public class UserController { } @ApiOperation(value = "密码重置", notes = "") + @RequiredRole(AdminTypeEnum.SECURITY) @GetMapping(value = "/resetPassword/{userId}") public ElectromagneticResult resetPassword(@PathVariable("userId") String userId) { return ElectromagneticResultUtil.success(userService.resetPassword(userId)); diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java index 1f1acc1..ca44fbe 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java @@ -153,4 +153,8 @@ public interface EdFileInfoService { */ ElectromagneticResult detail(String id); + /** + * 获取文件的层级Id + */ + String getCategoryId (String id); } diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/PermissionService.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/PermissionService.java index 1632f83..d994842 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/PermissionService.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/PermissionService.java @@ -43,4 +43,5 @@ public interface PermissionService { * @param ids */ Map filterExportIds(String[] ids); + } diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java index e8417a4..0da56d7 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java @@ -1125,4 +1125,20 @@ public class EdFileInfoServiceImpl extends ServiceImpl ids = rolePermissionMapper.selectObjs(queryWrapper1).stream().map(Object::toString).collect(Collectors.toList()); + + Set result = new HashSet<>(); + // 把父亲节点加上 + for (String id : ids) { + EdFileInfo file = edFileInfoMapper.selectById(id); + String[] parentIds = file.getFilePath().split("_"); + result.addAll(Arrays.asList(parentIds)); + } + return new ArrayList<>(result); } /** diff --git a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/annotations/RequiredPermission.java b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/annotations/RequiredPermission.java index 9d4314e..1c754fe 100644 --- a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/annotations/RequiredPermission.java +++ b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/annotations/RequiredPermission.java @@ -2,13 +2,13 @@ package com.electromagnetic.industry.software.common.annotations; import com.electromagnetic.industry.software.common.enums.FilePermission; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; +@Documented @Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) +@Target({ElementType.METHOD, ElementType.PARAMETER}) + public @interface RequiredPermission { + FilePermission value(); } diff --git a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/annotations/RequiredRole.java b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/annotations/RequiredRole.java new file mode 100644 index 0000000..fa2c78e --- /dev/null +++ b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/annotations/RequiredRole.java @@ -0,0 +1,12 @@ +package com.electromagnetic.industry.software.common.annotations; + +import com.electromagnetic.industry.software.common.enums.AdminTypeEnum; + +import java.lang.annotation.*; + +@Documented +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface RequiredRole { + AdminTypeEnum value(); +} diff --git a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/exception/PermissionDeniedException.java b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/exception/PermissionDeniedException.java new file mode 100644 index 0000000..7e5651d --- /dev/null +++ b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/exception/PermissionDeniedException.java @@ -0,0 +1,21 @@ +package com.electromagnetic.industry.software.common.exception; + +public class PermissionDeniedException extends RuntimeException { + + public PermissionDeniedException() { + super("Permission Denied: You do not have access to perform this operation."); + } + + public PermissionDeniedException(String message) { + super(message); + } + + public PermissionDeniedException(String message, Throwable cause) { + super(message, cause); + } + + public PermissionDeniedException(Throwable cause) { + super(cause); + } +} +