diff --git a/classes/Database/LDAP/Search/Result.php b/classes/Database/LDAP/Search/Result.php new file mode 100644 index 0000000..9bc35e2 --- /dev/null +++ b/classes/Database/LDAP/Search/Result.php @@ -0,0 +1,4 @@ + diff --git a/classes/Kohana/Auth/LDAP.php b/classes/Kohana/Auth/LDAP.php index 429a163..1f37156 100644 --- a/classes/Kohana/Auth/LDAP.php +++ b/classes/Kohana/Auth/LDAP.php @@ -9,7 +9,7 @@ * @copyright (c) 2013 phpLDAPadmin Development Team * @license http://dev.phpldapadmin.org/license.html */ -class Kohana_Auth_LDAP extends Auth { +abstract class Kohana_Auth_LDAP extends Auth { // Unnused required abstract functions public function password($username) {} public function check_password($password) {} diff --git a/classes/Kohana/Database/LDAP.php b/classes/Kohana/Database/LDAP.php index 39a7255..b399063 100644 --- a/classes/Kohana/Database/LDAP.php +++ b/classes/Kohana/Database/LDAP.php @@ -21,10 +21,6 @@ abstract class Kohana_Database_LDAP extends Kohana_LDAP { * @defunct This required abstruct function is defunct for LDAP */ public function commit() { throw HTTP_Exception::factory(501,'We shouldnt be here: :method',array(':method'=>__METHOD__)); } - /** - * @defunct This required abstruct function is defunct for LDAP - */ - public function list_columns($table, $like = NULL, $add_prefix = TRUE) { throw HTTP_Exception::factory(501,'We shouldnt be here: :method',array(':method'=>__METHOD__)); } /** * @defunct This required abstruct function is defunct for LDAP */ @@ -45,6 +41,13 @@ abstract class Kohana_Database_LDAP extends Kohana_LDAP { /** REQUIRED ABSTRACT FUNCTIONS **/ public function escape($value) { return $value;} + /** + * @override We provide the columns that are in all LDAP objects + */ + public function list_columns($table,$like=NULL,$add_prefix=TRUE) { + return array('dn'=>array(),'objectclass'=>array()); + } + /** * @override We override this parent function, since LDAP doesnt quote columns */ @@ -166,7 +169,7 @@ abstract class Kohana_Database_LDAP extends Kohana_LDAP { $u = $x->search(NULL) ->scope('sub') ->where($this->_config['login_attr'],'=',$user) - ->run(); + ->execute(); if (! $u) return FALSE; @@ -178,10 +181,9 @@ abstract class Kohana_Database_LDAP extends Kohana_LDAP { die(); } - foreach ($u as $base => $entries) - foreach ($entries as $dn => $details) - if ($this->_bind($dn,$pass)) - return $this; + foreach ($u as $dn => $leaf) + if ($this->_bind($dn,$pass)) + return $this; // We didnt find an AUTH DN to bind with return FALSE; diff --git a/classes/Kohana/Database/LDAP/Result.php b/classes/Kohana/Database/LDAP/Result.php index ca26776..e873ff3 100644 --- a/classes/Kohana/Database/LDAP/Result.php +++ b/classes/Kohana/Database/LDAP/Result.php @@ -1,4 +1,5 @@ _current_entry) + return array(); + + if ($this->_as_object === TRUE) { + // Return an stdClass + throw HTTP_Exception::factory(501,'Not implemented'); + + } elseif (is_string($this->_as_object)) { + // Return an object of given class name + throw HTTP_Exception::factory(501,'Not implemented'); + + } else { + // Return an array of the row + // @todo We could probably cache this for optimisation + $attrs = $vals = array(); + array_push($attrs,ldap_first_attribute($this->_result['l'],$this->_current_entry)); + + while ($x = ldap_next_attribute($this->_result['l'],$this->_current_entry)) + array_push($attrs,$x); + + foreach ($attrs as $attr) { + $vals[strtolower($attr)] = ldap_get_values($this->_result['l'],$this->_current_entry,$attr); + + // We dont need the count entry + unset($vals[strtolower($attr)]['count']); + } + + $vals['dn'] = $this->key(); + return $vals; + } + } + + /** + * Implements [Iterator::key], returns the dn. + * + * echo key($result); + * + * @return string LDAP Distringuised Name + */ + public function key() { + return ldap_get_dn($this->_result['l'],$this->_current_entry); + } + + /** + * Implements [Iterator::next], moves to the next row. + * + * next($result); + * + * @return $this + */ + public function next() { + $this->_current_entry = ldap_next_entry($this->_result['l'],$this->_current_entry); + ++$this->_current_row; + + return $this; + } + + /** + * @override We cant go backwards! + */ + public function prev() { + throw new Kohana_Exception('Cant go backwards'); + } + + /** + * Implements [Iterator::rewind], moves to the first entry. + * + * reset($result); + * + * @return void + */ + public function rewind() { + if ($this->_total_rows) + $this->_current_entry = ldap_first_entry($this->_result['l'],$this->_result['r']); + + $this->_current_row = 0; + } + + /** + * Implements [SeekableIterator::seek], to seek to an entry. + * + * [!!] This method is only used internally. + * + * @return boolean + */ + public function seek($dn) { + $this->_current_entry = ldap_first_entry($this->_result['l'],$this->_result['r']); + + do { + if ($dn == $this->key()) + return TRUE; + + // Increment internal row for optimization assuming rows are fetched in order + $this->_current_entry = ldap_next_entry($this->_result['l'],$this->_current_entry); + + } while ($this->_current_entry); + + // We didnt find it + return FALSE; + } + + /** + * Implements [Iterator::valid], checks if the current row exists. + * + * [!!] This method is only used internally. + * + * @return boolean + */ + public function valid() { + return (boolean)$this->_current_entry; + } + + /** ArrayAccess **/ + + public function offsetExists($offset) { + return $this->valid(); + } + + /** Custom Methods **/ + public function __construct($result, $sql, $as_object = FALSE, array $params = NULL) { parent::__construct($result, $sql, $as_object, $params); @@ -53,104 +182,5 @@ class Kohana_Database_LDAP_Result extends Database_Result { return $result; } - - public function current() { - if (! $this->_current_entry) - return array(); - - if ($this->_as_object === TRUE) { - // Return an stdClass - throw HTTP_Exception::factory(501,'Not implemented'); - - } elseif (is_string($this->_as_object)) { - // Return an object of given class name - throw HTTP_Exception::factory(501,'Not implemented'); - - } else { - // Return an array of the row - // @todo We could probably cache this for optimisation - $attrs = $vals = array(); - array_push($attrs,ldap_first_attribute($this->_result['l'],$this->_current_entry)); - - while ($x = ldap_next_attribute($this->_result['l'],$this->_current_entry)) - array_push($attrs,$x); - - foreach ($attrs as $attr) { - $vals[strtolower($attr)] = ldap_get_values($this->_result['l'],$this->_current_entry,$attr); - - // We dont need the count entry - unset($vals[strtolower($attr)]['count']); - } - - return $vals; - } - } - - /** - * Implements [Iterator::key], returns the dn. - * - * echo key($result); - * - * @return integer - */ - public function key() { - return ldap_get_dn($this->_result['l'],$this->_current_entry); - } - - /** - * Implements [Iterator::next], moves to the next row. - * - * next($result); - * - * @return $this - */ - public function next() { - $this->_current_entry = ldap_next_entry($this->_result['l'],$this->_current_entry); - ++$this->_current_row; - - return $this; - } - - public function offsetExists($offset) { - return $this->valid(); - } - - public function prev() { - throw new Kohana_Exception('Cant go backwards'); - } - - public function seek($dn) { - $this->_current_entry = ldap_first_entry($this->_result['l'],$this->_result['r']); - - do { - if ($dn == $this->key()) - return TRUE; - - // Increment internal row for optimization assuming rows are fetched in order - $this->_current_entry = ldap_next_entry($this->_result['l'],$this->_current_entry); - - } while ($this->_current_entry); - - // We didnt find it - return FALSE; - } - - public function rewind() { - if ($this->_total_rows) - $this->_current_entry = ldap_first_entry($this->_result['l'],$this->_result['r']); - - $this->_current_row = 0; - } - - /** - * Implements [Iterator::valid], checks if the current row exists. - * - * [!!] This method is only used internally. - * - * @return boolean - */ - public function valid() { - return (boolean)$this->_current_entry; - } - } // End Database_LDAP_Result +?> diff --git a/classes/Kohana/Database/LDAP/Result/Cached.php b/classes/Kohana/Database/LDAP/Result/Cached.php index b10e497..f84f1e4 100644 --- a/classes/Kohana/Database/LDAP/Result/Cached.php +++ b/classes/Kohana/Database/LDAP/Result/Cached.php @@ -1,4 +1,5 @@ diff --git a/classes/Kohana/Database/LDAP/Search.php b/classes/Kohana/Database/LDAP/Search.php index e3f3e17..0ed99d0 100644 --- a/classes/Kohana/Database/LDAP/Search.php +++ b/classes/Kohana/Database/LDAP/Search.php @@ -27,6 +27,9 @@ abstract class Kohana_Database_LDAP_Search { // Cache lifetime protected $_lifetime = NULL; + // Parameters for __construct when using object results + protected $_object_params = array(); + /** * Callable database methods * @var array @@ -34,6 +37,14 @@ abstract class Kohana_Database_LDAP_Search { protected static $_db_methods = array( 'where', 'and_where', 'or_where', 'where_open', 'and_where_open', 'or_where_open', 'where_close', 'and_where_close', 'or_where_close', + 'limit', + ); + + /** + * ORM methods that are called, but dont do anything in LDAP + */ + protected static $_orm_ignore_methods = array( + 'from', ); /** @@ -74,18 +85,19 @@ abstract class Kohana_Database_LDAP_Search { // Return the property return $this->{'_'.$method}; - } - elseif (in_array($method,Database_LDAP_Search::$_db_methods)) - { + + } elseif (in_array($method,Database_LDAP_Search::$_db_methods)) { // Add pending database call which is executed after query type is determined $this->_db_pending[] = array('name' => $method,'args' => $args); return $this; - } - else - { - throw new Kohana_Exception('Invalid method :method called in :class', - array(':method' => $method,':class' => get_class($this))); + + } elseif (in_array($method,Database_LDAP_Search::$_orm_ignore_methods)) { + return $this; + + } else { + throw new Kohana_Exception('Invalid method :method called in :class (:args)', + array(':method' => $method,':class' => get_class($this),':args'=>print_r($args,TRUE))); } } @@ -99,16 +111,37 @@ abstract class Kohana_Database_LDAP_Search { $this->_db_applied[$name] = $name; - call_user_func_array(array($search,$name),$args); + switch ($name) { + case 'limit': + $this->_size_limit = $args[0]; + break; + + default: + call_user_func_array(array($search,$name),$args); + } } return $search; } + public function as_assoc() { + $this->_as_object = FALSE; + + $this->_object_params = array(); + + return $this; + } + /** * Figure out the bases */ - public function base() { + public function base(array $base=NULL) { + if (! is_null($base)) + $this->_base = $base; + + if ($this->_base) + return $this->_base; + // If the base is set in the configuration file, then just return that. if (! is_null($x=Kohana::$config->load('database.default.connection.database'))) return $x; @@ -117,25 +150,22 @@ abstract class Kohana_Database_LDAP_Search { $u = $x->search(array('')) ->scope('base') - ->run(); - - // Remove the '' base - $u = array_pop($u); + ->execute(); // Quick validation - if ($u->count() > 1) + if ($u['']->count() > 1) throw HTTP_Exception::factory(501,'We got more than 1 null DN?'); - return isset($u['']['namingcontexts']) ? $u['']['namingcontexts'] : array(); + return isset($u['']['']['namingcontexts']) ? $u['']['']['namingcontexts'] : array(); } /** * Enables the query to be cached for a specified amount of time. * - * @param integer $lifetime number of seconds to cache, 0 deletes it from the cache - * @param boolean whether or not to execute the query during a cache hit - * @return $this - * @uses Kohana::$cache_life + * @param integer $lifetime number of seconds to cache, 0 deletes it from the cache + * @param boolean whether or not to execute the query during a cache hit + * @return $this + * @uses Kohana::$cache_life */ public function cached($lifetime=NULL,$force=FALSE) { if ($lifetime === NULL) { @@ -158,9 +188,22 @@ abstract class Kohana_Database_LDAP_Search { /** * Search the LDAP database */ - public function run($as_object=FALSE,$object_params=NULL) { + public function execute($db=NULL,$as_object=FALSE,$object_params=NULL) { $query = array(); + if (! is_object($this->_db)) + throw new Kohana_Exception('db must be an object'); + + // We'll override the DB if we have been given one + if (is_object($db)) + $this->_db = $db; + + if ($as_object === NULL) + $as_object = $this->_as_object; + + if ($object_params === NULL) + $object_params = $this->_object_params; + // Query Defaults $attrs_only = 0; @@ -168,10 +211,12 @@ abstract class Kohana_Database_LDAP_Search { if ($this->_db_pending) $this->_filter = $this->_build(); - $result = array(); - foreach ($this->_base as $base) { - $result[$base] = NULL; + // Validation that we are connected, no point contining if we are not. + if (! $this->_db->connection()) + throw HTTP_Exception::factory(501,'Cant run a search without a connection (:type,:filter)',array(':type'=>$this->_db,':filter'=>$this->_filter)); + $result = new Database_LDAP_Search_Result; + foreach ($this->_base as $base) { if ($this->_lifetime !== NULL AND $this->_db->caching()) { // Set the cache key based on the database instance name and SQL $cache_key = 'Database::query("'.$this->_db.'","'.$base.'","'.$this->_scope.'","'.$this->_filter.'")'; @@ -184,20 +229,26 @@ abstract class Kohana_Database_LDAP_Search { } // Search is not cached, OR caching is disabled, so we'll query - if (! $result[$base]) { - switch ($this->_scope) { - case 'base': - $search = ldap_read($this->_db->connection(),$base,$this->_filter,$this->_attrs,$attrs_only,$this->_size_limit,$this->_time_limit,$this->_deref); - break; + if (! isset($result[$base])) { + try { + switch ($this->_scope) { + case 'base': + $search = ldap_read($this->_db->connection(),$base,$this->_filter,$this->_attrs,$attrs_only,$this->_size_limit,$this->_time_limit,$this->_deref); + break; - case 'one': - $search = ldap_list($this->_db->connection(),$base,$this->_filter,$this->_attrs,$attrs_only,$this->_size_limit,$this->_time_limit,$this->_deref); - break; + case 'one': + $search = ldap_list($this->_db->connection(),$base,$this->_filter,$this->_attrs,$attrs_only,$this->_size_limit,$this->_time_limit,$this->_deref); + break; - case 'sub': - default: - $search = ldap_search($this->_db->connection(),$base,$this->_filter,$this->_attrs,$attrs_only,$this->_size_limit,$this->_time_limit,$this->_deref); - break; + case 'sub': + default: + $search = ldap_search($this->_db->connection(),$base,$this->_filter,$this->_attrs,$attrs_only,$this->_size_limit,$this->_time_limit,$this->_deref); + break; + } + + } catch (Exception $e) { + throw HTTP_Exception::factory(501,'Error running a query (SCOPE::scope,TYPE::type,FILTER::filter,ATTRS::attrs) [:error]', + array(':scope'=>$this->_scope,':type'=>$this->_db,':filter'=>$this->_filter,':attrs'=>join('|',$this->_attrs),':error'=>$e->getMessage())); } $result[$base] = new Database_LDAP_Result(array('l'=>$this->_db->connection(),'r'=>$search),array('b'=>$base,'s'=>$this->_scope,'f'=>$this->_filter),$as_object,$object_params); diff --git a/classes/Kohana/Database/LDAP/Search/Builder/Query.php b/classes/Kohana/Database/LDAP/Search/Builder/Query.php index db81504..87cbff6 100644 --- a/classes/Kohana/Database/LDAP/Search/Builder/Query.php +++ b/classes/Kohana/Database/LDAP/Search/Builder/Query.php @@ -10,8 +10,12 @@ * @license http://dev.phpldapadmin.org/license.html */ abstract class Kohana_Database_LDAP_Search_Builder_Query extends Database_Query_Builder { + // WHERE ... protected $_where = array(); + // LIMIT ... + protected $_limit = NULL; + /** * @defunct Not implemented */ @@ -207,9 +211,23 @@ abstract class Kohana_Database_LDAP_Search_Builder_Query extends Database_Query_ case 'OR': return '(|'.$filter.')'; + case '': + return '(&(objectClass=*))'; default: - throw new Kohana_Exception('Condition :condition not handled.',array(':condition'=>$condition)); + throw new Kohana_Exception('Condition ":condition" not handled.',array(':condition'=>$current_condition)); } } + + /** + * Return up to "LIMIT ..." results + * + * @param integer $number maximum results to return or NULL to reset + * @return $this + */ + public function limit($number) { + $this->_limit = $number; + + return $this; + } } ?> diff --git a/classes/Kohana/Database/LDAP/Search/Result.php b/classes/Kohana/Database/LDAP/Search/Result.php new file mode 100644 index 0000000..60d9bb3 --- /dev/null +++ b/classes/Kohana/Database/LDAP/Search/Result.php @@ -0,0 +1,90 @@ +result as $k=>$v) + $c += count($v); + + return $c; + } + + /** ArrayAccess **/ + + public function offsetExists($offset) { + return isset($this->result[$offset]); + } + + public function offsetGet($offset) { + return $this->result[$offset]; + } + + public function offsetSet($offset,$value) { + if (isset($this->result[$offset])) + $this->_count -= $this->result[$offset]->count(); + + $this->result[$offset] = $value; + $this->_count += $value->count(); + } + + public function offsetUnset($offset) { + unset($this->result[$offset]); + } + + /** Iterator **/ + + public function current() { + if (! $this->_rewound) + $this->rewind(); + + return current($this->result)->current(); + } + + public function key() { + return current($this->result)->key(); + } + + public function next() { + if (current($this->result)->valid() AND current($this->result)->next()->valid()) + return current($this->result); + + next($this->result); + + while (current($this->result) AND ! current($this->result)->valid()) + if (next($this->result) === FALSE) + break; + + return current($this->result); + } + + public function rewind() { + reset($this->result); + + if (! current($this->result)->valid()) + $this->next(FALSE); + + $this->_rewound = TRUE; + } + + public function valid() { + return is_object(current($this->result)) ? current($this->result)->valid() : FALSE; + } +} // End Database_LDAP_Search_Result +?> diff --git a/classes/Kohana/ORM/LDAP.php b/classes/Kohana/ORM/LDAP.php new file mode 100644 index 0000000..f732df3 --- /dev/null +++ b/classes/Kohana/ORM/LDAP.php @@ -0,0 +1,93 @@ +_cast_data) AND $id) { + if (is_array($id)) { + // Passing an array of column => values + foreach ($id as $column => $value) + $this->where($column, '=', $value); + + $this->find(); + + } else { + // Passing the primary key + $this->base($id)->find(); + } + } + } + + /** + * Initializes the Database Builder to given query type + * + * @param integer $type Type of Database query + * @return ORM + */ + protected function _build($type) { + // Construct new builder object based on query type + switch ($type) { + case Database::SELECT: + $this->_db_builder = new Database_LDAP_Search($this->_db,NULL); + break; + + default: + throw HTTP_Exception::factory(501,'Unknown type :type',array(':type'=>$type)); + } + + // Process pending database method calls + foreach ($this->_db_pending as $method) { + $name = $method['name']; + $args = $method['args']; + + $this->_db_applied[$name] = $name; + + call_user_func_array(array($this->_db_builder, $name), $args); + } + + return $this; + } + + protected function _initialize() { + parent::_initialize(); + + // Check if this model has already been initialized + if ($init = Arr::get(ORM::$_init_cache, $this->_object_name, FALSE)) { + + // We need to make sure that our _db is an LDAP DB source. + if ( ! is_object($this->_db) OR ! $this->_db instanceof LDAP) { + // Get database instance + $init['_db'] = LDAP::factory('user',NULL,$this->_db_group); + } + + ORM::$_init_cache[$this->_object_name] = $init; + $this->_db = $init['_db']; + } + } + + public function base($value) { + // Add pending database call which is executed after query type is determined + $this->_db_pending[] = array( + 'name' => 'base', + 'args' => array(array($value)), + ); + + return $this; + } +} +?> diff --git a/classes/Model/LDAP.php b/classes/Model/LDAP.php new file mode 100644 index 0000000..3e64ff4 --- /dev/null +++ b/classes/Model/LDAP.php @@ -0,0 +1,14 @@ + diff --git a/classes/ORM/LDAP.php b/classes/ORM/LDAP.php new file mode 100644 index 0000000..afd2ea8 --- /dev/null +++ b/classes/ORM/LDAP.php @@ -0,0 +1,4 @@ + diff --git a/tests/classes/LDAPCaching.php b/tests/classes/LDAPCaching.php index acd766b..26e4ac2 100644 --- a/tests/classes/LDAPCaching.php +++ b/tests/classes/LDAPCaching.php @@ -41,12 +41,12 @@ Class LDAPCaching extends Unittest_TestCase { $u = $x->search(array('')) ->scope('base') ->cached($cached,$force) - ->run(); + ->execute(); $u = $x->search(array('')) ->scope('base') ->cached($cached,$force) - ->run(); + ->execute(); if ($expect) $this->assertInstanceOf('Database_LDAP_Result',$u['']); diff --git a/tests/classes/LDAPResult.php b/tests/classes/LDAPResult.php new file mode 100644 index 0000000..e04ca1e --- /dev/null +++ b/tests/classes/LDAPResult.php @@ -0,0 +1,141 @@ +connect(); + + // We'll do a query first. + $u = $x->search(array('')) + ->scope('base') + ->execute(); + + $this->assertEquals(1,$u->count()); + + foreach ($u[''] as $k => $v) { + $this->assertEquals('',$k); + $this->assertTrue(is_array($v)); + } + + $x->disconnect(); + } + + function testDatabase_LDAP_Result_Many() { + $x = LDAP::factory('user'); + $x->connect(); + $y = LDAP::factory('auth'); + $y->connect(); + + // We'll do a query first. + $u = $x->search(NULL) + ->scope('sub') + ->where('uid','=','bart*') + ->execute(); + + foreach ($u['dc=example.com'] as $k => $v) { + $this->assertEquals('cn=Bart Simpson,dc=example.com',$k); + $this->assertTrue(is_array($v)); + } + + $this->assertEquals(2,count($u['o=Simpsons'])); + $this->assertEquals(count($u['o=Simpsons']),$u['o=Simpsons']->count()); + + $c = 0; + foreach ($u['o=Simpsons'] as $k => $v) { + if (! $c++) + $this->assertEquals('cn=Bart Simpson,ou=People,o=Simpsons',$k); + else + $this->assertEquals('cn=Bart Simpson-ML,ou=People,o=Simpsons',$k); + + $this->assertTrue(is_array($v)); + } + + $x->disconnect(); + } + + function testDatabase_LDAP_Search_Result_One() { + $x = LDAP::factory('user'); + $x->connect(); + + // We'll do a query first. + $u = $x->search(array('')) + ->scope('base') + ->execute(); + + $this->assertEquals(1,$u->count()); + + foreach ($u as $k => $v) { + $this->assertEquals('',$k); + $this->assertTrue(is_array($v)); + } + + $x->disconnect(); + } + + function testDatabase_LDAP_Search_Result_Many() { + $x = LDAP::factory('user'); + $x->connect(); + $y = LDAP::factory('auth'); + $y->connect(); + + // We'll do a query first. + $u = $x->search(NULL) + ->scope('sub') + ->where('uid','=','bart*') + ->execute(); + + $this->assertEquals(3,count($u)); + + $c = 0; + foreach ($u as $k => $v) { + switch (++$c) { + case 1: $this->assertEquals('cn=Bart Simpson,dc=example.com',$k); break; + case 2: $this->assertEquals('cn=Bart Simpson,ou=People,o=Simpsons',$k); break; + case 3: $this->assertEquals('cn=Bart Simpson-ML,ou=People,o=Simpsons',$k); break; + default: throw new Kohana_Exception('Unknown value of c? (:c)',array(':c'=>serialize($c))); + } + + $this->assertTrue(is_array($v)); + } + + $x->disconnect(); + } + + function testDatabase_LDAP_Search_Result_OneDeep() { + $x = LDAP::factory('user'); + $x->connect(); + $y = LDAP::factory('auth'); + $y->connect(); + + // We'll do a query first. + $u = $x->search(NULL) + ->scope('sub') + ->where('uid','=','bart-ml') + ->execute(); + + $this->assertEquals(1,count($u)); + + $c = 0; + foreach ($u as $k => $v) { + switch (++$c) { + case 1: $this->assertEquals('cn=Bart Simpson-ML,ou=People,o=Simpsons',$k); break; + default: throw new Kohana_Exception('Unknown value of c? (:c)',array(':c'=>serialize($c))); + } + + $this->assertTrue(is_array($v)); + } + + $x->disconnect(); + } +} diff --git a/tests/classes/LDAPorm.php b/tests/classes/LDAPorm.php new file mode 100644 index 0000000..c4975f5 --- /dev/null +++ b/tests/classes/LDAPorm.php @@ -0,0 +1,55 @@ +assertInstanceOf('ORM',$x); + } + + function testormloaddn() { + // @todo It would be nice if we auto connect as required. + $y = LDAP::factory('auth'); + $y->connect(); + $y = LDAP::factory('user'); + $y->connect(); + + $x = ORM::factory('LDAP','cn=Bart Simpson,ou=People,o=Simpsons'); + + $this->assertInstanceOf('ORM',$x); + } + + function testormdnval() { + // @todo It would be nice if we auto connect as required. + $y = LDAP::factory('auth'); + $y->connect(); + $y = LDAP::factory('user'); + $y->connect(); + + $x = ORM::factory('LDAP','cn=Bart Simpson,ou=People,o=Simpsons'); + $this->assertEquals($x->cn['0'],'Bart Simpson'); + } +}