Source code for pyeudiw.duckle_ql.parser_validator

"""
Parser and validator for DCQL (Duckle) Verifiable Presentation requests.

This module provides ParserValidator to detect and validate VP tokens when
the backend is configured with config.dcql_query (DCQL flow).
"""

import logging
from typing import Any

from pyeudiw.duckle_ql.handler import DuckleHandler
from pyeudiw.exceptions import ValidationError
from pyeudiw.duckle_ql.utils import DUCKLE_QUERY_KEY
from pyeudiw.satosa.backends.openid4vp.presentation_submission import MissingHandler


[docs] class ParserValidator: """ Validates Verifiable Presentation tokens for the DCQL (Duckle) flow. Use is_active_duckle_request() to check if the current request is a DCQL request (i.e. config.dcql_query is set). When active, parse() and validate() use the DuckleHandler to process the VP token. """ def __init__(self, token: Any, handlers: dict, config: dict): self.token = token self.config = config self.handler = self._extract_handler(handlers)
[docs] def parse(self) -> list[dict]: return [self.handler.parse(self.token)]
[docs] def validate(self, verifier_id: str, verifier_nonce: str) -> None: """ Validate the DCQL presentation data using the DuckleHandler. :raises MissingHandler: If the handler for the format is not found. :raises VPTokenDescriptorMapMismatch: If the number of VP tokens does not match the number of descriptors. :raises ParseError: If parsing fails. """ try: self.handler.validate(self.token, verifier_id, verifier_nonce) except Exception as e: raise ValidationError(f"Error parsing token at position: {e}")
def _extract_handler(self, handlers: dict): if self.config.get(DUCKLE_QUERY_KEY): for value in handlers.values(): if isinstance(value, DuckleHandler): return value raise MissingHandler("Handler not found for DCQL tokens!") logging.error("Handler not defined for current token!") return None
[docs] def is_active_duckle_request(self) -> bool: """ Return True if the backend is configured for DCQL (Duckle) flow (config.dcql_query present) and the token is a single object (DCQL VP format), not a list of encoded VPs (PE format). """ if isinstance(self.token, list): return False return bool(self.config.get(DUCKLE_QUERY_KEY))