diff --git a/app/ldap/server/ldap.js b/app/ldap/server/ldap.js index 0dceec62d8868..eafdd3161796b 100644 --- a/app/ldap/server/ldap.js +++ b/app/ldap/server/ldap.js @@ -370,6 +370,14 @@ export default class LDAP { values[key] = value; } } + + if (key === 'ou' && Array.isArray(value)) { + value.forEach((item, index) => { + if (item instanceof Buffer) { + value[index] = item.toString(); + } + }); + } }); return values; diff --git a/app/ldap/server/sync.js b/app/ldap/server/sync.js index 9993fe54549ed..1ef91246142ec 100644 --- a/app/ldap/server/sync.js +++ b/app/ldap/server/sync.js @@ -320,12 +320,17 @@ export function mapLDAPGroupsToChannels(ldap, ldapUser, user) { for (const channel of channels) { let room = Rooms.findOneByNonValidatedName(channel); + if (!room) { room = createRoomForSync(channel); } if (isUserInLDAPGroup(ldap, ldapUser, user, ldapField)) { - userChannels.push(room._id); - } else if (syncUserRolesEnforceAutoChannels) { + if (room.teamMain) { + logger.error(`Can't add user to channel ${ channel } because it is a team.`); + } else { + userChannels.push(room._id); + } + } else if (syncUserRolesEnforceAutoChannels && !room.teamMain) { const subscription = Subscriptions.findOneByRoomIdAndUserId(room._id, user._id); if (subscription) { removeUserFromRoom(room._id, user); diff --git a/ee/app/ldap-enterprise/server/index.js b/ee/app/ldap-enterprise/server/index.js index 406b2c6bc88c3..dcea594531d21 100644 --- a/ee/app/ldap-enterprise/server/index.js +++ b/ee/app/ldap-enterprise/server/index.js @@ -9,12 +9,13 @@ import { onLicense } from '../../license/server'; onLicense('ldap-enterprise', () => { const { createSettings } = require('./settings'); - const { validateLDAPRolesMappingChanges } = require('./ldapEnterprise'); + const { validateLDAPRolesMappingChanges, validateLDAPTeamsMappingChanges } = require('./ldapEnterprise'); const { onLdapLogin } = require('./listener'); Meteor.startup(function() { createSettings(); validateLDAPRolesMappingChanges(); + validateLDAPTeamsMappingChanges(); let LDAP_Enable_LDAP_Roles_To_RC_Roles; let LDAP_Enable_LDAP_Groups_To_RC_Teams; diff --git a/ee/app/ldap-enterprise/server/ldapEnterprise.js b/ee/app/ldap-enterprise/server/ldapEnterprise.js index 759325ae69fe6..02e9718780b67 100644 --- a/ee/app/ldap-enterprise/server/ldapEnterprise.js +++ b/ee/app/ldap-enterprise/server/ldapEnterprise.js @@ -26,6 +26,14 @@ const validateLDAPRolesMappingStructure = (mappedRoles) => { } }; +const validateLDAPTeamsMappingStructure = (mappedTeams) => { + const mappedRocketChatTeams = Object.values(mappedTeams); + const validStructureMapping = mappedRocketChatTeams.every(mustBeAnArrayOfStrings); + if (!validStructureMapping) { + throw new Error('Please verify your mapping for LDAP X RocketChat Teams. The structure is invalid, the structure should be an object like: {key: LdapTeam, value: [An array of rocket.chat teams]}'); + } +}; + export const getLdapRolesByUsername = (username, ldap) => { const searchOptions = { filter: settings.get('LDAP_Query_To_Get_User_Groups').replace(/#{username}/g, username), @@ -43,9 +51,13 @@ export const getLdapTeamsByUsername = (username, ldap) => { scope: ldap.options.User_Search_Scope || 'sub', sizeLimit: ldap.options.Search_Size_Limit, }; - const getLdapTeams = (ldapUserGroups) => ldapUserGroups.filter((field) => field && field.ou).map((field) => field.ou); const ldapUserGroups = ldap.searchAllSync(ldap.options.BaseDN, searchOptions); - return Array.isArray(ldapUserGroups) ? getLdapTeams(ldapUserGroups) : []; + + if (!Array.isArray(ldapUserGroups)) { + return []; + } + + return ldapUserGroups.filter((field) => field && field.ou).map((field) => field.ou).flat(); }; export const getRocketChatRolesByLdapRoles = (mappedRoles, ldapUserRoles) => { @@ -79,8 +91,7 @@ export const getRocketChatTeamsByLdapTeams = (mappedTeams, ldapUserTeams) => { return []; } - const rcTeams = filteredTeams.map((ldapTeam) => mappedTeams[ldapTeam]); - return [...new Set(rcTeams)]; + return [...new Set(filteredTeams.map((ldapTeam) => mappedTeams[ldapTeam]).flat())]; }; export const updateUserUsingMappedLdapRoles = (userId, roles) => { @@ -88,7 +99,7 @@ export const updateUserUsingMappedLdapRoles = (userId, roles) => { }; async function updateUserUsingMappedLdapTeamsAsync(userId, teamNames, map) { - const allTeamNames = [...new Set(Object.values(map))]; + const allTeamNames = [...new Set(Object.values(map).flat())]; const allTeams = await Team.listByNames(allTeamNames, { projection: { _id: 1, name: 1 } }); const inTeamIds = allTeams.filter(({ name }) => teamNames.includes(name)).map(({ _id }) => _id); @@ -118,3 +129,16 @@ export const validateLDAPRolesMappingChanges = () => { } }); }; + +export const validateLDAPTeamsMappingChanges = () => { + settings.get('LDAP_Groups_To_Rocket_Chat_Teams', (key, value) => { + try { + if (value) { + const mappedTeams = JSON.parse(value); + validateLDAPTeamsMappingStructure(mappedTeams); + } + } catch (error) { + logger.error(error); + } + }); +};