- Added GitHub spec-kit for development workflow - Standardized file signatures to Descomplicar® format - Updated development configuration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
414 lines
14 KiB
PHP
414 lines
14 KiB
PHP
/**
|
|
* Descomplicar® Crescimento Digital
|
|
* https://descomplicar.pt
|
|
*/
|
|
|
|
<?php
|
|
|
|
/**
|
|
* Integration Test: OAuth Flow
|
|
*
|
|
* Tests the complete OAuth 2.0 authentication flow with Moloni API
|
|
* These tests verify end-to-end OAuth functionality
|
|
*
|
|
* @package DeskMoloni
|
|
* @subpackage Tests\Integration
|
|
* @version 3.0.0
|
|
* @author Descomplicar®
|
|
*/
|
|
|
|
define('BASEPATH', true);
|
|
define('ENVIRONMENT', 'testing');
|
|
|
|
// Mock CI environment for testing
|
|
if (!class_exists('CI_Controller')) {
|
|
class CI_Controller {
|
|
public function __construct() {}
|
|
}
|
|
}
|
|
|
|
echo "\n" . str_repeat("=", 80) . "\n";
|
|
echo "OAUTH FLOW INTEGRATION TESTS\n";
|
|
echo "Testing complete OAuth 2.0 authentication workflow\n";
|
|
echo str_repeat("=", 80) . "\n\n";
|
|
|
|
$test_results = [];
|
|
$start_time = microtime(true);
|
|
|
|
// Test 1: OAuth Library Integration
|
|
echo "1. 🧪 Testing OAuth Library Integration...\n";
|
|
|
|
$oauth_file = __DIR__ . '/../../libraries/Moloni_oauth.php';
|
|
$token_manager_file = __DIR__ . '/../../libraries/TokenManager.php';
|
|
$config_model_file = __DIR__ . '/../../models/Desk_moloni_config_model.php';
|
|
|
|
$integration_score = 0;
|
|
|
|
if (file_exists($oauth_file)) {
|
|
echo " ✅ OAuth library available\n";
|
|
$integration_score++;
|
|
|
|
// Try to include and test basic instantiation
|
|
try {
|
|
require_once $oauth_file;
|
|
if (class_exists('Moloni_oauth')) {
|
|
echo " ✅ OAuth class can be instantiated\n";
|
|
$integration_score++;
|
|
} else {
|
|
echo " ❌ OAuth class not properly defined\n";
|
|
}
|
|
} catch (Exception $e) {
|
|
echo " ❌ OAuth library has syntax errors: " . $e->getMessage() . "\n";
|
|
}
|
|
} else {
|
|
echo " ❌ OAuth library missing\n";
|
|
}
|
|
|
|
if (file_exists($token_manager_file)) {
|
|
echo " ✅ TokenManager library available\n";
|
|
$integration_score++;
|
|
} else {
|
|
echo " ❌ TokenManager library missing\n";
|
|
}
|
|
|
|
if (file_exists($config_model_file)) {
|
|
echo " ✅ Config model available\n";
|
|
$integration_score++;
|
|
} else {
|
|
echo " ❌ Config model missing\n";
|
|
}
|
|
|
|
$test_results['library_integration'] = ($integration_score >= 3);
|
|
|
|
// Test 2: OAuth Configuration Flow
|
|
echo "\n2. 🧪 Testing OAuth Configuration Flow...\n";
|
|
|
|
$config_tests = [
|
|
'client_id_validation' => 'Client ID format validation',
|
|
'client_secret_validation' => 'Client secret format validation',
|
|
'redirect_uri_validation' => 'Redirect URI format validation',
|
|
'scope_validation' => 'OAuth scope validation',
|
|
'endpoint_configuration' => 'API endpoint configuration'
|
|
];
|
|
|
|
$config_score = 0;
|
|
|
|
// Test OAuth parameter validation
|
|
if (file_exists($oauth_file)) {
|
|
$content = file_get_contents($oauth_file);
|
|
|
|
foreach ($config_tests as $test => $description) {
|
|
// Check for validation patterns
|
|
$patterns = [
|
|
'client_id_validation' => 'client_id.*validate|validate.*client_id',
|
|
'client_secret_validation' => 'client_secret.*validate|validate.*client_secret',
|
|
'redirect_uri_validation' => 'redirect_uri.*validate|validate.*redirect',
|
|
'scope_validation' => 'scope.*validate|validate.*scope',
|
|
'endpoint_configuration' => 'auth_url|token_url|api_url'
|
|
];
|
|
|
|
if (isset($patterns[$test]) && preg_match("/{$patterns[$test]}/i", $content)) {
|
|
echo " ✅ {$description} found\n";
|
|
$config_score++;
|
|
} else {
|
|
echo " ❌ {$description} missing\n";
|
|
}
|
|
}
|
|
} else {
|
|
echo " ❌ Cannot test configuration - OAuth library missing\n";
|
|
}
|
|
|
|
$test_results['configuration_flow'] = ($config_score >= 3);
|
|
|
|
// Test 3: Authorization URL Generation
|
|
echo "\n3. 🧪 Testing Authorization URL Generation...\n";
|
|
|
|
$auth_url_components = [
|
|
'base_url' => 'https://api.moloni.pt',
|
|
'response_type' => 'response_type=code',
|
|
'client_id_param' => 'client_id=',
|
|
'redirect_uri_param' => 'redirect_uri=',
|
|
'state_param' => 'state=',
|
|
'pkce_challenge' => 'code_challenge'
|
|
];
|
|
|
|
$auth_url_score = 0;
|
|
|
|
if (file_exists($oauth_file)) {
|
|
$content = file_get_contents($oauth_file);
|
|
|
|
foreach ($auth_url_components as $component => $pattern) {
|
|
if (stripos($content, $pattern) !== false) {
|
|
echo " ✅ {$component} component found\n";
|
|
$auth_url_score++;
|
|
} else {
|
|
echo " ❌ {$component} component missing\n";
|
|
}
|
|
}
|
|
} else {
|
|
echo " ❌ Cannot test authorization URL - OAuth library missing\n";
|
|
}
|
|
|
|
$test_results['authorization_url'] = ($auth_url_score >= 4);
|
|
|
|
// Test 4: Callback Handling
|
|
echo "\n4. 🧪 Testing OAuth Callback Handling...\n";
|
|
|
|
$callback_features = [
|
|
'authorization_code_extraction' => 'code.*GET|GET.*code',
|
|
'state_validation' => 'state.*validate|csrf.*check',
|
|
'error_handling' => 'error.*callback|oauth.*error',
|
|
'token_exchange' => 'access_token|token_exchange'
|
|
];
|
|
|
|
$callback_score = 0;
|
|
|
|
if (file_exists($oauth_file)) {
|
|
$content = file_get_contents($oauth_file);
|
|
|
|
foreach ($callback_features as $feature => $pattern) {
|
|
if (preg_match("/{$pattern}/i", $content)) {
|
|
echo " ✅ {$feature} found\n";
|
|
$callback_score++;
|
|
} else {
|
|
echo " ❌ {$feature} missing\n";
|
|
}
|
|
}
|
|
} else {
|
|
echo " ❌ Cannot test callback handling - OAuth library missing\n";
|
|
}
|
|
|
|
$test_results['callback_handling'] = ($callback_score >= 3);
|
|
|
|
// Test 5: Token Management Integration
|
|
echo "\n5. 🧪 Testing Token Management Integration...\n";
|
|
|
|
$token_features = [
|
|
'token_storage' => 'Token secure storage capability',
|
|
'token_retrieval' => 'Token retrieval capability',
|
|
'token_refresh' => 'Token refresh mechanism',
|
|
'token_validation' => 'Token validation capability',
|
|
'token_encryption' => 'Token encryption capability'
|
|
];
|
|
|
|
$token_score = 0;
|
|
|
|
if (file_exists($token_manager_file)) {
|
|
$content = file_get_contents($token_manager_file);
|
|
|
|
foreach ($token_features as $feature => $description) {
|
|
$patterns = [
|
|
'token_storage' => 'save_token|store_token',
|
|
'token_retrieval' => 'get_token|retrieve_token',
|
|
'token_refresh' => 'refresh_token',
|
|
'token_validation' => 'validate_token|is_valid',
|
|
'token_encryption' => 'encrypt|decrypt'
|
|
];
|
|
|
|
if (isset($patterns[$feature]) && preg_match("/{$patterns[$feature]}/i", $content)) {
|
|
echo " ✅ {$description} found\n";
|
|
$token_score++;
|
|
} else {
|
|
echo " ❌ {$description} missing\n";
|
|
}
|
|
}
|
|
} else {
|
|
echo " ❌ Cannot test token management - TokenManager missing\n";
|
|
}
|
|
|
|
$test_results['token_management'] = ($token_score >= 4);
|
|
|
|
// Test 6: Security Features
|
|
echo "\n6. 🧪 Testing OAuth Security Features...\n";
|
|
|
|
$security_features = [
|
|
'pkce_implementation' => 'PKCE (Proof Key for Code Exchange)',
|
|
'state_parameter' => 'State parameter for CSRF protection',
|
|
'secure_storage' => 'Secure token storage',
|
|
'token_expiration' => 'Token expiration handling',
|
|
'error_sanitization' => 'Error message sanitization'
|
|
];
|
|
|
|
$security_score = 0;
|
|
|
|
if (file_exists($oauth_file)) {
|
|
$content = file_get_contents($oauth_file);
|
|
|
|
foreach ($security_features as $feature => $description) {
|
|
$patterns = [
|
|
'pkce_implementation' => 'pkce|code_verifier|code_challenge',
|
|
'state_parameter' => 'state.*parameter|csrf.*state',
|
|
'secure_storage' => 'encrypt.*token|secure.*storage',
|
|
'token_expiration' => 'expires_in|expiration|token.*valid',
|
|
'error_sanitization' => 'sanitize.*error|clean.*error'
|
|
];
|
|
|
|
if (isset($patterns[$feature]) && preg_match("/{$patterns[$feature]}/i", $content)) {
|
|
echo " ✅ {$description} found\n";
|
|
$security_score++;
|
|
} else {
|
|
echo " ❌ {$description} missing\n";
|
|
}
|
|
}
|
|
} else {
|
|
echo " ❌ Cannot test security features - OAuth library missing\n";
|
|
}
|
|
|
|
$test_results['security_features'] = ($security_score >= 3);
|
|
|
|
// Test 7: API Integration
|
|
echo "\n7. 🧪 Testing API Integration...\n";
|
|
|
|
$api_integration = [
|
|
'http_client' => 'HTTP client for API calls',
|
|
'authentication_headers' => 'Authorization header handling',
|
|
'api_error_handling' => 'API error response handling',
|
|
'rate_limiting' => 'Rate limiting consideration'
|
|
];
|
|
|
|
$api_score = 0;
|
|
|
|
if (file_exists($oauth_file)) {
|
|
$content = file_get_contents($oauth_file);
|
|
|
|
foreach ($api_integration as $feature => $description) {
|
|
$patterns = [
|
|
'http_client' => 'curl|http|request',
|
|
'authentication_headers' => 'Authorization|Bearer.*token',
|
|
'api_error_handling' => 'api.*error|http.*error',
|
|
'rate_limiting' => 'rate.*limit|throttle'
|
|
];
|
|
|
|
if (isset($patterns[$feature]) && preg_match("/{$patterns[$feature]}/i", $content)) {
|
|
echo " ✅ {$description} found\n";
|
|
$api_score++;
|
|
} else {
|
|
echo " ❌ {$description} missing\n";
|
|
}
|
|
}
|
|
} else {
|
|
echo " ❌ Cannot test API integration - OAuth library missing\n";
|
|
}
|
|
|
|
$test_results['api_integration'] = ($api_score >= 3);
|
|
|
|
// Test 8: Error Handling & Recovery
|
|
echo "\n8. 🧪 Testing Error Handling & Recovery...\n";
|
|
|
|
$error_handling = [
|
|
'network_errors' => 'Network connectivity errors',
|
|
'api_errors' => 'API response errors',
|
|
'token_errors' => 'Token-related errors',
|
|
'configuration_errors' => 'Configuration errors',
|
|
'recovery_mechanisms' => 'Error recovery mechanisms'
|
|
];
|
|
|
|
$error_score = 0;
|
|
|
|
if (file_exists($oauth_file)) {
|
|
$content = file_get_contents($oauth_file);
|
|
|
|
foreach ($error_handling as $feature => $description) {
|
|
$patterns = [
|
|
'network_errors' => 'network.*error|connection.*error',
|
|
'api_errors' => 'api.*error|http.*error',
|
|
'token_errors' => 'token.*error|invalid.*token',
|
|
'configuration_errors' => 'config.*error|invalid.*config',
|
|
'recovery_mechanisms' => 'retry|recover|fallback'
|
|
];
|
|
|
|
if (isset($patterns[$feature]) && preg_match("/{$patterns[$feature]}/i", $content)) {
|
|
echo " ✅ {$description} found\n";
|
|
$error_score++;
|
|
} else {
|
|
echo " ❌ {$description} missing\n";
|
|
}
|
|
}
|
|
} else {
|
|
echo " ❌ Cannot test error handling - OAuth library missing\n";
|
|
}
|
|
|
|
$test_results['error_handling'] = ($error_score >= 3);
|
|
|
|
// Generate Final Report
|
|
$execution_time = microtime(true) - $start_time;
|
|
|
|
echo "\n" . str_repeat("=", 80) . "\n";
|
|
echo "OAUTH FLOW INTEGRATION TEST REPORT\n";
|
|
echo str_repeat("=", 80) . "\n";
|
|
|
|
$passed_tests = array_filter($test_results, function($result) {
|
|
return $result === true;
|
|
});
|
|
|
|
$failed_tests = array_filter($test_results, function($result) {
|
|
return $result === false;
|
|
});
|
|
|
|
echo "Execution Time: " . number_format($execution_time, 2) . "s\n";
|
|
echo "Tests Passed: " . count($passed_tests) . "\n";
|
|
echo "Tests Failed: " . count($failed_tests) . "\n";
|
|
|
|
if (count($failed_tests) > 0) {
|
|
echo "\n🔴 INTEGRATION TESTS FAILING\n";
|
|
echo "OAuth flow implementation needs completion\n";
|
|
|
|
echo "\nFailed Integration Areas:\n";
|
|
foreach ($test_results as $test => $result) {
|
|
if ($result === false) {
|
|
echo " ❌ " . ucwords(str_replace('_', ' ', $test)) . "\n";
|
|
}
|
|
}
|
|
} else {
|
|
echo "\n🟢 ALL INTEGRATION TESTS PASSING\n";
|
|
echo "OAuth flow implementation is complete and functional\n";
|
|
}
|
|
|
|
echo "\n📋 OAUTH FLOW REQUIREMENTS:\n";
|
|
echo " 1. Complete OAuth 2.0 library implementation\n";
|
|
echo " 2. Secure PKCE implementation for enhanced security\n";
|
|
echo " 3. Robust token management and encryption\n";
|
|
echo " 4. Comprehensive error handling and recovery\n";
|
|
echo " 5. API integration with proper authentication\n";
|
|
echo " 6. Configuration validation and management\n";
|
|
echo " 7. State parameter for CSRF protection\n";
|
|
echo " 8. Callback handling with proper validation\n";
|
|
|
|
echo "\n🎯 OAUTH SUCCESS CRITERIA:\n";
|
|
echo " - Complete authorization flow with Moloni API\n";
|
|
echo " - Secure token storage and management\n";
|
|
echo " - PKCE implementation for security\n";
|
|
echo " - Automatic token refresh capability\n";
|
|
echo " - Comprehensive error handling\n";
|
|
echo " - State validation for CSRF protection\n";
|
|
echo " - Proper API integration\n";
|
|
|
|
echo "\n🔄 OAUTH FLOW STEPS:\n";
|
|
echo " 1. Configuration → Set client credentials and endpoints\n";
|
|
echo " 2. Authorization → Generate authorization URL with PKCE\n";
|
|
echo " 3. User Consent → Redirect to Moloni for user authorization\n";
|
|
echo " 4. Callback → Handle authorization code and state validation\n";
|
|
echo " 5. Token Exchange → Exchange code for access/refresh tokens\n";
|
|
echo " 6. Token Storage → Securely store encrypted tokens\n";
|
|
echo " 7. API Access → Use tokens for authenticated API calls\n";
|
|
echo " 8. Token Refresh → Automatically refresh expired tokens\n";
|
|
|
|
// Save results
|
|
$reports_dir = __DIR__ . '/../reports';
|
|
if (!is_dir($reports_dir)) {
|
|
mkdir($reports_dir, 0755, true);
|
|
}
|
|
|
|
$report_file = $reports_dir . '/oauth_flow_integration_test_' . date('Y-m-d_H-i-s') . '.json';
|
|
file_put_contents($report_file, json_encode([
|
|
'timestamp' => date('Y-m-d H:i:s'),
|
|
'test_type' => 'oauth_flow_integration',
|
|
'status' => count($failed_tests) > 0 ? 'failing' : 'passing',
|
|
'results' => $test_results,
|
|
'execution_time' => $execution_time,
|
|
'integration_areas' => count($test_results),
|
|
'oauth_flow_steps' => 8
|
|
], JSON_PRETTY_PRINT));
|
|
|
|
echo "\n📄 Integration test results saved to: {$report_file}\n";
|
|
echo str_repeat("=", 80) . "\n"; |