Source code for oci_policy_analysis.presentation.formatters

##########################################################################
# Copyright (c) 2024, Oracle and/or its affiliates.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
#
# DISCLAIMER This is not an official Oracle application, It does not supported by Oracle Support.
#
# formatters.py
#
# @author: Andrew Gregory
#
# Supports Python 3.12 and above
#
# coding: utf-8
##########################################################################
"""Presentation-layer formatting helpers."""

import json
from typing import Any

from oci_policy_analysis.common.models_iam import DynamicGroup, Group, User
from oci_policy_analysis.common.models_policy import DefineStatement, RegularPolicyStatement


def format_compartment_policy_name(
    compartment_path: str | None,
    policy_name: str | None,
    *,
    separator: str = ' :: ',
    empty: str = '-',
) -> str:
    """Format a reusable "compartment path + policy name" display label."""
    comp = str(compartment_path or '').strip()
    name = str(policy_name or '').strip()
    if comp and name:
        return f'{comp}{separator}{name}'
    return name or comp or empty


[docs] def for_display_policy(statement: RegularPolicyStatement) -> dict: """Return a dictionary suitable for display purposes for policy statements.""" principals_display = '' principals = statement.get('principals') principal_keys = statement.get('principal_keys') if isinstance(principals, list): principals_display = ', '.join( [(p.get('display_name') or p.get('principal_key') or '') for p in principals if isinstance(p, dict)] ) elif isinstance(principal_keys, list): principals_display = ', '.join(str(k) for k in principal_keys if k) row = { 'Action': statement.get('action', 'allow'), 'Policy Name': statement['policy_name'], # type: ignore 'Policy OCID': statement['policy_ocid'], # type: ignore 'Internal ID': statement['internal_id'], # type: ignore 'Compartment OCID': statement['compartment_ocid'], # type: ignore 'Policy Compartment': statement['compartment_path'], # type: ignore 'Statement Text': statement['statement_text'], # type: ignore 'Valid': statement['valid'], # type: ignore 'Invalid Reasons': ', '.join(statement['invalid_reasons']) if 'invalid_reasons' in statement and isinstance(statement['invalid_reasons'], list) else '', 'Subject Type': statement['subject_type'] if 'subject_type' in statement else '', 'Subject': statement['subject'] if 'subject' in statement else '', 'Principals': principals_display, 'Principal Keys': ', '.join(str(k) for k in principal_keys) if isinstance(principal_keys, list) else '', '_Principals Raw': principals, 'Verb': statement['verb'] if 'verb' in statement else '', 'Resource': statement['resource'] if 'resource' in statement else '', 'Permission': statement['permission'] if 'permission' in statement else '', 'Location Type': statement['location_type'] if 'location_type' in statement else '', 'Location': statement['location'] if 'location' in statement else '', 'Effective Path': statement['effective_path'] if 'effective_path' in statement else '', 'Conditions': statement['conditions'] if 'conditions' in statement else '', 'Comments': statement['comments'] if 'comments' in statement else '', 'Parsing Notes': '; '.join(statement['parsing_notes']) if 'parsing_notes' in statement else '', 'Creation Time': statement['creation_time'] if 'creation_time' in statement else '', 'Parsed': statement['parsed'] if 'parsed' in statement else '', } # Include snake_case aliases so web views can reliably access keys like # policy_ocid/effective_path without title/acronym mismatches. row.update( { 'action': statement.get('action', 'allow'), 'policy_name': statement.get('policy_name', ''), 'policy_ocid': statement.get('policy_ocid', ''), 'internal_id': statement.get('internal_id', ''), 'compartment_ocid': statement.get('compartment_ocid', ''), 'policy_compartment': statement.get('compartment_path', ''), 'statement_text': statement.get('statement_text', ''), 'valid': statement.get('valid', ''), 'invalid_reasons': statement.get('invalid_reasons', []), 'subject_type': statement.get('subject_type', ''), 'subject': statement.get('subject', ''), # Keep Principals display string for tabular views, but expose raw list for inspectors. 'principals': principals if isinstance(principals, list) else [], 'principal_keys': principal_keys if isinstance(principal_keys, list) else [], 'verb': statement.get('verb', ''), 'resource': statement.get('resource', ''), 'permission': statement.get('permission', ''), 'location_type': statement.get('location_type', ''), 'location': statement.get('location', ''), 'effective_path': statement.get('effective_path', ''), 'conditions': statement.get('conditions', ''), 'comments': statement.get('comments', ''), 'parsing_notes': statement.get('parsing_notes', []), 'creation_time': statement.get('creation_time', ''), 'parsed': statement.get('parsed', ''), } ) return row
[docs] def for_display_tag_based_policy_row(statement: RegularPolicyStatement) -> dict: """Return a compact, tag-focused display dict for a regular statement.""" return { 'Policy Name': statement.get('policy_name', ''), 'Effective Path': statement.get('effective_path') or statement.get('compartment_path', ''), 'Statement Text': statement.get('statement_text', ''), 'Subject Type': statement.get('subject_type', ''), 'Subject': statement.get('subject', ''), 'Verb': statement.get('verb', ''), 'Resource': statement.get('resource', ''), 'Conditions': statement.get('conditions', ''), }
[docs] def for_display_user(u: User) -> dict: """Return a dictionary suitable for display purposes for users.""" return { 'Domain Name': u['domain_name'] if u['domain_name'] else 'Default', # type: ignore 'Username': u['user_name'], 'User ID': u.get('user_id', 'N/A'), 'User OCID': u.get('user_ocid', 'N/A'), 'Primary Email': u.get('email', 'N/A'), 'Display Name': u.get('display_name', 'N/A'), 'User Groups': ', '.join(u.get('groups', [])) if u.get('groups') else 'N/A', # type: ignore } # type: ignore
[docs] def for_display_group(g: Group) -> dict: """Return a dictionary suitable for display purposes for groups.""" return { 'Domain Name': g['domain_name'] if g['domain_name'] else 'Default', # type: ignore 'Group Name': g['group_name'], 'Group ID': g.get('group_id', 'N/A'), 'Group OCID': g.get('group_ocid', 'N/A'), 'Description': g.get('description', 'N/A'), } # type: ignore
[docs] def for_display_dynamic_group(dg: DynamicGroup) -> dict: """Return a dictionary suitable for display purposes for dynamic groups.""" return { 'Domain': dg['domain_name'] if dg['domain_name'] else 'Default', # type: ignore 'Domain OCID': dg.get('domain_ocid', 'N/A'), 'DG Name': dg['dynamic_group_name'], 'DG ID': dg.get('dynamic_group_id', 'N/A'), 'DG OCID': dg.get('dynamic_group_ocid', 'N/A'), 'Description': dg.get('description', 'N/A'), 'Matching Rule': dg.get('matching_rule', 'N/A'), 'In Use': dg.get('in_use', False), 'Creation Time': dg.get('creation_time', 'N/A'), 'Created By': dg.get('created_by_name', 'N/A'), 'Created By OCID': dg.get('created_by_ocid', 'N/A'), } # type: ignore
[docs] def for_display_define(define: DefineStatement) -> dict: """Return a dictionary suitable for display purposes for defines.""" return { 'Policy Name': define.get('policy_name', ''), 'Defined Type': define.get('defined_type', ''), 'Defined Name': define.get('defined_name', ''), 'OCID Alias': define.get('ocid_alias', ''), }
[docs] def for_display_admit(statement) -> dict: """Display-friendly dict for parsed AdmitStatement, mapped to UI columns.""" permissions_list_display = '' if 'admit_permissions' in statement: if isinstance(statement['admit_permissions'], list) and len(statement['admit_permissions']) > 0: permissions_list_display = '{' + ', '.join(statement['admit_permissions']) + '}' elif isinstance(statement['admit_permissions'], str): permissions_list_display = '{' + statement['admit_permissions'] + '}' return { 'Policy Name': statement.get('policy_name', ''), 'Policy Compartment': statement.get('compartment_path', ''), 'Statement Text': statement.get('statement_text', ''), 'Creation Time': statement.get('creation_time', ''), 'Parsed': statement.get('parsed', False), 'Action Type': statement.get('action_type', ''), 'Admitted Principal Type': statement.get('admitted_principal_type', ''), 'Admitted Principals': ', '.join(statement.get('admitted_principal', [])) if isinstance(statement.get('admitted_principal', []), list) else statement.get('admitted_principal', ''), 'Admitted Tenancy': statement.get('admitted_tenancy', ''), 'Admitted Action (or Permission)': f"{statement.get('admit_action', '')} {statement.get('admit_resource', '')}{permissions_list_display}", 'Location Type': statement.get('admit_location_type', ''), 'Location': statement.get('admit_location', ''), 'Where Clause': statement.get('where_clause', ''), 'Comments': statement.get('comment', ''), }
[docs] def for_display_endorse(statement) -> dict: """Display-friendly dict for parsed EndorseStatement, mapped to UI columns.""" permissions_list_display = '' if 'endorse_permissions' in statement: if isinstance(statement['endorse_permissions'], list) and len(statement['endorse_permissions']) > 0: permissions_list_display = '{' + ', '.join(statement['endorse_permissions']) + '}' elif isinstance(statement['endorse_permissions'], str): permissions_list_display = '{' + statement['endorse_permissions'] + '}' return { 'Policy Name': statement.get('policy_name', ''), 'Policy OCID': statement.get('policy_ocid', ''), 'Statement Text': statement.get('statement_text', ''), 'Creation Time': statement.get('creation_time', ''), 'Parsed': statement.get('parsed', False), 'Action Type': statement.get('action_type', ''), 'Endorsed Principal Type': statement.get('endorsed_principal_type', ''), 'Endorsed Principals': ', '.join(statement.get('endorsed_principal', [])) if isinstance(statement.get('endorsed_principal', []), list) else statement.get('endorsed_principal', ''), 'Endorsed Action (or Permission)': f"{statement.get('endorse_action', '')} {statement.get('endorse_resource', '')}{permissions_list_display}", 'Endorsed Tenancy Name': statement.get('endorse_tenancy', ''), 'Where Clause': statement.get('where_clause', ''), 'Comments': statement.get('comment', ''), }
def format_historical_diff_detail(old_value: dict[str, Any] | None, new_value: dict[str, Any] | None) -> list[str]: """Return display-friendly lines for historical compare detail payloads.""" lines: list[str] = [] if old_value is not None: lines.append(f'Old: {json.dumps(old_value, ensure_ascii=False, indent=2)}') if new_value is not None: lines.append(f'New: {json.dumps(new_value, ensure_ascii=False, indent=2)}') return lines def format_historical_changed_fields(changed_fields: list[dict[str, Any]] | None) -> list[str]: """Return compact one-level field diff lines for modified historical items.""" if not changed_fields: return [] lines: list[str] = [] for change in changed_fields: field = str(change.get('field') or '') old = json.dumps(change.get('old'), ensure_ascii=False) new = json.dumps(change.get('new'), ensure_ascii=False) lines.append(f'{field}: {old} -> {new}') return lines