<?php
/**
 * Security Audit Script for GitHub Code Viewer Plugin
 * Run this to verify all security measures are in place
 */

// Prevent direct access
if (!defined('WPINC')) {
    die('Direct access not permitted.');
}

if (!defined('ABSPATH')) {
    exit;
}

class MCB_Security_Audit {
    
    private $issues = array();
    private $passed = array();
    
    /**
     * Run complete security audit
     */
    public function run_audit() {
        $this->check_file_permissions();
        $this->check_index_files();
        $this->check_htaccess_files();
        $this->check_php_files_protection();
        $this->check_input_validation();
        $this->check_output_escaping();
        $this->check_nonce_usage();
        $this->check_capability_checks();
        $this->check_ssl_usage();
        $this->check_rate_limiting();
        
        return $this->generate_report();
    }
    
    /**
     * Check file permissions
     */
    private function check_file_permissions() {
        $plugin_dir = plugin_dir_path(__FILE__);
        
        // Check directory permissions (should be 755 or stricter)
        if (is_readable($plugin_dir)) {
            $perms = fileperms($plugin_dir);
            $octal = substr(sprintf('%o', $perms), -3);
            
            if ($octal > '755') {
                $this->issues[] = 'Directory permissions too permissive: ' . $octal;
            } else {
                $this->passed[] = 'Directory permissions OK: ' . $octal;
            }
        }
        
        // Check file permissions (should be 644 or stricter)
        $files = glob($plugin_dir . '*.php');
        foreach ($files as $file) {
            $perms = fileperms($file);
            $octal = substr(sprintf('%o', $perms), -3);
            
            if ($octal > '644') {
                $this->issues[] = 'File permissions too permissive for ' . basename($file) . ': ' . $octal;
            }
        }
        
        if (empty($this->issues)) {
            $this->passed[] = 'All file permissions are secure';
        }
    }
    
    /**
     * Check for index.php files in all directories
     */
    private function check_index_files() {
        $plugin_dir = plugin_dir_path(__FILE__);
        $directories = array(
            $plugin_dir,
            $plugin_dir . 'admin/',
            $plugin_dir . 'includes/',
            $plugin_dir . 'assets/',
            $plugin_dir . 'assets/css/',
            $plugin_dir . 'assets/js/'
        );
        
        foreach ($directories as $dir) {
            if (is_dir($dir) && !file_exists($dir . 'index.php')) {
                $this->issues[] = 'Missing index.php in ' . str_replace($plugin_dir, '', $dir);
            } else {
                $this->passed[] = 'index.php present in ' . str_replace($plugin_dir, '', $dir);
            }
        }
    }
    
    /**
     * Check for .htaccess files
     */
    private function check_htaccess_files() {
        $plugin_dir = plugin_dir_path(__FILE__);
        $required_htaccess = array(
            $plugin_dir => 'root',
            $plugin_dir . 'admin/' => 'admin',
            $plugin_dir . 'includes/' => 'includes',
            $plugin_dir . 'assets/' => 'assets'
        );
        
        foreach ($required_htaccess as $dir => $name) {
            if (file_exists($dir . '.htaccess')) {
                $this->passed[] = '.htaccess present in ' . $name . ' directory';
            } else {
                $this->issues[] = 'Missing .htaccess in ' . $name . ' directory';
            }
        }
    }
    
    /**
     * Check PHP files have direct access protection
     */
    private function check_php_files_protection() {
        $plugin_dir = plugin_dir_path(__FILE__);
        $php_files = $this->get_all_php_files($plugin_dir);
        
        foreach ($php_files as $file) {
            $content = file_get_contents($file);
            
            // Skip index.php files
            if (basename($file) === 'index.php') {
                continue;
            }
            
            // Check for ABSPATH or WPINC checks
            if (!strpos($content, 'ABSPATH') && !strpos($content, 'WPINC')) {
                $this->issues[] = 'No direct access protection in ' . str_replace($plugin_dir, '', $file);
            } else {
                $this->passed[] = 'Direct access protected: ' . basename($file);
            }
        }
    }
    
    /**
     * Check input validation
     */
    private function check_input_validation() {
        $checks = array(
            'sanitize_text_field' => 'Text sanitization',
            'wp_verify_nonce' => 'Nonce verification',
            'esc_attr' => 'Attribute escaping',
            'esc_html' => 'HTML escaping',
            'esc_js' => 'JavaScript escaping',
            'absint' => 'Integer validation',
            'filter_var' => 'Input filtering'
        );
        
        $plugin_dir = plugin_dir_path(__FILE__);
        $php_files = $this->get_all_php_files($plugin_dir);
        
        foreach ($checks as $function => $description) {
            $found = false;
            foreach ($php_files as $file) {
                $content = file_get_contents($file);
                if (strpos($content, $function) !== false) {
                    $found = true;
                    break;
                }
            }
            
            if ($found) {
                $this->passed[] = $description . ' implemented (' . $function . ')';
            } else {
                $this->issues[] = $description . ' not found (' . $function . ')';
            }
        }
    }
    
    /**
     * Check output escaping
     */
    private function check_output_escaping() {
        $escaping_functions = array(
            'esc_html',
            'esc_attr',
            'esc_url',
            'esc_js',
            'htmlspecialchars'
        );
        
        $plugin_dir = plugin_dir_path(__FILE__);
        $php_files = $this->get_all_php_files($plugin_dir);
        
        $escaping_found = false;
        foreach ($php_files as $file) {
            $content = file_get_contents($file);
            foreach ($escaping_functions as $func) {
                if (strpos($content, $func) !== false) {
                    $escaping_found = true;
                    break 2;
                }
            }
        }
        
        if ($escaping_found) {
            $this->passed[] = 'Output escaping implemented';
        } else {
            $this->issues[] = 'No output escaping functions found';
        }
    }
    
    /**
     * Check nonce usage
     */
    private function check_nonce_usage() {
        $nonce_functions = array(
            'wp_create_nonce',
            'wp_verify_nonce',
            'wp_nonce_field',
            'check_admin_referer'
        );
        
        $plugin_dir = plugin_dir_path(__FILE__);
        $php_files = $this->get_all_php_files($plugin_dir);
        
        $nonce_found = 0;
        foreach ($php_files as $file) {
            $content = file_get_contents($file);
            foreach ($nonce_functions as $func) {
                if (strpos($content, $func) !== false) {
                    $nonce_found++;
                    break;
                }
            }
        }
        
        if ($nonce_found >= 2) { // Should have both create and verify
            $this->passed[] = 'Nonce protection implemented';
        } else {
            $this->issues[] = 'Insufficient nonce protection';
        }
    }
    
    /**
     * Check capability checks
     */
    private function check_capability_checks() {
        $capability_functions = array(
            'current_user_can',
            'user_can',
            'is_admin'
        );
        
        $plugin_dir = plugin_dir_path(__FILE__);
        $php_files = $this->get_all_php_files($plugin_dir);
        
        $capability_found = false;
        foreach ($php_files as $file) {
            $content = file_get_contents($file);
            foreach ($capability_functions as $func) {
                if (strpos($content, $func) !== false) {
                    $capability_found = true;
                    break 2;
                }
            }
        }
        
        if ($capability_found) {
            $this->passed[] = 'Capability checks implemented';
        } else {
            $this->issues[] = 'No capability checks found';
        }
    }
    
    /**
     * Check SSL usage
     */
    private function check_ssl_usage() {
        $plugin_dir = plugin_dir_path(__FILE__);
        $php_files = $this->get_all_php_files($plugin_dir);
        
        $https_enforced = false;
        foreach ($php_files as $file) {
            $content = file_get_contents($file);
            if (strpos($content, 'https://api.github.com') !== false) {
                $https_enforced = true;
                break;
            }
        }
        
        if ($https_enforced) {
            $this->passed[] = 'HTTPS enforced for API calls';
        } else {
            $this->issues[] = 'HTTPS not enforced for API calls';
        }
    }
    
    /**
     * Check rate limiting
     */
    private function check_rate_limiting() {
        $plugin_dir = plugin_dir_path(__FILE__);
        $php_files = $this->get_all_php_files($plugin_dir);
        
        $rate_limiting = false;
        foreach ($php_files as $file) {
            $content = file_get_contents($file);
            if (strpos($content, 'rate_limit') !== false || strpos($content, 'throttl') !== false) {
                $rate_limiting = true;
                break;
            }
        }
        
        if ($rate_limiting) {
            $this->passed[] = 'Rate limiting implemented';
        } else {
            $this->issues[] = 'No rate limiting found';
        }
    }
    
    /**
     * Get all PHP files recursively
     */
    private function get_all_php_files($dir) {
        $files = array();
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dir)
        );
        
        foreach ($iterator as $file) {
            if ($file->isFile() && $file->getExtension() === 'php') {
                $files[] = $file->getPathname();
            }
        }
        
        return $files;
    }
    
    /**
     * Generate audit report
     */
    private function generate_report() {
        $report = array(
            'timestamp' => current_time('mysql'),
            'passed_count' => count($this->passed),
            'issues_count' => count($this->issues),
            'passed' => $this->passed,
            'issues' => $this->issues,
            'score' => $this->calculate_score(),
            'status' => empty($this->issues) ? 'SECURE' : 'NEEDS ATTENTION'
        );
        
        return $report;
    }
    
    /**
     * Calculate security score
     */
    private function calculate_score() {
        $total = count($this->passed) + count($this->issues);
        if ($total === 0) {
            return 0;
        }
        
        return round((count($this->passed) / $total) * 100);
    }
}

// Run audit if requested
if (isset($_GET['mcb_security_audit']) && current_user_can('manage_options')) {
    $audit = new MCB_Security_Audit();
    $report = $audit->run_audit();
    
    echo '<div class="wrap">';
    echo '<h1>GitHub Code Viewer Security Audit</h1>';
    echo '<div class="notice notice-' . (empty($report['issues']) ? 'success' : 'warning') . '">';
    echo '<p><strong>Security Score: ' . $report['score'] . '%</strong></p>';
    echo '<p>Status: ' . $report['status'] . '</p>';
    echo '</div>';
    
    if (!empty($report['passed'])) {
        echo '<h2>✅ Passed Checks (' . $report['passed_count'] . ')</h2>';
        echo '<ul>';
        foreach ($report['passed'] as $pass) {
            echo '<li style="color: green;">✓ ' . esc_html($pass) . '</li>';
        }
        echo '</ul>';
    }
    
    if (!empty($report['issues'])) {
        echo '<h2>⚠️ Issues Found (' . $report['issues_count'] . ')</h2>';
        echo '<ul>';
        foreach ($report['issues'] as $issue) {
            echo '<li style="color: red;">✗ ' . esc_html($issue) . '</li>';
        }
        echo '</ul>';
    }
    
    echo '<p><em>Audit completed at ' . $report['timestamp'] . '</em></p>';
    echo '</div>';
}
