- Added the update keyword allowing modification for one field.

This commit is contained in:
Dave M. 2021-03-24 13:48:28 +00:00
parent fa806e8e0d
commit 1b11917bf5
9 changed files with 186 additions and 21 deletions

View File

@ -17,6 +17,8 @@ class Ldap implements \Ulmus\Adapter\AdapterInterface {
public int $version = 3; public int $version = 3;
public bool $encrypt; public bool $encrypt;
public bool $forceSSL = false;
public array $hosts; public array $hosts;
@ -106,7 +108,10 @@ class Ldap implements \Ulmus\Adapter\AdapterInterface {
$ldapObject->startTLS(); $ldapObject->startTLS();
} }
elseif ($this->forceSSL) {
$ldapObject->startTLS();
}
return $ldapObject; return $ldapObject;
} }
@ -135,12 +140,13 @@ class Ldap implements \Ulmus\Adapter\AdapterInterface {
throw new AdapterConfigurationException("Your `account_suffix` is missing from your configuration array"); throw new AdapterConfigurationException("Your `account_suffix` is missing from your configuration array");
} }
/* if ( false !== ( $configuration['force_ssl'] ?? false ) ) {
if ( false !== ( $configuration['app'] ?? false ) ) { $this->forceSSL = true;
$this->app = $configuration['app'];
} }
*/
if ( getenv('DEBUG') ) {
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
}
} }
public function escapeIdentifier(string $segment, int $type, string $ignore = "") : string public function escapeIdentifier(string $segment, int $type, string $ignore = "") : string

View File

@ -2,7 +2,7 @@
namespace Ulmus\Ldap\Common; namespace Ulmus\Ldap\Common;
use function ldap_set_option, ldap_start_tls, ldap_bind, ldap_unbind, ldap_connect, ldap_close, ldap_get_entries, ldap_count_entries; use function ldap_set_option, ldap_start_tls, ldap_bind, ldap_unbind, ldap_connect, ldap_close, ldap_get_entries, ldap_mod_replace, ldap_count_entries, ldap_errno, ldap_error;
class LdapObject { class LdapObject {
@ -27,7 +27,7 @@ class LdapObject {
public function connect(string $host, string $baseDn) : bool public function connect(string $host, string $baseDn) : bool
{ {
$this->connection = ldap_connect($host); $this->connection = ldap_connect("ldap://$host");
$this->dn = $baseDn; $this->dn = $baseDn;
@ -46,7 +46,7 @@ class LdapObject {
ldap_start_tls($this->connection); ldap_start_tls($this->connection);
} }
public function bind(? string $dn, ? string $password) : bool public function bind(? string $dn, ? string $password = null) : bool
{ {
if ($this->binded) { if ($this->binded) {
throw new \Exception("LdapObject is already binded with a user. Use the unbind() method to release it."); throw new \Exception("LdapObject is already binded with a user. Use the unbind() method to release it.");
@ -62,6 +62,13 @@ class LdapObject {
} }
} }
public function rebind(? string $dn, ? string $password = null) : bool
{
$this->unbind();
return $this->bind($dn, $password);
}
public function select(array $filter, array $fields = []) public function select(array $filter, array $fields = [])
{ {
static::$dump && call_user_func_array(static::$dump, [ $filter, $fields ]); static::$dump && call_user_func_array(static::$dump, [ $filter, $fields ]);
@ -94,13 +101,15 @@ class LdapObject {
if ($result) { if ($result) {
$this->bufferedRows--; $this->bufferedRows--;
$dataset = []; $dataset = [
'dn' => ldap_get_dn($this->connection, $result)
];
if ( $attributes = ldap_get_attributes($this->connection, $result) ) { if ( $attributes = ldap_get_attributes($this->connection, $result) ) {
for ($i = 0; $i < $attributes['count']; $i++) { for ($i = 0; $i < $attributes['count']; $i++) {
$key = $attributes[$i]; $key = $attributes[$i];
$dataset[strtolower($key)] = $attributes[$key][0]; $dataset[$key] = $attributes[$key][0];
} }
} }
@ -110,15 +119,33 @@ class LdapObject {
return false; return false;
} }
public function rowCount() : int
{
return $this->rowCount;
}
public function fetchAll() public function fetchAll()
{ {
return ldap_get_entries($this->connection, $result); return ldap_get_entries($this->connection, $result);
} }
public function rowCount() : int
{
return $this->rowCount;
}
public function runQuery(array $filter, array $dataset)
{
static::$dump && call_user_func_array(static::$dump, [ $filter, $dataset ]);
if ( false === ( $queryResult = ldap_mod_replace($this->connection, $filter['dn'], $dataset) ) ) {
$this->throwLdapException();
}
$this->rowCount = 1;
return $this;
}
protected function throwLdapException() : void
{
throw new \Exception(sprintf('LDAP error #%s `%s`', ldap_errno($this->connection), ldap_error($this->connection)));
}
public function closeCursor() : void {} public function closeCursor() : void {}
} }

View File

@ -0,0 +1,35 @@
<?php
namespace Ulmus\Ldap\Common;
class PasswordHelper {
public static function unicode(string $password) : string
{
return mb_convert_encoding("\"$password\"", "UTF-16LE");
}
public static function hashSHA(string $password) : string
{
return '{SHA}' . base64_encode(sha1($password, true));
}
public static function hashSSHA(string $password) : string
{
$salt = static::salt();
return '{SSHA}' . base64_encode(sha1($password . $salt, true) . $salt);
}
public static function hashMD5(string $password) : string
{
$salt = static::salt();
$newmailbox["userpassword"] = "{MD5}" . base64_encode( sha1( $password . $salt, true) . $salt );
}
protected static function salt(int $length = 4, int $shuffle = 10) : string
{
return substr(str_shuffle(str_repeat('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',$shuffle)),0,$length);
}
}

View File

@ -12,7 +12,7 @@ class User
use \Ulmus\Ldap\EntityTrait; use \Ulmus\Ldap\EntityTrait;
/** /**
* @Id * @Field
*/ */
public string $samaccountname; public string $samaccountname;
@ -111,20 +111,30 @@ class User
*/ */
public int $logonCount; public int $logonCount;
/**
* @Field('name' => 'unicodePwd')
*/
public string $unicodePassword;
/**
* @Field
*/
public string $userPassword;
/** /**
* @Field * @Field
*/ */
public Datetime $lastLogonDate; public Datetime $lastLogonDate;
/** /**
* @Field('name' => 'createTimeStamp') * #Field('name' => 'createTimeStamp')
*/ */
public Datetime $createdAt; # public Datetime $createdAt;
/** /**
* @Field('name' => 'modifyTimeStamp') * #Field('name' => 'modifyTimeStamp')
*/ */
public Datetime $updatedAt; # public Datetime $updatedAt;
public function __toString() : string public function __toString() : string
{ {

View File

@ -9,6 +9,11 @@ use Ulmus\Ldap\Annotation\Classes\{ ObjectClass, };
trait EntityTrait { trait EntityTrait {
use \Ulmus\EntityTrait; use \Ulmus\EntityTrait;
/**
* @Id
*/
public string $dn;
public static function resolveEntity() : EntityResolver public static function resolveEntity() : EntityResolver
{ {
return Ulmus::resolveEntity(static::class); return Ulmus::resolveEntity(static::class);

21
src/Query/Set.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace Ulmus\Ldap\Query;
class Set extends \Ulmus\Query\Set
{
public function render() /* : mixed */
{
foreach($this->dataset as $key => $value) {
$this->queryBuilder->addParameter($value, $key);
$fields[] = $this->escapedFields[$key] ?? $key;
}
return [
'fields' => $fields,
];
}
}

17
src/Query/Update.php Normal file
View File

@ -0,0 +1,17 @@
<?php
namespace Ulmus\Ldap\Query;
class Update extends \Ulmus\Query\Fragment {
public int $order = -100;
public string $dn;
public function render() : array
{
return [
'dn' => $this->dn,
];
}
}

View File

@ -43,13 +43,32 @@ class QueryBuilder implements Ulmus\Query\QueryBuilderInterface
return $this; return $this;
} }
public function set(array $dataset, ? array $escapedFields = null) : self
{
if ( null === ( $set = $this->getFragment(Query\Set::class) ) ) {
$set = new Query\Set($this);
$this->push($set);
}
$set->set($dataset, $escapedFields);
return $this;
}
public function from(string $table, ? string $alias, ? string $schema) : self public function from(string $table, ? string $alias, ? string $schema) : self
{ {
return $this; return $this;
} }
public function update(string $table, ? string $alias = null, ? string $database = null, ? string $schema = null) : self public function update(string $dn) : self
{ {
if ( null === ( $update = $this->getFragment(Query\Update::class) ) ) {
$update = new Query\Update($this);
$this->push($update);
}
$update->dn = $dn;
return $this; return $this;
} }

View File

@ -34,6 +34,31 @@ class Repository extends \Ulmus\Repository
return $this; return $this;
} }
protected function updateSqlQuery(array $dataset) : self
{
$condition = array_pop($this->queryBuilder->where->conditionList);
if ($condition[0] === 'dn') {
if ( null === $this->queryBuilder->getFragment(Query\Update::class) ) {
$this->update($condition[1], "", "");
}
}
else {
array_push($this->queryBuilder->where->conditionList, $condition);
}
$this->set($dataset);
return $this;
}
public function update(string $dn, string $alias, ? string $schema) : self
{
$this->queryBuilder->update($dn, "", "");
return $this;
}
public function escapeValue(string $identifier) : string public function escapeValue(string $identifier) : string
{ {
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\Ldap::IDENTIFIER_FILTER); return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\Ldap::IDENTIFIER_FILTER);