pyhanko.sign.diff_analysis.form_rules_api module

Module defining API types for use by form analysis rules.

In principle, these aren’t relevant to the high-level validation API.

class pyhanko.sign.diff_analysis.form_rules_api.FormUpdatingRule(field_rules: List[pyhanko.sign.diff_analysis.form_rules_api.FieldMDPRule], ignored_acroform_keys=None)

Bases: object

Special whitelisting rule that validates changes to the form attached to the input document.

This rule is special in two ways:

  • it outputs FormUpdate objects instead of references;

  • it delegates most of the hard work to sub-rules (instances of FieldMDPRule).

A DiffPolicy can have at most one FormUpdatingRule, but there is no limit on the number of FieldMDPRule objects attached to it.

FormUpdate objects contain a reference plus metadata about the form field it belongs to.

  • field_rules – A list of FieldMDPRule objects to validate the individual form fields.

  • ignored_acroform_keys – Keys in the /AcroForm dictionary that may be changed. Changes are potentially subject to validation by other rules.

apply(old: pyhanko.pdf_utils.reader.HistoricalResolver, new: pyhanko.pdf_utils.reader.HistoricalResolver) Iterable[Tuple[pyhanko.sign.diff_analysis.policy_api.ModificationLevel, pyhanko.sign.diff_analysis.form_rules_api.FormUpdate]]

Evaluate changes in the document’s form between two revisions.

  • old – The older, base revision.

  • new – The newer revision to be vetted.

class pyhanko.sign.diff_analysis.form_rules_api.FormUpdate(updated_ref: pyhanko.pdf_utils.generic.Reference, paths_checked: Optional[Union[pyhanko.pdf_utils.reader.RawPdfPath, Iterable[pyhanko.pdf_utils.reader.RawPdfPath]]] = None, blanket_approve: bool = False, field_name: Optional[str] = None, valid_when_locked: bool = False, valid_when_certifying: bool = True)

Bases: pyhanko.sign.diff_analysis.rules_api.ReferenceUpdate

Container for a reference together with (optional) metadata.

Currently, this metadata consists of the relevant field’s (fully qualified) name, and whether the update should be approved or not if said field is locked by the FieldMDP policy currently in force.

field_name: Optional[str] = None

The relevant field’s fully qualified name, or None if there’s either no obvious associated field, or if there are multiple reasonable candidates.

valid_when_locked: bool = False

Flag indicating whether the update is valid even when the field is locked. This is only relevant if field_name is not None.

valid_when_certifying: bool = True

Flag indicating whether the update is valid when checking against an explicit DocMDP policy. Default is True. If False, the change will only be accepted if we are evaluating changes to a document after an approval signature.

class pyhanko.sign.diff_analysis.form_rules_api.FieldMDPRule

Bases: object

Sub-rules attached to a FormUpdatingRule.

apply(context: pyhanko.sign.diff_analysis.form_rules_api.FieldComparisonContext) Iterable[Tuple[pyhanko.sign.diff_analysis.policy_api.ModificationLevel, pyhanko.sign.diff_analysis.form_rules_api.FormUpdate]]

Apply the rule to the given FieldComparisonContext.


context – The context of this form revision evaluation, given as an instance of FieldComparisonContext.

class pyhanko.sign.diff_analysis.form_rules_api.FieldComparisonSpec(field_type: str, old_field_ref: Optional[pyhanko.pdf_utils.generic.Reference], new_field_ref: Optional[pyhanko.pdf_utils.generic.Reference], old_canonical_path: Optional[pyhanko.pdf_utils.reader.RawPdfPath])

Bases: object

Helper object that specifies a form field name together with references to its old and new versions.

field_type: str

The (fully qualified) form field name.

old_field_ref: Optional[pyhanko.pdf_utils.generic.Reference]

A reference to the field’s dictionary in the old revision, if present.

new_field_ref: Optional[pyhanko.pdf_utils.generic.Reference]

A reference to the field’s dictionary in the new revision, if present.

old_canonical_path: Optional[pyhanko.pdf_utils.reader.RawPdfPath]

Path from the trailer through the AcroForm structure to this field (in the older revision). If the field is new, set to None.

property old_field: Optional[pyhanko.pdf_utils.generic.DictionaryObject]

The field’s dictionary in the old revision, if present, otherwise None.

property new_field: Optional[pyhanko.pdf_utils.generic.DictionaryObject]

The field’s dictionary in the new revision, if present, otherwise None.

class pyhanko.sign.diff_analysis.form_rules_api.FieldComparisonContext(field_specs: Dict[str, pyhanko.sign.diff_analysis.form_rules_api.FieldComparisonSpec], old: pyhanko.pdf_utils.reader.HistoricalResolver, new: pyhanko.pdf_utils.reader.HistoricalResolver)

Bases: object

Context for a form diffing operation.

field_specs: Dict[str, pyhanko.sign.diff_analysis.form_rules_api.FieldComparisonSpec]

Dictionary mapping field names to FieldComparisonSpec objects.

old: pyhanko.pdf_utils.reader.HistoricalResolver

The older, base revision.

new: pyhanko.pdf_utils.reader.HistoricalResolver

The newer revision.