Browse Source

feat: add role-based permission checks to controllers

Replace @PreAuthorize annotations with programmatic SecurityUtils.hasRole()
checks across all mutation methods in 5 controllers. Requires HR_ADMIN or
higher role for create/update/delete operations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
wangkangyjy 2 months ago
parent
commit
77d3ca40a9

+ 17 - 6
backend/src/main/java/com/yimeng/okr/controller/AssessmentPeriodController.java

@@ -3,10 +3,11 @@ package com.yimeng.okr.controller;
 import com.yimeng.okr.dto.ApiResult;
 import com.yimeng.okr.entity.AssessmentPeriod;
 import com.yimeng.okr.enums.PeriodStatus;
+import com.yimeng.okr.enums.UserRole;
+import com.yimeng.okr.exception.BusinessException;
 import com.yimeng.okr.security.SecurityUtils;
 import com.yimeng.okr.service.AssessmentPeriodService;
 import lombok.RequiredArgsConstructor;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
@@ -37,37 +38,47 @@ public class AssessmentPeriodController {
     }
 
     @PostMapping
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<AssessmentPeriod> create(@RequestBody AssessmentPeriod period) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         return ApiResult.success(periodService.create(period));
     }
 
     @PutMapping("/{id}")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Void> update(@PathVariable Long id, @RequestBody AssessmentPeriod period) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         period.setId(id);
         periodService.update(period);
         return ApiResult.success();
     }
 
     @DeleteMapping("/{id}")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Void> delete(@PathVariable Long id) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         periodService.delete(id);
         return ApiResult.success();
     }
 
     @PutMapping("/{id}/status")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Void> transitionStatus(@PathVariable Long id, @RequestBody Map<String, String> body) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         PeriodStatus target = PeriodStatus.valueOf(body.get("status"));
         periodService.transitionStatus(id, target);
         return ApiResult.success();
     }
 
     @PostMapping("/batch")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<List<AssessmentPeriod>> batchCreate(@RequestBody Map<String, Object> body) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         return ApiResult.success(periodService.batchCreate(body));
     }
 }

+ 12 - 0
backend/src/main/java/com/yimeng/okr/controller/DimensionController.java

@@ -2,6 +2,9 @@ package com.yimeng.okr.controller;
 
 import com.yimeng.okr.dto.ApiResult;
 import com.yimeng.okr.entity.AssessmentDimension;
+import com.yimeng.okr.enums.UserRole;
+import com.yimeng.okr.exception.BusinessException;
+import com.yimeng.okr.security.SecurityUtils;
 import com.yimeng.okr.service.DimensionService;
 import lombok.RequiredArgsConstructor;
 import org.springframework.web.bind.annotation.*;
@@ -22,11 +25,17 @@ public class DimensionController {
 
     @PostMapping
     public ApiResult<AssessmentDimension> create(@RequestBody AssessmentDimension dim) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         return ApiResult.success(service.create(dim));
     }
 
     @PutMapping("/{id}")
     public ApiResult<Void> update(@PathVariable Long id, @RequestBody AssessmentDimension dim) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         dim.setId(id);
         service.update(dim);
         return ApiResult.success();
@@ -34,6 +43,9 @@ public class DimensionController {
 
     @DeleteMapping("/{id}")
     public ApiResult<Void> delete(@PathVariable Long id) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         service.delete(id);
         return ApiResult.success();
     }

+ 12 - 0
backend/src/main/java/com/yimeng/okr/controller/KpiController.java

@@ -3,6 +3,9 @@ package com.yimeng.okr.controller;
 import com.yimeng.okr.dto.ApiResult;
 import com.yimeng.okr.entity.KpiConfig;
 import com.yimeng.okr.entity.KpiTemplate;
+import com.yimeng.okr.enums.UserRole;
+import com.yimeng.okr.exception.BusinessException;
+import com.yimeng.okr.security.SecurityUtils;
 import com.yimeng.okr.service.KpiService;
 import lombok.RequiredArgsConstructor;
 import org.springframework.web.bind.annotation.*;
@@ -25,11 +28,17 @@ public class KpiController {
 
     @PostMapping("/templates")
     public ApiResult<KpiTemplate> createTemplate(@RequestBody KpiTemplate template) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         return ApiResult.success(kpiService.createTemplate(template));
     }
 
     @PutMapping("/templates/{id}")
     public ApiResult<Void> updateTemplate(@PathVariable Long id, @RequestBody KpiTemplate template) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         template.setId(id);
         kpiService.updateTemplate(template);
         return ApiResult.success();
@@ -37,6 +46,9 @@ public class KpiController {
 
     @DeleteMapping("/templates/{id}")
     public ApiResult<Void> deleteTemplate(@PathVariable Long id) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         kpiService.deleteTemplate(id);
         return ApiResult.success();
     }

+ 34 - 12
backend/src/main/java/com/yimeng/okr/controller/OrganizationController.java

@@ -4,9 +4,11 @@ import com.yimeng.okr.dto.ApiResult;
 import com.yimeng.okr.dto.DepartmentTreeNode;
 import com.yimeng.okr.dto.UserInfo;
 import com.yimeng.okr.entity.SysDepartment;
+import com.yimeng.okr.enums.UserRole;
+import com.yimeng.okr.exception.BusinessException;
+import com.yimeng.okr.security.SecurityUtils;
 import com.yimeng.okr.service.OrganizationService;
 import lombok.RequiredArgsConstructor;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
@@ -25,22 +27,28 @@ public class OrganizationController {
     }
 
     @PostMapping("/departments")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<SysDepartment> createDepartment(@RequestBody SysDepartment dept) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         return ApiResult.success(organizationService.createDepartment(dept));
     }
 
     @PutMapping("/departments/{id}")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Void> updateDepartment(@PathVariable Long id, @RequestBody SysDepartment dept) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         dept.setId(id);
         organizationService.updateDepartment(dept);
         return ApiResult.success();
     }
 
     @DeleteMapping("/departments/{id}")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Void> deleteDepartment(@PathVariable Long id) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         organizationService.deleteDepartment(id);
         return ApiResult.success();
     }
@@ -61,55 +69,69 @@ public class OrganizationController {
     }
 
     @PutMapping("/users/{id}/superior")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Void> updateSuperior(@PathVariable Long id, @RequestBody Map<String, Long> body) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         organizationService.updateUserSuperior(id, body.get("superiorId"));
         return ApiResult.success();
     }
 
     @PutMapping("/users/{id}/department")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Void> updateDepartment(@PathVariable Long id, @RequestBody Map<String, Long> body) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         organizationService.updateUserDepartment(id, body.get("departmentId"));
         return ApiResult.success();
     }
 
     @PutMapping("/users/{id}/position")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Void> updatePosition(@PathVariable Long id, @RequestBody Map<String, String> body) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         organizationService.updateUserPosition(id, body.get("position"));
         return ApiResult.success();
     }
 
     @GetMapping("/users/my-subordinates")
     public ApiResult<List<UserInfo>> getMySubordinates() {
-        Long userId = com.yimeng.okr.security.SecurityUtils.getCurrentUserId();
+        Long userId = SecurityUtils.getCurrentUserId();
         return ApiResult.success(organizationService.getSubordinates(userId));
     }
 
     @PostMapping("/users")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<UserInfo> createUser(@RequestBody Map<String, Object> body) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         return ApiResult.success(organizationService.createUser(body));
     }
 
     @PutMapping("/users/{id}")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Void> updateUser(@PathVariable Long id, @RequestBody Map<String, Object> body) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         organizationService.updateUser(id, body);
         return ApiResult.success();
     }
 
     @DeleteMapping("/users/{id}")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Void> deleteUser(@PathVariable Long id) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         organizationService.deleteUser(id);
         return ApiResult.success();
     }
 
     @PostMapping("/init-seed")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Void> initSeedData() {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         organizationService.initSeedData();
         return ApiResult.success();
     }

+ 6 - 2
backend/src/main/java/com/yimeng/okr/controller/SystemController.java

@@ -3,9 +3,11 @@ package com.yimeng.okr.controller;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.yimeng.okr.dto.ApiResult;
 import com.yimeng.okr.entity.OperationLog;
+import com.yimeng.okr.enums.UserRole;
+import com.yimeng.okr.exception.BusinessException;
+import com.yimeng.okr.security.SecurityUtils;
 import com.yimeng.okr.service.SystemService;
 import lombok.RequiredArgsConstructor;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
 @RestController
@@ -16,12 +18,14 @@ public class SystemController {
     private final SystemService systemService;
 
     @GetMapping("/logs")
-    @PreAuthorize("hasRole('SUPER_ADMIN')")
     public ApiResult<Page<OperationLog>> getLogs(
             @RequestParam(defaultValue = "1") int page,
             @RequestParam(defaultValue = "20") int size,
             @RequestParam(required = false) String action,
             @RequestParam(required = false) String entityType) {
+        if (!SecurityUtils.hasRole(UserRole.HR_ADMIN)) {
+            throw new BusinessException(403, "无权限,需要HR管理员或以上权限");
+        }
         return ApiResult.success(systemService.getLogs(page, size, action, entityType));
     }
 }