diff --git a/invenio_checks/ext.py b/invenio_checks/ext.py index 7283d3e..b3d23fa 100644 --- a/invenio_checks/ext.py +++ b/invenio_checks/ext.py @@ -26,29 +26,15 @@ def __init__(self, app=None): def init_app(self, app): """Flask application initialization.""" self.init_config(app) - self.init_services(app) app.extensions["invenio-checks"] = self self.checks_registry = ChecksRegistry() self.checks_registry.load_from_entry_points(app, "invenio_checks.check_types") + self.service = CheckConfigService( + config=ChecksConfigServiceConfig.build(app), + ) def init_config(self, app): """Initialize configuration.""" for k in dir(config): if k.startswith("CHECKS_"): app.config.setdefault(k, getattr(config, k)) - - def service_configs(self, app): - """Customized service configs.""" - - class ServiceConfigs: - checks_configs = ChecksConfigServiceConfig.build(app) - - return ServiceConfigs - - def init_services(self, app): - """Initialize the service and resource for Requests.""" - service_configs = self.service_configs(app) - - self.checks_configs_service = CheckConfigService( - config=service_configs.checks_configs, - ) diff --git a/invenio_checks/proxies.py b/invenio_checks/proxies.py index f8a804d..96ae951 100644 --- a/invenio_checks/proxies.py +++ b/invenio_checks/proxies.py @@ -14,6 +14,6 @@ ) current_checks_configs_service = LocalProxy( - lambda: current_app.extensions["invenio-checks"].checks_configs_service + lambda: current_app.extensions["invenio-checks"].service ) """Proxy to the instantiated checks_configs service.""" diff --git a/invenio_checks/services/schema.py b/invenio_checks/services/schema.py index ac8707b..e051800 100644 --- a/invenio_checks/services/schema.py +++ b/invenio_checks/services/schema.py @@ -8,12 +8,15 @@ """Service schemas.""" from datetime import timezone +from uuid import UUID -from marshmallow import EXCLUDE, Schema, fields +from marshmallow import EXCLUDE, Schema, ValidationError, fields, validates from marshmallow_utils.fields import SanitizedUnicode, TZDateTime from marshmallow_utils.permissions import FieldPermissionsMixin +from sqlalchemy.orm import validates -from ..models import CheckRunStatus +from ..models import CheckRunStatus, Severity +from ..proxies import current_checks_registry class CheckConfigSchema(Schema, FieldPermissionsMixin): @@ -25,14 +28,31 @@ class Meta: unknown = EXCLUDE id = fields.UUID(dump_only=True) - - created = TZDateTime(timezone=timezone.utc, format="iso", dump_only=True) - updated = TZDateTime(timezone=timezone.utc, format="iso", dump_only=True) - - title = SanitizedUnicode(required=True) - description = SanitizedUnicode() - - active = fields.Boolean(load_default=True) + community_id = fields.Str(required=True) + check_id = fields.Str(required=True) + params = fields.Dict(required=False, default={}) + severity = fields.Str(required=False, default=Severity.INFO.value) + enabled = fields.Bool(required=False, default=True) + + @validates("community_id") + def validate_community_id(self, value): + """Validate that the community_id is a valid UUID.""" + try: + UUID(value) + except ValueError: + raise ValidationError("Invalid UUID format for community_id.") + + @validates("check_id") + def validate_check_id(self, value): + """Validate that the check_id exists in the registry.""" + if not current_checks_registry.get(value): + raise ValidationError(f"Check with id '{value}' not found.") + + @validates("severity") + def validate_severity(self, value): + """Validate that the severity is a valid enum value.""" + if value not in [s.value for s in Severity]: + raise ValidationError(f"Invalid severity value: {value}.") class CheckRunSchema(Schema, FieldPermissionsMixin): diff --git a/invenio_checks/services/services.py b/invenio_checks/services/services.py index d54489b..02f632c 100644 --- a/invenio_checks/services/services.py +++ b/invenio_checks/services/services.py @@ -15,9 +15,11 @@ ModelDeleteOp, unit_of_work, ) -from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound +from marshmallow import ValidationError +from sqlalchemy.orm.exc import NoResultFound -from ..models import CheckConfig +from ..models import CheckConfig, Severity +from .schema import CheckConfigSchema class BaseClass(RecordService): @@ -49,13 +51,19 @@ def create(self, identity, data, uow=None, **kwargs): """Create a check configuration.""" self.require_permission(identity, "create") + schema = CheckConfigSchema() + try: + validated_data = schema.load(data) + except ValidationError as e: + raise ValueError(f"Validation error: {e.messages}") + try: check_config = CheckConfig( - community_id=UUID(data["community_id"]), - check_id=data["check_id"], - params=data.get("params", {}), - severity=data.get("severity", "I"), - enabled=data.get("enabled", True), + community_id=UUID(validated_data["community_id"]), + check_id=validated_data["check_id"], + params=validated_data.get("params", {}), + severity=validated_data.get("severity", Severity.INFO.value), + enabled=validated_data.get("enabled", True), ) uow.register(ModelCommitOp(check_config)) return check_config