LDAPService
class LDAPService implements Flushable (View source)
Class LDAPService
Provides LDAP operations expressed in terms of the SilverStripe domain. All other modules should access LDAP through this class.
This class builds on top of LDAPGateway's detailed code by adding:
- caching
- data aggregation and restructuring from multiple lower-level calls
- error handling
LDAPService relies on Laminas LDAP module's data structures for some parameters and some return values.
Traits
A class that can be instantiated or replaced via DI
Allows an object to have extensions applied to it.
Provides extensions to this object to integrate it with standard config API methods.
Allows an object to declare a set of custom methods
Config options
extensions | array | An array of extension names and parameters to be applied to this object upon construction. |
from Extensible |
unextendable_classes | array | Classes that cannot be extended |
from Extensible |
dependencies | array | ||
users_search_locations | array | If configured, only user objects within these locations will be exposed to this service. |
|
groups_search_locations | array | If configured, only group objects within these locations will be exposed to this service. |
|
new_users_dn | string | Location to create new users in (distinguished name). |
|
new_groups_dn | string | Location to create new groups in (distinguished name). |
|
_cache_nested_groups | array | ||
default_group | string | If this is configured to a "Code" value of a Group in SilverStripe, the user will always be added to this group's membership when imported, regardless of any sort of group mappings. |
|
password_history_workaround | bool | For samba4 directory, there is no way to enforce password history on password resets. |
Properties
protected static | array | $extra_methods | Custom method sources |
from CustomMethods |
protected | array | $extra_method_registers | Name of methods to invoke by defineMethods for this instance |
from CustomMethods |
protected static | array | $built_in_methods | Non-custom public methods. |
from CustomMethods |
protected | Extension[] | $extension_instances | from Extensible | |
protected | callable[][] | $beforeExtendCallbacks | List of callbacks to call prior to extensions having extend called on them, each grouped by methodName. |
from Extensible |
protected | callable[][] | $afterExtendCallbacks | List of callbacks to call after extensions having extend called on them, each grouped by methodName. |
from Extensible |
public | LDAPGateway | $gateway |
Methods
An implementation of the factory method, allows you to create an instance of a class
Creates a class instance by the "singleton" design pattern.
Attempts to locate and call a method dynamically added to a class at runtime if a default cannot be located
Adds any methods from Extension instances attached to this object.
Register an callback to invoke that defines extra methods
Return TRUE if a method exists on this object
Determines if a custom method with this name is defined.
Get meta-data details on a named method
Return the names of all the methods available on this object
Get all public built in methods for this class
Find all methods on the given object.
Add all the methods from an object property.
Add all the methods from an object property (which is an Extension) to this object.
Add a wrapper method - a method which points to another method with a different name. For example, Thumbnail(x) can be wrapped to generateThumbnail(x)
Add callback as a method.
Allows user code to hook into Object::extend prior to control being delegated to extensions. Each callback will be reset once called.
Allows user code to hook into Object::extend after control being delegated to extensions. Each callback will be reset once called.
Adds any methods from Extension instances attached to this object.
Add an extension to a specific class.
No description
Get extra config sources for this class
Return TRUE if a class has a specified extension.
Calls a method if available on both this object and all applied Extensions, and then attempts to merge all results into an array
Run the given function on all of this object's extensions. Note that this method originally returned void, so if you wanted to return results, you're hosed
Get an extension instance attached to this object by name.
Returns TRUE if this object instance has a specific extension applied in $extension_instances. Extension instances are initialized at constructor time, meaning if you use add_extension() afterwards, the added extension will just be added to new instances of the extended class. Use the static method has_extension() to check if a class (not an instance) has a specific extension.
Get all extension instances for this specific object instance.
Get a configuration accessor for this class. Short hand for Config::inst()->get($this->class, .....).
Gets the uninherited value for the given config option
Get the cache object used for LDAP results. Note that the default lifetime set here is 8 hours, but you can change that by adding configuration:
Setter for gateway. Useful for overriding the gateway with a fake for testing.
Return the LDAP gateway currently in use. Can be strung together to access the underlying Laminas\Ldap instance, or the PHP ldap resource itself. For example:
- Get the Laminas\Ldap object: $service->getGateway()->getLdap() // Laminas\Ldap\Ldap object
- Get the underlying PHP ldap resource: $service->getGateway()->getLdap()->getResource() // php resource
Authenticate the given username and password with LDAP.
Return all nodes (organizational units, containers, and domains) within the current base DN.
Return all AD groups in configured search locations, including all nested groups.
Return all member groups (and members of those, recursively) underneath a specific group DN.
Get a particular AD group's data given a GUID.
Get a particular AD group's data given a DN.
Return all AD users in configured search locations, including all users in nested groups.
Get a specific AD user's data given a GUID.
Get a specific AD user's data given a DN.
Get a specific user's data given an email.
Get a specific user's data given a username.
Given a group DN, get the group membership data in LDAP.
Attempts to process the thumbnail photo for a given user and store it against a Member object. This will
overwrite any old file with the same name. The filename of the photo will be set to 'thumbnailphoto-
Ensure the user is mapped to any applicable groups.
Update the Member data back to the corresponding LDAP user object.
Ensure the user belongs to the correct groups in LDAP from their membership to local LDAP mapped SilverStripe groups.
Change a members password on the AD. Works with ActiveDirectory compatible services that saves the
password in the unicodePwd
attribute.
A simple proxy to LDAP copy/delete operation.
Details
static Injectable
create(mixed ...$args)
An implementation of the factory method, allows you to create an instance of a class
This method will defer class substitution to the Injector API, which can be customised via the Config API to declare substitution classes.
This can be called in one of two ways - either calling via the class directly, or calling on Object and passing the class name as the first parameter. The following are equivalent: $list = DataList::create(SiteTree::class); $list = SiteTree::get();
static Injectable
singleton(string $class = null)
Creates a class instance by the "singleton" design pattern.
It will always return the same instance for this class, which can be used for performance reasons and as a simple way to access instance methods which don't rely on instance data (e.g. the custom SilverStripe static handling).
mixed
__call(string $method, array $arguments)
Attempts to locate and call a method dynamically added to a class at runtime if a default cannot be located
You can add extra methods to a class using Extensions}, {@link Object::createMethod() or Object::addWrapperMethod()
protected
defineMethods()
Adds any methods from Extension instances attached to this object.
All these methods can then be called directly on the instance (transparently mapped through __call()}), or called explicitly through {@link extend().
protected
registerExtraMethodCallback(string $name, callable $callback)
Register an callback to invoke that defines extra methods
bool
hasMethod(string $method)
Return TRUE if a method exists on this object
This should be used rather than PHP's inbuild method_exists() as it takes into account methods added via extensions
protected bool
hasCustomMethod($method)
Determines if a custom method with this name is defined.
protected array
getExtraMethodConfig(string $method)
Get meta-data details on a named method
array
allMethodNames(bool $custom = false)
Return the names of all the methods available on this object
static protected array
findBuiltInMethods(string|object $class = null)
Get all public built in methods for this class
protected array
findMethodsFrom(object $object)
Find all methods on the given object.
protected
addMethodsFrom(string $property, string|int $index = null)
Add all the methods from an object property.
protected
removeMethodsFrom(string $property, string|int $index = null)
Add all the methods from an object property (which is an Extension) to this object.
protected
addWrapperMethod(string $method, string $wrap)
Add a wrapper method - a method which points to another method with a different name. For example, Thumbnail(x) can be wrapped to generateThumbnail(x)
protected
addCallbackMethod(string $method, callable $callback)
Add callback as a method.
protected
beforeExtending(string $method, callable $callback)
Allows user code to hook into Object::extend prior to control being delegated to extensions. Each callback will be reset once called.
protected
afterExtending(string $method, callable $callback)
Allows user code to hook into Object::extend after control being delegated to extensions. Each callback will be reset once called.
protected
defineExtensionMethods()
Adds any methods from Extension instances attached to this object.
All these methods can then be called directly on the instance (transparently mapped through __call()}), or called explicitly through {@link extend().
static bool
add_extension(string $classOrExtension, string $extension = null)
Add an extension to a specific class.
The preferred method for adding extensions is through YAML config, since it avoids autoloading the class, and is easier to override in more specific configurations.
As an alternative, extensions can be added to a specific class directly in the Object::$extensions array. See SiteTree::$extensions for examples. Keep in mind that the extension will only be applied to new instances, not existing ones (including all instances created through singleton()).
static
remove_extension(string $extension)
Remove an extension from a class.
Note: This will not remove extensions from parent classes, and must be called directly on the class assigned the extension.
Keep in mind that this won't revert any datamodel additions of the extension at runtime, unless its used before the schema building kicks in (in your _config.php). Doesn't remove the extension from any Object instances which are already created, but will have an effect on new extensions. Clears any previously created singletons through singleton() to avoid side-effects from stale extension information.
static array
get_extensions(string $class = null, bool $includeArgumentString = false)
No description
static array|null
get_extra_config_sources(string $class = null)
Get extra config sources for this class
static bool
has_extension(string $classOrExtension, string $requiredExtension = null, bool $strict = false)
Return TRUE if a class has a specified extension.
This supports backwards-compatible format (static Object::has_extension($requiredExtension)) and new format ($object->has_extension($class, $requiredExtension))
array
invokeWithExtensions(string $method, mixed ...$arguments)
Calls a method if available on both this object and all applied Extensions, and then attempts to merge all results into an array
array
extend(string $method, mixed ...$arguments)
Run the given function on all of this object's extensions. Note that this method originally returned void, so if you wanted to return results, you're hosed
Currently returns an array, with an index resulting every time the function is called. Only adds returns if they're not NULL, to avoid bogus results from methods just defined on the parent extension. This is important for permission-checks through extend, as they use min() to determine if any of the returns is FALSE. As min() doesn't do type checking, an included NULL return would fail the permission checks.
The extension methods are defined during __construct()} in {@link defineMethods().
Extension|null
getExtensionInstance(string $extension)
Get an extension instance attached to this object by name.
bool
hasExtension(string $extension)
Returns TRUE if this object instance has a specific extension applied in $extension_instances. Extension instances are initialized at constructor time, meaning if you use add_extension() afterwards, the added extension will just be added to new instances of the extended class. Use the static method has_extension() to check if a class (not an instance) has a specific extension.
Caution: Don't use singleton(
Extension[]
getExtensionInstances()
Get all extension instances for this specific object instance.
See get_extensions() to get all applied extension classes for this class (not the instance).
This method also provides lazy-population of the extension_instances property.
static Config_ForClass
config()
Get a configuration accessor for this class. Short hand for Config::inst()->get($this->class, .....).
mixed
uninherited(string $name)
Gets the uninherited value for the given config option
static CacheInterface
get_cache()
Get the cache object used for LDAP results. Note that the default lifetime set here is 8 hours, but you can change that by adding configuration:
SilverStripe\Core\Injector\Injector:
Psr\SimpleCache\CacheInterface.ldap:
constructor:
defaultLifetime: 3600 # time in seconds
static
flush()
Flushes out the LDAP results cache when flush=1 is called.
setGateway($gateway)
Setter for gateway. Useful for overriding the gateway with a fake for testing.
LDAPGateway
getGateway()
Return the LDAP gateway currently in use. Can be strung together to access the underlying Laminas\Ldap instance, or the PHP ldap resource itself. For example:
- Get the Laminas\Ldap object: $service->getGateway()->getLdap() // Laminas\Ldap\Ldap object
- Get the underlying PHP ldap resource: $service->getGateway()->getLdap()->getResource() // php resource
bool
enabled()
Checkes whether or not the service is enabled.
array
authenticate(string $username, string $password)
Authenticate the given username and password with LDAP.
array
getNodes(bool $cached = true, array $attributes = [])
Return all nodes (organizational units, containers, and domains) within the current base DN.
array
getGroups(bool $cached = true, array $attributes = [], string $indexBy = 'dn')
Return all AD groups in configured search locations, including all nested groups.
Uses groups_search_locations if defined, otherwise falls back to NULL, which tells LDAPGateway to use the default baseDn defined in the connection.
array
getNestedGroups(string $dn, array $attributes = [])
Return all member groups (and members of those, recursively) underneath a specific group DN.
Note that these get cached in-memory per-request for performance to avoid re-querying for the same results.
array
getGroupByGUID(string $guid, array $attributes = [])
Get a particular AD group's data given a GUID.
array
getGroupByDN(string $dn, array $attributes = [])
Get a particular AD group's data given a DN.
array
getUsers(array $attributes = [])
Return all AD users in configured search locations, including all users in nested groups.
Uses users_search_locations if defined, otherwise falls back to NULL, which tells LDAPGateway to use the default baseDn defined in the connection.
array
getUserByGUID(string $guid, array $attributes = [])
Get a specific AD user's data given a GUID.
array
getUserByDN(string $dn, array $attributes = [])
Get a specific AD user's data given a DN.
array
getUserByEmail(string $email, array $attributes = [])
Get a specific user's data given an email.
array
getUserByUsername(string $username, array $attributes = [])
Get a specific user's data given a username.
string|null
getUsernameByEmail(string $email)
Get a username for an email.
array
getLDAPGroupMembers(string $dn)
Given a group DN, get the group membership data in LDAP.
protected bool
processThumbnailPhoto(Member $member, string $fieldName, array $data, string $attributeName)
Attempts to process the thumbnail photo for a given user and store it against a Member object. This will
overwrite any old file with the same name. The filename of the photo will be set to 'thumbnailphoto-
At the moment only JPEG files are supported, as this is mainly to support Active Directory, which always provides the photo in a JPEG format, and always at a specific resolution.
updateMemberGroups(array $data, Member $member, array $mappedGroupsToKeep = [])
Ensure the user is mapped to any applicable groups.
bool
updateGroupFromLDAP(Group $group, array $data)
Sync a specific Group by updating it with LDAP data.
createLDAPUser(Member $member)
Creates a new LDAP user from the passed Member record.
Note that the Member record must have a non-empty Username field for this to work.
createLDAPGroup(Group $group)
Creates a new LDAP group from the passed Group record.
updateLDAPFromMember(Member $member)
Update the Member data back to the corresponding LDAP user object.
updateLDAPGroupsForMember(Member $member)
Ensure the user belongs to the correct groups in LDAP from their membership to local LDAP mapped SilverStripe groups.
This also removes them from LDAP groups if they've been taken out of one. It will not affect group membership of non-mapped groups, so it will not touch such internal AD groups like "Domain Users".
addLDAPUserToGroup(string $userDn, string $groupDn)
Add LDAP user by DN to LDAP group.
ValidationResult
setPassword(Member $member, string $password, string|null $oldPassword = null)
Change a members password on the AD. Works with ActiveDirectory compatible services that saves the
password in the unicodePwd
attribute.
Ensure that the LDAP bind:ed user can change passwords and that the connection is secure.
deleteLDAPMember(Member $member)
Delete an LDAP user mapped to the Member record
update(string $dn, array $attributes)
A simple proxy to LDAP update operation.
delete(string $dn, bool $recursively = false)
A simple proxy to LDAP delete operation.
move(string $fromDn, string $toDn, bool $recursively = false)
A simple proxy to LDAP copy/delete operation.
add(string $dn, array $attributes)
A simple proxy to LDAP add operation.
LoggerInterface
getLogger()
Get a logger