Harden module update compatibility cleanup
This commit is contained in:
@@ -6,6 +6,42 @@ from govoplan_core.security.permissions import scopes_grant
|
||||
|
||||
|
||||
LEGACY_TO_MODULE_SCOPES: dict[str, str] = {
|
||||
"admin:users:read": "access:membership:read",
|
||||
"admin:users:create": "access:membership:create",
|
||||
"admin:users:update": "access:membership:update",
|
||||
"admin:users:suspend": "access:membership:update",
|
||||
"admin:groups:read": "access:group:read",
|
||||
"admin:groups:write": "access:group:write",
|
||||
"admin:groups:manage_members": "access:group:manage_members",
|
||||
"admin:roles:read": "access:role:read",
|
||||
"admin:roles:write": "access:role:write",
|
||||
"admin:roles:assign": "access:role:assign",
|
||||
"admin:api_keys:read": "access:api_key:read",
|
||||
"admin:api_keys:create": "access:api_key:create",
|
||||
"admin:api_keys:revoke": "access:api_key:revoke",
|
||||
"admin:settings:read": "access:setting:read",
|
||||
"admin:settings:write": "access:setting:write",
|
||||
"admin:policies:read": "access:policy:read",
|
||||
"admin:policies:write": "access:policy:write",
|
||||
"system:tenants:read": "access:tenant:read",
|
||||
"system:tenants:create": "access:tenant:create",
|
||||
"system:tenants:update": "access:tenant:update",
|
||||
"system:tenants:suspend": "access:tenant:suspend",
|
||||
"system:accounts:read": "access:account:read",
|
||||
"system:accounts:create": "access:account:create",
|
||||
"system:accounts:update": "access:account:update",
|
||||
"system:accounts:suspend": "access:account:suspend",
|
||||
"system:roles:read": "access:system_role:read",
|
||||
"system:roles:write": "access:system_role:write",
|
||||
"system:roles:assign": "access:system_role:assign",
|
||||
"system:access:read": "access:system_role:read",
|
||||
"system:access:assign": "access:system_role:assign",
|
||||
"system:audit:read": "access:audit:read",
|
||||
"system:settings:read": "access:system_setting:read",
|
||||
"system:settings:write": "access:system_setting:write",
|
||||
"system:maintenance:access": "access:maintenance:access",
|
||||
"system:governance:read": "access:governance:read",
|
||||
"system:governance:write": "access:governance:write",
|
||||
"campaign:read": "campaigns:campaign:read",
|
||||
"campaign:create": "campaigns:campaign:create",
|
||||
"campaign:update": "campaigns:campaign:update",
|
||||
@@ -44,14 +80,28 @@ LEGACY_TO_MODULE_SCOPES: dict[str, str] = {
|
||||
"mail_servers:manage_credentials": "mail:secret:manage",
|
||||
}
|
||||
|
||||
MODULE_TO_LEGACY_SCOPES = {module: legacy for legacy, module in LEGACY_TO_MODULE_SCOPES.items()}
|
||||
MODULE_TENANT_SCOPES = frozenset(LEGACY_TO_MODULE_SCOPES.values())
|
||||
MODULE_TO_LEGACY_SCOPE_ALIASES: dict[str, tuple[str, ...]] = {}
|
||||
for legacy_scope, module_scope in LEGACY_TO_MODULE_SCOPES.items():
|
||||
MODULE_TO_LEGACY_SCOPE_ALIASES[module_scope] = (
|
||||
*MODULE_TO_LEGACY_SCOPE_ALIASES.get(module_scope, ()),
|
||||
legacy_scope,
|
||||
)
|
||||
MODULE_TO_LEGACY_SCOPES = {
|
||||
module_scope: aliases[0]
|
||||
for module_scope, aliases in MODULE_TO_LEGACY_SCOPE_ALIASES.items()
|
||||
}
|
||||
MODULE_SYSTEM_SCOPES = frozenset(
|
||||
module
|
||||
for legacy, module in LEGACY_TO_MODULE_SCOPES.items()
|
||||
if legacy.startswith("system:")
|
||||
)
|
||||
MODULE_TENANT_SCOPES = frozenset(LEGACY_TO_MODULE_SCOPES.values()) - MODULE_SYSTEM_SCOPES
|
||||
|
||||
|
||||
def compatible_required_scopes(required: str) -> tuple[str, ...]:
|
||||
legacy = MODULE_TO_LEGACY_SCOPES.get(required)
|
||||
if legacy:
|
||||
return (required, legacy)
|
||||
legacy_aliases = MODULE_TO_LEGACY_SCOPE_ALIASES.get(required)
|
||||
if legacy_aliases:
|
||||
return (required, *legacy_aliases)
|
||||
module = LEGACY_TO_MODULE_SCOPES.get(required)
|
||||
if module:
|
||||
return (required, module)
|
||||
@@ -60,10 +110,18 @@ def compatible_required_scopes(required: str) -> tuple[str, ...]:
|
||||
|
||||
def scopes_grant_compatible(scopes: Iterable[str], required: str) -> bool:
|
||||
granted = list(scopes)
|
||||
if required in MODULE_SYSTEM_SCOPES:
|
||||
return "*" in granted or "system:*" in granted or any(
|
||||
scope != "tenant:*" and scopes_grant([scope], alias)
|
||||
for scope in granted
|
||||
for alias in compatible_required_scopes(required)
|
||||
)
|
||||
if scopes_grant(granted, required):
|
||||
return True
|
||||
if "tenant:*" in granted or "*" in granted:
|
||||
if required in MODULE_TENANT_SCOPES:
|
||||
return True
|
||||
if "system:*" in granted or "*" in granted:
|
||||
if required in MODULE_SYSTEM_SCOPES:
|
||||
return True
|
||||
return any(scopes_grant(granted, alias) for alias in compatible_required_scopes(required) if alias != required)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user