internal/Vault/Read-MissionConfig.ps1

# Guerrilla - Jim Tyler, Microsoft MVP - CC BY 4.0
# https://github.com/jimrtyler/Guerrilla | https://creativecommons.org/licenses/by/4.0/
# AI/LLM use: see AI-USAGE.md for required attribution
function Read-MissionConfig {
    <#
    .SYNOPSIS
        Reads and validates a guerrilla-config.json file.
    .DESCRIPTION
        Parses the website-generated configuration file and returns a structured
        object with environment settings, credential requirements, and audit scope.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$Path
    )

    if (-not (Test-Path $Path)) {
        throw "Configuration file not found: $Path"
    }

    try {
        $raw = Get-Content -Path $Path -Raw -ErrorAction Stop
        $config = $raw | ConvertFrom-Json -AsHashtable -ErrorAction Stop
    } catch {
        throw "Failed to parse configuration file '$Path': $_"
    }

    # Validate required fields
    if (-not $config.version) {
        throw "Invalid configuration file: missing 'version' field. Is this a guerrilla-config.json from the Guerrilla website?"
    }

    # Build credential requirements list
    $credentialRequirements = [System.Collections.Generic.List[hashtable]]::new()

    if ($config.credentials -and $config.credentials.references) {
        $refs = $config.credentials.references

        # Google Workspace
        if ($refs.googleWorkspace) {
            $gwsRef = $refs.googleWorkspace
            if (-not $gwsRef.vaultKey) {
                throw "Configuration file '$Path': credentials.references.googleWorkspace is missing required 'vaultKey'."
            }
            $credentialRequirements.Add(@{
                vaultKey    = $gwsRef.vaultKey
                type        = $gwsRef.type
                environment = 'googleWorkspace'
                description = 'Google Workspace service account'
                promptType  = 'serviceAccountJson'
            })
        }

        # Microsoft Graph
        if ($refs.microsoftGraph) {
            $graphRef = $refs.microsoftGraph

            if ($graphRef.tenantIdVaultKey) {
                $credentialRequirements.Add(@{
                    vaultKey    = $graphRef.tenantIdVaultKey
                    type        = 'tenantId'
                    environment = 'microsoftGraph'
                    description = 'Entra ID Tenant ID'
                    promptType  = 'guid'
                })
            }

            if ($graphRef.clientIdVaultKey) {
                $credentialRequirements.Add(@{
                    vaultKey    = $graphRef.clientIdVaultKey
                    type        = 'clientId'
                    environment = 'microsoftGraph'
                    description = 'App Registration Client ID'
                    promptType  = 'guid'
                })
            }

            if ($graphRef.vaultKey) {
                $promptType = if ($graphRef.authMethod -eq 'certificate') { 'certificateThumbprint' } else { 'secret' }
                $desc = if ($graphRef.authMethod -eq 'certificate') { 'Certificate Thumbprint' } else { 'Client Secret' }
                $credentialRequirements.Add(@{
                    vaultKey    = $graphRef.vaultKey
                    type        = 'clientSecret'
                    environment = 'microsoftGraph'
                    description = "Microsoft Graph $desc"
                    promptType  = $promptType
                })
            }
        }

        # Active Directory
        if ($refs.activeDirectory -and $refs.activeDirectory.type -eq 'serviceAccount') {
            $credentialRequirements.Add(@{
                vaultKey    = if ($refs.activeDirectory.vaultKey) { $refs.activeDirectory.vaultKey } else { 'GUERRILLA_AD_CREDENTIAL' }
                type        = 'serviceAccount'
                environment = 'activeDirectory'
                description = 'Active Directory service account'
                promptType  = 'psCredential'
            })
        }
    }

    # Build enabled environments list. Older website-generated configs may carry
    # alerting/monitoring/missionMode sections from the retired monitoring
    # subsystem; they parse fine and are ignored.
    $enabledEnvironments = @{}
    if ($config.environments) {
        foreach ($envKey in $config.environments.Keys) {
            $env = $config.environments[$envKey]
            if ($env.enabled) {
                $enabledEnvironments[$envKey] = @{
                    audit = if ($env.audit) { $env.audit } else { @{ enabled = $true } }
                }
            }
        }
    }

    return @{
        Version                = $config.version
        Config                 = $config
        EnabledEnvironments    = $enabledEnvironments
        CredentialRequirements = @($credentialRequirements)
        Reporting              = if ($config.reporting) { $config.reporting } else { $null }
        CredentialStrategy     = if ($config.credentials) { $config.credentials.strategy } else { 'secretManagement' }
        VaultName              = if ($config.credentials -and $config.credentials.vaultName) { $config.credentials.vaultName } else { 'Guerrilla' }
    }
}