| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- import dotenv from 'dotenv';
- import axios from 'axios';
- // Load environment variables
- dotenv.config();
- console.log('Environment variables loaded.');
- // Configuration constants
- const KEYCLOAK_URL = process.env.KEYCLOAK_URL || 'https://auth.mrx8086.com';
- const ADMIN_USERNAME = process.env.KEYCLOAK_ADMIN_USER;
- const ADMIN_PASSWORD = process.env.KEYCLOAK_ADMIN_PASSWORD;
- const REALM_NAME = 'office-automation';
- console.log('Configuration constants set:', { KEYCLOAK_URL, ADMIN_USERNAME, REALM_NAME });
- // Helper function for API error handling
- const handleAxiosError = (error, operation, config, response) => {
- console.error(`Error during ${operation}:`);
- if (config) {
- console.error('Request:', {
- method: config.method,
- url: config.url,
- headers: config.headers,
- data: config.data,
- });
- }
- if (error.response) {
- console.error('Response:', {
- status: error.response.status,
- data: error.response.data
- });
- } else {
- console.error('Error Message:', error.message);
- }
- throw error;
- };
- // Get Admin Token
- async function getAdminToken() {
- console.log('Getting admin token...');
- try {
- const response = await axios.post(
- `${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token`,
- new URLSearchParams({
- 'client_id': 'admin-cli',
- 'username': ADMIN_USERNAME,
- 'password': ADMIN_PASSWORD,
- 'grant_type': 'password'
- }),
- {
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded'
- }
- }
- );
- console.log('Admin token received.');
- return response.data.access_token;
- } catch (error) {
- handleAxiosError(error, 'getting admin token');
- }
- }
- async function getClientScope(token, scopeName) {
- console.log(`Getting client scope "${scopeName}"...`);
- try {
- const response = await axios.get(
- `${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/client-scopes`,
- {
- headers: {
- 'Authorization': `Bearer ${token}`
- },
- params: {
- name: scopeName
- }
- }
- );
- if (response.data.length === 0) {
- console.log(`Client Scope "${scopeName}" not found.`);
- return null;
- }
- console.log(`Client scope "${scopeName}" found:`, response.data);
- return response.data[0];
- } catch (error) {
- handleAxiosError(error, `getting client scope "${scopeName}"`, error.config, error.response);
- return null;
- }
- }
- async function createClientScope(token, scopeName, consentScreenText) {
- console.log(`Attempting to create client scope "${scopeName}"...`);
- try {
- const response = await axios.post(`${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/client-scopes`,
- {
- "name": scopeName,
- "protocol": "openid-connect",
- "attributes": {},
- "consentScreenText": consentScreenText,
- "includeInTokenScope": true
- },
- {
- headers: {
- 'Authorization': `Bearer ${token}`,
- 'Content-Type': 'application/json'
- }
- });
- console.log(`Client scope "${scopeName}" created successfully`);
- return response.data;
- } catch (error) {
- console.error(`Error creating client scope "${scopeName}":`, error);
- handleAxiosError(error, `creating ${scopeName} client scope`, error.config, error.response);
- return null;
- }
- }
- async function createMapper(token, clientScopeId, mapperName) {
- console.log(`Attempting to create mapper "${mapperName}" for client scope ID "${clientScopeId}"...`);
- try {
- const response = await axios.post(`${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/client-scopes/${clientScopeId}/protocol-mappers/models`,
- {
- "name": mapperName,
- "protocol": "openid-connect",
- "protocolMapper": "oidc-group-membership-mapper",
- "config": {
- "full.path": "false",
- "id.token.claim": "false",
- "access.token.claim": "true",
- "userinfo.token.claim": "true",
- "claim.name": "groups",
- "add.to.introspection": "false"
- }
- },
- {
- headers: {
- 'Authorization': `Bearer ${token}`,
- 'Content-Type': 'application/json'
- }
- });
- console.log(`Mapper "${mapperName}" created for client scope ID "${clientScopeId}"`);
- return response.data;
- } catch (error) {
- console.error(`Error creating mapper "${mapperName}" for client scope ID "${clientScopeId}":`, error);
- handleAxiosError(error, `creating mapper "${mapperName}"`, error.config, error.response);
- return null;
- }
- }
- async function createGroupsNextcloudScope(token) {
- const scopeName = "groups-nextcloud-test";
- const mapperName = "groups-mapper-test";
- console.log("Starting createGroupsNextcloudScope");
- let clientScope = await getClientScope(token, scopeName);
- if (!clientScope) {
- clientScope = await createClientScope(token, scopeName, "Grant access to user groups in nextcloud");
- } else {
- console.log(`Client scope "${scopeName}" exists, skipping creation. Details:`, clientScope);
- }
- if (clientScope) {
- console.log("Check for mappers in groups-nextcloud-test scope");
- try {
- const mappersResponse = await axios.get(`${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/client-scopes/${clientScope.id}/protocol-mappers/models`,
- {
- headers: {
- 'Authorization': `Bearer ${token}`
- }
- });
- if (!mappersResponse.data.find(m => m.name === mapperName)) {
- await createMapper(token, clientScope.id, mapperName);
- } else {
- console.log(`Mapper "${mapperName}" exists, skipping creation. Details:`, mappersResponse.data.find(m => m.name === mapperName));
- }
- } catch (error) {
- console.error("Error checking for mappers:", error);
- handleAxiosError(error, `checking mappers for ${scopeName}`, error.config, error.response);
- }
- }
- console.log("Finished createGroupsNextcloudScope");
- }
- async function createSimpleTestScope(token) {
- const uniqueSuffix = Date.now();
- const simpleScopeName = `test-simple-scope-${uniqueSuffix}`;
- console.log(`Attempting to create simple test scope with name: ${simpleScopeName}`);
- const simpleScope = await createClientScope(token, simpleScopeName, "Simple test scope");
- if (simpleScope) {
- console.log(`Successfully created simple test scope:`, simpleScope);
- }
- }
- // Main function
- async function setupRealm() {
- try {
- console.log('Starting Keycloak setup...');
- const token = await getAdminToken();
- // Create a simple test client scope
- await createSimpleTestScope(token);
- // Create client scope groups-nextcloud
- await createGroupsNextcloudScope(token);
- console.log('Setup completed successfully');
- } catch (error) {
- console.error('Setup failed:', error);
- process.exit(1);
- }
- }
- // Execute the script
- setupRealm();
|