Add organizations module surface
This commit is contained in:
@@ -1,28 +1,122 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from govoplan_core.core.access import CAPABILITY_AUTH_PERMISSION_EVALUATOR, CAPABILITY_AUTH_PRINCIPAL_RESOLVER
|
||||
from govoplan_core.core.identity import CAPABILITY_IDENTITY_DIRECTORY, IdentityDirectory
|
||||
from govoplan_core.core.module_guards import persistent_table_uninstall_guard
|
||||
from govoplan_core.core.modules import DocumentationTopic, MigrationSpec, ModuleContext, ModuleManifest
|
||||
from govoplan_core.core.modules import (
|
||||
DocumentationTopic,
|
||||
FrontendModule,
|
||||
FrontendRoute,
|
||||
MigrationSpec,
|
||||
ModuleContext,
|
||||
ModuleManifest,
|
||||
NavItem,
|
||||
PermissionDefinition,
|
||||
RoleTemplate,
|
||||
)
|
||||
from govoplan_core.core.organizations import CAPABILITY_ORGANIZATION_DIRECTORY
|
||||
from govoplan_core.db.base import Base
|
||||
from govoplan_organizations.backend.db import models as organization_models # noqa: F401 - populate metadata
|
||||
|
||||
|
||||
def _organization_directory(context: ModuleContext) -> object:
|
||||
ORGANIZATIONS_READ_SCOPES = (
|
||||
"organizations:model:read",
|
||||
"organizations:unit:read",
|
||||
"organizations:function:read",
|
||||
"admin:settings:read",
|
||||
)
|
||||
|
||||
|
||||
def _permission(scope: str, label: str, description: str) -> PermissionDefinition:
|
||||
module_id, resource, action = scope.split(":", 2)
|
||||
return PermissionDefinition(
|
||||
scope=scope,
|
||||
label=label,
|
||||
description=description,
|
||||
category="Organizations",
|
||||
level="tenant",
|
||||
module_id=module_id,
|
||||
resource=resource,
|
||||
action=action,
|
||||
)
|
||||
|
||||
|
||||
PERMISSIONS = (
|
||||
_permission("organizations:model:read", "View organization model", "Read organization meta-model definitions such as unit types, structures, and relation types."),
|
||||
_permission("organizations:model:write", "Manage organization model", "Create and edit organization meta-model definitions."),
|
||||
_permission("organizations:unit:read", "View organization units", "Read concrete organization units and relations."),
|
||||
_permission("organizations:unit:write", "Manage organization units", "Create and edit concrete organization units and relations."),
|
||||
_permission("organizations:function:read", "View organization functions", "Read function definitions and identity-held assignments."),
|
||||
_permission("organizations:function:write", "Manage organization functions", "Create and edit function definitions."),
|
||||
_permission("organizations:function:assign", "Assign organization functions", "Assign identity-held functions in organization units."),
|
||||
)
|
||||
|
||||
ROLE_TEMPLATES = (
|
||||
RoleTemplate(
|
||||
slug="organization_modeler",
|
||||
name="Organization modeler",
|
||||
description="Manage organization meta-model, concrete units, structures, functions, and assignments.",
|
||||
permissions=tuple(permission.scope for permission in PERMISSIONS),
|
||||
),
|
||||
RoleTemplate(
|
||||
slug="organization_viewer",
|
||||
name="Organization viewer",
|
||||
description="Read organization model, organization units, and function assignments.",
|
||||
permissions=("organizations:model:read", "organizations:unit:read", "organizations:function:read"),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _route_factory(context: ModuleContext):
|
||||
del context
|
||||
from govoplan_organizations.backend.api.v1.routes import router
|
||||
|
||||
return router
|
||||
|
||||
|
||||
def _organization_directory(context: ModuleContext) -> object:
|
||||
identity_directory: IdentityDirectory | None = None
|
||||
registry = context.registry
|
||||
if hasattr(registry, "has_capability") and registry.has_capability(CAPABILITY_IDENTITY_DIRECTORY):
|
||||
capability = registry.require_capability(CAPABILITY_IDENTITY_DIRECTORY)
|
||||
if isinstance(capability, IdentityDirectory):
|
||||
identity_directory = capability
|
||||
from govoplan_organizations.backend.directory import SqlOrganizationDirectory
|
||||
|
||||
return SqlOrganizationDirectory()
|
||||
return SqlOrganizationDirectory(identity_directory=identity_directory)
|
||||
|
||||
|
||||
manifest = ModuleManifest(
|
||||
id="organizations",
|
||||
name="Organizations",
|
||||
version="0.1.6",
|
||||
dependencies=("tenancy",),
|
||||
migration_spec=MigrationSpec(module_id="organizations", metadata=Base.metadata),
|
||||
required_capabilities=(CAPABILITY_AUTH_PRINCIPAL_RESOLVER, CAPABILITY_AUTH_PERMISSION_EVALUATOR),
|
||||
optional_dependencies=("tenancy", "identity", "access", "audit", "policy"),
|
||||
permissions=PERMISSIONS,
|
||||
role_templates=ROLE_TEMPLATES,
|
||||
route_factory=_route_factory,
|
||||
nav_items=(NavItem(path="/organizations", label="Organizations", icon="users", required_any=ORGANIZATIONS_READ_SCOPES, order=70),),
|
||||
frontend=FrontendModule(
|
||||
module_id="organizations",
|
||||
package_name="@govoplan/organizations-webui",
|
||||
routes=(FrontendRoute(path="/organizations", component="OrganizationsPage", required_any=ORGANIZATIONS_READ_SCOPES, order=70),),
|
||||
nav_items=(NavItem(path="/organizations", label="Organizations", icon="users", required_any=ORGANIZATIONS_READ_SCOPES, order=70),),
|
||||
),
|
||||
migration_spec=MigrationSpec(
|
||||
module_id="organizations",
|
||||
metadata=Base.metadata,
|
||||
script_location=str(Path(__file__).with_name("migrations") / "versions"),
|
||||
),
|
||||
uninstall_guard_providers=(
|
||||
persistent_table_uninstall_guard(
|
||||
organization_models.OrganizationUnitType,
|
||||
organization_models.OrganizationStructure,
|
||||
organization_models.OrganizationRelationType,
|
||||
organization_models.OrganizationRelation,
|
||||
organization_models.OrganizationUnit,
|
||||
organization_models.OrganizationFunctionType,
|
||||
organization_models.OrganizationFunction,
|
||||
organization_models.OrganizationFunctionAssignment,
|
||||
label="Organizations",
|
||||
@@ -37,8 +131,9 @@ manifest = ModuleManifest(
|
||||
title="Organization model",
|
||||
summary="Organizations owns units, hierarchy, functions, and function assignments. Access maps those facts to roles and rights.",
|
||||
body=(
|
||||
"Use organization functions to model responsibilities that outlive people. "
|
||||
"A function assignment can apply to one organization unit or to that unit and all subunits."
|
||||
"Use organization unit types, structures, and relation types to model how the institution describes itself. "
|
||||
"A concrete organization unit can participate in several structures at the same time, such as an employer hierarchy and an academic structure. "
|
||||
"Functions are held by identities in organization units. Accounts only exercise those functions through identity and access policy."
|
||||
),
|
||||
layer="configured",
|
||||
documentation_types=("admin", "user"),
|
||||
|
||||
Reference in New Issue
Block a user