Content
View differences
Updated by Christophe Bliard 15 days ago
**When I** set up The LDAP group synchronization with an LDAP server that does not support User-Group sync only works using the `memberOf` "memberOf" attribute on user entries,
**help me** configure a "Group member attribute" on in other words the synchronization filter so that OpenProject reads group membership directly from the group entry,
**so users perspective. I avoid** having would like to modify my LDAP schema or use have a different server just to use OpenProject group sync,
**and I gain** the ability to synchronize groups from any standards-compliant LDAP server regardless of whether it supports `memberOf` on user entries.
## Background
OpenProject LDAP group synchronization relies on **reverse lookup** by default: it searches feature for users whose `memberOf` attribute matches the group DN. This requires the `memberOf` attribute to be maintained on user entries — which is the case for Active Directory and OpenLDAP with the memberof overlay, but not for all LDAP servers.
LDAP servers following RFC 2256 perspective (e.g. using the `groupOfUniqueNames` object class) store membership on the **group entry** itself (e.g. via `uniqueMember`), and do not maintain `memberOf` on user entries. These servers are currently incompatible with OpenProject group sync.
## Feature description
### New field: Group member memberUid attribute (on synchronized filters)
A new optional **Group member attribute** field should be added to the synchronized filter create and edit forms.
* **Left empty (default):** behavior is unchanged — OpenProject uses reverse lookup, searching for users with `(memberOf=\<group DN\>)`.
* **Set to an attribute name** (e.g. `uniqueMember`, `member`): OpenProject should switch to **forward lookup** — it reads the member DNs directly from the group entry using that attribute, then resolves each DN individually to find the corresponding OpenProject user.
### Button label: "Discover LDAP groups"
The button on the filter detail page that triggers an immediate synchronization run should be labeled **"Discover LDAP groups"** to clearly communicate that it only runs group discovery.
It finds groups matching the filter and creates the corresponding synchronized groups and OpenProject groups; it currently does not trigger member synchronization (unchanged behavior). Member synchronization is handled by the hourly background job, or manually via `bundle exec rake ldap_groups:synchronize`.
## Acceptance criteria
* A new optional **Group member attribute** field is available on the synchronized filter create and edit forms
* When the field is left empty, LDAP group sync behavior is unchanged (reverse lookup via `memberOf`)
* When the field is set to an attribute name (e.g. `uniqueMember`, `member`):
* OpenProject reads that attribute from the group entry to get the list of member DNs
* Each member DN is resolved individually via a base-scoped LDAP search
* Resolved users are added to the OpenProject group; users no longer in the group are removed
* If a member DN cannot be resolved, synchronization continues for the remaining members
* Forward lookup should only apply to groups discovered through a synchronized filter. Manually-created synchronized groups should always use reverse lookup (`memberOf`)
* Existing synchronized filters without a Group member attribute should continue to work exactly as before
* The button on the filter detail page should be labeled **"Discover LDAP groups"** and should only trigger group discovery, not member synchronization
* Running `bundle exec rake ldap_groups:synchronize` should trigger a full synchronization (group discovery + member sync) for all configured filters
## Technical notes
* A new nullable `member_lookup_attribute` string column should be added to the `ldap_groups_synchronized_filters` table (migration required)
* Forward lookup performs one LDAP search per member DN; acceptable for a background job running hourly
* Both lookup strategies should share the same membership update logic (add new members, remove members no longer present)
## Permissions and visibility considerations
* The Group member attribute field is only visible to administrators, in the LDAP group synchronization admin section
* No change to user-facing behavior
## Translation considerations
* New label and help text needed for the Group member attribute field
* Button label should be "Discover LDAP groups" instead of "Synchronize"
* Admin UI help text should be updated to explain both reverse and forward lookup
## Out of scope
* Forward lookup for manually-created synchronized groups (always use reverse lookup)
* Auto-detection of the LDAP schema / object class
* Support for nested/recursive LDAP groups; will be handled by <mention class="mention" data-id="34049" data-type="work_package" data-text="##OP-7450" data-display-id="OP-7450">##OP-7450</mention>. groups).
**help me** configure a "Group member attribute" on
**so
**and I gain** the ability to synchronize groups from any standards-compliant LDAP server regardless of whether it supports `memberOf` on user entries.
## Background
OpenProject LDAP group synchronization relies on **reverse lookup** by default: it searches
LDAP servers following RFC 2256
## Feature description
### New field: Group member
A new optional **Group member attribute** field should be added to the synchronized filter create and edit forms.
* **Left empty (default):** behavior is unchanged — OpenProject uses reverse lookup, searching for users with `(memberOf=\<group DN\>)`.
* **Set to an attribute name** (e.g. `uniqueMember`, `member`): OpenProject should switch to **forward lookup** — it reads the member DNs directly from the group entry using that attribute, then resolves each DN individually to find the corresponding OpenProject user.
### Button label: "Discover LDAP groups"
The button on the filter detail page that triggers an immediate synchronization run should be labeled **"Discover LDAP groups"** to clearly communicate that it only runs group discovery.
It finds groups matching the filter and creates the corresponding synchronized groups and OpenProject groups; it currently does not trigger member synchronization (unchanged behavior). Member synchronization is handled by the hourly background job, or manually via `bundle exec rake ldap_groups:synchronize`.
## Acceptance criteria
* A new optional **Group member attribute** field is available on the synchronized filter create and edit forms
* When the field is left empty, LDAP group sync behavior is unchanged (reverse lookup via `memberOf`)
* When the field is set to an attribute name (e.g. `uniqueMember`, `member`):
* OpenProject reads that attribute from the group entry to get the list of member DNs
* Each member DN is resolved individually via a base-scoped LDAP search
* Resolved users are added to the OpenProject group; users no longer in the group are removed
* If a member DN cannot be resolved, synchronization continues for the remaining members
* Forward lookup should only apply to groups discovered through a synchronized filter. Manually-created synchronized groups should always use reverse lookup (`memberOf`)
* Existing synchronized filters without a Group member attribute should continue to work exactly as before
* The button on the filter detail page should be labeled **"Discover LDAP groups"** and should only trigger group discovery, not member synchronization
* Running `bundle exec rake ldap_groups:synchronize` should trigger a full synchronization (group discovery + member sync) for all configured filters
## Technical notes
* A new nullable `member_lookup_attribute` string column should be added to the `ldap_groups_synchronized_filters` table (migration required)
* Forward lookup performs one LDAP search per member DN; acceptable for a background job running hourly
* Both lookup strategies should share the same membership update logic (add new members, remove members no longer present)
## Permissions and visibility considerations
* The Group member attribute field is only visible to administrators, in the LDAP group synchronization admin section
* No change to user-facing behavior
## Translation considerations
* New label and help text needed for the Group member attribute field
* Button label should be "Discover LDAP groups" instead of "Synchronize"
* Admin UI help text should be updated to explain both reverse and forward lookup
## Out of scope
* Forward lookup for manually-created synchronized groups (always use reverse lookup)
* Auto-detection of the LDAP schema / object class
* Support for nested/recursive LDAP groups; will be handled by <mention class="mention" data-id="34049" data-type="work_package" data-text="##OP-7450" data-display-id="OP-7450">##OP-7450</mention>.