274 lines
12 KiB
HTML
274 lines
12 KiB
HTML
<!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> |