Skip to content

Commit fcec0fa

Browse files
ricardogarimggazzo
authored andcommitted
fix!: make SAML default user role override global default registration roles (#37810)
1 parent 531a3d0 commit fcec0fa

File tree

4 files changed

+31
-21
lines changed

4 files changed

+31
-21
lines changed

.changeset/six-squids-pretend.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@rocket.chat/meteor': major
3+
---
4+
5+
Fixes role assignment precedence in SAML provisioning, ensuring that SAML-specific default roles take priority over global registration roles, and preventing role merging when both are configured.

apps/meteor/app/authentication/server/startup/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ Accounts.insertUserDoc = async function (options, user) {
294294

295295
delete user.globalRoles;
296296

297-
if (user.services && !user.services.password) {
297+
if (user.services && !user.services.password && !options.skipAuthServiceDefaultRoles) {
298298
const defaultAuthServiceRoles = parseCSV(settings.get('Accounts_Registration_AuthenticationServices_Default_Roles') || '');
299299

300300
if (defaultAuthServiceRoles.length > 0) {

apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,19 @@ const showErrorMessage = function (res: ServerResponse, err: string): void {
3030
};
3131

3232
const convertRoleNamesToIds = async (roleNamesOrIds: string[]): Promise<IRole['_id'][]> => {
33-
const roles = (await Roles.findInIdsOrNames(roleNamesOrIds).toArray()).map((role) => role._id);
33+
const normalizedRoleNamesOrIds = roleNamesOrIds.map((role) => role.trim()).filter((role) => role.length > 0);
34+
if (!normalizedRoleNamesOrIds.length) {
35+
throw new Error(`No valid role names or ids provided for conversion: ${roleNamesOrIds.join(', ')}`);
36+
}
37+
38+
const roles = (await Roles.findInIdsOrNames(normalizedRoleNamesOrIds).toArray()).map((role) => role._id);
3439

35-
if (roles.length !== roleNamesOrIds.length) {
36-
SystemLogger.warn(`Failed to convert some role names to ids: ${roleNamesOrIds.join(', ')}`);
40+
if (roles.length !== normalizedRoleNamesOrIds.length) {
41+
SystemLogger.warn(`Failed to convert some role names to ids: ${normalizedRoleNamesOrIds.join(', ')}`);
3742
}
3843

3944
if (!roles.length) {
40-
throw new Error(`We should have at least one existing role to create the user: ${roleNamesOrIds.join(', ')}`);
45+
throw new Error(`We should have at least one existing role to create the user: ${normalizedRoleNamesOrIds.join(', ')}`);
4146
}
4247

4348
return roles;
@@ -93,14 +98,8 @@ export class SAML {
9398
}
9499

95100
public static async insertOrUpdateSAMLUser(userObject: ISAMLUser): Promise<{ userId: string; token: string }> {
96-
const {
97-
generateUsername,
98-
immutableProperty,
99-
nameOverwrite,
100-
mailOverwrite,
101-
channelsAttributeUpdate,
102-
defaultUserRole = 'user',
103-
} = SAMLUtils.globalSettings;
101+
const { generateUsername, immutableProperty, nameOverwrite, mailOverwrite, channelsAttributeUpdate, defaultUserRole } =
102+
SAMLUtils.globalSettings;
104103

105104
let customIdentifierMatch = false;
106105
let customIdentifierAttributeName: string | null = null;
@@ -142,9 +141,14 @@ export class SAML {
142141
const active = !settings.get('Accounts_ManuallyApproveNewUsers');
143142

144143
if (!user) {
145-
// If we received any role from the mapping, use them - otherwise use the default role for creation.
146-
const roleNamesOrIds = userObject.roles?.length ? userObject.roles : ensureArray<string>(defaultUserRole.split(','));
147-
const roles = await convertRoleNamesToIds(roleNamesOrIds);
144+
let roleNamesOrIds: string[] = [];
145+
if (userObject.roles && userObject.roles.length > 0) {
146+
roleNamesOrIds = userObject.roles;
147+
} else if (defaultUserRole) {
148+
roleNamesOrIds = ensureArray<string>(defaultUserRole.split(','));
149+
}
150+
151+
const roles = roleNamesOrIds.length > 0 ? await convertRoleNamesToIds(roleNamesOrIds) : [];
148152

149153
const newUser: Record<string, any> = {
150154
name: fullName,
@@ -178,7 +182,11 @@ export class SAML {
178182
}
179183
}
180184

181-
const userId = await Accounts.insertUserDoc({}, newUser);
185+
// only set skipAuthServiceDefaultRoles if SAML is providing its own roles
186+
// otherwise, leave it as false to fallback to generic auth service default roles
187+
// from Accounts_Registration_AuthenticationServices_Default_Roles
188+
const skipAuthServiceDefaultRoles = roleNamesOrIds.length > 0;
189+
const userId = await Accounts.insertUserDoc({ skipAuthServiceDefaultRoles, skipNewUserRolesSetting: true }, newUser);
182190
user = await Users.findOneById(userId);
183191

184192
if (user && userObject.channels && channelsAttributeUpdate !== true) {

apps/meteor/app/meteor-accounts-saml/server/lib/Utils.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export class SAMLUtils {
7373
globalSettings.mailOverwrite = Boolean(samlConfigs.mailOverwrite);
7474
globalSettings.channelsAttributeUpdate = Boolean(samlConfigs.channelsAttributeUpdate);
7575
globalSettings.includePrivateChannelsInUpdate = Boolean(samlConfigs.includePrivateChannelsInUpdate);
76+
globalSettings.defaultUserRole = samlConfigs.defaultUserRole;
7677

7778
if (samlConfigs.immutableProperty && typeof samlConfigs.immutableProperty === 'string') {
7879
globalSettings.immutableProperty = samlConfigs.immutableProperty;
@@ -82,10 +83,6 @@ export class SAMLUtils {
8283
globalSettings.usernameNormalize = samlConfigs.usernameNormalize;
8384
}
8485

85-
if (samlConfigs.defaultUserRole && typeof samlConfigs.defaultUserRole === 'string') {
86-
globalSettings.defaultUserRole = samlConfigs.defaultUserRole;
87-
}
88-
8986
if (samlConfigs.userDataFieldMap && typeof samlConfigs.userDataFieldMap === 'string') {
9087
globalSettings.userDataFieldMap = samlConfigs.userDataFieldMap;
9188
}

0 commit comments

Comments
 (0)