228 lines
5.9 KiB
PHP

<?php
namespace Ulmus\Ldap\Adapter;
use Ulmus\{Adapter\AdapterInterface,
Common\PdoObject,
Exception\AdapterConfigurationException,
Ldap\Entity\User,
Migration\FieldDefinition,
Ulmus};
use LDAP\Result;
use Ulmus\Ldap\Common\LdapObject;
use function ldap_set_option, ldap_start_tls, ldap_bind, ldap_unbind, ldap_connect, ldap_close, ldap_get_entries;
class Ldap implements \Ulmus\Adapter\AdapterInterface {
const ALLOWED_ATTRIBUTES = [
''
];
public const IDENTIFIER_DN = 101;
public const IDENTIFIER_FILTER = 102;
public int $version = 3;
public bool $encrypt;
public bool $forceSSL = false;
public array $hosts;
public string $baseDn;
public string $username;
public string $password;
public string $accountSuffix;
public string $pathCertCrt;
public string $pathCertKey;
public LdapObject $ldapObject;
public function __construct(
? string/*|array*/ $host = null,
? string $baseDn = null,
? string $username = null,
? string $password = null,
? string $accountSuffix = null
) {
if ($host) {
$this->hosts = is_array($host) ? $host : [ $host ];
}
if ($baseDn) {
$this->baseDn = $baseDn;
}
if ($username) {
$this->username = $username;
}
if ($password) {
$this->password = $password;
}
if ($accountSuffix) {
$this->accountSuffix = $accountSuffix;
}
}
public function authenticate(string $dn, string $password) : false|Result
{
$this->ldapObject = $this->getLdapObject();
return $this->ldapObject->bind($dn, $password);
}
public function connect() : object
{
$this->ldapObject = $this->getLdapObject();
$this->bindUser();
return $this->ldapObject;
}
public function bindUser() : void
{
if ( ! $this->ldapObject->bind($this->username, $this->password) ) {
throw new \Exception("LDAP bind failed with given user {$this->username}.");
}
}
protected function getLdapObject() : LdapObject
{
$ldapObject = new LdapObject();
$ldapObject->connect($this->hosts[0], $this->baseDn);
$ldapObject->setOptions([
\LDAP_OPT_PROTOCOL_VERSION => $this->version,
\LDAP_OPT_REFERRALS => 0,
]);
if ( isset($this->pathCertCrt) && isset($this->pathCertKey) ) {
$ldapObject->setOptions([
\LDAP_OPT_X_TLS_CERTFILE => $this->pathCertCrt,
\LDAP_OPT_X_TLS_KEYFILE => $this->pathCertKey,
], false);
$ldapObject->startTLS();
}
elseif ($this->forceSSL) {
$ldapObject->startTLS();
}
return $ldapObject;
}
public function buildDataSourceName() : string
{
return "";
}
public function setup(array $configuration) : void
{
$configuration = array_change_key_case($configuration, \CASE_LOWER);
if ( false === ( $this->hosts = $configuration['hosts'] ?? false ) ) {
throw new AdapterConfigurationException("Your `host` setting is missing. It is a mandatory parameter for this driver.");
}
elseif ( false === ( $this->baseDn = $configuration['base_dn'] ?? false ) ) {
throw new AdapterConfigurationException("Your `base_dn` setting is missing. The adapter won't connect without it.");
}
elseif ( false === ( $this->username = $configuration['username'] ?? false ) ) {
throw new AdapterConfigurationException("Your `username` is missing from your configuration array");
}
elseif ( false === ( $this->password = $configuration['password'] ?? false ) ) {
throw new AdapterConfigurationException("Your `password` is missing from your configuration array");
}
elseif ( false === ( $this->accountSuffix = $configuration['account_suffix'] ?? false ) ) {
throw new AdapterConfigurationException("Your `account_suffix` is missing from your configuration array");
}
if ( false !== ( $configuration['force_ssl'] ?? false ) ) {
$this->forceSSL = true;
}
if ( getenv('DEBUG') ) {
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
}
}
public function writableValue(/* mixed */ $value) /*: mixed*/
{
switch (true) {
case is_object($value):
return Ulmus::convertObject($value);
}
return $value;
}
public function escapeIdentifier(string $segment, int $type, string $ignore = "") : string
{
switch($type) {
case static::IDENTIFIER_DN:
return ldap_escape($segment, $ignore, LDAP_ESCAPE_DN);
case static::IDENTIFIER_FILTER:
case static::IDENTIFIER_FIELD:
return ldap_escape($segment, $ignore, LDAP_ESCAPE_FILTER);
default:
return ldap_escape($segment, $ignore);
}
}
public function defaultEngine(): ? string
{
return null;
}
public function repositoryClass() : string
{
return \Ulmus\Ldap\Repository::class;
}
public function queryBuilderClass() : string
{
return \Ulmus\Ldap\QueryBuilder::class;
}
public function tableSyntax() : array
{
return [
];
}
public function databaseName() : string
{
return $this->baseDn;
}
public function whitelistAttributes(array &$parameters) : void
{
$parameters = array_intersect_key($parameters, array_flip(static::ALLOWED_ATTRIBUTES));
}
public function generateAlterColumn(FieldDefinition $definition, array $field) : string|\Stringable
{
return implode(" ", [
]);
}
public function splitAlterQuery() : bool
{
return false;
}
}