"""Our schema module""" from typing import Any, Dict, Optional, Union from jsonschema.exceptions import ValidationError # docker-compose require jsonschema < 4 so use Draft7 for now from jsonschema.validators import Draft7Validator from bson import ObjectId from bson.errors import InvalidId # fmt:off # NOTE: Commented out properties are left intentionally, so it is easier to see # what properties are optional. schema = { "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "properties": { "document_version": {"type": "integer", "minimum": 2}, "tags": { "type": "array", "uniqueItems": True, "items": {"type": "string", "enum": ["dev", "display", "hide", "notify"]}, "minItems": 1, "maxItems": 3 # hide is incompatible with notify and/or display }, "ip": {"type": "string"}, "port": {"type": "integer", "minimum": 1, "maximum": 65535}, "whois_description": {"type": "string"}, "asn": {"type": "string"}, "asn_country_code": {"type": "string"}, "ptr": {"type": "string"}, "abuse_mail": {"type": "string"}, "domain": {"type": "string"}, "timestamp": {"type": "string", "format": "date-time"}, "display_name": {"type": "string"}, "description": {"type": "string"}, "custom_data": { "type": "object", "patternProperties": { ".*": { "type": "object", "properties": { "display_name": {"type": "string"}, "data": {"type": ["string", "boolean", "integer"]}, "description": {"type": "string"}, }, "required": [ "display_name", "data", # "description" ] }, }, }, "result": { "type": "object", "patternProperties": { ".*": { "type": "object", "properties": { "display_name": {"type": "string"}, "vulnerable": {"type": "boolean"}, "investigation_needed": {"type": "boolean"}, "reliability": {"type": "integer", "minimum": 1, "maximum": 5}, "severity": {"type": "integer", "minimum": 1, "maximum": 5}, "description": {"type": "string"}, }, "oneOf": [ { "properties": {"investigation_needed": {"const": True}}, "required": ["display_name", "investigation_needed", "description"] }, { "properties": {"vulnerable": {"type": "boolean"}}, "if": {"properties": {"vulnerable": {"const": True}}}, "then": {"required": ["display_name", "vulnerable", "reliability", "severity", "description"]}, "else": {"required": ["display_name", "vulnerable"]} } ] } } } }, "required": [ "document_version", "tags", "ip", "port", "whois_description", "asn", "asn_country_code", "ptr", "abuse_mail", "domain", "timestamp", "display_name", "result" # "description", # "custom_data", ], } def valid_schema(json_data: Dict[str, Any]) -> bool: """Check if json data follows the schema. :param json_data: Json object :return: bool """ try: # docker-compose require jsonschema < 4 so use Draft7 for now Draft7Validator(schema).validate(json_data) except ValidationError as exc: print(f"Validation failed with error: {exc.message}") return False return True def object_id_from_data(data: Union[str, Dict[str, Any]]) -> Optional[ObjectId]: """Get ObjectId from key. None if invalid. :param data: Key. :return: Optional[ObjectId] """ if isinstance(data, str): try: return ObjectId(data) except InvalidId: return None elif isinstance(data, Dict): if "_id" in data and isinstance(data["_id"], str): try: return ObjectId(data["_id"]) except InvalidId: return None return None