<?php
// Security tab — API Key Management (root-only).
// Variables ($apiKeys) are prepared in the parent server-settings.php before
// the include.
?>

<?php if (defined('AUTH_USER') && AUTH_USER === 'root'): ?>
<!-- API Key Management (Root Only) -->
<div class="row">
    <div class="col-md-12">
        <div class="card mb-4">
            <div class="card-header">
                <h5 class="card-title mb-0">API Key Management</h5>
                <p class="text-muted small mb-0">Manage API keys for external integrations like WHMCS</p>
            </div>
            <div class="card-body">

                <!-- Display new API key if just created -->
                <?php if (isset($_SESSION['new_api_key']) && isset($_SESSION['new_api_secret'])): ?>
                <div class="alert alert-success alert-dismissible">
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                    <h5><i class="fa fa-check-circle"></i> API Key Created Successfully</h5>
                    <p><strong>API Key:</strong> <code><?php echo htmlspecialchars($_SESSION['new_api_key']); ?></code></p>
                    <p><strong>API Secret:</strong> <code id="api-secret-display"><?php echo htmlspecialchars($_SESSION['new_api_secret']); ?></code>
                    <button type="button" class="btn btn-sm btn-outline-secondary ms-2" onclick="copyToClipboard('api-secret-display')">
                        <i class="fa fa-copy"></i> Copy
                    </button></p>
                    <p class="text-danger"><strong>Important:</strong> Please copy the API secret now. It will not be shown again for security reasons.</p>
                </div>
                <?php
                // Clear the session variables after displaying
                unset($_SESSION['new_api_key'], $_SESSION['new_api_secret']);
                endif;
                ?>

                <!-- Create New API Key Form -->
                <div class="card mb-4">
                    <div class="card-header">
                        <h6 class="card-title mb-0">Create New API Key</h6>
                    </div>
                    <div class="card-body">
                        <form method="post">
                            <input type="hidden" name="action" value="create_api_key">
                            <input type="hidden" name="csrf_token" value="<?php echo get_csrf_token(); ?>">

                            <div class="row">
                                <div class="col-md-6">
                                    <div class="mb-3">
                                        <label for="key_name" class="form-label">Key Name</label>
                                        <input type="text" class="form-control" id="key_name" name="key_name"
                                               placeholder="WHMCS Integration Key" required>
                                        <div class="form-text text-muted">Descriptive name for this API key</div>
                                    </div>
                                </div>
                                <div class="col-md-6">
                                    <div class="mb-3">
                                        <label for="rate_limit" class="form-label">Rate Limit (per hour)</label>
                                        <input type="number" class="form-control" id="rate_limit" name="rate_limit"
                                               value="1000" min="1" max="10000">
                                        <div class="form-text text-muted">Maximum API requests per hour</div>
                                    </div>
                                </div>
                            </div>

                            <div class="mb-3">
                                <label class="form-label">Permissions</label>
                                <div class="row">
                                    <div class="col-md-3">
                                        <div class="form-check">
                                            <input class="form-check-input" type="checkbox" name="permissions[user_management]" value="1" id="perm-user">
                                            <label class="form-check-label" for="perm-user">User Management</label>
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        <div class="form-check">
                                            <input class="form-check-input" type="checkbox" name="permissions[resource_management]" value="1" id="perm-resources">
                                            <label class="form-check-label" for="perm-resources">Resource Management</label>
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        <div class="form-check">
                                            <input class="form-check-input" type="checkbox" name="permissions[sso_access]" value="1" id="perm-sso">
                                            <label class="form-check-label" for="perm-sso">SSO Access</label>
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        <div class="form-check">
                                            <input class="form-check-input" type="checkbox" name="permissions[system_stats]" value="1" id="perm-stats">
                                            <label class="form-check-label" for="perm-stats">System Statistics</label>
                                        </div>
                                    </div>
                                </div>
                                <div class="row mt-2">
                                    <div class="col-md-3">
                                        <div class="form-check">
                                            <input class="form-check-input" type="checkbox" name="permissions[ai_monitor_management]" value="1" id="perm-ai-monitor">
                                            <label class="form-check-label" for="perm-ai-monitor">AI Monitor Management</label>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <div class="mb-3">
                                <label for="ip_whitelist" class="form-label">IP Whitelist (optional)</label>
                                <input type="text" class="form-control" id="ip_whitelist" name="ip_whitelist"
                                       placeholder="192.168.1.100, 10.0.0.50">
                                <div class="form-text text-muted">Comma-separated list of allowed IP addresses (leave empty for no restrictions)</div>
                            </div>

                            <div class="mb-3">
                                <label for="notes" class="form-label">Notes (optional)</label>
                                <textarea class="form-control" id="notes" name="notes" rows="2"
                                          placeholder="Additional notes about this API key"></textarea>
                            </div>

                            <button type="submit" class="btn btn-primary">
                                <i class="fa fa-plus"></i> Create API Key
                            </button>
                        </form>
                    </div>
                </div>

                <!-- Existing API Keys -->
                <div class="card">
                    <div class="card-header">
                        <h6 class="card-title mb-0">Existing API Keys</h6>
                    </div>
                    <div class="card-body">
                        <?php if (!empty($apiKeys)): ?>
                        <div class="table-responsive">
                            <table class="table table-striped">
                                <thead>
                                    <tr>
                                        <th>Name</th>
                                        <th>API Key</th>
                                        <th>Permissions</th>
                                        <th>Rate Limit</th>
                                        <th>Status</th>
                                        <th>Last Used</th>
                                        <th>Usage Count</th>
                                        <th>Actions</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php foreach ($apiKeys as $key): ?>
                                    <tr>
                                        <td>
                                            <strong><?php echo htmlspecialchars($key['key_name']); ?></strong>
                                            <?php if ($key['notes']): ?>
                                            <br><small class="text-muted"><?php echo htmlspecialchars($key['notes']); ?></small>
                                            <?php endif; ?>
                                        </td>
                                        <td>
                                            <code class="small"><?php echo htmlspecialchars(substr($key['api_key'], 0, 20) . '...'); ?></code>
                                            <button type="button" class="btn btn-sm btn-outline-secondary ms-1"
                                                    onclick="copyToClipboard('<?php echo htmlspecialchars($key['api_key']); ?>')">
                                                <i class="fa fa-copy"></i>
                                            </button>
                                        </td>
                                        <td>
                                            <?php if (!empty($key['permissions'])): ?>
                                                <?php foreach ($key['permissions'] as $perm => $enabled): ?>
                                                    <?php if ($enabled): ?>
                                                        <span class="badge bg-info me-1"><?php echo ucwords(str_replace('_', ' ', $perm)); ?></span>
                                                    <?php endif; ?>
                                                <?php endforeach; ?>
                                            <?php else: ?>
                                                <span class="text-muted">None</span>
                                            <?php endif; ?>
                                        </td>
                                        <td><?php echo number_format($key['rate_limit_per_hour']); ?>/hour</td>
                                        <td>
                                            <span class="badge <?php echo $key['is_active'] ? 'bg-success' : 'bg-danger'; ?>">
                                                <?php echo $key['is_active'] ? 'Active' : 'Inactive'; ?>
                                            </span>
                                        </td>
                                        <td>
                                            <?php if ($key['last_used_at']): ?>
                                                <small><?php echo date('M j, Y g:i A', strtotime($key['last_used_at'])); ?></small>
                                            <?php else: ?>
                                                <small class="text-muted">Never</small>
                                            <?php endif; ?>
                                        </td>
                                        <td><?php echo number_format($key['usage_count']); ?></td>
                                        <td>
                                            <?php if ($key['is_active']): ?>
                                            <form method="post" class="d-inline" onsubmit="return confirm('Are you sure you want to deactivate this API key?');">
                                                <input type="hidden" name="action" value="deactivate_api_key">
                                                <input type="hidden" name="csrf_token" value="<?php echo get_csrf_token(); ?>">
                                                <input type="hidden" name="key_id" value="<?php echo $key['id']; ?>">
                                                <button type="submit" class="btn btn-sm btn-outline-danger">
                                                    <i class="fa fa-times"></i> Deactivate
                                                </button>
                                            </form>
                                            <?php else: ?>
                                                <span class="text-muted small">Deactivated</span>
                                            <?php endif; ?>
                                        </td>
                                    </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                        </div>
                        <?php else: ?>
                        <div class="text-center text-muted py-4">
                            <i class="fa fa-key fa-3x mb-3"></i>
                            <h5>No API Keys</h5>
                            <p>Create your first API key to enable external integrations.</p>
                        </div>
                        <?php endif; ?>

                        <!-- Utility Actions -->
                        <hr>
                        <div class="d-flex gap-2">
                            <form method="post" class="d-inline">
                                <input type="hidden" name="action" value="cleanup_sso_tokens">
                                <input type="hidden" name="csrf_token" value="<?php echo get_csrf_token(); ?>">
                                <button type="submit" class="btn btn-sm btn-outline-warning">
                                    <i class="fa fa-trash"></i> Cleanup Expired SSO Tokens
                                </button>
                            </form>
                        </div>

                        <div class="mt-3">
                            <small class="text-muted">
                                <strong>API Usage:</strong><br>
                                • <strong>User Management:</strong> Create, delete, and modify user accounts<br>
                                • <strong>Resource Management:</strong> Update user resource limits and quotas<br>
                                • <strong>SSO Access:</strong> Generate single sign-on tokens for auto-login<br>
                                • <strong>System Statistics:</strong> Access server stats and health information<br>
                                • API keys are used with X-API-Key and X-API-Secret headers<br>
                                • Documentation: <code>/api/external/</code> endpoints
                            </small>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Web Application Firewall (Coraza + OWASP CRS via SPOE) -->
<?php
$waf_mode = $current_config['coraza_waf']['mode'] ?? 'off';
$waf_valid_modes = ['off', 'detect_only', 'enforce'];
if (!in_array($waf_mode, $waf_valid_modes, true)) {
    $waf_mode = 'off';
}
// Live sidecar status — purely cosmetic; the source of truth is settings.json.
// Use proc_open argv form (no shell) to satisfy code-review tooling that
// flags any *exec( calls.
$waf_container_status = 'unknown';
$descs = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
$proc = @proc_open(
    ['/usr/bin/docker', 'ps', '--filter', 'name=coraza-spoa', '--format', '{{.Status}}'],
    $descs, $pipes
);
if (is_resource($proc)) {
    $ps_output = trim((string) stream_get_contents($pipes[1]));
    fclose($pipes[1]);
    fclose($pipes[2]);
    proc_close($proc);
    if ($ps_output === '') {
        $waf_container_status = 'stopped';
    } elseif (stripos($ps_output, 'healthy') !== false) {
        $waf_container_status = 'healthy';
    } elseif (stripos($ps_output, 'Up') === 0) {
        $waf_container_status = 'running';
    } else {
        $waf_container_status = $ps_output;
    }
}
$waf_mode_labels = [
    'off' => ['Off', 'secondary', 'WAF disabled. No SPOE in haproxy.cfg, no sidecar running.'],
    'detect_only' => ['Detect-only', 'info', 'All Coraza rules log to audit.log; nothing is blocked. Use during burn-in to observe false-positive volume per customer before enforcing.'],
    'enforce' => ['Enforcing', 'success', 'Day-one enforce list active: scanner UAs, RCE shell injection, webshell paths, /etc/passwd LFI, Log4Shell JNDI. Everything else is detect-only.'],
];
[$waf_mode_label, $waf_mode_badge, $waf_mode_help] = $waf_mode_labels[$waf_mode];
?>
<div class="row">
    <div class="col-md-12">
        <div class="card mb-4">
            <div class="card-header d-flex justify-content-between align-items-center">
                <h5 class="card-title mb-0"><i class="fa fa-shield"></i> Web Application Firewall</h5>
                <span class="badge bg-<?php echo $waf_mode_badge; ?>"><?php echo htmlspecialchars($waf_mode_label); ?></span>
            </div>
            <div class="card-body">
                <p class="text-muted small">
                    Inspects inbound HTTP requests via <a href="https://coraza.io" target="_blank" rel="noopener">Coraza</a> using OWASP CRS rules.
                    Runs as a sidecar container (<code>coraza-spoa</code>) consulted by HAProxy over SPOE on every request.
                    Audit log: <code>/var/log/coraza/audit.log</code> (JSON, picked up by the AI Monitor).
                </p>

                <div class="alert alert-light border small mb-3">
                    <strong>Current container status:</strong>
                    <span class="badge bg-<?php echo $waf_container_status === 'healthy' ? 'success' : ($waf_container_status === 'stopped' ? 'secondary' : 'warning'); ?>">
                        <?php echo htmlspecialchars($waf_container_status); ?>
                    </span>
                    <span class="text-muted ms-2"><?php echo htmlspecialchars($waf_mode_help); ?></span>
                </div>

                <form method="post">
                    <input type="hidden" name="action" value="update_coraza_waf">
                    <input type="hidden" name="csrf_token" value="<?php echo get_csrf_token(); ?>">

                    <div class="mb-3">
                        <label class="form-label">Mode</label>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="waf_mode" id="waf_mode_off"
                                   value="off" <?php echo $waf_mode === 'off' ? 'checked' : ''; ?>>
                            <label class="form-check-label" for="waf_mode_off">
                                <strong>Off</strong> — sidecar stopped, no SPOE in HAProxy config. Safe default for new installs.
                            </label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="waf_mode" id="waf_mode_detect"
                                   value="detect_only" <?php echo $waf_mode === 'detect_only' ? 'checked' : ''; ?>>
                            <label class="form-check-label" for="waf_mode_detect">
                                <strong>Detect-only</strong> — Coraza inspects every request and writes matches to the audit log, but does NOT block.
                                Recommended for the first 48-72h after enabling on a new server so you can see what would fire (especially on noisy customer apps like WordPress + Divi + WooCommerce) before enforcing.
                            </label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="waf_mode" id="waf_mode_enforce"
                                   value="enforce" <?php echo $waf_mode === 'enforce' ? 'checked' : ''; ?>>
                            <label class="form-check-label" for="waf_mode_enforce">
                                <strong>Enforcing</strong> — day-one enforce list blocks unambiguous attack signatures
                                (scanner UAs <code>913xxx</code>, RCE shell injection <code>932100-932160</code>,
                                webshell paths <code>933170-933200</code>, <code>/etc/passwd</code> LFI <code>930120</code>,
                                Log4Shell JNDI <code>944100-944300</code>). Everything else continues to log only.
                            </label>
                        </div>
                    </div>

                    <div class="alert alert-warning small">
                        <strong>Note:</strong> saving causes a brief HAProxy reload (~3-5s) on this server while the
                        config is regenerated and the sidecar is started/stopped/recreated. Plan changes during
                        a low-traffic window if customer sites have strict uptime SLAs.
                    </div>

                    <button type="submit" class="btn btn-primary">
                        <i class="fa fa-save"></i> Apply WAF Mode
                    </button>
                </form>

                <hr>

                <div class="small text-muted">
                    <strong>Operational notes:</strong>
                    Coraza's audit log is consumed by the AI Monitor's <code>coraza_audit</code> log source. Per-rule
                    false-positive tuning lives in the <code>haproxy-manager-base</code> repo at <code>coraza-spoa/overrides.conf</code>
                    — promote new high-confidence rule ranges or add per-rule exceptions there, then rebuild the
                    sidecar image. Fail-open is the default: a SPOA outage lets traffic flow uninspected rather
                    than 503-ing customer sites.
                </div>
            </div>
        </div>
    </div>
</div>

<!-- cPanel Import: Sanitization Sandbox Container -->
<?php
$cpimp_settings = $current_config['cpanel_import'] ?? [];
$cpimp_mode     = $cpimp_settings['execution_mode']
    ?? 'direct';
if (!in_array($cpimp_mode, ['direct', 'sanitization-container'], true)) {
    $cpimp_mode = 'direct';
}
$cpimp_image      = $cpimp_settings['image']
    ?? 'repo.anhonesthost.net/cloud-hosting-platform/cpanel-importer:latest';
$cpimp_fall_back  = (bool) ($cpimp_settings['fall_back_to_direct_on_image_unavailable'] ?? true);

// Best-effort: is the image actually present on this host right now?
$cpimp_image_status_label = 'unknown';
$cpimp_image_status_badge = 'secondary';
$descs2 = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
$proc2  = @proc_open(
    ['/usr/bin/docker', 'image', 'inspect', '--format', '{{.Id}}', $cpimp_image],
    $descs2, $pipes2
);
if (is_resource($proc2)) {
    fclose($pipes2[1]);
    fclose($pipes2[2]);
    $rc2 = proc_close($proc2);
    if ($rc2 === 0) {
        $cpimp_image_status_label = 'present';
        $cpimp_image_status_badge = 'success';
    } else {
        $cpimp_image_status_label = 'not pulled';
        $cpimp_image_status_badge = 'warning';
    }
}
?>
<div class="row">
    <div class="col-md-12">
        <div class="card mb-4">
            <div class="card-header d-flex justify-content-between align-items-center">
                <h5 class="card-title mb-0"><i class="fa fa-archive"></i> cPanel Import: Sanitization Sandbox</h5>
                <span class="badge bg-<?php echo $cpimp_mode === 'sanitization-container' ? 'success' : 'secondary'; ?>">
                    <?php echo $cpimp_mode === 'sanitization-container' ? 'Sandbox on' : 'Direct (default)'; ?>
                </span>
            </div>
            <div class="card-body">
                <p class="text-muted small mb-3">
                    Runs every cPanel import tarball through a hardened container
                    (<code>cpanel-importer</code>) before the panel extracts files into
                    <code>/docker/users/&lt;user&gt;/</code>. The container scans every file with
                    ClamAV + SaneSecurity PHP-malware signatures, quarantines unambiguous
                    webshells, auto-cleans known injection patterns, swaps MyISAM tables to
                    InnoDB, and refuses WordPress dumps with high-confidence compromise
                    signals. The host filesystem is not visible inside the container.
                </p>

                <div class="alert alert-light border small mb-3">
                    <strong>Image:</strong> <code><?php echo htmlspecialchars($cpimp_image); ?></code>
                    <span class="badge bg-<?php echo $cpimp_image_status_badge; ?> ms-2">
                        <?php echo htmlspecialchars($cpimp_image_status_label); ?>
                    </span>
                    <br>
                    <span class="text-muted">
                        Pre-pulled during <code>setup.sh</code> and refreshed by
                        <code>scripts/updates/staging/setup-cpanel-importer-sandbox.sh</code>.
                        If the image is not pullable on this host and "fall back to direct"
                        is on, imports continue to work using the legacy in-process extract
                        with a loud warning in the import log.
                    </span>
                </div>

                <form method="post">
                    <input type="hidden" name="action" value="update_cpanel_import_sanitization">
                    <input type="hidden" name="csrf_token" value="<?php echo get_csrf_token(); ?>">

                    <div class="mb-3">
                        <label class="form-label">Execution mode</label>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="cpimp_mode" id="cpimp_mode_direct"
                                   value="direct" <?php echo $cpimp_mode === 'direct' ? 'checked' : ''; ?>>
                            <label class="form-check-label" for="cpimp_mode_direct">
                                <strong>Direct (default)</strong> — the panel's worker extracts
                                the tarball in-process under the existing systemd sandbox
                                (<code>whp-cpanel-import@.service</code>). Pre-extract symlink
                                scan still runs. No ClamAV, no engine swap, no content scan.
                            </label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="cpimp_mode" id="cpimp_mode_sandbox"
                                   value="sanitization-container" <?php echo $cpimp_mode === 'sanitization-container' ? 'checked' : ''; ?>>
                            <label class="form-check-label" for="cpimp_mode_sandbox">
                                <strong>Sanitization sandbox</strong> — each import spawns the
                                <code>cpanel-importer</code> container (read-only rootfs, no
                                network, no docker.sock, UID 999). The cleaned tree is what
                                the rest of the importer sees. Verdict + quarantine list
                                surface on the import-results page.
                            </label>
                        </div>
                    </div>

                    <div class="form-check mb-3">
                        <input class="form-check-input" type="checkbox" name="cpimp_fall_back" id="cpimp_fall_back"
                               value="1" <?php echo $cpimp_fall_back ? 'checked' : ''; ?>>
                        <label class="form-check-label" for="cpimp_fall_back">
                            <strong>Fall back to direct mode if the image is unavailable</strong>
                            <span class="form-text text-muted d-block">
                                With this off, an unpullable image is a hard failure (imports
                                refuse to start). With it on, the import continues with the
                                legacy in-process extract and the fallback is logged loudly.
                                Recommended on while the image rollout stabilizes.
                            </span>
                        </label>
                    </div>

                    <button type="submit" class="btn btn-primary">
                        <i class="fa fa-save"></i> Save Sanitization Settings
                    </button>
                </form>

                <hr>

                <div class="small text-muted">
                    <strong>Quarantine + cleaned-extract retention:</strong>
                    <code>/docker/whp/cpanel-importer-quarantine/&lt;importid&gt;/</code> holds
                    flagged files and per-file pre-clean originals.
                    <code>/docker/whp/cpanel-importer-extract/&lt;importid&gt;/</code> holds
                    the cleaned cpmove tree plus the merged report.json. Both default to a
                    90-day retention sweep (configurable via
                    <code>cpanel_import.quarantine_retention_days</code> in
                    <code>/docker/whp/settings.json</code>).
                </div>
            </div>
        </div>
    </div>
</div>
<?php endif; ?>
