]> source.dussan.org Git - nextcloud-server.git/commitdiff
LDAP: establish wrapper interface to allow proper mocking
authorArthur Schiwon <blizzz@owncloud.com>
Tue, 20 Aug 2013 12:23:49 +0000 (14:23 +0200)
committerArthur Schiwon <blizzz@owncloud.com>
Fri, 27 Sep 2013 11:34:15 +0000 (13:34 +0200)
apps/user_ldap/lib/access.php
apps/user_ldap/lib/connection.php
apps/user_ldap/lib/ildapwrapper.php [new file with mode: 0644]
apps/user_ldap/lib/ldap.php

index 6cdeff366770dbdcc8a2632d7ed8ebfea52544d4..4b7920b7162c7bd5bd58e6203b03227de8b856ff 100644 (file)
@@ -73,13 +73,13 @@ abstract class Access extends BackendBase {
                        \OCP\Util::writeLog('user_ldap', 'readAttribute: '.$dn.' found', \OCP\Util::DEBUG);
                        return array();
                }
-               $er = $this->ldap->first_entry($cr, $rr);
+               $er = $this->ldap->firstEntry($cr, $rr);
                if(!$this->ldap->isResource($er)) {
                        //did not match the filter, return false
                        return false;
                }
                //LDAP attributes are not case sensitive
-               $result = \OCP\Util::mb_array_change_key_case($this->ldap->get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
+               $result = \OCP\Util::mb_array_change_key_case($this->ldap->getAttributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
                $attr = mb_strtolower($attr, 'UTF-8');
 
                if(isset($result[$attr]) && $result[$attr]['count'] > 0) {
@@ -683,13 +683,13 @@ abstract class Access extends BackendBase {
 
                $findings = array();
                foreach($sr as $key => $res) {
-                   $findings = array_merge($findings, $this->ldap->get_entries($link_resource, $res ));
+                   $findings = array_merge($findings, $this->ldap->getEntries($link_resource, $res ));
                }
                if($pagedSearchOK) {
                        \OCP\Util::writeLog('user_ldap', 'Paged search successful', \OCP\Util::INFO);
                        foreach($sr as $key => $res) {
                                $cookie = null;
-                               if($this->ldap->control_paged_result_response($link_resource, $res, $cookie)) {
+                               if($this->ldap->controlPagedResultResponse($link_resource, $res, $cookie)) {
                                        \OCP\Util::writeLog('user_ldap', 'Set paged search cookie', \OCP\Util::INFO);
                                        $this->setPagedResultCookie($base[$key], $filter, $limit, $offset, $cookie);
                                }
@@ -1103,8 +1103,9 @@ abstract class Access extends BackendBase {
                                        if($offset > 0) {
                                                \OCP\Util::writeLog('user_ldap', 'Cookie '.$cookie, \OCP\Util::INFO);
                                        }
-                                       $pagedSearchOK = $this->ldap->control_paged_result($this->connection->getConnectionResource(),
-                                               $limit, false, $cookie);
+                                       $pagedSearchOK = $this->ldap->controlPagedResult(
+                                               $this->connection->getConnectionResource(), $limit,
+                                               false, $cookie);
                                        if(!$pagedSearchOK) {
                                                return false;
                                        }
index 6a0d00405c07f4a3fdeb5ebed2098baef1a7b086..6850169f2df5b11e9a34caa958f8479dfeb990b5 100644 (file)
@@ -656,10 +656,10 @@ class Connection extends BackendBase {
                        $host .= ':' . $port;
                }
                $this->ldapConnectionRes = $this->ldap->connect($host, $port);
-               if($this->ldap->set_option($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
-                       if($this->ldap->set_option($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
+               if($this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
+                       if($this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
                                if($this->config['ldapTLS']) {
-                                       $this->ldap->start_tls($this->ldapConnectionRes);
+                                       $this->ldap->startTls($this->ldapConnectionRes);
                                }
                        }
                }
diff --git a/apps/user_ldap/lib/ildapwrapper.php b/apps/user_ldap/lib/ildapwrapper.php
new file mode 100644 (file)
index 0000000..56f5cfb
--- /dev/null
@@ -0,0 +1,179 @@
+<?php
+
+/**
+ * ownCloud – LDAP Wrapper Interface
+ *
+ * @author Arthur Schiwon
+ * @copyright 2013 Arthur Schiwon blizzz@owncloud.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\user_ldap\lib;
+
+interface ILDAPWrapper {
+
+       //LDAP functions in use
+
+       /**
+        * @brief Bind to LDAP directory
+        * @param $link LDAP link resource
+        * @param $dn an RDN to log in with
+        * @param $password the password
+        * @return true on success, false otherwise
+        *
+        * with $dn and $password as null a anonymous bind is attempted.
+        */
+       public function bind($link, $dn, $password);
+
+       /**
+        * @brief connect to an LDAP server
+        * @param $host The host to connect to
+        * @param $port The port to connect to
+        * @return a link resource on success, otherwise false
+        */
+       public function connect($host, $port);
+
+       /**
+        * @brief Send LDAP pagination control
+        * @param $link LDAP link resource
+        * @param $pagesize number of results per page
+        * @param $isCritical Indicates whether the pagination is critical of not.
+        * @param $cookie structure sent by LDAP server
+        * @return true on success, false otherwise
+        */
+       public function controlPagedResult($link, $pagesize, $isCritical, $cookie);
+
+       /**
+        * @brief Retrieve the LDAP pagination cookie
+        * @param $link LDAP link resource
+        * @param $result LDAP result resource
+        * @param $cookie structure sent by LDAP server
+        *
+        * Corresponds to ldap_control_paged_result_response
+        */
+       public function controlPagedResultResponse($link, $result, &$cookie);
+
+       /**
+        * @brief Return the LDAP error number of the last LDAP command
+        * @param $link LDAP link resource
+        * @return error message as string
+        */
+       public function errno($link);
+
+       /**
+        * @brief Return the LDAP error message of the last LDAP command
+        * @param $link LDAP link resource
+        * @return error code as integer
+        */
+       public function error($link);
+
+       /**
+        * @brief Return first result id
+        * @param $link LDAP link resource
+        * @param $result LDAP result resource
+        * @return an LDAP search result resource
+        * */
+       public function firstEntry($link, $result);
+
+       /**
+        * @brief Get attributes from a search result entry
+        * @param $link LDAP link resource
+        * @param $result LDAP result resource
+        * @return array containing the results, false on error
+        * */
+       public function getAttributes($link, $result);
+
+       /**
+        * @brief Get all result entries
+        * @param $link LDAP link resource
+        * @param $result LDAP result resource
+        * @return array containing the results, false on error
+        */
+       public function getEntries($link, $result);
+
+       /**
+        * @brief Read an entry
+        * @param $link LDAP link resource
+        * @param $baseDN The DN of the entry to read from
+        * @param $filter An LDAP filter
+        * @param $attr array of the attributes to read
+        * @return an LDAP search result resource
+        */
+       public function read($link, $baseDN, $filter, $attr);
+
+       /**
+        * @brief Search LDAP tree
+        * @param $link LDAP link resource
+        * @param $baseDN The DN of the entry to read from
+        * @param $filter An LDAP filter
+        * @param $attr array of the attributes to read
+        * @return an LDAP search result resource, false on error
+        */
+       public function search($link, $baseDN, $filter, $attr);
+
+       /**
+        * @brief Sets the value of the specified option to be $value
+        * @param $link LDAP link resource
+        * @param $option a defined LDAP Server option
+        * @param $value the new value for the option
+        * @return true on success, false otherwise
+        */
+       public function setOption($link, $option, $value);
+
+       /**
+        * @brief establish Start TLS
+        * @param $link LDAP link resource
+        * @return true on success, false otherwise
+        */
+       public function startTls($link);
+
+       /**
+        * @brief Sort the result of a LDAP search
+        * @param $link LDAP link resource
+        * @param $result LDAP result resource
+        * @param $sortfilter attribute to use a key in sort
+        */
+       public function sort($link, $result, $sortfilter);
+
+       /**
+        * @brief Unbind from LDAP directory
+        * @param $link LDAP link resource
+        * @return true on success, false otherwise
+        */
+       public function unbind($link);
+
+       //additional required methods in owncloud
+
+       /**
+        * @brief Checks whether the server supports LDAP
+        * @return true if it the case, false otherwise
+        * */
+       public function areLDAPFunctionsAvailable();
+
+       /**
+        * @brief Checks whether PHP supports LDAP Paged Results
+        * @return true if it the case, false otherwise
+        * */
+       public function hasPagedResultSupport();
+
+       /**
+        * @brief Checks whether the submitted parameter is a resource
+        * @param $resource the resource variable to check
+        * @return true if it is a resource, false otherwise
+        */
+       public function isResource($resource);
+
+}
\ No newline at end of file
index 1de901aec12143999eb793ebeca159043b51bb1a..0f082147b147d863eebae22a9d2653438703d783 100644 (file)
 
 namespace OCA\user_ldap\lib;
 
-class LDAP {
+class LDAP implements ILDAPWrapper {
        protected $curFunc = '';
        protected $curArgs = array();
 
-       //Simple wrapper for the ldap functions
-       public function __call($name, $arguments) {
-               $func = 'ldap_' . $name;
-               if(function_exists($func)) {
-                       $this->preFunctionCall($func, $arguments);
-                       $result = call_user_func_array($func, $arguments);
-                       $this->postFunctionCall();
-                       return $result;
-               }
+       public function bind($link, $dn, $password) {
+               return $this->invokeLDAPMethod('bind', $link, $dn, $password);
        }
 
-       public function control_paged_result_response($linkResource, $resultResource, &$cookie) {
+       public function connect($host, $port) {
+               return $this->invokeLDAPMethod('connect', $host, $port);
+       }
+
+       public function controlPagedResultResponse($link, $result, &$cookie) {
                $this->preFunctionCall('ldap_control_paged_result_response',
-                       array($linkResource, $resultResource, $cookie));
-               $result = ldap_control_paged_result_response(
-                       $linkResource, $resultResource, $cookie);
+                       array($link, $result, $cookie));
+               $result = ldap_control_paged_result_response($link, $result, $cookie);
                $this->postFunctionCall();
 
                return $result;
        }
 
+       public function controlPagedResult($link, $pagesize, $isCritical, $cookie) {
+               return $this->invokeLDAPMethod('control_paged_result', $link, $pagesize,
+                                                                               $isCritical, $cookie);
+       }
+
+       public function errno($link) {
+               return $this->invokeLDAPMethod('errno', $link);
+       }
+
+       public function error($link) {
+               return $this->invokeLDAPMethod('error', $link);
+       }
+
+       public function firstEntry($link, $result) {
+               return $this->invokeLDAPMethod('first_entry', $link, $result);
+       }
+
+       public function getAttributes($link, $result) {
+               return $this->invokeLDAPMethod('get_attributes', $link, $result);
+       }
+
+       public function getEntries($link, $result) {
+               return $this->invokeLDAPMethod('get_entries', $link, $result);
+       }
+
+       public function read($link, $baseDN, $filter, $attr) {
+               return $this->invokeLDAPMethod('read', $link, $baseDN, $filter, $attr);
+       }
+
+       public function search($link, $baseDN, $filter, $attr) {
+               return $this->invokeLDAPMethod('search', $link, $baseDN,
+                                                                               $filter, $attr);
+       }
+
+       public function setOption($link, $option, $value) {
+               $this->invokeLDAPMethod('set_option', $link, $option, $value);
+       }
+
+       public function sort($link, $result, $sortfilter) {
+               return $this->invokeLDAPMethod('sort', $link, $result, $sortfilter);
+       }
+
+       public function startTls($link) {
+               return $this->invokeLDAPMethod('start_tls', $link);
+       }
+
+       public function unbind($link) {
+               return $this->invokeLDAPMethod('unbind', $link);
+       }
+
+       /**
+        * @brief Checks whether the server supports LDAP
+        * @return true if it the case, false otherwise
+        * */
        public function areLDAPFunctionsAvailable() {
                return function_exists('ldap_connect');
        }
 
+       /**
+        * @brief Checks whether PHP supports LDAP Paged Results
+        * @return true if it the case, false otherwise
+        * */
        public function hasPagedResultSupport() {
                $hasSupport = function_exists('ldap_control_paged_result')
                        && function_exists('ldap_control_paged_result_response');
@@ -59,8 +113,7 @@ class LDAP {
        }
 
        /**
-        * Checks whether the submitted parameter is a resource
-        *
+        * @brief Checks whether the submitted parameter is a resource
         * @param $resource the resource variable to check
         * @return true if it is a resource, false otherwise
         */
@@ -68,24 +121,38 @@ class LDAP {
                return is_resource($resource);
        }
 
+       private function invokeLDAPMethod() {
+               $arguments = func_get_args();
+               $func = 'ldap_' . array_shift($arguments);
+               if(function_exists($func)) {
+                       $this->preFunctionCall($func, $arguments);
+                       $result = call_user_func_array($func, $arguments);
+                       $this->postFunctionCall();
+                       return $result;
+               }
+       }
+
        private function preFunctionCall($functionName, $args) {
                $this->curFunc = $functionName;
                $this->curArgs = $args;
        }
 
        private function postFunctionCall() {
-               if(is_resource($this->curArgs[0])) {
+               if($this->isResource($this->curArgs[0])) {
                        $errorCode = ldap_errno($this->curArgs[0]);
                        $errorMsg  = ldap_error($this->curArgs[0]);
                        if($errorCode !== 0) {
                                if($this->curFunc === 'ldap_sort' && $errorCode === -4) {
                                        //You can safely ignore that decoding error.
                                        //… says https://bugs.php.net/bug.php?id=18023
-                               } else if($this->curFunc === 'ldap_get_entries' && $errorCode === -4) {
+                               } else if($this->curFunc === 'ldap_get_entries'
+                                                 && $errorCode === -4) {
                                } else if ($errorCode === 32) {
                                        //for now
                                } else {
-                                       throw new \Exception('LDAP error '.$errorMsg.' (' .$errorCode.') after calling '.$this->curFunc.' with arguments '.print_r($this->curArgs, true));
+                                       throw new \Exception('LDAP error '.$errorMsg.' (' .
+                                               $errorCode.') after calling '.$this->curFunc.
+                                               ' with arguments '.print_r($this->curArgs, true));
                                }
                        }
                }