{ "name": "Keycloak User Creation", "nodes": [ { "parameters": { "path": "create-user", "options": { "responseMode": "lastNode", "responseData": "allEntries" } }, "name": "Webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 1, "position": [ 100, 300 ], "webhookId": "create-user-webhook" }, { "parameters": { "url": "https://connect.slm-lab.net/admin/realms/cercle/users", "options": {}, "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "nodeCredentialType": "httpHeaderAuth", "headerParameters": { "parameters": [ { "name": "Authorization", "value": "={{$node[\"Get Admin Token\"].json[\"access_token\"]}}" } ] } }, "name": "HTTP Request", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ 500, 300 ] }, { "parameters": { "url": "https://connect.slm-lab.net/realms/cercle/protocol/openid-connect/token", "options": {}, "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "nodeCredentialType": "httpHeaderAuth", "headerParameters": { "parameters": [ { "name": "Content-Type", "value": "application/x-www-form-urlencoded" } ] }, "bodyParameters": { "parameters": [ { "name": "grant_type", "value": "client_credentials" }, { "name": "client_id", "value": "lab" }, { "name": "client_secret", "value": "LwgeE1ntADD20OuWC88S3pR0EaO7FtO4" } ] } }, "name": "Get Admin Token", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ 300, 300 ] }, { "parameters": { "conditions": { "string": [ { "value1": "={{$json[\"isValid\"]}}", "value2": "false" } ] } }, "name": "IF", "type": "n8n-nodes-base.if", "typeVersion": 1, "position": [ 300, 500 ] }, { "parameters": { "functionCode": "// Validate username according to Keycloak requirements\nconst username = $input.item.json.username;\n\n// Keycloak username requirements:\n// - Only alphanumeric characters, dots (.), hyphens (-), and underscores (_)\n// - Must start with a letter or number\n// - Must be between 3 and 255 characters\nconst usernameRegex = /^[a-zA-Z0-9][a-zA-Z0-9._-]{2,254}$/;\n\nif (!usernameRegex.test(username)) {\n return {\n isValid: false,\n error: \"Le nom d'utilisateur doit commencer par une lettre ou un chiffre, ne contenir que des lettres, chiffres, points, tirets et underscores, et faire entre 3 et 255 caractères\"\n };\n}\n\nreturn { isValid: true };" }, "name": "Validate Username", "type": "n8n-nodes-base.function", "typeVersion": 1, "position": [ 300, 400 ] }, { "parameters": { "url": "https://connect.slm-lab.net/admin/realms/cercle/roles", "options": {} }, "name": "Get Available Roles", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ 500, 400 ] }, { "parameters": { "functionCode": "// Filter valid roles\nconst requestedRoles = $input.item.json.roles || [];\nconst availableRoles = $input.item.json.roles;\n\nconst validRoles = requestedRoles.filter(roleName => \n availableRoles.some(r => r.name === roleName)\n);\n\nif (validRoles.length === 0) {\n return {\n isValid: false,\n error: \"Aucun rôle valide n'a été spécifié\"\n };\n}\n\nreturn {\n isValid: true,\n validRoles: validRoles,\n roleObjects: validRoles.map(roleName => \n availableRoles.find(r => r.name === roleName)\n )\n};" }, "name": "Validate Roles", "type": "n8n-nodes-base.function", "typeVersion": 1, "position": [ 700, 400 ] }, { "parameters": { "url": "https://connect.slm-lab.net/admin/realms/cercle/users", "options": {}, "body": { "username": "={{$input.item.json.username}}", "enabled": true, "emailVerified": true, "firstName": "={{$input.item.json.firstName}}", "lastName": "={{$input.item.json.lastName}}", "email": "={{$input.item.json.email}}", "credentials": [ { "type": "password", "value": "={{$input.item.json.password}}", "temporary": false } ] } }, "name": "Create User", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ 900, 400 ] }, { "parameters": { "url": "https://connect.slm-lab.net/admin/realms/cercle/users?username={{$input.item.json.username}}", "options": {} }, "name": "Get Created User", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ 1100, 400 ] }, { "parameters": { "url": "https://connect.slm-lab.net/admin/realms/cercle/users/{{$input.item.json[0].id}}/role-mappings/realm", "options": {}, "body": "={{$input.item.json.roleObjects}}" }, "name": "Assign Roles", "type": "n8n-nodes-base.httpRequest", "typeVersion": 3, "position": [ 1300, 400 ] }, { "parameters": { "functionCode": "// Format success response\nreturn {\n success: true,\n user: {\n ...$input.item.json[0],\n roles: $input.item.json.validRoles\n }\n};" }, "name": "Format Response", "type": "n8n-nodes-base.function", "typeVersion": 1, "position": [ 1500, 400 ] }, { "parameters": { "functionCode": "// Format error response\nreturn {\n success: false,\n error: $input.item.json.error\n};" }, "name": "Format Error", "type": "n8n-nodes-base.function", "typeVersion": 1, "position": [ 500, 600 ] } ], "connections": { "Webhook": { "main": [ [ { "node": "Get Admin Token", "type": "main", "index": 0 } ] ] }, "Get Admin Token": { "main": [ [ { "node": "HTTP Request", "type": "main", "index": 0 }, { "node": "Validate Username", "type": "main", "index": 0 } ] ] }, "Validate Username": { "main": [ [ { "node": "IF", "type": "main", "index": 0 } ] ] }, "IF": { "main": [ [ { "node": "Format Error", "type": "main", "index": 0 } ], [ { "node": "Get Available Roles", "type": "main", "index": 0 } ] ] }, "Get Available Roles": { "main": [ [ { "node": "Validate Roles", "type": "main", "index": 0 } ] ] }, "Validate Roles": { "main": [ [ { "node": "Create User", "type": "main", "index": 0 } ] ] }, "Create User": { "main": [ [ { "node": "Get Created User", "type": "main", "index": 0 } ] ] }, "Get Created User": { "main": [ [ { "node": "Assign Roles", "type": "main", "index": 0 } ] ] }, "Assign Roles": { "main": [ [ { "node": "Format Response", "type": "main", "index": 0 } ] ] } }, "settings": { "executionOrder": "v1" }, "version": 1 }