From ecd5300c3b96933a42d2e897f4bc27bc350a59da Mon Sep 17 00:00:00 2001 From: Abderraouf El Gasser Date: Mon, 27 Mar 2023 18:55:35 +0200 Subject: [PATCH 1/4] feat: added implementation for group mapping in SAML strategies --- .../authentication/saml/authentication.js | 20 +++++++++++++++++++ .../authentication/saml/definition.yml | 12 +++++++++++ 2 files changed, 32 insertions(+) diff --git a/server/modules/authentication/saml/authentication.js b/server/modules/authentication/saml/authentication.js index 6eeef27a80..a39cd20bf3 100644 --- a/server/modules/authentication/saml/authentication.js +++ b/server/modules/authentication/saml/authentication.js @@ -56,6 +56,26 @@ module.exports = { picture: _.get(profile, conf.mappingPicture, '') } }) + + // map users LDAP groups to wiki groups with the same name, and remove any groups that don't match LDAP + // Code stolen from the LDAP implementation with a slight variation on the field we extract the value from + // In SAML v2 groups come in profile.attributes and can be 1 string or an array of strings + if (conf.mapGroups) { + const maybeArrayOfGroups = _.get(profile.attributes, conf.mappingGroups) + const groups = (maybeArrayOfGroups && !_.isArray(maybeArrayOfGroups)) ? [maybeArrayOfGroups] : maybeArrayOfGroups + + if (groups && _.isArray(groups)) { + const currentGroups = (await user.$relatedQuery('groups').select('groups.id')).map(g => g.id) + const expectedGroups = Object.values(WIKI.auth.groups).filter(g => groups.includes(g.name)).map(g => g.id) + for (const groupId of _.difference(expectedGroups, currentGroups)) { + await user.$relatedQuery('groups').relate(groupId) + } + for (const groupId of _.difference(currentGroups, expectedGroups)) { + await user.$relatedQuery('groups').unrelate().where('groupId', groupId) + } + } + } + cb(null, user) } catch (err) { cb(err, null) diff --git a/server/modules/authentication/saml/definition.yml b/server/modules/authentication/saml/definition.yml index bfb24d15ff..9fbcde9b78 100644 --- a/server/modules/authentication/saml/definition.yml +++ b/server/modules/authentication/saml/definition.yml @@ -162,3 +162,15 @@ props: default: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/picture' hint: The field storing the user avatar picture. Can be a variable name or a URI-formatted string. order: 43 + mapGroups: + type: Boolean + title: Map Groups + hint: Map groups matching names from the users LDAP/Active Directory groups. User groups Field Mapping must also be defined for this to work. Note this will remove any groups the user has that doesn't match an LDAP/Active Directory group. + default: false + order: 44 + mappingGroups: + title: User groups Field Mapping + type: String + default: 'memberOf' + hint: The field storing the user groups attribute. Can be a variable name or a URI-formatted string. + order: 45 From 07bf6861c1faf41a2514d0c2101324dcbef39b79 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Mon, 20 Nov 2023 16:52:51 -0500 Subject: [PATCH 2/4] chore: Update definition.yml --- server/modules/authentication/saml/definition.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/modules/authentication/saml/definition.yml b/server/modules/authentication/saml/definition.yml index 9fbcde9b78..aaad4e0bdb 100644 --- a/server/modules/authentication/saml/definition.yml +++ b/server/modules/authentication/saml/definition.yml @@ -165,12 +165,12 @@ props: mapGroups: type: Boolean title: Map Groups - hint: Map groups matching names from the users LDAP/Active Directory groups. User groups Field Mapping must also be defined for this to work. Note this will remove any groups the user has that doesn't match an LDAP/Active Directory group. + hint: Map groups matching names from the users LDAP/Active Directory groups. User Groups Field Mapping must also be defined for this to work. Note this will remove any groups the user has that doesn't match an LDAP/Active Directory group. default: false order: 44 mappingGroups: - title: User groups Field Mapping + title: User Groups Field Mapping type: String default: 'memberOf' - hint: The field storing the user groups attribute. Can be a variable name or a URI-formatted string. + hint: The field storing the user groups attribute (when Map Groups is enabled). Can be a variable name or a URI-formatted string. order: 45 From 104eff1cd24a041c871d4ca5fc2da39d5062d1d5 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Mon, 20 Nov 2023 16:55:42 -0500 Subject: [PATCH 3/4] chore: Update authentication.js --- server/modules/authentication/saml/authentication.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/modules/authentication/saml/authentication.js b/server/modules/authentication/saml/authentication.js index a39cd20bf3..1324890793 100644 --- a/server/modules/authentication/saml/authentication.js +++ b/server/modules/authentication/saml/authentication.js @@ -57,8 +57,8 @@ module.exports = { } }) - // map users LDAP groups to wiki groups with the same name, and remove any groups that don't match LDAP - // Code stolen from the LDAP implementation with a slight variation on the field we extract the value from + // map users provider groups to wiki groups with the same name, and remove any groups that don't match + // Code copied from the LDAP implementation with a slight variation on the field we extract the value from // In SAML v2 groups come in profile.attributes and can be 1 string or an array of strings if (conf.mapGroups) { const maybeArrayOfGroups = _.get(profile.attributes, conf.mappingGroups) From 58d2b06eb18424841370b85da101a98c15d2d41a Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Mon, 20 Nov 2023 16:58:41 -0500 Subject: [PATCH 4/4] chore: Update definition.yml --- server/modules/authentication/saml/definition.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/authentication/saml/definition.yml b/server/modules/authentication/saml/definition.yml index aaad4e0bdb..c39dd73125 100644 --- a/server/modules/authentication/saml/definition.yml +++ b/server/modules/authentication/saml/definition.yml @@ -165,7 +165,7 @@ props: mapGroups: type: Boolean title: Map Groups - hint: Map groups matching names from the users LDAP/Active Directory groups. User Groups Field Mapping must also be defined for this to work. Note this will remove any groups the user has that doesn't match an LDAP/Active Directory group. + hint: Map groups matching names from the provider user groups. User Groups Field Mapping must also be defined for this to work. Note this will remove any groups the user has that doesn't match any group from the provider. default: false order: 44 mappingGroups: