Files
skybridge/test/sso_manual_test.html
2025-08-26 19:15:37 -04:00

274 lines
12 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KMS SSO Manual Testing</title>
<style>
body { font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; background: #f5f5f5; }
.container { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
h1 { color: #333; border-bottom: 3px solid #007acc; padding-bottom: 10px; }
h2 { color: #007acc; margin-top: 30px; }
.test-section { margin: 20px 0; padding: 20px; border: 1px solid #ddd; border-radius: 5px; background: #fafafa; }
.btn { display: inline-block; padding: 12px 20px; margin: 10px 5px; background: #007acc; color: white; text-decoration: none; border-radius: 5px; font-weight: bold; }
.btn:hover { background: #005a9e; }
.btn-secondary { background: #28a745; }
.btn-warning { background: #ffc107; color: #333; }
.status { padding: 10px; margin: 10px 0; border-radius: 3px; }
.status.success { background: #d4edda; border: 1px solid #c3e6cb; color: #155724; }
.status.error { background: #f8d7da; border: 1px solid #f5c6cb; color: #721c24; }
.status.info { background: #d1ecf1; border: 1px solid #bee5eb; color: #0c5460; }
.code { background: #f8f9fa; padding: 15px; border-radius: 5px; font-family: monospace; margin: 10px 0; overflow-x: auto; }
.endpoint { margin: 10px 0; }
.endpoint strong { color: #007acc; }
pre { background: #f8f9fa; padding: 15px; border-radius: 5px; overflow-x: auto; }
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin: 20px 0; }
.card { padding: 20px; border: 1px solid #ddd; border-radius: 5px; background: white; }
.user-info { background: #e7f3ff; padding: 10px; border-radius: 5px; margin: 10px 0; }
</style>
</head>
<body>
<div class="container">
<h1>🔐 KMS SSO Manual Testing Suite</h1>
<div class="status info">
<strong>Environment Status:</strong> Local Development
<div id="services-status">Loading service status...</div>
</div>
<div class="grid">
<div class="card">
<h2>🎯 OAuth2/OIDC Testing (Keycloak)</h2>
<div class="user-info">
<strong>Test Users:</strong><br>
• admin@example.com / admin123 (Full access)<br>
• test@example.com / test123 (Limited access)<br>
• limited@example.com / limited123 (Read-only)
</div>
<div class="endpoint">
<strong>Admin Console:</strong><br>
<a href="http://localhost:8090" target="_blank" class="btn">Open Keycloak Admin</a>
<small>Login: admin / admin</small>
</div>
<div class="endpoint">
<strong>OAuth2 Authorization Flow:</strong><br>
<a href="http://localhost:8090/realms/kms/protocol/openid-connect/auth?client_id=kms-api&response_type=code&redirect_uri=http://localhost:3000/callback&scope=openid+email+profile&state=test123" target="_blank" class="btn">Test OAuth2 Login</a>
</div>
<div class="endpoint">
<strong>Discovery Document:</strong><br>
<a href="http://localhost:8090/realms/kms/.well-known/openid-configuration" target="_blank" class="btn btn-secondary">View OIDC Config</a>
</div>
</div>
<div class="card">
<h2>📝 SAML Testing (SimpleSAMLphp)</h2>
<div class="user-info">
<strong>Test Users:</strong><br>
• user1 / user1pass<br>
• user2 / user2pass
</div>
<div class="endpoint">
<strong>Admin Console:</strong><br>
<a href="http://localhost:8091/simplesaml" target="_blank" class="btn">Open SAML Admin</a>
<small>Login: admin / secret</small>
</div>
<div class="endpoint">
<strong>SAML Metadata:</strong><br>
<a href="http://localhost:8091/simplesaml/saml2/idp/metadata.php" target="_blank" class="btn btn-secondary">View Metadata</a>
</div>
<div class="endpoint">
<strong>Test Authentication:</strong><br>
<a href="http://localhost:8091/simplesaml/module.php/core/authenticate.php?as=default-sp" target="_blank" class="btn">Test SAML Login</a>
</div>
</div>
</div>
<div class="test-section">
<h2>🚀 KMS API Testing</h2>
<div class="endpoint">
<strong>Frontend Application:</strong><br>
<a href="http://localhost:3000" target="_blank" class="btn">Open KMS Frontend</a>
</div>
<div class="endpoint">
<strong>API Health Check:</strong><br>
<a href="http://localhost:8081/health" target="_blank" class="btn btn-secondary">Check API Health</a>
</div>
<div class="code">
<strong>Test API with Header Auth (simulates SSO result):</strong>
<pre id="api-test-command">curl -H "X-User-Email: admin@example.com" \
-H "Accept: application/json" \
http://localhost:8081/api/applications</pre>
<button onclick="testAPI()" class="btn">Run API Test</button>
<div id="api-result"></div>
</div>
</div>
<div class="test-section">
<h2>🔍 Testing Workflows</h2>
<h3>1. OAuth2 Flow Test</h3>
<ol>
<li>Click "Test OAuth2 Login" above</li>
<li>Login with admin@example.com / admin123</li>
<li>You'll be redirected to your callback URL with an authorization code</li>
<li>Note: This currently shows a 404 because the callback isn't implemented yet</li>
</ol>
<h3>2. SAML Flow Test</h3>
<ol>
<li>Open "SAML Admin" console</li>
<li>Go to "Authentication" → "Test authentication"</li>
<li>Login with user1 / user1pass</li>
<li>View the SAML assertion that would be sent to your app</li>
</ol>
<h3>3. Permission System Test</h3>
<ol>
<li>Use the API test above with different user emails</li>
<li>Try: admin@example.com, test@example.com, limited@example.com</li>
<li>See how responses differ based on user permissions</li>
</ol>
</div>
<div class="test-section">
<h2>📊 Current Implementation Status</h2>
<div class="status success">
<strong>✅ Working:</strong><br>
• Keycloak OAuth2/OIDC provider with test realm<br>
• SimpleSAMLphp SAML IdP with test users<br>
• KMS API with header authentication<br>
• Hierarchical permission system (25+ permissions)<br>
• Application and token management<br>
• Database with proper permission structure
</div>
<div class="status error">
<strong>❌ Missing:</strong><br>
• OAuth2 callback handler in KMS API<br>
• SAML assertion processing in KMS API<br>
• Frontend SSO login integration<br>
• Automatic permission mapping from SSO claims
</div>
<div class="status info">
<strong> Next Steps:</strong><br>
• Complete OAuth2 callback implementation<br>
• Add SAML response handling<br>
• Map SSO user attributes to KMS permissions<br>
• Add SSO login buttons to frontend
</div>
</div>
<div class="test-section">
<h2>🛠️ Development Commands</h2>
<div class="code">
<pre># Start SSO services
podman-compose -f docker-compose.yml -f docker-compose.sso.yml up -d
# Run automated tests
./test/quick_sso_test.sh
# Check service logs
podman-compose logs keycloak
podman-compose logs saml-idp
podman-compose logs api-service
# Reset to header auth mode
podman-compose up -d</pre>
</div>
</div>
</div>
<script>
// Check service status
async function checkServiceStatus() {
const services = [
{ name: 'KMS API', url: 'http://localhost:8081/health', expected: 'healthy' },
{ name: 'Keycloak', url: 'http://localhost:8090', expected: null },
{ name: 'SAML IdP', url: 'http://localhost:8091/simplesaml', expected: null }
];
let statusHtml = '<br>';
for (const service of services) {
try {
const response = await fetch(service.url, { mode: 'cors' });
const text = await response.text();
if (service.expected && text === service.expected) {
statusHtml += `<span style="color: green;">✅ ${service.name}: Healthy</span><br>`;
} else if (response.ok) {
statusHtml += `<span style="color: green;">✅ ${service.name}: Online</span><br>`;
} else {
statusHtml += `<span style="color: orange;">⚠️ ${service.name}: Response ${response.status}</span><br>`;
}
} catch (error) {
statusHtml += `<span style="color: red;">❌ ${service.name}: Not accessible (CORS/Network)</span><br>`;
}
}
document.getElementById('services-status').innerHTML = statusHtml;
}
// Test API with header auth
async function testAPI() {
const resultDiv = document.getElementById('api-result');
resultDiv.innerHTML = '<div style="color: blue;">Testing API...</div>';
try {
const response = await fetch('http://localhost:8081/api/applications', {
headers: {
'X-User-Email': 'admin@example.com',
'Accept': 'application/json'
},
mode: 'cors'
});
if (response.ok) {
const data = await response.json();
resultDiv.innerHTML = `
<div class="status success">
<strong>✅ API Test Successful!</strong><br>
Found ${data.count} applications<br>
<details>
<summary>View Response</summary>
<pre>${JSON.stringify(data, null, 2)}</pre>
</details>
</div>
`;
} else {
resultDiv.innerHTML = `
<div class="status error">
<strong>❌ API Test Failed</strong><br>
Status: ${response.status} ${response.statusText}
</div>
`;
}
} catch (error) {
resultDiv.innerHTML = `
<div class="status error">
<strong>❌ API Test Error</strong><br>
${error.message}<br>
<small>Note: This might be due to CORS policy. Try the curl command instead.</small>
</div>
`;
}
}
// Check status on load
window.addEventListener('load', checkServiceStatus);
</script>
</body>
</html>