| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- import dotenv from 'dotenv';
- import axios from 'axios';
- // Lade Umgebungsvariablen
- dotenv.config();
- // Konfigurationskonstanten
- 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';
- // Client IDs aus Umgebungsvariablen
- const NEXTCLOUD_CLIENT_ID = process.env.NEXTCLOUD_CLIENT_ID || 'nextcloud';
- const PAPERLESS_CLIENT_ID = process.env.PAPERLESS_CLIENT_ID || 'paperless';
- const NODERED_CLIENT_ID = process.env.NODERED_CLIENT_ID || 'nodered';
- // Hilfsfunktion für API-Fehlerbehandlung
- 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;
- };
- // Admin Token abrufen
- async function getAdminToken() {
- 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'
- }
- }
- );
- return response.data.access_token;
- } catch (error) {
- handleAxiosError(error, 'getting admin token');
- }
- }
- // Funktion um Client Infos abzufragen
- async function getClient(token, clientId) {
- try {
- const response = await axios.get(
- `${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients`,
- {
- headers: {
- 'Authorization': `Bearer ${token}`
- },
- params: {
- clientId: clientId
- }
- }
- );
- if (response.data.length === 0) {
- console.error(`Client ${clientId} not found`);
- return null;
- }
- return response.data[0];
- } catch (error) {
- handleAxiosError(error, `getting client ${clientId}`);
- }
- }
- // Funktion um Client Mapper abzufragen
- async function getClientMappers(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}/protocol-mappers/models`,
- {
- headers: {
- 'Authorization': `Bearer ${token}`
- }
- }
- );
- return response.data;
- } catch (error) {
- handleAxiosError(error, `getting client mappers for ${clientId}`, error.config, error.response);
- return [];
- }
- }
- async function ensureClientMappers(token, clientId) {
- const client = await getClient(token, clientId);
- if (!client) {
- return console.error(`Client ${clientId} not found, can't create mappers.`);
- }
- let existingMappers = await getClientMappers(token, clientId)
- const requiredMappers = [
- {
- name: "groups",
- protocol: "openid-connect",
- protocolMapper: "oidc-group-membership-mapper",
- config: {
- "full.path": "true",
- "id.token.claim": "true",
- "access.token.claim": "true",
- "userinfo.token.claim": "true",
- "claim.name": "groups"
- }
- },
- {
- name: "realm roles",
- protocol: "openid-connect",
- protocolMapper: "oidc-usermodel-realm-role-mapper",
- config: {
- "id.token.claim": "true",
- "access.token.claim": "true",
- "userinfo.token.claim": "true",
- "claim.name": "roles",
- "jsonType.label": "String",
- "multivalued": "true"
- }
- }
- ];
- for (const mapper of requiredMappers) {
- const existingMapper = existingMappers.find(m => m.name === mapper.name);
- try {
- if (existingMapper) {
- // Update existierenden Mapper
- await axios.put(
- `${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients/${client.id}/protocol-mappers/models/${existingMapper.id}`,
- { ...existingMapper, ...mapper },
- {
- headers: {
- 'Authorization': `Bearer ${token}`,
- 'Content-Type': 'application/json'
- }
- }
- );
- console.log(`Mapper ${mapper.name} updated for client ${clientId}`);
- } else {
- // Erstelle neuen Mapper
- await axios.post(
- `${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients/${client.id}/protocol-mappers/models`,
- mapper,
- {
- headers: {
- 'Authorization': `Bearer ${token}`,
- 'Content-Type': 'application/json'
- }
- }
- );
- console.log(`Mapper ${mapper.name} created for client ${clientId}`);
- }
- } catch (error) {
- handleAxiosError(error, `managing mapper ${mapper.name} for client ${clientId}`, error.config, error.response);
- // Wir werfen den Fehler nicht weiter, damit andere Mapper noch verarbeitet werden können
- }
- }
- // Get Mappers and log
- existingMappers = await getClientMappers(token, clientId);
- console.log(`Current Mappers for Client ${clientId}:`, existingMappers.map(mapper => ({name: mapper.name, id: mapper.id})));
- }
- // Hauptfunktion
- async function main() {
- try {
- console.log('Starting Client Mapper Check...');
- const token = await getAdminToken();
- // Clients erstellen
- const clients = [
- NEXTCLOUD_CLIENT_ID,
- PAPERLESS_CLIENT_ID,
- NODERED_CLIENT_ID
- ];
- for (const client of clients) {
- await ensureClientMappers(token, client);
- }
- console.log('Client Mapper Check completed successfully');
- } catch (error) {
- console.error('Client Mapper Check failed:', error);
- process.exit(1);
- }
- }
- // Script ausführen
- main();
|