-
Notifications
You must be signed in to change notification settings - Fork 13k
feat: ldap custom variables / string manipulation #35717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
79609eb
wip: LDAP sync for federation
pierre-lehnen-rc c672ea3
fixed replace operation
pierre-lehnen-rc e86d817
added split operation
pierre-lehnen-rc 2fc1062
add variable processing logs
pierre-lehnen-rc 2e51f1c
changeset
pierre-lehnen-rc 9eabbc9
Update .changeset/beige-days-push.md
pierre-lehnen-rc 2c5d2a2
Update .changeset/beige-days-push.md
pierre-lehnen-rc 159c1fe
unit tests
pierre-lehnen-rc 2ce7dca
improvements over the old code
pierre-lehnen-rc daa2941
add test for empty key
pierre-lehnen-rc 9d5c292
Merge branch 'develop' into feat/ldap-variables
pierre-lehnen-rc 1fece62
merge error
pierre-lehnen-rc dfb09f1
Merge branch 'develop' into feat/ldap-variables
kodiakhq[bot] dddc99f
Merge branch 'develop' into feat/ldap-variables
kodiakhq[bot] ffa345d
Merge branch 'develop' into feat/ldap-variables
kodiakhq[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| '@rocket.chat/core-typings': minor | ||
| '@rocket.chat/i18n': minor | ||
| '@rocket.chat/meteor': minor | ||
| --- | ||
|
|
||
| Adds new settings to allow configuring custom variables with string manipulation functions on the LDAP data mapper |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| import type { ILDAPEntry } from '@rocket.chat/core-typings'; | ||
| import { expect } from 'chai'; | ||
| import 'mocha'; | ||
|
|
||
| import { getLdapDynamicValue } from './getLdapDynamicValue'; | ||
|
|
||
| describe('getLdapDynamicValue', () => { | ||
| const ldapUser: ILDAPEntry = { | ||
| _raw: {}, | ||
| displayName: 'John Doe', | ||
| email: '[email protected]', | ||
| uid: 'johndoe', | ||
| emptyField: '', | ||
| }; | ||
pierre-lehnen-rc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| it('should return undefined if attributeSetting is undefined', () => { | ||
| const result = getLdapDynamicValue(ldapUser, undefined); | ||
| expect(result).to.be.undefined; | ||
| }); | ||
|
|
||
| it('should return the correct value from a single valid attribute', () => { | ||
| const result = getLdapDynamicValue(ldapUser, 'displayName'); | ||
| expect(result).to.equal('John Doe'); | ||
| }); | ||
|
|
||
| it('should return the correct value from a template attribute', () => { | ||
| const result = getLdapDynamicValue(ldapUser, 'Hello, #{displayName}!'); | ||
| expect(result).to.equal('Hello, John Doe!'); | ||
| }); | ||
|
|
||
| it('should replace missing keys with an empty string in a template', () => { | ||
| const result = getLdapDynamicValue(ldapUser, 'Hello, #{nonExistentField}!'); | ||
| expect(result).to.equal('Hello, !'); | ||
| }); | ||
|
|
||
| it('should return the first valid key from a CSV list of attributes', () => { | ||
| const result = getLdapDynamicValue(ldapUser, 'nonExistentField,email,uid'); | ||
| expect(result).to.equal('[email protected]'); | ||
| }); | ||
|
|
||
| it('should return undefined if none of the keys in CSV list exist', () => { | ||
| const result = getLdapDynamicValue(ldapUser, 'nonExistentField,anotherNonExistentField'); | ||
| expect(result).to.be.undefined; | ||
| }); | ||
|
|
||
| it('should handle attribute keys with surrounding whitespace correctly', () => { | ||
| const result = getLdapDynamicValue(ldapUser, ' email '); | ||
| expect(result).to.equal('[email protected]'); | ||
| }); | ||
|
|
||
| it('should correctly resolve multiple variables in a template', () => { | ||
| const result = getLdapDynamicValue(ldapUser, 'User: #{displayName}, Email: #{email}, UID: #{uid}'); | ||
| expect(result).to.equal('User: John Doe, Email: [email protected], UID: johndoe'); | ||
| }); | ||
|
|
||
| it('should return undefined if the attribute has an empty value', () => { | ||
| const result = getLdapDynamicValue(ldapUser, 'emptyField'); | ||
| expect(result).to.be.undefined; | ||
| }); | ||
|
|
||
| it('should return an empty string if using only a template attribute that has an empty value', () => { | ||
| const result = getLdapDynamicValue(ldapUser, '#{emptyField}'); | ||
| expect(result).to.be.equal(''); | ||
| }); | ||
| }); | ||
pierre-lehnen-rc marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import type { ILDAPEntry } from '@rocket.chat/core-typings'; | ||
|
|
||
| import { getLdapString } from './getLdapString'; | ||
| import { ldapKeyExists } from './ldapKeyExists'; | ||
|
|
||
| export function getLdapDynamicValue(ldapUser: ILDAPEntry, attributeSetting: string | undefined): string | undefined { | ||
| if (!attributeSetting) { | ||
| return; | ||
| } | ||
|
|
||
| // If the attribute setting is a template, then convert the variables in it | ||
| if (attributeSetting.includes('#{')) { | ||
| return attributeSetting.replace(/#{(.+?)}/g, (_match, field) => { | ||
| const key = field.trim(); | ||
|
|
||
| if (ldapKeyExists(ldapUser, key)) { | ||
| // We've already validated so it won't ever return undefined, but add a fallback to ensure it doesn't break if something gets changed | ||
| return getLdapString(ldapUser, key) || ''; | ||
| } | ||
|
|
||
| return ''; | ||
| }); | ||
| } | ||
|
|
||
| // If it's not a template, then treat the setting as a CSV list of possible attribute names and return the first valid one. | ||
| const attributeList: string[] = attributeSetting.replace(/\s/g, '').split(','); | ||
pierre-lehnen-rc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const key = attributeList.find((field) => ldapKeyExists(ldapUser, field)); | ||
| if (key) { | ||
| return getLdapString(ldapUser, key); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| import type { ILDAPEntry } from '@rocket.chat/core-typings'; | ||
| import { expect } from 'chai'; | ||
| import 'mocha'; | ||
|
|
||
| import { getLdapString } from './getLdapString'; | ||
|
|
||
| const ldapUser: ILDAPEntry = { | ||
| _raw: {}, | ||
| username: 'john_doe', | ||
| email: '[email protected]', | ||
| phoneNumber: '123-456-7890', | ||
| memberOf: 'group1,group2', | ||
| }; | ||
|
|
||
| describe('getLdapString', () => { | ||
| it('should return the correct value for a given key', () => { | ||
| expect(getLdapString(ldapUser, 'username')).to.equal('john_doe'); | ||
| expect(getLdapString(ldapUser, 'email')).to.equal('[email protected]'); | ||
| expect(getLdapString(ldapUser, 'phoneNumber')).to.equal('123-456-7890'); | ||
| expect(getLdapString(ldapUser, 'memberOf')).to.equal('group1,group2'); | ||
| }); | ||
|
|
||
| it('should trim the key and return the correct value', () => { | ||
| expect(getLdapString(ldapUser, ' username ')).to.equal('john_doe'); | ||
| expect(getLdapString(ldapUser, ' email ')).to.equal('[email protected]'); | ||
| }); | ||
|
|
||
| it('should return undefined for non-existing keys', () => { | ||
| expect(getLdapString(ldapUser, 'nonExistingKey')).to.be.undefined; | ||
| expect(getLdapString(ldapUser, 'foo')).to.be.undefined; | ||
| }); | ||
|
|
||
| it('should handle empty keys and return an empty string', () => { | ||
| expect(getLdapString(ldapUser, '')).to.be.undefined; | ||
| expect(getLdapString(ldapUser, ' ')).to.be.undefined; | ||
| }); | ||
|
|
||
| it('should handle keys with only whitespace', () => { | ||
| expect(getLdapString(ldapUser, ' ')).to.be.undefined; | ||
| expect(getLdapString(ldapUser, ' ')).to.be.undefined; | ||
| }); | ||
|
|
||
| it('should handle case-sensitive keys accurately', () => { | ||
| expect(getLdapString(ldapUser, 'Username')).to.be.undefined; | ||
| expect(getLdapString(ldapUser, 'EMAIL')).to.be.undefined; | ||
pierre-lehnen-rc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }); | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| import type { ILDAPEntry } from '@rocket.chat/core-typings'; | ||
|
|
||
| export function getLdapString(ldapUser: ILDAPEntry, key: string): string | undefined { | ||
| return ldapUser[key.trim()]; | ||
pierre-lehnen-rc marked this conversation as resolved.
Show resolved
Hide resolved
pierre-lehnen-rc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.