Add Link class to allow mock LDAP link in unit tests
This commit is contained in:
parent
db27becda5
commit
d183309280
2 changed files with 211 additions and 16 deletions
33
src/Ldap.php
33
src/Ldap.php
|
@ -88,7 +88,7 @@ class Ldap {
|
|||
|
||||
/**
|
||||
* The LDAP connection
|
||||
* @var resource|false
|
||||
* @var Link|false
|
||||
*/
|
||||
protected $_link = false;
|
||||
|
||||
|
@ -100,12 +100,12 @@ class Ldap {
|
|||
|
||||
/**
|
||||
* Scopes associated with their search function
|
||||
* @var array<string,callable>
|
||||
* @var array<string,string>
|
||||
*/
|
||||
protected static $search_function_by_scope = array(
|
||||
'one' => 'ldap_list',
|
||||
'base' => 'ldap_read',
|
||||
'sub' => 'ldap_search',
|
||||
'one' => 'list',
|
||||
'base' => 'read',
|
||||
'sub' => 'search',
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -242,14 +242,15 @@ class Ldap {
|
|||
return false;
|
||||
|
||||
foreach($this -> hosts as $host) {
|
||||
$this->_link = @ldap_connect($host, $this->port);
|
||||
if ($this->_link === false) {
|
||||
$this->_link = new Link();
|
||||
if ($this->_link->connect($host, $this->port) === false) {
|
||||
$this->_link = false;
|
||||
$this -> error("Fail to connect on $host", false);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->starttls) {
|
||||
if (@ldap_start_tls($this->_link) === false) {
|
||||
if ($this->_link->start_tls() === false) {
|
||||
$this -> close();
|
||||
$this -> error("Fail to start TLS on $host", false);
|
||||
continue;
|
||||
|
@ -298,7 +299,7 @@ class Ldap {
|
|||
if (is_null($dn)) $dn = $this -> bind_dn;
|
||||
if (is_null($password)) $password = $this -> bind_password;
|
||||
if (!$this -> _link) return $this -> connect($raise, $dn, $password);
|
||||
if (@ldap_bind($this->_link, $dn, $password) === false)
|
||||
if ($this->_link->bind($dn, $password) === false)
|
||||
return $this -> log_error($dn?"Fail to bind as $dn":"Fail to anonymously bind", $raise);
|
||||
return true;
|
||||
}
|
||||
|
@ -320,7 +321,7 @@ class Ldap {
|
|||
if (!is_string($option) || !defined($option) || strpos($option, 'LDAP_') !== 0)
|
||||
return $this->error("Unkown Option requested", $raise);
|
||||
// @phpstan-ignore-next-line
|
||||
if (@ldap_set_option($this->_link, constant($option), $value))
|
||||
if ($this->_link->set_option(constant($option), $value))
|
||||
return true;
|
||||
return $this -> log_error("Fail to set option $option", $raise);
|
||||
}
|
||||
|
@ -331,7 +332,7 @@ class Ldap {
|
|||
*/
|
||||
public function close() {
|
||||
if ($this->_link)
|
||||
@ldap_close($this->_link);
|
||||
$this->_link->close();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -344,10 +345,10 @@ class Ldap {
|
|||
protected function log_error($prefix, $raise=null, ...$extra_args) {
|
||||
if ($extra_args)
|
||||
$prefix = call_user_func_array('sprintf', array_merge(array($prefix), $extra_args));
|
||||
$errno = $this->_link?@ldap_errno($this->_link):false;
|
||||
$errno = $this->_link?$this->_link->errno():false;
|
||||
if (!$errno)
|
||||
return $this -> error("%s: unkown error", $raise, $prefix);
|
||||
$err = @ldap_err2str($errno);
|
||||
$err = $this->_link?$this->_link->err2str($errno):false;
|
||||
if (!$err)
|
||||
return $this -> error("%s: error #%s", $raise, $errno);
|
||||
return $this -> error("%s: %s (#%s)", $raise, $err, $errno);
|
||||
|
@ -474,8 +475,8 @@ class Ldap {
|
|||
|
||||
// Run the search
|
||||
$search = @call_user_func(
|
||||
self :: $search_function_by_scope[$scope],
|
||||
$this->_link,
|
||||
// @phpstan-ignore-next-line
|
||||
array($this->_link, self :: $search_function_by_scope[$scope]),
|
||||
$base,
|
||||
$filter,
|
||||
self :: get_param($params, 'attributes', array(), 'array'),
|
||||
|
@ -489,7 +490,7 @@ class Ldap {
|
|||
"Error occured searching on base '%s' with filter '%s'", $raise, $base, $filter);
|
||||
|
||||
// @phpstan-ignore-next-line
|
||||
$result = ldap_get_entries($this->_link, $search);
|
||||
$result = $this->_link->get_entries($search);
|
||||
if (!is_array($result))
|
||||
return $this -> log_error(
|
||||
"Error occured retreiving the result of the search on base '%s' with filter '%s'",
|
||||
|
|
194
src/Link.php
Normal file
194
src/Link.php
Normal file
|
@ -0,0 +1,194 @@
|
|||
<?php
|
||||
namespace EesyLDAP;
|
||||
|
||||
|
||||
class Link {
|
||||
|
||||
/**
|
||||
* The LDAP connection
|
||||
* @var resource|false
|
||||
*/
|
||||
protected $_link = false;
|
||||
|
||||
/**
|
||||
* Connect on LDAP host
|
||||
* @param string $uri LDAP server URI
|
||||
* @param int|null $port Optional LDAP server port (default: null == 389)
|
||||
* @see ldap_connect()
|
||||
* @return bool
|
||||
*/
|
||||
public function connect($uri, $port=null) {
|
||||
$this->_link = @ldap_connect($uri, is_null($port)?389:$port);
|
||||
return boolval($this->_link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start TLS
|
||||
* @see ldap_start_tls()
|
||||
* @return bool
|
||||
*/
|
||||
public function start_tls() {
|
||||
if (!$this -> _link) return false;
|
||||
return @ldap_start_tls($this->_link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the LDAP error number of the last LDAP command
|
||||
* @see ldap_errno()
|
||||
* @return int|false
|
||||
*/
|
||||
public function errno() {
|
||||
if (!$this -> _link) return false;
|
||||
return @ldap_errno($this->_link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert LDAP error number into string error message
|
||||
* @param int $errno
|
||||
* @see ldap_err2str()
|
||||
* @return string
|
||||
*/
|
||||
public function err2str($errno) {
|
||||
return @ldap_err2str($errno);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind on LDAP link
|
||||
* @param string|null $dn Bind DN (optional, default: null = anonymous bind)
|
||||
* @param string|null $password Bind password (optional, default: null = anonymous bind)
|
||||
* @see ldap_bind()
|
||||
* @return bool
|
||||
*/
|
||||
public function bind($dn=null, $password=null) {
|
||||
if (!$this -> _link) return false;
|
||||
return @ldap_bind($this->_link, $dn, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an LDAP option
|
||||
*
|
||||
* @param int $option Option to set
|
||||
* @param string|int|bool $value Value to set Option to
|
||||
*
|
||||
* @see ldap_set_option()
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function set_option($option, $value) {
|
||||
if (!$this->_link)
|
||||
return false;
|
||||
return @ldap_set_option($this->_link, $option, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Single-level search
|
||||
*
|
||||
* @param string $base The base DN of the search
|
||||
* @param string $filter The LDAP filter string of the search
|
||||
* @param array<string> $attributes Array of expected attribute names (optional, default: all)
|
||||
* @param int $attributes_only If 1, only attribute names will be return (optional, default: 0)
|
||||
* @param int $sizelimit Limit the count of entries fetched (optional, default: -1)
|
||||
* @param int $timelimit Number of seconds how long is spend on the search (optional, default: -1)
|
||||
* @param int $deref Specifies how aliases should be handled during the search (optional,
|
||||
* default: LDAP_DEREF_NEVER)
|
||||
* @param array<array<mixed>> $controls Array of LDAP Controls to send with the request
|
||||
* (optional, default: null)
|
||||
*
|
||||
* @see ldap_list()
|
||||
* @access public
|
||||
* @return resource|false
|
||||
*/
|
||||
public function list(
|
||||
$base, $filter, $attributes=[], $attributes_only=0, $sizelimit=-1, $timelimit=-1,
|
||||
$deref=LDAP_DEREF_NEVER, $controls=[]
|
||||
) {
|
||||
if (!$this->_link)
|
||||
return false;
|
||||
return @ldap_list(
|
||||
$this->_link, $base, $filter, $attributes, $attributes_only, $sizelimit, $timelimit, $deref,
|
||||
$controls
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an LDAP entry
|
||||
*
|
||||
* @param string $base The base DN of the search
|
||||
* @param string $filter The LDAP filter string of the search
|
||||
* @param array<string> $attributes Array of expected attribute names (optional, default: all)
|
||||
* @param int $attributes_only If 1, only attribute names will be return (optional, default: 0)
|
||||
* @param int $sizelimit Limit the count of entries fetched (optional, default: -1)
|
||||
* @param int $timelimit Number of seconds how long is spend on the search (optional, default: -1)
|
||||
* @param int $deref Specifies how aliases should be handled during the search (optional,
|
||||
* default: LDAP_DEREF_NEVER)
|
||||
* @param array<array<mixed>> $controls Array of LDAP Controls to send with the request
|
||||
* (optional, default: empty array)
|
||||
*
|
||||
* @see ldap_read()
|
||||
* @access public
|
||||
* @return resource|false
|
||||
*/
|
||||
public function read(
|
||||
$base, $filter, $attributes=[], $attributes_only=0, $sizelimit=-1, $timelimit=-1,
|
||||
$deref=LDAP_DEREF_NEVER, $controls=[]
|
||||
) {
|
||||
if (!$this->_link)
|
||||
return false;
|
||||
return ldap_read(
|
||||
$this->_link, $base, $filter, $attributes, $attributes_only, $sizelimit, $timelimit, $deref,
|
||||
$controls
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search in LDAP tree
|
||||
*
|
||||
* @param string $base The base DN of the search
|
||||
* @param string $filter The LDAP filter string of the search
|
||||
* @param array<string> $attributes Array of expected attribute names (optional, default: all)
|
||||
* @param int $attributes_only If 1, only attribute names will be return (optional, default: 0)
|
||||
* @param int $sizelimit Limit the count of entries fetched (optional, default: -1)
|
||||
* @param int $timelimit Number of seconds how long is spend on the search (optional, default: -1)
|
||||
* @param int $deref Specifies how aliases should be handled during the search (optional,
|
||||
* default: LDAP_DEREF_NEVER)
|
||||
* @param array<array<mixed>> $controls Array of LDAP Controls to send with the request
|
||||
* (optional, default: empty array)
|
||||
*
|
||||
* @see ldap_search()
|
||||
* @access public
|
||||
* @return resource|false
|
||||
*/
|
||||
public function search(
|
||||
$base, $filter, $attributes=[], $attributes_only=0, $sizelimit=-1, $timelimit=-1,
|
||||
$deref=LDAP_DEREF_NEVER, $controls=[]
|
||||
) {
|
||||
if (!$this->_link)
|
||||
return false;
|
||||
return @ldap_search(
|
||||
$this->_link, $base, $filter, $attributes, $attributes_only, $sizelimit, $timelimit, $deref,
|
||||
$controls
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all result entries
|
||||
* @param resource $result An LDAP\Result instance, returned by ldap_list() or ldap_search()
|
||||
* @see ldap_get_entries()
|
||||
* @return array<mixed>|false
|
||||
*/
|
||||
public function get_entries($result) {
|
||||
if (!$this -> _link) return false;
|
||||
return @ldap_get_entries($this->_link, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close LDAP link (if established)
|
||||
* @see ldap_close()
|
||||
* @return void
|
||||
*/
|
||||
public function close() {
|
||||
if ($this->_link)
|
||||
@ldap_close($this->_link);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue