I'd like a more elegant and readable (if possible using functional programming style) for collection filtering (groupToAdd and groupToDelete collection handling)
Just getting rid of multiple _.findIndex() < 0 or _.indexOf() > -1 would make me happy
const {wrap} = require('co');
const _ = require('lodash');
function* manageUserOrganizations(userId, newOrgs, application, token, logger) {
logger.debug('retrieving existing user groups');
const userGroups = yield keycloak.getGroupsByUser(userId, token, logger);
// determine groups operation to handle
let groupToAdd;
let groupToDelete;
if (newOrgs && newOrgs.length) {
// if some organizations to assign are provided add every one not already belonging to user
groupToAdd = _.filter(application.subGroups, (elt) => _.findIndex(userGroups, {name: elt.name}) < 0);
groupToAdd = _.filter(groupToAdd, (elt) => _.indexOf(newOrgs, elt.name) > -1);
// and remove every one belonging to user but not provided (including application itself)
groupToDelete = _.filter(userGroups, (elt) => _.indexOf(newOrgs, elt.name) < 0);
} else {
// otherwise add the application itself except if it already belongs to user
groupToAdd = _.findIndex(userGroups, {name: application.name}) > -1 ? [] : [application];
// and remove all other existing groups
groupToDelete = _.filter(userGroups, (elt) => elt.name !== application.name);
}
// handle user group assignation / removal
yield Promise.all(_.flatten([
groupToAdd
.map(wrap(assignUserGroup(userId, token, logger.subProcess()))),
groupToDelete
.map(wrap(removeUserGroup(userId, token, logger.subProcess())))
]));
}
organizations
or applications
are handled as groups
in keycloak context
below are an example of variables values:
application.subGroups || userGroups: [{id: 665, name: 'orgName'}, {id: 667, name: 'newOrgName'}]
newOrgs: ['someOrgName', 'anotherOrgName'
]