diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/TokenController.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/TokenController.java index 19115087..3e099610 100644 --- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/TokenController.java +++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/controller/TokenController.java @@ -41,12 +41,12 @@ public class TokenController extends BaseApiController { @Valid @RequestBody TokenCreateRequest request) { String scopeJson; if (request.scopes() == null || request.scopes().isEmpty()) { - scopeJson = "[\"skill:read\",\"skill:publish\"]"; + scopeJson = "[\"skill:read\",\"skill:publish\",\"skill:manage\"]"; } else { try { scopeJson = objectMapper.writeValueAsString(request.scopes()); } catch (JsonProcessingException e) { - scopeJson = "[\"skill:read\",\"skill:publish\"]"; + scopeJson = "[\"skill:read\",\"skill:publish\",\"skill:manage\"]"; } } diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/device/DeviceAuthService.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/device/DeviceAuthService.java index e838c9a8..333a1ca1 100644 --- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/device/DeviceAuthService.java +++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/device/DeviceAuthService.java @@ -29,7 +29,7 @@ public class DeviceAuthService { private static final long PENDING_CODE_TTL_MINUTES = EXPIRES_IN_SECONDS / 60L; private static final long USED_CODE_TTL_MINUTES = 1L; private static final String CLI_DEVICE_TOKEN_NAME = "CLI Device Flow"; - private static final String CLI_DEVICE_SCOPE_JSON = "[\"skill:read\",\"skill:publish\"]"; + private static final String CLI_DEVICE_SCOPE_JSON = "[\"skill:read\",\"skill:publish\",\"skill:manage\"]"; private final RedisTemplate redisTemplate; private final ApiTokenService apiTokenService; diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/RouteSecurityPolicyRegistry.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/RouteSecurityPolicyRegistry.java index 9d1133f1..e9de30d6 100644 --- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/RouteSecurityPolicyRegistry.java +++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/policy/RouteSecurityPolicyRegistry.java @@ -126,6 +126,25 @@ public class RouteSecurityPolicyRegistry { ApiTokenPolicy.allow(HttpMethod.POST, "/api/v1/reviews/**"), ApiTokenPolicy.allow(HttpMethod.GET, "/api/web/reviews/**"), ApiTokenPolicy.allow(HttpMethod.POST, "/api/web/reviews/**"), + // Lifecycle governance — require skill:manage scope (must appear before broad allow) + ApiTokenPolicy.require(HttpMethod.POST, "/api/v1/skills/*/*/hide", "skill:manage"), + ApiTokenPolicy.require(HttpMethod.POST, "/api/v1/skills/*/*/unhide", "skill:manage"), + ApiTokenPolicy.require(HttpMethod.POST, "/api/v1/skills/*/*/archive", "skill:manage"), + ApiTokenPolicy.require(HttpMethod.POST, "/api/v1/skills/*/*/unarchive", "skill:manage"), + ApiTokenPolicy.require(HttpMethod.POST, "/api/web/skills/*/*/hide", "skill:manage"), + ApiTokenPolicy.require(HttpMethod.POST, "/api/web/skills/*/*/unhide", "skill:manage"), + ApiTokenPolicy.require(HttpMethod.POST, "/api/web/skills/*/*/archive", "skill:manage"), + ApiTokenPolicy.require(HttpMethod.POST, "/api/web/skills/*/*/unarchive", "skill:manage"), + // Social / personal actions — no scope required + ApiTokenPolicy.allow(HttpMethod.PUT, "/api/v1/skills/*/star"), + ApiTokenPolicy.allow(HttpMethod.DELETE, "/api/v1/skills/*/star"), + ApiTokenPolicy.allow(HttpMethod.PUT, "/api/web/skills/*/star"), + ApiTokenPolicy.allow(HttpMethod.DELETE, "/api/web/skills/*/star"), + ApiTokenPolicy.allow(HttpMethod.PUT, "/api/v1/skills/*/rating"), + ApiTokenPolicy.allow(HttpMethod.PUT, "/api/web/skills/*/rating"), + ApiTokenPolicy.allow(HttpMethod.POST, "/api/v1/skills/*/*/reports"), + ApiTokenPolicy.allow(HttpMethod.POST, "/api/web/skills/*/*/reports"), + // Broad fallback for remaining skill operations (publish, etc.) ApiTokenPolicy.allow(HttpMethod.POST, "/api/v1/skills/**"), ApiTokenPolicy.allow(HttpMethod.POST, "/api/web/skills/**"), ApiTokenPolicy.allow(HttpMethod.PUT, "/api/v1/skills/**"),