mrx8086 11 місяців тому
батько
коміт
579430d44b
2 змінених файлів з 106 додано та 29 видалено
  1. 84 3
      scripts/setup/keycloak/setup_realm.js
  2. 22 26
      scripts/setup/keycloak/test_realm.js

+ 84 - 3
scripts/setup/keycloak/setup_realm.js

@@ -25,7 +25,7 @@ const CLIENTS = {
 
 // Hilfsfunktion für API-Fehlerbehandlung
 const handleAxiosError = (error, operation, config, response) => {
-     console.error(`Error during ${operation}:`);
+    console.error(`Error during ${operation}:`);
     if (config) {
       console.error('Request:', {
           method: config.method,
@@ -120,6 +120,7 @@ async function checkClientExists(token, clientId) {
     return !!client;
 }
 
+
 async function getClientMappers(token, clientId) {
     try {
         const client = await getClient(token, clientId);
@@ -141,6 +142,83 @@ async function getClientMappers(token, clientId) {
     }
 }
 
+async function getClientScopes(token, clientId){
+    try {
+        const client = await getClient(token, clientId);
+        if(!client)
+            return [];
+
+        const response = await axios.get(
+            `${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients/${client.id}/client-scopes`,
+            {
+                 headers: {
+                        'Authorization': `Bearer ${token}`
+                    }
+            }
+        );
+
+        return response.data;
+
+    } catch(error){
+      handleAxiosError(error, `getting client scopes for ${clientId}`, error.config, error.response);
+        return [];
+    }
+}
+
+async function getClientScope(token, 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.error(`Client Scope ${scopeName} not found`);
+            return null;
+        }
+
+        return response.data[0]
+    } catch (error){
+        handleAxiosError(error, `getting client scope ${scopeName}`, error.config, error.response);
+        return null;
+    }
+}
+
+async function addDefaultClientScope(token, clientId, scopeName){
+    try {
+        const client = await getClient(token, clientId);
+        const scope = await getClientScope(token, scopeName);
+         if(!client || !scope){
+           return null;
+         }
+
+
+        await axios.put(
+                `${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients/${client.id}/default-client-scopes/${scope.id}`,
+                null,
+                {
+                  headers: {
+                        'Authorization': `Bearer ${token}`,
+                        'Content-Type': 'application/json'
+                    }
+               }
+        );
+
+        console.log(`Client scope ${scopeName} added as default scope for client ${clientId}`)
+
+    } catch(error){
+       handleAxiosError(error, `adding client scope ${scopeName} as default for client ${clientId}`);
+    }
+}
+
+
 // Realm erstellen
 async function createRealm(token) {
     const realmConfig = {
@@ -390,7 +468,7 @@ async function createDefaultGroups(token) {
 
 async function createTestToken(token, username) {
     try {
-        const nextcloudClientId = Object.keys(CLIENTS).find(key => key.includes('nextcloud')) || 'nextcloud';
+         const nextcloudClientId = Object.keys(CLIENTS).find(key => key.includes('nextcloud')) || 'nextcloud';
          const client = await getClient(token, nextcloudClientId);
 
         if (!client)
@@ -523,10 +601,13 @@ async function setupRealm() {
         }
 
         // Clients erstellen
-         for (const clientId in CLIENTS) {
+        for (const clientId in CLIENTS) {
             await createClient(token, clientId, clientId, CLIENTS[clientId].redirectUris);
         }
 
+       const nextcloudClientId = Object.keys(CLIENTS).find(key => key.includes('nextcloud')) || 'nextcloud';
+        await addDefaultClientScope(token, nextcloudClientId, "openid");
+
         // Gruppen erstellen
         await createDefaultGroups(token);
 

+ 22 - 26
scripts/setup/keycloak/test_realm.js

@@ -5,13 +5,10 @@ dotenv.config();
 
 const KEYCLOAK_URL = process.env.KEYCLOAK_URL || 'https://auth.mrx8086.com';
 const NEXTCLOUD_CLIENT_ID = process.env.NEXTCLOUD_CLIENT_ID || 'nextcloud';
-const CLIENT_SECRET = process.env.KEYCLOAK_NEXTCLOUD_CLIENT_SECRET;
 const TESTADMIN_USERNAME = "testadmin@mrx8086.com";
 const TESTADMIN_PASSWORD = process.env.TESTADMIN_PASSWORD || "initial123!";
 const REALM_NAME = 'office-automation';
-
-
-
+const CLIENT_SECRET = process.env.KEYCLOAK_NEXTCLOUD_CLIENT_SECRET;
 
 // Hilfsfunktion für API-Fehlerbehandlung
 const handleAxiosError = (error, operation, config, response) => {
@@ -37,29 +34,28 @@ const handleAxiosError = (error, operation, config, response) => {
 
 // Funktion um den Access Token abzufragen
 async function getAccessToken(username, password) {
-    try {
-      const response = await axios.post(
-        `${KEYCLOAK_URL}/realms/${REALM_NAME}/protocol/openid-connect/token`,
-        new URLSearchParams({
-          client_id: NEXTCLOUD_CLIENT_ID,
-          client_secret: CLIENT_SECRET,
-          grant_type: 'password',
-          username: username,
-          password: password,
-          scope: "openid profile email groups",
-        }),
-        {
-          headers: {
-            'Content-Type': 'application/x-www-form-urlencoded',
-          },
-        }
-      );
-      return response.data.access_token;
-    } catch (error) {
-        handleAxiosError(error, 'getting access token', error.config, error.response);
-        return null;
-    }
+  try {
+    const response = await axios.post(
+      `${KEYCLOAK_URL}/realms/${REALM_NAME}/protocol/openid-connect/token`,
+      new URLSearchParams({
+        client_id: NEXTCLOUD_CLIENT_ID,
+        client_secret: CLIENT_SECRET,
+        grant_type: 'password',
+        username: username,
+        password: password,
+      }),
+      {
+        headers: {
+          'Content-Type': 'application/x-www-form-urlencoded',
+        },
+      }
+    );
+    return response.data.access_token;
+  } catch (error) {
+      handleAxiosError(error, 'getting access token', error.config, error.response);
+      return null;
   }
+}
 
 
 // Funktion zum Decodieren eines JWT-Tokens