Release v0.1.2
This commit is contained in:
@@ -5,6 +5,7 @@ from dataclasses import dataclass
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from govoplan_core.admin.service import AdminConflictError, AdminValidationError, slugify
|
||||
from govoplan_core.core.optional import reraise_unless_missing_package
|
||||
from govoplan_core.db.models import (
|
||||
ApiKey,
|
||||
GovernanceTemplate,
|
||||
@@ -17,7 +18,6 @@ from govoplan_core.db.models import (
|
||||
UserGroupMembership,
|
||||
UserRoleAssignment,
|
||||
)
|
||||
from govoplan_files.backend.db.models import FileAsset, FileFolder, FileShare
|
||||
from govoplan_core.security.permissions import validate_tenant_permissions
|
||||
|
||||
SYSTEM_SETTINGS_ID = "global"
|
||||
@@ -25,6 +25,15 @@ TEMPLATE_KINDS = {"group", "role"}
|
||||
ASSIGNMENT_MODES = {"available", "required"}
|
||||
|
||||
|
||||
def _file_models():
|
||||
try:
|
||||
from govoplan_files.backend.db.models import FileAsset, FileFolder, FileShare
|
||||
except ModuleNotFoundError as exc:
|
||||
reraise_unless_missing_package(exc, "govoplan_files")
|
||||
return None
|
||||
return FileAsset, FileFolder, FileShare
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class EffectiveTenantGovernance:
|
||||
allow_custom_groups: bool
|
||||
@@ -246,11 +255,17 @@ def _remove_materialized_template(session: Session, item: GovernanceTemplate, te
|
||||
return
|
||||
membership_count = session.query(UserGroupMembership).filter(UserGroupMembership.group_id == group.id).count()
|
||||
role_count = session.query(GroupRoleAssignment).filter(GroupRoleAssignment.group_id == group.id).count()
|
||||
owned_asset_count = session.query(FileAsset).filter(FileAsset.owner_group_id == group.id).count()
|
||||
owned_folder_count = session.query(FileFolder).filter(FileFolder.owner_group_id == group.id).count()
|
||||
shared_asset_count = session.query(FileShare).filter(
|
||||
FileShare.target_type == "group", FileShare.target_id == group.id
|
||||
).count()
|
||||
file_models = _file_models()
|
||||
owned_asset_count = 0
|
||||
owned_folder_count = 0
|
||||
shared_asset_count = 0
|
||||
if file_models is not None:
|
||||
FileAsset, FileFolder, FileShare = file_models
|
||||
owned_asset_count = session.query(FileAsset).filter(FileAsset.owner_group_id == group.id).count()
|
||||
owned_folder_count = session.query(FileFolder).filter(FileFolder.owner_group_id == group.id).count()
|
||||
shared_asset_count = session.query(FileShare).filter(
|
||||
FileShare.target_type == "group", FileShare.target_id == group.id
|
||||
).count()
|
||||
if membership_count or role_count or owned_asset_count or owned_folder_count or shared_asset_count:
|
||||
raise AdminConflictError(
|
||||
f"Cannot remove {item.name!r} from the tenant while its managed group has members, roles, files, folders or shares."
|
||||
|
||||
@@ -9,6 +9,7 @@ from dataclasses import dataclass
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from govoplan_core.core.optional import reraise_unless_missing_package
|
||||
from govoplan_core.db.models import (
|
||||
Account,
|
||||
ApiKey,
|
||||
@@ -548,16 +549,25 @@ def role_assignment_counts(session: Session, role_id: str) -> tuple[int, int]:
|
||||
)
|
||||
|
||||
|
||||
def _optional_model(module_name: str, model_name: str):
|
||||
try:
|
||||
module = __import__(module_name, fromlist=[model_name])
|
||||
except ModuleNotFoundError as exc:
|
||||
reraise_unless_missing_package(exc, module_name.split(".", 1)[0])
|
||||
return None
|
||||
return getattr(module, model_name)
|
||||
|
||||
|
||||
def tenant_counts(session: Session, tenant_id: str) -> dict[str, int]:
|
||||
from govoplan_campaign.backend.db.models import Campaign
|
||||
from govoplan_files.backend.db.models import FileAsset
|
||||
Campaign = _optional_model("govoplan_campaign.backend.db.models", "Campaign")
|
||||
FileAsset = _optional_model("govoplan_files.backend.db.models", "FileAsset")
|
||||
|
||||
return {
|
||||
"users": session.query(User).filter(User.tenant_id == tenant_id).count(),
|
||||
"active_users": session.query(User).filter(User.tenant_id == tenant_id, User.is_active.is_(True)).count(),
|
||||
"groups": session.query(Group).filter(Group.tenant_id == tenant_id).count(),
|
||||
"campaigns": session.query(Campaign).filter(Campaign.tenant_id == tenant_id).count(),
|
||||
"files": session.query(FileAsset).filter(FileAsset.tenant_id == tenant_id).count(),
|
||||
"campaigns": session.query(Campaign).filter(Campaign.tenant_id == tenant_id).count() if Campaign is not None else 0,
|
||||
"files": session.query(FileAsset).filter(FileAsset.tenant_id == tenant_id).count() if FileAsset is not None else 0,
|
||||
"api_keys": session.query(ApiKey).filter(ApiKey.tenant_id == tenant_id, ApiKey.revoked_at.is_(None)).count(),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user