diff --git a/ordinis-auth/src/main/java/cloud/nstart/terravault/ordinis/auth/ScopeContext.java b/ordinis-auth/src/main/java/cloud/nstart/terravault/ordinis/auth/ScopeContext.java index 7e7ea8c..c9f1e90 100644 --- a/ordinis-auth/src/main/java/cloud/nstart/terravault/ordinis/auth/ScopeContext.java +++ b/ordinis-auth/src/main/java/cloud/nstart/terravault/ordinis/auth/ScopeContext.java @@ -101,14 +101,18 @@ public class ScopeContext { * Маппинг имени роли в scope. Поддерживает: * "ordinis-public" / "public" → PUBLIC * "ORDINIS_INTERNAL" → INTERNAL - * суффикс после "-" или "_": "x-RESTRICTED" → RESTRICTED + * "ordinis:client:public" → PUBLIC (Альтум-style colon-separated) + * суффикс после "-", "_" или ":": "x:RESTRICTED" → RESTRICTED * просто "PUBLIC"|"INTERNAL"|"RESTRICTED" */ private static String normalizeRoleToScope(String role) { if (role == null) return null; - String s = role.trim().toUpperCase().replace("ORDINIS-", "").replace("ORDINIS_", ""); - int dash = Math.max(s.lastIndexOf('-'), s.lastIndexOf('_')); - if (dash >= 0) s = s.substring(dash + 1); + String s = role.trim().toUpperCase() + .replace("ORDINIS-", "") + .replace("ORDINIS_", "") + .replace("ORDINIS:", ""); + int sep = Math.max(Math.max(s.lastIndexOf('-'), s.lastIndexOf('_')), s.lastIndexOf(':')); + if (sep >= 0) s = s.substring(sep + 1); return s; } diff --git a/ordinis-auth/src/test/java/cloud/nstart/terravault/ordinis/auth/ScopeContextTest.java b/ordinis-auth/src/test/java/cloud/nstart/terravault/ordinis/auth/ScopeContextTest.java index 52eee89..e21b17d 100644 --- a/ordinis-auth/src/test/java/cloud/nstart/terravault/ordinis/auth/ScopeContextTest.java +++ b/ordinis-auth/src/test/java/cloud/nstart/terravault/ordinis/auth/ScopeContextTest.java @@ -58,6 +58,24 @@ class ScopeContextTest { .containsExactlyInAnyOrder(DataScope.PUBLIC, DataScope.INTERNAL); } + @Test + void mapsAltumColonSeparatedRoles() { + // Альтум-style: realm role "ordinis:client:public" → DataScope.PUBLIC. + setJwtWithRealmRoles(List.of( + "ordinis:client:public", + "ordinis:client:internal", + "ordinis:client:restricted")); + assertThat(new ScopeContext(propsNoQuery).currentScopes()) + .containsExactlyInAnyOrder(DataScope.PUBLIC, DataScope.INTERNAL, DataScope.RESTRICTED); + } + + @Test + void mapsMixedColonAndDashRoles() { + setJwtWithRealmRoles(List.of("ordinis:client:public", "ordinis-restricted")); + assertThat(new ScopeContext(propsNoQuery).currentScopes()) + .containsExactlyInAnyOrder(DataScope.PUBLIC, DataScope.RESTRICTED); + } + @Test void unrecognizedRolesGivePublicFallback() { setJwtWithRealmRoles(List.of("admin", "viewer"));