#!/usr/bin/env python3
"""Synthetic authorization model, not a vendor API test. Python 3.10+."""
import json

PROBES = [
    dict(id='P1', object='contact', action='read', record='C01', field='email', required=True),
    dict(id='P2', object='company', action='read', record='A01', field='name', required=True),
    dict(id='P3', object='contact', action='update', record='C01', field='qualified', required=True),
    dict(id='P4', object='contact', action='read', record='C02', field='email', required=False),
    dict(id='P5', object='contact', action='read', record='C01', field='phone', required=False),
    dict(id='P6', object='contact', action='update', record='C01', field='owner', required=False),
    dict(id='P7', object='contact', action='delete', record='C01', field='*', required=False),
    dict(id='P8', object='note', action='read', record='N01', field='body', required=False),
    dict(id='P9', object='company', action='read', record='A02', field='name', required=False),
]
# Configured workflow is identical under all profiles. It does not authorize probes.
CONFIGURED_IDS = {'P1', 'P2', 'P3'}
ACTION_GRANTS = {('contact', 'read'), ('company', 'read'), ('contact', 'update')}
# Deliberately idealized server-enforced constraints; not a claimed vendor feature.
PRINCIPAL_GRANTS = {('contact', 'read', 'C01', 'email'),
                    ('company', 'read', 'A01', 'name'),
                    ('contact', 'update', 'C01', 'qualified')}

def authorized(profile, probe):
    if profile == 'broad':
        return True
    if (probe['object'], probe['action']) not in ACTION_GRANTS:
        return False
    if profile == 'object_action':
        return True
    return (probe['object'], probe['action'], probe['record'], probe['field']) in PRINCIPAL_GRANTS

def run():
    results = {}
    for profile in ['broad', 'object_action', 'constrained_principal']:
        allowed = [p['id'] for p in PROBES if authorized(profile, p)]
        excess = [p['id'] for p in PROBES if not p['required'] and authorized(profile, p)]
        missing = [p['id'] for p in PROBES if p['required'] and not authorized(profile, p)]
        results[profile] = dict(configured_operations=sorted(CONFIGURED_IDS), allowed=allowed,
                                outside_workflow=excess, missing_required=missing)
    assert results['broad']['outside_workflow'] == ['P4', 'P5', 'P6', 'P7', 'P8', 'P9']
    assert results['object_action']['outside_workflow'] == ['P4', 'P5', 'P6', 'P9']
    assert results['constrained_principal']['allowed'] == ['P1', 'P2', 'P3']
    assert all(not v['missing_required'] for v in results.values())
    assert all(set(v['configured_operations']) == CONFIGURED_IDS for v in results.values())
    return dict(method='Synthetic, authored object/action/record/field authorization predicates; no network or CRM.',
                verified_date='2026-10-26', probes=PROBES, results=results,
                limitations=['No vendor implementation, OAuth token, real record or live permission test.',
                             'Counts depend on these nine selected probes and are not risk scores.',
                             'Object/action grants are independent here; real vendor scopes can bundle actions.',
                             'Idealized principal restrictions may be unavailable for a real connector.'])

if __name__ == '__main__':
    print(json.dumps(run(), indent=2))
