From f7256a0c567998df3e38274a2797b87533913750 Mon Sep 17 00:00:00 2001 From: zio Date: Tue, 14 Jul 2026 21:52:34 +0900 Subject: [PATCH] fix(auth): global ADMIN has full permissions; member role no longer masked by hm flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Owner: 'admin은 모든 권한'. requireRole(ORGANIZER)-style endpoints 403'd for admin because roleFor() returned HALL_MANAGER (hm/ADMIN flag) even when the user held an explicit ORGANIZER membership. - EventAccessGuard.requireRole: isAdmin() bypasses the allowed-role set (tenant boundary still enforced) - KintexPrincipal.roleFor: explicit event membership role wins; HALL_MANAGER only as fallback - HallAssignController: ADMIN allowed alongside hall manager Co-Authored-By: Claude Fable 5 --- .../com/zioinfo/kintex/auth/EventAccessGuard.java | 9 ++++++++- .../com/zioinfo/kintex/auth/KintexPrincipal.java | 12 ++++++++++-- .../kintex/hallassign/HallAssignController.java | 4 ++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/backend/src/main/java/com/zioinfo/kintex/auth/EventAccessGuard.java b/src/backend/src/main/java/com/zioinfo/kintex/auth/EventAccessGuard.java index 6d8b1eb..4deedb8 100644 --- a/src/backend/src/main/java/com/zioinfo/kintex/auth/EventAccessGuard.java +++ b/src/backend/src/main/java/com/zioinfo/kintex/auth/EventAccessGuard.java @@ -58,9 +58,16 @@ public class EventAccessGuard { } } - /** 해당 행사에서 허용된 역할 중 하나여야 함. 없으면 403. */ + /** + * 해당 행사에서 허용된 역할 중 하나여야 함. 없으면 403. + * 전역 시스템관리자(role_code=ADMIN)는 역할 집합과 무관하게 전권(2026-07-14 소유자 방침 + * "admin은 모든 권한") — 단 테넌트 경계(assertTenantOwnsEvent)는 그대로 적용된다. + */ public KintexPrincipal requireRole(KintexPrincipal principal, String eventId, EventRole... allowed) { requireEventAccess(principal, eventId); + if (principal.isAdmin()) { + return principal; + } EventRole role = principal.roleFor(eventId); Set allowedSet = Set.of(allowed); if (role == null || !allowedSet.contains(role)) { diff --git a/src/backend/src/main/java/com/zioinfo/kintex/auth/KintexPrincipal.java b/src/backend/src/main/java/com/zioinfo/kintex/auth/KintexPrincipal.java index 60ffe57..231fb3e 100644 --- a/src/backend/src/main/java/com/zioinfo/kintex/auth/KintexPrincipal.java +++ b/src/backend/src/main/java/com/zioinfo/kintex/auth/KintexPrincipal.java @@ -42,12 +42,20 @@ public record KintexPrincipal( return "ADMIN".equalsIgnoreCase(roleCode); } - /** 해당 행사에서 사용자의 역할(없으면 null). 홀매니저·ADMIN은 항상 HALL_MANAGER로 간주. */ + /** + * 해당 행사에서 사용자의 역할(없으면 null). 명시적 행사 멤버십 역할이 있으면 그것이 우선 — + * 홀매니저/ADMIN 플래그가 실제 멤버 역할(예: ORGANIZER)을 가려 역할 제한 엔드포인트에서 + * 403이 나던 결함 수정(2026-07-14). 멤버십이 없을 때만 HALL_MANAGER로 간주. + */ public EventRole roleFor(String eventId) { + EventRole member = eventRoles == null ? null : eventRoles.get(eventId); + if (member != null) { + return member; + } if (hallManager || isAdmin()) { return EventRole.HALL_MANAGER; } - return eventRoles == null ? null : eventRoles.get(eventId); + return null; } public boolean hasAccess(String eventId) { diff --git a/src/backend/src/main/java/com/zioinfo/kintex/hallassign/HallAssignController.java b/src/backend/src/main/java/com/zioinfo/kintex/hallassign/HallAssignController.java index ec26933..39d8c47 100644 --- a/src/backend/src/main/java/com/zioinfo/kintex/hallassign/HallAssignController.java +++ b/src/backend/src/main/java/com/zioinfo/kintex/hallassign/HallAssignController.java @@ -114,10 +114,10 @@ public class HallAssignController { return ApiResponse.ok(service.quote(req)); } - /** 홀 배정 변경 권한 — 킨텍스 내부 홀매니저만(§2 최종 배정 확정은 킨텍스 내부 의사결정). */ + /** 홀 배정 변경 권한 — 킨텍스 내부 홀매니저 + 전역 ADMIN(전권, 2026-07-14 소유자 방침). */ private void requireHallManager(KintexPrincipal principal) { guard.require(principal); - if (!principal.hallManager()) { + if (!principal.hallManager() && !principal.isAdmin()) { throw new ApiException(ErrorCode.FORBIDDEN, "홀 배정은 킨텍스 홀매니저만 변경할 수 있습니다."); } }