diff --git a/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/portal/SkillControllerDownloadTest.java b/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/portal/SkillControllerDownloadTest.java index ef24b46b..a1baa691 100644 --- a/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/portal/SkillControllerDownloadTest.java +++ b/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/portal/SkillControllerDownloadTest.java @@ -1,6 +1,8 @@ package com.iflytek.skillhub.controller.portal; import static org.mockito.BDDMockito.given; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -52,7 +54,9 @@ class SkillControllerDownloadTest { "https://download.example/presigned" )); - mockMvc.perform(get("/api/v1/skills/global/demo-skill/versions/1.0.0/download")) + mockMvc.perform(get("/api/v1/skills/global/demo-skill/versions/1.0.0/download") + .with(user("test-user")) + .with(csrf())) .andExpect(status().isFound()) .andExpect(header().string("Location", "https://download.example/presigned")); } @@ -68,8 +72,21 @@ class SkillControllerDownloadTest { null )); - mockMvc.perform(get("/api/v1/skills/global/demo-skill/versions/1.0.0/download")) + mockMvc.perform(get("/api/v1/skills/global/demo-skill/versions/1.0.0/download") + .with(user("test-user")) + .with(csrf())) .andExpect(status().isOk()) .andExpect(header().string("Content-Disposition", "attachment; filename=\"demo-skill-1.0.0.zip\"")); } + + @Test + void downloadVersion_requiresAuthentication() throws Exception { + mockMvc.perform(get("/api/v1/skills/global/demo-skill/versions/1.0.0/download") + .with(csrf())) + .andDo(result -> { + System.out.println("Status: " + result.getResponse().getStatus()); + System.out.println("Body: " + result.getResponse().getContentAsString()); + }) + .andExpect(status().isUnauthorized()); + } } diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java index 5e56b6f6..ba1f128e 100644 --- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java +++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java @@ -96,12 +96,9 @@ public class SecurityConfig { "/api/v1/skills/*/*/versions/*/files", "/api/v1/skills/*/*/versions/*/file", "/api/v1/skills/*/*/resolve", - "/api/v1/skills/*/*/download", - "/api/v1/skills/*/*/versions/*/download", "/api/v1/skills/*/*/tags", "/api/v1/skills/*/*/tags/*/files", - "/api/v1/skills/*/*/tags/*/file", - "/api/v1/skills/*/*/tags/*/download" + "/api/v1/skills/*/*/tags/*/file" ).permitAll() .requestMatchers(HttpMethod.GET, "/api/v1/namespaces", "/api/v1/namespaces/*").permitAll() .requestMatchers("/api/v1/admin/**").hasAnyRole("SUPER_ADMIN", "SKILL_ADMIN", "USER_ADMIN", "AUDITOR") diff --git a/web/src/pages/skill-detail.tsx b/web/src/pages/skill-detail.tsx index 7e3df7d5..67223007 100644 --- a/web/src/pages/skill-detail.tsx +++ b/web/src/pages/skill-detail.tsx @@ -56,6 +56,10 @@ export function SkillDetailPage() { }) const handleDownload = () => { + if (!user) { + requireLogin() + return + } if (!latestVersion) { return }