test(samba): refs #5770create class SambaHelper

This commit is contained in:
Javier Segarra 2024-05-11 15:48:25 +02:00
parent 4222e2d4d9
commit 50997f6c7b
1 changed files with 186 additions and 172 deletions

View File

@ -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() {
}
}