mirror of
https://github.com/iflytek/skillhub.git
synced 2026-08-28 11:25:00 +00:00
fix(portal): keep skill detail on viewer permissions
This commit is contained in:
parent
a1e4904d97
commit
edcc248244
4 changed files with 66 additions and 35 deletions
|
|
@ -70,12 +70,10 @@ public class SkillController extends BaseApiController {
|
|||
@PathVariable String namespace,
|
||||
@PathVariable String slug,
|
||||
@RequestAttribute(value = "userId", required = false) String userId,
|
||||
@RequestAttribute(value = "userNsRoles", required = false) Map<Long, NamespaceRole> userNsRoles,
|
||||
@RequestAttribute(value = "platformRoles", required = false) java.util.Set<String> platformRoles) {
|
||||
@RequestAttribute(value = "userNsRoles", required = false) Map<Long, NamespaceRole> userNsRoles) {
|
||||
|
||||
SkillQueryService.SkillDetailDTO detail = skillQueryService.getSkillDetail(
|
||||
namespace, slug, userId, userNsRoles != null ? userNsRoles : Map.of(),
|
||||
platformRoles != null ? platformRoles : java.util.Set.<String>of());
|
||||
namespace, slug, userId, userNsRoles != null ? userNsRoles : Map.of());
|
||||
|
||||
SkillDetailResponse response = new SkillDetailResponse(
|
||||
detail.id(),
|
||||
|
|
|
|||
|
|
@ -149,8 +149,7 @@ class SkillControllerTest {
|
|||
eq("team"),
|
||||
eq("demo"),
|
||||
eq((String) null),
|
||||
eq(Map.<Long, NamespaceRole>of()),
|
||||
org.mockito.ArgumentMatchers.<java.util.Set<String>>any()))
|
||||
eq(Map.<Long, NamespaceRole>of())))
|
||||
.thenReturn(new SkillQueryService.SkillDetailDTO(
|
||||
1L,
|
||||
"demo",
|
||||
|
|
@ -197,8 +196,7 @@ class SkillControllerTest {
|
|||
eq("team"),
|
||||
eq("demo"),
|
||||
eq((String) null),
|
||||
eq(Map.<Long, NamespaceRole>of()),
|
||||
org.mockito.ArgumentMatchers.<java.util.Set<String>>any()))
|
||||
eq(Map.<Long, NamespaceRole>of())))
|
||||
.thenThrow(new DomainForbiddenException("error.namespace.archived", "team"));
|
||||
|
||||
mockMvc.perform(get("/api/web/skills/team/demo"))
|
||||
|
|
|
|||
|
|
@ -150,28 +150,15 @@ public class SkillQueryService {
|
|||
String skillSlug,
|
||||
String currentUserId,
|
||||
Map<Long, NamespaceRole> userNsRoles) {
|
||||
return getSkillDetail(namespaceSlug, skillSlug, currentUserId, userNsRoles, Set.of());
|
||||
}
|
||||
|
||||
public SkillDetailDTO getSkillDetail(
|
||||
String namespaceSlug,
|
||||
String skillSlug,
|
||||
String currentUserId,
|
||||
Map<Long, NamespaceRole> userNsRoles,
|
||||
Set<String> platformRoles) {
|
||||
|
||||
Namespace namespace = findNamespace(namespaceSlug);
|
||||
Skill skill = resolveVisibleSkill(namespace.getId(), skillSlug, currentUserId);
|
||||
|
||||
// Archived namespace: only members (or super admins) may view
|
||||
if (namespace.getStatus() == com.iflytek.skillhub.domain.namespace.NamespaceStatus.ARCHIVED
|
||||
&& !isNamespaceMember(namespace.getId(), currentUserId, userNsRoles)
|
||||
&& !isSuperAdmin(platformRoles)) {
|
||||
&& !isNamespaceMember(namespace.getId(), currentUserId, userNsRoles)) {
|
||||
throw new DomainForbiddenException("error.namespace.archived", namespaceSlug);
|
||||
}
|
||||
|
||||
// Visibility check
|
||||
if (!visibilityChecker.canAccess(skill, currentUserId, userNsRoles, platformRoles)) {
|
||||
if (!visibilityChecker.canAccess(skill, currentUserId, userNsRoles)) {
|
||||
throw new DomainForbiddenException("error.skill.access.denied", skillSlug);
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +190,7 @@ public class SkillQueryService {
|
|||
skill.getNamespaceId(),
|
||||
skill.getCreatedAt(),
|
||||
skill.getUpdatedAt(),
|
||||
canManageRestrictedSkill(skill, currentUserId, userNsRoles, platformRoles),
|
||||
canManageRestrictedSkill(skill, currentUserId, userNsRoles),
|
||||
canSubmitPromotion(namespace, skill, publishedVersion, currentUserId, userNsRoles),
|
||||
headlineVersion == null || "PUBLISHED".equals(headlineVersion.status()),
|
||||
currentUserId == null || !Objects.equals(skill.getOwnerId(), currentUserId),
|
||||
|
|
@ -215,6 +202,15 @@ public class SkillQueryService {
|
|||
);
|
||||
}
|
||||
|
||||
public SkillDetailDTO getSkillDetail(
|
||||
String namespaceSlug,
|
||||
String skillSlug,
|
||||
String currentUserId,
|
||||
Map<Long, NamespaceRole> userNsRoles,
|
||||
Set<String> platformRoles) {
|
||||
return getSkillDetail(namespaceSlug, skillSlug, currentUserId, userNsRoles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists skills within a namespace after filtering out records the caller is
|
||||
* not allowed to discover.
|
||||
|
|
@ -647,13 +643,6 @@ public class SkillQueryService {
|
|||
}
|
||||
|
||||
private boolean canManageRestrictedSkill(Skill skill, String currentUserId, Map<Long, NamespaceRole> userNsRoles) {
|
||||
return canManageRestrictedSkill(skill, currentUserId, userNsRoles, Set.of());
|
||||
}
|
||||
|
||||
private boolean canManageRestrictedSkill(Skill skill, String currentUserId, Map<Long, NamespaceRole> userNsRoles, Set<String> platformRoles) {
|
||||
if (platformRoles != null && platformRoles.contains("SUPER_ADMIN")) {
|
||||
return true;
|
||||
}
|
||||
if (currentUserId == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -695,10 +684,6 @@ public class SkillQueryService {
|
|||
return currentUserId != null && userNsRoles.containsKey(namespaceId);
|
||||
}
|
||||
|
||||
private boolean isSuperAdmin(Set<String> platformRoles) {
|
||||
return platformRoles != null && platformRoles.contains("SUPER_ADMIN");
|
||||
}
|
||||
|
||||
private String resolveOwnerPreviewReviewComment(SkillLifecycleProjectionService.VersionProjection ownerPreviewVersion) {
|
||||
if (ownerPreviewVersion == null || !"REJECTED".equals(ownerPreviewVersion.status())) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -771,6 +771,56 @@ class SkillQueryServiceTest {
|
|||
assertFalse(result.canSubmitPromotion());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetSkillDetail_ShouldNotGrantLifecyclePermissionToSuperAdminInPortal() throws Exception {
|
||||
String namespaceSlug = "test-ns";
|
||||
String skillSlug = "test-skill";
|
||||
String userId = "super-1";
|
||||
Map<Long, NamespaceRole> userNsRoles = Map.of(1L, NamespaceRole.MEMBER);
|
||||
|
||||
Namespace namespace = new Namespace(namespaceSlug, "Test NS", "owner-1");
|
||||
setId(namespace, 1L);
|
||||
Skill skill = new Skill(1L, skillSlug, "owner-1", SkillVisibility.PUBLIC);
|
||||
setId(skill, 1L);
|
||||
skill.setStatus(SkillStatus.ACTIVE);
|
||||
skill.setLatestVersionId(11L);
|
||||
|
||||
SkillVersion published = new SkillVersion(1L, "1.0.0", "owner-1");
|
||||
setId(published, 11L);
|
||||
published.setStatus(SkillVersionStatus.PUBLISHED);
|
||||
|
||||
when(namespaceRepository.findBySlug(namespaceSlug)).thenReturn(Optional.of(namespace));
|
||||
when(skillRepository.findByNamespaceIdAndSlug(1L, skillSlug)).thenReturn(List.of(skill));
|
||||
when(skillVersionRepository.findById(11L)).thenReturn(Optional.of(published));
|
||||
|
||||
SkillQueryService.SkillDetailDTO result = service.getSkillDetail(
|
||||
namespaceSlug, skillSlug, userId, userNsRoles, Set.of("SUPER_ADMIN"));
|
||||
|
||||
assertFalse(result.canManageLifecycle());
|
||||
assertFalse(result.canSubmitPromotion());
|
||||
assertEquals("PUBLISHED", result.resolutionMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetSkillDetail_ShouldNotGrantPrivateVisibilityToSuperAdminInPortal() throws Exception {
|
||||
String namespaceSlug = "test-ns";
|
||||
String skillSlug = "test-skill";
|
||||
String userId = "super-1";
|
||||
|
||||
Namespace namespace = new Namespace(namespaceSlug, "Test NS", "owner-1");
|
||||
setId(namespace, 1L);
|
||||
Skill skill = new Skill(1L, skillSlug, "owner-1", SkillVisibility.PRIVATE);
|
||||
setId(skill, 1L);
|
||||
skill.setStatus(SkillStatus.ACTIVE);
|
||||
skill.setLatestVersionId(11L);
|
||||
|
||||
when(namespaceRepository.findBySlug(namespaceSlug)).thenReturn(Optional.of(namespace));
|
||||
when(skillRepository.findByNamespaceIdAndSlug(1L, skillSlug)).thenReturn(List.of(skill));
|
||||
|
||||
assertThrows(DomainForbiddenException.class, () ->
|
||||
service.getSkillDetail(namespaceSlug, skillSlug, userId, Map.of(), Set.of("SUPER_ADMIN")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetSkillDetail_ShouldPreferPendingVersionForOwnerPreview() throws Exception {
|
||||
String namespaceSlug = "test-ns";
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue