test(samba): refs #5770create class SambaHelper
This commit is contained in:
parent
4222e2d4d9
commit
50997f6c7b
|
@ -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() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue