feat(release): disclose module permissions in catalog
This commit is contained in:
@@ -217,6 +217,11 @@ requirements. Missing dependency/interface providers and unsupported update
|
|||||||
windows are surfaced before an operator adds the entry to a plan; installer
|
windows are surfaced before an operator adds the entry to a plan; installer
|
||||||
preflight remains authoritative.
|
preflight remains authoritative.
|
||||||
|
|
||||||
|
Catalog entries also carry the permission definitions declared by the tagged
|
||||||
|
module manifest. Admin groups and exposes their scopes before an install or
|
||||||
|
update is planned. This is disclosure only: installing a module does not grant
|
||||||
|
its permissions to an account, role, group, tenant, or service account.
|
||||||
|
|
||||||
Package lifecycle and availability are intentionally separate:
|
Package lifecycle and availability are intentionally separate:
|
||||||
|
|
||||||
- install, update, and uninstall change the instance-wide package composition;
|
- install, update, and uninstall change the instance-wide package composition;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import tomllib
|
|||||||
import unittest
|
import unittest
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from govoplan_core.core.modules import ModuleManifest
|
from govoplan_core.core.modules import ModuleManifest, PermissionDefinition
|
||||||
from govoplan_core.core.provider_governance import (
|
from govoplan_core.core.provider_governance import (
|
||||||
ExternalProviderDeclaration,
|
ExternalProviderDeclaration,
|
||||||
ModuleArchitectureDeclaration,
|
ModuleArchitectureDeclaration,
|
||||||
@@ -88,6 +88,18 @@ class ReleaseCatalogEntrySynthesisTests(unittest.TestCase):
|
|||||||
id="example",
|
id="example",
|
||||||
name="Example",
|
name="Example",
|
||||||
version="1.2.3",
|
version="1.2.3",
|
||||||
|
permissions=(
|
||||||
|
PermissionDefinition(
|
||||||
|
scope="example:records:read",
|
||||||
|
label="Read records",
|
||||||
|
description="Read example records.",
|
||||||
|
category="Records",
|
||||||
|
level="tenant",
|
||||||
|
module_id="example",
|
||||||
|
resource="records",
|
||||||
|
action="read",
|
||||||
|
),
|
||||||
|
),
|
||||||
architecture=architecture,
|
architecture=architecture,
|
||||||
external_providers=(provider,),
|
external_providers=(provider,),
|
||||||
),
|
),
|
||||||
@@ -112,6 +124,19 @@ class ReleaseCatalogEntrySynthesisTests(unittest.TestCase):
|
|||||||
"default_authority_mode"
|
"default_authority_mode"
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
{
|
||||||
|
"scope": "example:records:read",
|
||||||
|
"label": "Read records",
|
||||||
|
"description": "Read example records.",
|
||||||
|
"category": "Records",
|
||||||
|
"level": "tenant",
|
||||||
|
"resource": "records",
|
||||||
|
"action": "read",
|
||||||
|
"deprecated": False,
|
||||||
|
},
|
||||||
|
entry["permissions"][0],
|
||||||
|
)
|
||||||
|
|
||||||
def test_selective_update_synthesizes_initial_entries_from_package_manifests(self) -> None:
|
def test_selective_update_synthesizes_initial_entries_from_package_manifests(self) -> None:
|
||||||
payload: dict[str, object] = {
|
payload: dict[str, object] = {
|
||||||
|
|||||||
@@ -172,6 +172,23 @@ def manifest_catalog_entry(
|
|||||||
entry["dependencies"] = list(manifest.dependencies)
|
entry["dependencies"] = list(manifest.dependencies)
|
||||||
if manifest.optional_dependencies:
|
if manifest.optional_dependencies:
|
||||||
entry["optional_dependencies"] = list(manifest.optional_dependencies)
|
entry["optional_dependencies"] = list(manifest.optional_dependencies)
|
||||||
|
if manifest.permissions:
|
||||||
|
entry["permissions"] = [
|
||||||
|
{
|
||||||
|
"scope": permission.scope,
|
||||||
|
"label": permission.label,
|
||||||
|
"description": permission.description,
|
||||||
|
"category": permission.category,
|
||||||
|
"level": permission.level,
|
||||||
|
"resource": permission.resource,
|
||||||
|
"action": permission.action,
|
||||||
|
"deprecated": permission.deprecated,
|
||||||
|
}
|
||||||
|
for permission in sorted(
|
||||||
|
manifest.permissions,
|
||||||
|
key=lambda item: item.scope,
|
||||||
|
)
|
||||||
|
]
|
||||||
if manifest.architecture is not None:
|
if manifest.architecture is not None:
|
||||||
entry["architecture"] = manifest.architecture.to_dict()
|
entry["architecture"] = manifest.architecture.to_dict()
|
||||||
entry["information_governance"] = manifest.information_governance.to_dict()
|
entry["information_governance"] = manifest.information_governance.to_dict()
|
||||||
|
|||||||
Reference in New Issue
Block a user