Skip to content

Commit 8768ea7

Browse files
fregataaclaude
andauthored
feat(BA-4611): Add bridge methods between ScopeType/EntityType and RBACElementType (#9143)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c8b1cde commit 8768ea7

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

changes/9143.feature.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add bridge methods (`to_element()`, `to_scope_type()`, `to_entity_type()`) between `ScopeType`/`EntityType` and `RBACElementType` to enable incremental migration of upper layers independently of DB/ORM changes.

src/ai/backend/common/data/permission/types.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,14 @@ def member_accessible_entity_types_in_domain(cls) -> set[EntityType]:
270270
"""
271271
return {*cls._resource_types(), cls.USER}
272272

273+
def to_element(self) -> RBACElementType:
274+
from ai.backend.common.exception import RBACTypeConversionError
275+
276+
try:
277+
return RBACElementType(self.value)
278+
except ValueError as e:
279+
raise RBACTypeConversionError(f"{self!r} has no corresponding RBACElementType") from e
280+
273281

274282
class FieldType(enum.StrEnum):
275283
"""Field types for RBAC field-scoped entities.
@@ -304,6 +312,14 @@ class ScopeType(enum.StrEnum):
304312
ARTIFACT_REVISION = "artifact_revision"
305313
ROLE = "role"
306314

315+
def to_element(self) -> RBACElementType:
316+
from ai.backend.common.exception import RBACTypeConversionError
317+
318+
try:
319+
return RBACElementType(self.value)
320+
except ValueError as e:
321+
raise RBACTypeConversionError(f"{self!r} has no corresponding RBACElementType") from e
322+
307323

308324
GLOBAL_SCOPE_ID = "global"
309325

@@ -356,6 +372,30 @@ class RBACElementType(enum.StrEnum):
356372
# === Entity-level scopes (for entity-scope permissions) ===
357373
ARTIFACT_REVISION = "artifact_revision"
358374

375+
def to_scope_type(self) -> ScopeType:
376+
"""Temporary bridge for DB/ORM layers that still use ScopeType.
377+
378+
TODO: Remove after the RBAC ORM migration and ScopeType removal are complete.
379+
"""
380+
from ai.backend.common.exception import RBACTypeConversionError
381+
382+
try:
383+
return ScopeType(self.value)
384+
except ValueError as e:
385+
raise RBACTypeConversionError(f"{self!r} has no corresponding ScopeType") from e
386+
387+
def to_entity_type(self) -> EntityType:
388+
"""Temporary bridge for DB/ORM layers that still use EntityType.
389+
390+
TODO: Remove after the RBAC ORM migration and EntityType RBAC usage removal are complete.
391+
"""
392+
from ai.backend.common.exception import RBACTypeConversionError
393+
394+
try:
395+
return EntityType(self.value)
396+
except ValueError as e:
397+
raise RBACTypeConversionError(f"{self!r} has no corresponding EntityType") from e
398+
359399

360400
class RelationType(enum.StrEnum):
361401
"""Classification of parent-child entity edges in BEP-1048.

src/ai/backend/common/exception.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,3 +1153,17 @@ def error_code(self) -> ErrorCode:
11531153
operation=ErrorOperation.AUTH,
11541154
error_detail=ErrorDetail.INVALID_PARAMETERS,
11551155
)
1156+
1157+
1158+
class RBACTypeConversionError(BackendAIError, web.HTTPInternalServerError):
1159+
"""Raised when an RBAC enum value cannot be converted to another RBAC enum type."""
1160+
1161+
error_type = "https://api.backend.ai/probs/rbac-type-conversion-error"
1162+
error_title = "RBAC type conversion failed."
1163+
1164+
def error_code(self) -> ErrorCode:
1165+
return ErrorCode(
1166+
domain=ErrorDomain.PERMISSION,
1167+
operation=ErrorOperation.GENERIC,
1168+
error_detail=ErrorDetail.INTERNAL_ERROR,
1169+
)

0 commit comments

Comments
 (0)