diff --git a/modules/account/back/models/samba-config.js b/modules/account/back/models/samba-config.js index 38a2555fb..047bedd4f 100644 --- a/modules/account/back/models/samba-config.js +++ b/modules/account/back/models/samba-config.js @@ -172,185 +172,199 @@ module.exports = Self => { await this.adClient.searchForeach(this.fullUsersDn, opts, o => usersToSync.add(o.sAMAccountName)); }, - deleteRole(role) { - return this.sambaTool('group', ['delete', role]); - }, - addRole({description, name}) { - return this.sambaTool('group', - ['add', `${ROLE_PREFIX}${name}`, `--groupou=${this.groupDn}`, `--description=${description}`]); - }, - getRoleMembers(role) { - return this.getMembers(`(cn=${role})`, this.fullGroupsDn); - }, - getMembers(filter = '', type = this.fullUsersDn) { - const options = { - scope: 'sub', - attributes: ['cn', 'member', 'member.cn'] - }; - if (filter !== '') - Object.assign(options, {filter}); - return this.adClient.searchAll(type, options); - }, - removeMembers(role, user) { - return this.sambaTool('group', ['removemembers', role, user]); - }, - addMembers(role, user) { - return this.sambaTool('group', ['addmembers', role, user]); - }, - handleRoleMembers(users) { - if (users.length === 0) return []; - let members = users[0]?.member; - if (!members) return []; - if (!Array.isArray(members))members = [members]; - return members.map((member => member.match(/CN=(.*?),(.*)/)[1])); - }, - async handleUsersRole(role, currentUsers, users) { - const forbiddenUsers = ['guest']; - users = users.filter(u => !u.includes(forbiddenUsers)); - const usersToDelete = differences(currentUsers, users); - if (usersToDelete.length > 0) { - const results = await Promise.all(usersToDelete.map(user => - this.removemembers(role, user))); - printResults(results); - } - const usersToInsert = differences(users, currentUsers); - if (usersToInsert.length > 0) { - const results = await Promise.all(usersToInsert.map(user => - this.addmembers(role, user))); - printResults(results); - } - }, async syncRoles() { await this.init(); - let $ = app.models; - // let { - // client, - // accountConfig - // } = this; - // Prepare data + const sambaHandler = new SambaHelper(this); try { - // const filter = '(cn=VN_*)'; - - // const baseDN = 'cn=Users,dc=verdnatura,dc=es'; - const ldapMembersGroups = await this.getMembers(); - // OBTENER ROLES - let roles = (await $.VnRole.find({ - fields: ['id', 'name', 'description'], - order: 'modified DESC', - limit: 2 - })).reduce((map, role) => { - map.set(`${ROLE_PREFIX}${role.name}`, role); - return map; - }, new Map()); - const rolesKeys = Array.from(roles.keys()); - // OBTENER LDAPSJS ROLES - const ldapGroups = await this.adClient.searchAll(this.fullGroupsDn, { - scope: 'sub', - attributes: ['cn', 'description'], - }); - - // OBTENER SAMBA ROLES - let sambaCurrentGroups = ldapGroups - .filter(group => Object.prototype.hasOwnProperty.call(group, 'cn')) - .reduce((map, group) => { - map.set(`${group.cn}`, group); - return map; - }, new Map()); - const sambaRolesKeys = Array.from(sambaCurrentGroups.keys());// .map(({cn}) => cn); - // handleExecResponse(await this.sambaTool('group', ['list'])) - // .filter(group => group.startsWith(ROLE_PREFIX)); - - // Encontrar elementos a eliminar - const rolesToDelete = differences(sambaRolesKeys, rolesKeys); - - // Encontrar elementos a insertar - const rolesToInsert = differences(rolesKeys, sambaRolesKeys); - - // Encontrar elementos a actualizar - const rolesToUpdate = differences(rolesKeys, [...rolesToDelete, ...rolesToInsert]); - - // OBTENER USUARIOS Y SUS ROLES - if ( - rolesToDelete.length > 0 || - rolesToInsert.length > 0 || - rolesToUpdate.length > 0) { - let users = await $.VnUser.find({ - include: { - relation: 'role', - scope: {fields: ['name'], - where: {'name': {nin: rolesToDelete}} - } - }, - fields: ['name', 'roleFk'], - // where: {'active': true} - }); - let usersMap = toMap(users, user => { - let role = user.role(); - if (!role) { - console.info(`User ${user.name} has not valid role`); - return; - } - return {key: `${ROLE_PREFIX}${role.name}`, val: user.name}; - }); - usersMap.set('group1', ['employee']); - if (rolesToDelete.length > 0) { - // PROCEDIMIENTO PARA ELIMINAR USUARIOS ASOCIADOS AL ROL - let usersToUngroup = rolesToDelete.flatMap(role => { - const exist = usersMap.get(role); - - if (exist) { - return usersMap.get(role)?.map( - user => this.removeMembers(role, user) - ); - } else return []; - } - ); - const resultsUsersUngroup = await Promise.all(usersToUngroup); - printResults(resultsUsersUngroup); - - // PROCEDIMIENTO PARA ELIMINAR ROLES - const resultsRoleDelete = await Promise.all( - rolesToDelete.map(this.deleteRole) - ); - printResults(resultsRoleDelete); - } - - if (rolesToInsert.length > 0) { - // PROCEDIMIENTO PARA INSERTAR ROLES - const resultsRoleInsert = await Promise.all( - rolesToInsert.map(role => this.addRole(roles.get(role)))); - printResults(resultsRoleInsert); - - // PROCEDIMIENTO PARA INSERTAR USUARIOS ASOCIADOS AL ROL - let usersToGroup = rolesToInsert.flatMap(role => usersMap.get(role).map( - user => this.addMembers(role, user) - ) - ); - const resultsUserGroup = await Promise.all(usersToGroup); - printResults(resultsUserGroup); - } - - if (rolesToUpdate.length > 0) { - // OBTENER LDAPSJS MIEMBROS ROLES - - for await (const role of rolesToUpdate) { - // let roleHasUpdated = false; - if (roles.get(role).$description != sambaCurrentGroups.get(role).description) { - await this.deleteRole(role); - await this.addRole(roles.get(role)); - // roleHasUpdated = true; - } - const users = usersMap.get(role); - const currentUsers = this.handleRoleMembers(await this.getRoleMembers(role)); - if (currentUsers.length === 0 && users.length === 0) continue; - await this.handleUsersRole(role, currentUsers, users); - } - } - } + await sambaHandler.syncFromDB(); + await sambaHandler.syncMembers(); } catch (error) { console.error(error); } }, }); }; + +class SambaHelper { + constructor(ctx) { + Object.assign(this, ctx); + } + deleteRole(role) { + return this.sambaTool('group', ['delete', role]); + } + + addRole({description, name}) { + return this.sambaTool('group', + ['add', `${ROLE_PREFIX}${name}`, `--groupou=${this.groupDn}`, `--description=${description}`]); + } + + getRoleMembers(role) { + return this.getMembers(`(cn=${role})`, this.fullGroupsDn); + } + + getMembers(filter = '', type = this.fullUsersDn) { + const options = { + scope: 'sub', + attributes: ['cn', 'member'] + }; + if (filter !== '') + Object.assign(options, {filter}); + return this.adClient.searchAll(type, options); + } + + removeMembers(role, user) { + return this.sambaTool('group', ['removemembers', role, user]); + } + + addMembers(role, user) { + return this.sambaTool('group', ['addmembers', role, user]); + } + + handleRoleMembers(users) { + if (users.length === 0) return []; + let members = users[0]?.member; + if (!members) return []; + if (!Array.isArray(members))members = [members]; + return members.map((member => member.match(/CN=(.*?),(.*)/)[1])); + } + + async handleUsersRole(role, currentUsers, users) { + const forbiddenUsers = ['guest']; + users = users.filter(u => !u.includes(forbiddenUsers)); + const usersToDelete = differences(currentUsers, users); + if (usersToDelete.length > 0) { + const results = await Promise.all(usersToDelete.map(user => + this.removemembers(role, user))); + printResults(results); + } + const usersToInsert = differences(users, currentUsers); + if (usersToInsert.length > 0) { + const results = await Promise.all(usersToInsert.map(user => + this.addmembers(role, user))); + printResults(results); + } + } + + async syncFromDB() { + // const baseDN = 'cn=Users,dc=verdnatura,dc=es'; + const ldapMembersGroups = await this.getMembers(); + // OBTENER ROLES + let roles = (await app.models.VnRole.find({ + fields: ['id', 'name', 'description'], + order: 'modified DESC', + limit: 2 + })).reduce((map, role) => { + map.set(`${ROLE_PREFIX}${role.name}`, role); + return map; + }, new Map()); + const rolesKeys = Array.from(roles.keys()); + // OBTENER LDAPSJS ROLES + const ldapGroups = await this.adClient.searchAll(this.fullGroupsDn, { + scope: 'sub', + attributes: ['cn', 'description'], + }); + + // OBTENER SAMBA ROLES + let sambaCurrentGroups = ldapGroups + .filter(group => Object.prototype.hasOwnProperty.call(group, 'cn')) + .reduce((map, group) => { + map.set(`${group.cn}`, group); + return map; + }, new Map()); + const sambaRolesKeys = Array.from(sambaCurrentGroups.keys());// .map(({cn}) => cn); + // handleExecResponse(await this.sambaTool('group', ['list'])) + // .filter(group => group.startsWith(ROLE_PREFIX)); + + // Encontrar elementos a eliminar + const rolesToDelete = differences(sambaRolesKeys, rolesKeys); + + // Encontrar elementos a insertar + const rolesToInsert = differences(rolesKeys, sambaRolesKeys); + + // Encontrar elementos a actualizar + const rolesToUpdate = differences(rolesKeys, [...rolesToDelete, ...rolesToInsert]); + + // OBTENER USUARIOS Y SUS ROLES + if ( + rolesToDelete.length > 0 || + rolesToInsert.length > 0 || + rolesToUpdate.length > 0) { + let users = await app.models.VnUser.find({ + include: { + relation: 'role', + scope: {fields: ['name'], + where: {'name': {nin: rolesToDelete}} + } + }, + fields: ['name', 'roleFk'], + // where: {'active': true} + }); + let usersMap = toMap(users, user => { + let role = user.role(); + if (!role) { + console.info(`User ${user.name} has not valid role`); + return; + } + return {key: `${ROLE_PREFIX}${role.name}`, val: user.name}; + }); + usersMap.set('group1', ['employee']); + if (rolesToDelete.length > 0) { + // PROCEDIMIENTO PARA ELIMINAR USUARIOS ASOCIADOS AL ROL + let usersToUngroup = rolesToDelete.flatMap(role => { + const exist = usersMap.get(role); + + if (exist) { + return usersMap.get(role)?.map( + user => this.removeMembers(role, user) + ); + } else return []; + } + ); + const resultsUsersUngroup = await Promise.all(usersToUngroup); + printResults(resultsUsersUngroup); + + // PROCEDIMIENTO PARA ELIMINAR ROLES + const resultsRoleDelete = await Promise.all( + rolesToDelete.map(this.deleteRole) + ); + printResults(resultsRoleDelete); + } + + if (rolesToInsert.length > 0) { + // PROCEDIMIENTO PARA INSERTAR ROLES + const resultsRoleInsert = await Promise.all( + rolesToInsert.map(role => this.addRole(roles.get(role)))); + printResults(resultsRoleInsert); + + // PROCEDIMIENTO PARA INSERTAR USUARIOS ASOCIADOS AL ROL + let usersToGroup = rolesToInsert.flatMap(role => usersMap.get(role).map( + user => this.addMembers(role, user) + ) + ); + const resultsUserGroup = await Promise.all(usersToGroup); + printResults(resultsUserGroup); + } + + if (rolesToUpdate.length > 0) { + // OBTENER LDAPSJS MIEMBROS ROLES + + for await (const role of rolesToUpdate) { + // let roleHasUpdated = false; + if (roles.get(role).$description != sambaCurrentGroups.get(role).description) { + await this.deleteRole(role); + await this.addRole(roles.get(role)); + // roleHasUpdated = true; + } + const users = usersMap.get(role); + const currentUsers = this.handleRoleMembers(await this.getRoleMembers(role)); + if (currentUsers.length === 0 && users.length === 0) continue; + await this.handleUsersRole(role, currentUsers, users); + } + } + } + } + syncMembers() { + + } +}