Skip to content
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

Add LdapConfig to type+doc structure of LdapService soft-config #377

Draft
wants to merge 6 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
### ⚙️ Technical

* Support for bulk updating of Role categories.
* Add `LdapConfig` class to type + document structure of primary `LdapService` soft-config.

## 20.3.1 - 2024-07-23

Expand Down
43 changes: 28 additions & 15 deletions grails-app/services/io/xh/hoist/ldap/LdapService.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.xh.hoist.ldap

import groovy.transform.MapConstructor
import io.xh.hoist.BaseService
import io.xh.hoist.cache.Cache
import org.apache.directory.api.ldap.model.entry.Attribute
Expand All @@ -13,16 +14,9 @@ import static io.xh.hoist.util.DateTimeUtils.SECONDS
* Service to query a set of LDAP servers for People, Groups, and Group memberships.
*
* Requires the following application configs:
* - 'xhLdapConfig' with the following options
* - enabled - true to enable
* - timeoutMs - time to wait for any individual search to resolve.
* - cacheExpireSecs - length of time to cache results. Set to -1 to disable caching.
* - servers - list of servers to be queried, each containing:
* - host
* - baseUserDn
* - baseGroupDn
* - 'xhLdapUsername' - dn of query user.
* - 'xhLdapPassword' - password for user
* - 'xhLdapConfig' - see {@link LdapConfig} for shape / properties
* - 'xhLdapUsername' - dn of query user
* - 'xhLdapPassword' - password for query user
*
* This service will cache results, per server, for the configured interval.
* This service may return partial results if any particular server fails to return results.
Expand Down Expand Up @@ -126,14 +120,14 @@ class LdapService extends BaseService {
searchMany("(|(memberOf=$dn) (memberOf:1.2.840.113556.1.4.1941:=$dn))", LdapPerson, strictMode)
}

private <T extends LdapObject> List<T> doQuery(Map server, String baseFilter, Class<T> objType, boolean strictMode) {
private <T extends LdapObject> List<T> doQuery(LdapServerConfig server, String baseFilter, Class<T> objType, boolean strictMode) {
if (!enabled) throw new RuntimeException('LdapService not enabled - check xhLdapConfig app config.')
if (queryUsername == 'none') throw new RuntimeException('LdapService enabled but query user not configured - check xhLdapUsername app config, or disable via xhLdapConfig.')

boolean isPerson = LdapPerson.class.isAssignableFrom(objType)
String host = server.host,
filter = "(&(objectCategory=${isPerson ? 'Person' : 'Group'})$baseFilter)",
key = server.toString() + filter
filter = "(&(objectCategory=${isPerson ? 'Person' : 'Group'})$baseFilter)",
key = server.toString() + filter

List<T> ret = cache.get(key)
if (ret != null) return ret
Expand Down Expand Up @@ -165,8 +159,8 @@ class LdapService extends BaseService {
return ret
}

private Map getConfig() {
configService.getMap('xhLdapConfig')
private LdapConfig getConfig() {
new LdapConfig(configService.getMap('xhLdapConfig'))
}

private String getQueryUsername() {
Expand All @@ -186,3 +180,22 @@ class LdapService extends BaseService {
super.clearCaches()
}
}


/**
* Typed representation of `xhLdapConfig` values.
*/
@MapConstructor
class LdapConfig {
Boolean enabled
Integer timeoutMs
Integer cacheExpireSecs
List<LdapServerConfig> servers
}

@MapConstructor
class LdapServerConfig {
String host
String baseUserDn
String baseGroupDn
}
Loading