]> source.dussan.org Git - nextcloud-server.git/commitdiff
LDAP: move PHP LDAP functions calls to an LDAP Wrapper for better isolation and mock...
authorArthur Schiwon <blizzz@owncloud.com>
Wed, 12 Jun 2013 00:08:02 +0000 (02:08 +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/backendbase.php [new file with mode: 0644]
apps/user_ldap/lib/ldap.php [new file with mode: 0644]

index 52aa39012fd0b2788403169ef45d4d0c658d73c0..d09571a8a66685a149c04f2856decce3ae2425fd 100644 (file)
@@ -23,7 +23,7 @@
 
 namespace OCA\user_ldap\lib;
 
-abstract class Access {
+abstract class Access extends BackendBase {
        protected $connection;
        //never ever check this var directly, always use getPagedSearchResultState
        protected $pagedSearchedSuccessful;
@@ -60,7 +60,7 @@ abstract class Access {
                        return false;
                }
                $dn = $this->DNasBaseParameter($dn);
-               $rr = @ldap_read($cr, $dn, $filter, array($attr));
+               $rr = @$this->ldap->read($cr, $dn, $filter, array($attr));
                if(!is_resource($rr)) {
                        if(!empty($attr)) {
                                //do not throw this message on userExists check, irritates
@@ -73,13 +73,13 @@ abstract class Access {
                        \OCP\Util::writeLog('user_ldap', 'readAttribute: '.$dn.' found', \OCP\Util::DEBUG);
                        return array();
                }
-               $er = ldap_first_entry($cr, $rr);
+               $er = $this->ldap->first_entry($cr, $rr);
                if(!is_resource($er)) {
                        //did not match the filter, return false
                        return false;
                }
                //LDAP attributes are not case sensitive
-               $result = \OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
+               $result = \OCP\Util::mb_array_change_key_case($this->ldap->get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
                $attr = mb_strtolower($attr, 'UTF-8');
 
                if(isset($result[$attr]) && $result[$attr]['count'] > 0) {
@@ -664,11 +664,11 @@ abstract class Access {
                $pagedSearchOK = $this->initPagedSearch($filter, $base, $attr, $limit, $offset);
 
                $linkResources = array_pad(array(), count($base), $link_resource);
-               $sr = ldap_search($linkResources, $base, $filter, $attr);
-               $error = ldap_errno($link_resource);
+               $sr = $this->ldap->search($linkResources, $base, $filter, $attr);
+               $error = $this->ldap->errno($link_resource);
                if(!is_array($sr) || $error !== 0) {
                        \OCP\Util::writeLog('user_ldap',
-                               'Error when searching: '.ldap_error($link_resource).' code '.ldap_errno($link_resource),
+                               'Error when searching: '.$this->ldap->error($link_resource).' code '.$this->ldap->errno($link_resource),
                                \OCP\Util::ERROR);
                        \OCP\Util::writeLog('user_ldap', 'Attempt for Paging?  '.print_r($pagedSearchOK, true), \OCP\Util::ERROR);
                        return array();
@@ -677,19 +677,19 @@ abstract class Access {
                // Do the server-side sorting
                foreach(array_reverse($attr) as $sortAttr){
                        foreach($sr as $searchResource) {
-                               ldap_sort($link_resource, $searchResource, $sortAttr);
+                               $this->ldap->sort($link_resource, $searchResource, $sortAttr);
                        }
                }
 
                $findings = array();
                foreach($sr as $key => $res) {
-                   $findings = array_merge($findings, ldap_get_entries($link_resource, $res ));
+                   $findings = array_merge($findings, $this->ldap->get_entries($link_resource, $res ));
                }
                if($pagedSearchOK) {
                        \OCP\Util::writeLog('user_ldap', 'Paged search successful', \OCP\Util::INFO);
                        foreach($sr as $key => $res) {
                                $cookie = null;
-                               if(ldap_control_paged_result_response($link_resource, $res, $cookie)) {
+                               if($this->ldap->control_paged_result_response($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,7 +1103,7 @@ abstract class Access {
                                        if($offset > 0) {
                                                \OCP\Util::writeLog('user_ldap', 'Cookie '.$cookie, \OCP\Util::INFO);
                                        }
-                                       $pagedSearchOK = ldap_control_paged_result($this->connection->getConnectionResource(),
+                                       $pagedSearchOK = $this->ldap->control_paged_result($this->connection->getConnectionResource(),
                                                $limit, false, $cookie);
                                        if(!$pagedSearchOK) {
                                                return false;
diff --git a/apps/user_ldap/lib/backendbase.php b/apps/user_ldap/lib/backendbase.php
new file mode 100644 (file)
index 0000000..7ed079b
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * ownCloud – LDAP BackendBase
+ *
+ * @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;
+
+abstract class BackendBase {
+       protected $ldap;
+
+       public function __construct() {
+               $this->ldap = new LDAP();
+       }
+
+       /**
+        * @brief sets the LDAP Wrapper to be used
+        *
+        * @param $ldapWrapper an instance of the Wrapper
+        * @return true on success, otherwise false
+        *
+        * The LDAP Wrapper must implement the PHP LDAP functions, which are used
+        * in the LDAP backend
+        */
+       public function setLDAPWrapper($ldapWrapper) {
+               if(is_object($ldapWrapper)) {
+                       unset($this->ldap);
+                       $this->ldap = $ldapWrapper;
+                       return true;
+               }
+               return false;
+       }
+}
\ No newline at end of file
diff --git a/apps/user_ldap/lib/ldap.php b/apps/user_ldap/lib/ldap.php
new file mode 100644 (file)
index 0000000..86c57c3
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * ownCloud – LDAP Wrapper
+ *
+ * @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;
+
+class LDAP {
+       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 control_paged_result_response($linkResource, $resultResource, &$cookie) {
+               $this->preFunctionCall('ldap_control_paged_result_response',
+                       array($linkResource, $resultResource, $cookie));
+               $result = ldap_control_paged_result_response(
+                       $linkResource, $resultResource, $cookie);
+               $this->postFunctionCall();
+
+               return $result;
+       }
+
+       public function areLDAPFunctionsAvailable() {
+               return function_exists('ldap_connect');
+       }
+
+       public function hasPagedResultSupport() {
+               $hasSupport = function_exists('ldap_control_paged_result')
+                       && function_exists('ldap_control_paged_result_response');
+               return $hasSupport;
+       }
+
+       private function preFunctionCall($functionName, $args) {
+               $this->curFunc = $functionName;
+               $this->curArgs = $args;
+       }
+
+       private function postFunctionCall() {
+               if(is_resource($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 ($errorCode === 32) {
+                                       //for now
+                               } else {
+                                       throw new \Exception('LDAP error '.$errorMsg.' (' .$errorCode.') after calling '.$this->curFunc.' with arguments '.print_r($this->curArgs, true));
+                               }
+                       }
+               }
+
+               $this->curFunc = '';
+               $this->curArgs = array();
+       }
+}
\ No newline at end of file