From 20cb0af8ad3ec7ea063edb6c52d94a8a289e8a97 Mon Sep 17 00:00:00 2001 From: Frank Karlitschek Date: Tue, 24 Jul 2012 10:06:00 +0200 Subject: [PATCH 01/28] migrate the webapps call to ocs --- webapps.php | 54 ----------------------------------------------------- 1 file changed, 54 deletions(-) delete mode 100644 webapps.php diff --git a/webapps.php b/webapps.php deleted file mode 100644 index 82e677a51c7..00000000000 --- a/webapps.php +++ /dev/null @@ -1,54 +0,0 @@ -. -* -*/ - -$RUNTIME_NOAPPS = TRUE; //no apps, yet - -require_once('lib/base.php'); - - -//valid user account -if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser=''; -if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw=''; - -if(!OC_User::login($authuser,$authpw)){ - header('WWW-Authenticate: Basic realm="your valid user account"'); - header('HTTP/1.0 401 Unauthorized'); - exit; -}else{ - - $apps=OC_App::getEnabledApps(); - $values=array(); - foreach($apps as $app) { - $info=OC_App::getAppInfo($app); - if(isset($info['standalone'])) { - $newvalue=array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>''); - $values[]=$newvalue; - } - - } - - echo(json_encode($values)); - exit; - - -} From d28be8de64a3fe6ab52782a4aaeaaf96565a8012 Mon Sep 17 00:00:00 2001 From: Frank Karlitschek Date: Tue, 24 Jul 2012 15:18:52 +0200 Subject: [PATCH 02/28] add the calls for the new keyserver. Still not connectect to the encryption system --- lib/ocs.php | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/lib/ocs.php b/lib/ocs.php index 9d30e172f55..3157aae99e6 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -153,6 +153,10 @@ class OC_OCS { OC_OCS::privatedatadelete($format, $app, $key); // CLOUD + // systemWebApps + }elseif(($method=='get') and ($ex[$paracount-5] == 'v1.php') and ($ex[$paracount-4]=='cloud') and ($ex[$paracount-3] == 'system') and ($ex[$paracount-2] == 'webapps')){ + OC_OCS::systemwebapps($format); + // quotaget }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'quota')){ $user=$ex[$paracount-3]; @@ -164,6 +168,16 @@ class OC_OCS { $quota = self::readData('post', 'quota', 'int'); OC_OCS::quotaset($format,$user,$quota); + // keygetpublic + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'publickey')){ + $user=$ex[$paracount-3]; + OC_OCS::publicKeyGet($format,$user); + + // keygetprivate + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'privatekey')){ + $user=$ex[$paracount-3]; + OC_OCS::privateKeyGet($format,$user); + // add more calls here // please document all the call in the draft spec @@ -545,6 +559,29 @@ class OC_OCS { // CLOUD API ############################################# + /** + * get a list of installed web apps + * @param string $format + * @return string xml/json + */ + private static function systemWebApps($format) { + $login=OC_OCS::checkpassword(); + $apps=OC_App::getEnabledApps(); + $values=array(); + foreach($apps as $app) { + $info=OC_App::getAppInfo($app); + if(isset($info['standalone'])) { + $newvalue=array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>''); + $values[]=$newvalue; + } + + } + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $values, 'cloud', '', 2, 0, 0); + echo($txt); + + } + + /** * get the quota of a user * @param string $format @@ -573,10 +610,10 @@ class OC_OCS { $xml['used']=$used; $xml['relative']=$relative; - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', 'full', 1, count($xml), 0); + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); echo($txt); }else{ - echo self::generateXml('', 'fail', 300, 'User does not exist'); + echo self::generateXml('', 'fail', 300, 'User does not exist'); } }else{ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); @@ -596,16 +633,56 @@ class OC_OCS { // todo // not yet implemented - // edit logic here + // add logic here error_log('OCS call: user:'.$user.' quota:'.$quota); $xml=array(); - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', 'full', 1, count($xml), 0); + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); echo($txt); }else{ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); } } + /** + * get the public key of a user + * @param string $format + * @param string $user + * @return string xml/json + */ + private static function publicKeyGet($format,$user) { + $login=OC_OCS::checkpassword(); + + if(OC_User::userExists($user)){ + // calculate the disc space + $txt='this is the public key of '.$user; + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + } + + /** + * get the private key of a user + * @param string $format + * @param string $user + * @return string xml/json + */ + private static function privateKeyGet($format,$user) { + $login=OC_OCS::checkpassword(); + if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { + + if(OC_User::userExists($user)){ + // calculate the disc space + $txt='this is the private key of '.$user; + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } + } From fdcbc23ed6bb520f50c7c4ce5f169e6716e1c5f0 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 20 Jul 2012 13:09:09 +0200 Subject: [PATCH 03/28] define an interface for the User Backend --- lib/user.php | 4 +-- lib/user/backend.php | 2 +- lib/user/interface.php | 69 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 lib/user/interface.php diff --git a/lib/user.php b/lib/user.php index 549319b3a77..e3c9c23effa 100644 --- a/lib/user.php +++ b/lib/user.php @@ -21,7 +21,7 @@ */ /** - * This class provides wrapper methods for user management. Multiple backends are + * This class provides wrapper methods for user management. Multiple backends are * supported. User management operations are delegated to the configured backend for * execution. * @@ -83,7 +83,7 @@ class OC_User { * Set the User Authentication Module */ public static function useBackend( $backend = 'database' ){ - if($backend instanceof OC_User_Backend){ + if($backend instanceof OC_User_Interface){ self::$_usedBackends[get_class($backend)]=$backend; }else{ // You'll never know what happens diff --git a/lib/user/backend.php b/lib/user/backend.php index be068a63ce0..daa942d261c 100644 --- a/lib/user/backend.php +++ b/lib/user/backend.php @@ -42,7 +42,7 @@ define('OC_USER_BACKEND_CHECK_PASSWORD', 0x000100); * * Subclass this for your own backends, and see OC_User_Example for descriptions */ -abstract class OC_User_Backend { +abstract class OC_User_Backend implements OC_User_Interface { protected $possibleActions = array( OC_USER_BACKEND_CREATE_USER => 'createUser', diff --git a/lib/user/interface.php b/lib/user/interface.php new file mode 100644 index 00000000000..a04c761630b --- /dev/null +++ b/lib/user/interface.php @@ -0,0 +1,69 @@ +. + * + */ + +interface OC_User_Interface { + + /** + * @brief Get all supported actions + * @returns bitwise-or'ed actions + * + * Returns the supported actions as int to be + * compared with OC_USER_BACKEND_CREATE_USER etc. + */ + public function getSupportedActions(); + + /** + * @brief Check if backend implements actions + * @param $actions bitwise-or'ed actions + * @returns boolean + * + * Returns the supported actions as int to be + * compared with OC_USER_BACKEND_CREATE_USER etc. + */ + public function implementsActions($actions); + + /** + * @brief delete a user + * @param $uid The username of the user to delete + * @returns true/false + * + * Deletes a user + */ + public function deleteUser($uid); + + /** + * @brief Get a list of all users + * @returns array with all uids + * + * Get a list of all users. + */ + public function getUsers(); + + /** + * @brief check if a user exists + * @param string $uid the username + * @return boolean + */ + public function userExists($uid); + +} \ No newline at end of file From e499bc37c839cc8b33d81e8eb360a4dfd1050ca2 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 20 Jul 2012 13:15:12 +0200 Subject: [PATCH 04/28] define an interface for the Group Backend --- lib/group.php | 8 ++-- lib/group/backend.php | 2 +- lib/group/interface.php | 86 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 lib/group/interface.php diff --git a/lib/group.php b/lib/group.php index ceee5fa4edb..12e5f5ebb30 100644 --- a/lib/group.php +++ b/lib/group.php @@ -43,7 +43,7 @@ class OC_Group { * @returns true/false */ public static function useBackend( $backend ){ - if($backend instanceof OC_Group_Backend){ + if($backend instanceof OC_Group_Interface){ self::$_usedBackends[]=$backend; } } @@ -168,7 +168,7 @@ class OC_Group { if($run){ $succes=false; - + //add the user to the all backends that have the group foreach(self::$_usedBackends as $backend){ if(!$backend->implementsActions(OC_GROUP_BACKEND_ADD_TO_GROUP)) @@ -245,7 +245,7 @@ class OC_Group { asort($groups); return $groups; } - + /** * check if a group exists * @param string $gid @@ -259,7 +259,7 @@ class OC_Group { } return false; } - + /** * @brief get a list of all users in a group * @returns array with user ids diff --git a/lib/group/backend.php b/lib/group/backend.php index 24778afd1e5..ebc078f152a 100644 --- a/lib/group/backend.php +++ b/lib/group/backend.php @@ -37,7 +37,7 @@ define('OC_GROUP_BACKEND_REMOVE_FROM_GOUP', 0x00001000); /** * Abstract base class for user management */ -abstract class OC_Group_Backend { +abstract class OC_Group_Backend implements OC_Group_Interface { protected $possibleActions = array( OC_GROUP_BACKEND_CREATE_GROUP => 'createGroup', OC_GROUP_BACKEND_DELETE_GROUP => 'deleteGroup', diff --git a/lib/group/interface.php b/lib/group/interface.php new file mode 100644 index 00000000000..f86a6dd0898 --- /dev/null +++ b/lib/group/interface.php @@ -0,0 +1,86 @@ +. + * + */ + +interface OC_Group_Interface { + + /** + * @brief Get all supported actions + * @returns bitwise-or'ed actions + * + * Returns the supported actions as int to be + * compared with OC_USER_BACKEND_CREATE_USER etc. + */ + public function getSupportedActions(); + + /** + * @brief Check if backend implements actions + * @param $actions bitwise-or'ed actions + * @returns boolean + * + * Returns the supported actions as int to be + * compared with OC_GROUP_BACKEND_CREATE_GROUP etc. + */ + public function implementsActions($actions); + + /** + * @brief is user in group? + * @param $uid uid of the user + * @param $gid gid of the group + * @returns true/false + * + * Checks whether the user is member of a group or not. + */ + public function inGroup($uid, $gid); + + /** + * @brief Get all groups a user belongs to + * @param $uid Name of the user + * @returns array with group names + * + * This function fetches all groups a user belongs to. It does not check + * if the user exists at all. + */ + public function getUserGroups($uid); + + /** + * @brief get a list of all groups + * @returns array with group names + * + * Returns a list with all groups + */ + public function getGroups(); + + /** + * check if a group exists + * @param string $gid + * @return bool + */ + public function groupExists($gid); + + /** + * @brief get a list of all users in a group + * @returns array with user ids + */ + public function usersInGroup($gid); + +} \ No newline at end of file From 0bdebe0e4a5249e45cebce1696e3e0ed05b892d1 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 20 Jul 2012 13:18:02 +0200 Subject: [PATCH 05/28] LDAP: pass user backend as instance, not classname --- apps/user_ldap/appinfo/app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php index 330574c1d42..a3c4b0cf9ff 100644 --- a/apps/user_ldap/appinfo/app.php +++ b/apps/user_ldap/appinfo/app.php @@ -28,7 +28,7 @@ require_once('apps/user_ldap/group_ldap.php'); OCP\App::registerAdmin('user_ldap','settings'); // register user backend -OC_User::useBackend( 'LDAP' ); +OC_User::useBackend( new OC_USER_LDAP() ); OC_Group::useBackend( new OC_GROUP_LDAP() ); // add settings page to navigation From 0196e6eada346e25e080e74ea4f19e76cd878169 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 20 Jul 2012 16:25:54 +0200 Subject: [PATCH 06/28] Offer User and Group interfaces in public API --- lib/public/groupinterface.php | 31 +++++++++++++++++++++++++++++++ lib/public/userinterface.php | 31 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 lib/public/groupinterface.php create mode 100644 lib/public/userinterface.php diff --git a/lib/public/groupinterface.php b/lib/public/groupinterface.php new file mode 100644 index 00000000000..97833028118 --- /dev/null +++ b/lib/public/groupinterface.php @@ -0,0 +1,31 @@ +. +* +*/ + +/** + * Public interface of ownCloud for apps to use. + * Group Class. + * + */ + +namespace OCP; + +interface GroupInterface extends \OC_Group_Interface {} \ No newline at end of file diff --git a/lib/public/userinterface.php b/lib/public/userinterface.php new file mode 100644 index 00000000000..b73a8f8d8b0 --- /dev/null +++ b/lib/public/userinterface.php @@ -0,0 +1,31 @@ +. +* +*/ + +/** + * Public interface of ownCloud for apps to use. + * User Class. + * + */ + +namespace OCP; + +interface UserInterface extends \OC_User_Interface {} \ No newline at end of file From 81c0ca4ffb1065fc5f59ee916c06758605639fc8 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 20 Jul 2012 16:26:46 +0200 Subject: [PATCH 07/28] remove only internally used function from interface --- lib/user/interface.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/user/interface.php b/lib/user/interface.php index a04c761630b..dc3685dc20d 100644 --- a/lib/user/interface.php +++ b/lib/user/interface.php @@ -23,15 +23,6 @@ interface OC_User_Interface { - /** - * @brief Get all supported actions - * @returns bitwise-or'ed actions - * - * Returns the supported actions as int to be - * compared with OC_USER_BACKEND_CREATE_USER etc. - */ - public function getSupportedActions(); - /** * @brief Check if backend implements actions * @param $actions bitwise-or'ed actions From afdc5bf264cbb061807d1d34a9ca451fd5eb72a4 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 20 Jul 2012 16:28:20 +0200 Subject: [PATCH 08/28] LDAP: switch user backend from extending class OC_User_Backend to implementing OC_User_Interface for improved flexibility --- apps/user_ldap/user_ldap.php | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index b51d9a55cc7..7ff9b23af05 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -23,7 +23,7 @@ * */ -class OC_USER_LDAP extends OC_User_Backend { +class OC_USER_LDAP implements OCP\UserInterface { // cached settings protected $ldapUserFilter; @@ -139,4 +139,27 @@ class OC_USER_LDAP extends OC_User_Backend { return true; } + /** + * @brief delete a user + * @param $uid The username of the user to delete + * @returns true/false + * + * Deletes a user + */ + public function deleteUser($uid) { + return false; + } + + /** + * @brief Check if backend implements actions + * @param $actions bitwise-or'ed actions + * @returns boolean + * + * Returns the supported actions as int to be + * compared with OC_USER_BACKEND_CREATE_USER etc. + */ + public function implementsActions($actions) { + return (bool)(OC_USER_BACKEND_CHECK_PASSWORD & $actions); + } + } \ No newline at end of file From 5888cb48b6c33a19cf1b798f5bade48526afe651 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 20 Jul 2012 17:41:41 +0200 Subject: [PATCH 09/28] Support for OCA namespace --- apps/user_ldap/appinfo/app.php | 1 + apps/user_ldap/user_ldap.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php index a3c4b0cf9ff..0e201a38edc 100644 --- a/apps/user_ldap/appinfo/app.php +++ b/apps/user_ldap/appinfo/app.php @@ -24,6 +24,7 @@ require_once('apps/user_ldap/lib_ldap.php'); require_once('apps/user_ldap/user_ldap.php'); require_once('apps/user_ldap/group_ldap.php'); +// OC::$CLASSPATH['OCA\user_ldap\LDAP_Access']='apps/user_ldap/lib/access.php'; OCP\App::registerAdmin('user_ldap','settings'); diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 7ff9b23af05..ee5089924e6 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -23,7 +23,7 @@ * */ -class OC_USER_LDAP implements OCP\UserInterface { +class OC_USER_LDAP extends OCA\user_ldap\LDAP_Access implements OCP\UserInterface { // cached settings protected $ldapUserFilter; From 57c375ea245d57567316254df2968b5b929733a7 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 20 Jul 2012 17:42:32 +0200 Subject: [PATCH 10/28] Support for OCA namespace --- lib/base.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/base.php b/lib/base.php index 631ed4fcce6..888dc265d64 100644 --- a/lib/base.php +++ b/lib/base.php @@ -83,6 +83,9 @@ class OC{ elseif(strpos($className,'OCP\\')===0){ require_once 'public/'.strtolower(str_replace('\\','/',substr($className,3)) . '.php'); } + elseif(strpos($className,'OCA\\')===0){ + require_once 'apps/'.strtolower(str_replace('\\','/',substr($className,3)) . '.php'); + } elseif(strpos($className,'Sabre_')===0) { require_once str_replace('_','/',$className) . '.php'; } From 42492338fc708a09ada3d4ef6f4cc8aa0c670ee3 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 20 Jul 2012 17:43:44 +0200 Subject: [PATCH 11/28] LDAP: put app under the OCA\user_ldap\ namespace --- apps/user_ldap/appinfo/app.php | 8 +++--- apps/user_ldap/group_ldap.php | 46 ++++++++++++++++++---------------- apps/user_ldap/user_ldap.php | 36 +++++++++++++------------- 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php index 0e201a38edc..b5dd718d710 100644 --- a/apps/user_ldap/appinfo/app.php +++ b/apps/user_ldap/appinfo/app.php @@ -22,15 +22,13 @@ */ require_once('apps/user_ldap/lib_ldap.php'); -require_once('apps/user_ldap/user_ldap.php'); -require_once('apps/user_ldap/group_ldap.php'); -// OC::$CLASSPATH['OCA\user_ldap\LDAP_Access']='apps/user_ldap/lib/access.php'; +// require_once('apps/user_ldap/group_ldap.php'); OCP\App::registerAdmin('user_ldap','settings'); // register user backend -OC_User::useBackend( new OC_USER_LDAP() ); -OC_Group::useBackend( new OC_GROUP_LDAP() ); +OC_User::useBackend(new OCA\user_ldap\USER_LDAP()); +OC_Group::useBackend(new OCA\user_ldap\GROUP_LDAP()); // add settings page to navigation $entry = array( diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index d438c7d84df..06db535490a 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -21,7 +21,9 @@ * */ -class OC_GROUP_LDAP extends OC_Group_Backend { +namespace OCA\user_ldap; + +class GROUP_LDAP extends \OC_Group_Backend { // //group specific settings protected $ldapGroupFilter; protected $ldapGroupMemberAssocAttr; @@ -33,8 +35,8 @@ class OC_GROUP_LDAP extends OC_Group_Backend { protected $_groups = array(); public function __construct() { - $this->ldapGroupFilter = OCP\Config::getAppValue('user_ldap', 'ldap_group_filter', '(objectClass=posixGroup)'); - $this->ldapGroupMemberAssocAttr = OCP\Config::getAppValue('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember'); + $this->ldapGroupFilter = \OCP\Config::getAppValue('user_ldap', 'ldap_group_filter', '(objectClass=posixGroup)'); + $this->ldapGroupMemberAssocAttr = \OCP\Config::getAppValue('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember'); if(!empty($this->ldapGroupFilter) && !empty($this->ldapGroupMemberAssocAttr)) { $this->configured = true; @@ -56,14 +58,14 @@ class OC_GROUP_LDAP extends OC_Group_Backend { if(isset($this->_group_user[$gid][$uid])) { return $this->_group_user[$gid][$uid]; } - $dn_user = OC_LDAP::username2dn($uid); - $dn_group = OC_LDAP::groupname2dn($gid); + $dn_user = \OC_LDAP::username2dn($uid); + $dn_group = \OC_LDAP::groupname2dn($gid); // just in case if(!$dn_group || !$dn_user) { return false; } //usually, LDAP attributes are said to be case insensitive. But there are exceptions of course. - $members = OC_LDAP::readAttribute($dn_group, $this->ldapGroupMemberAssocAttr); + $members = \OC_LDAP::readAttribute($dn_group, $this->ldapGroupMemberAssocAttr); if(!$members) { return false; } @@ -73,8 +75,8 @@ class OC_GROUP_LDAP extends OC_Group_Backend { if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') { $dns = array(); foreach($members as $mid) { - $filter = str_replace('%uid', $mid, OC_LDAP::conf('ldapLoginFilter')); - $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn'); + $filter = str_replace('%uid', $mid, \OC_LDAP::conf('ldapLoginFilter')); + $ldap_users = \OC_LDAP::fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { continue; } @@ -102,7 +104,7 @@ class OC_GROUP_LDAP extends OC_Group_Backend { if(isset($this->_user_groups[$uid])) { return $this->_user_groups[$uid]; } - $userDN = OC_LDAP::username2dn($uid); + $userDN = \OC_LDAP::username2dn($uid); if(!$userDN) { $this->_user_groups[$uid] = array(); return array(); @@ -113,19 +115,19 @@ class OC_GROUP_LDAP extends OC_Group_Backend { || (strtolower($this->ldapGroupMemberAssocAttr) == 'member')) { $uid = $userDN; } else if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') { - $result = OC_LDAP::readAttribute($userDN, 'uid'); + $result = \OC_LDAP::readAttribute($userDN, 'uid'); $uid = $result[0]; } else { // just in case $uid = $userDN; } - $filter = OC_LDAP::combineFilterWithAnd(array( + $filter = \OC_LDAP::combineFilterWithAnd(array( $this->ldapGroupFilter, $this->ldapGroupMemberAssocAttr.'='.$uid )); - $groups = OC_LDAP::fetchListOfGroups($filter, array(OC_LDAP::conf('ldapGroupDisplayName'),'dn')); - $this->_user_groups[$uid] = array_unique(OC_LDAP::ownCloudGroupNames($groups), SORT_LOCALE_STRING); + $groups = \OC_LDAP::fetchListOfGroups($filter, array(\OC_LDAP::conf('ldapGroupDisplayName'),'dn')); + $this->_user_groups[$uid] = array_unique(\OC_LDAP::ownCloudGroupNames($groups), SORT_LOCALE_STRING); return $this->_user_groups[$uid]; } @@ -142,13 +144,13 @@ class OC_GROUP_LDAP extends OC_Group_Backend { return $this->_group_users[$gid]; } - $groupDN = OC_LDAP::groupname2dn($gid); + $groupDN = \OC_LDAP::groupname2dn($gid); if(!$groupDN) { $this->_group_users[$gid] = array(); return array(); } - $members = OC_LDAP::readAttribute($groupDN, $this->ldapGroupMemberAssocAttr); + $members = \OC_LDAP::readAttribute($groupDN, $this->ldapGroupMemberAssocAttr); if(!$members) { $this->_group_users[$gid] = array(); return array(); @@ -158,21 +160,21 @@ class OC_GROUP_LDAP extends OC_Group_Backend { $isMemberUid = (strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid'); foreach($members as $member) { if($isMemberUid) { - $filter = OCP\Util::mb_str_replace('%uid', $member, OC_LDAP::conf('ldapLoginFilter'), 'UTF-8'); - $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn'); + $filter = \OCP\Util::mb_str_replace('%uid', $member, \OC_LDAP::conf('ldapLoginFilter'), 'UTF-8'); + $ldap_users = \OC_LDAP::fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { continue; } - $result[] = OC_LDAP::dn2username($ldap_users[0]); + $result[] = \OC_LDAP::dn2username($ldap_users[0]); continue; } else { - if($ocname = OC_LDAP::dn2username($member)){ + if($ocname = \OC_LDAP::dn2username($member)){ $result[] = $ocname; } } } if(!$isMemberUid) { - $result = array_intersect($result, OCP\User::getUsers()); + $result = array_intersect($result, \OCP\User::getUsers()); } $this->_group_users[$gid] = array_unique($result, SORT_LOCALE_STRING); return $this->_group_users[$gid]; @@ -189,8 +191,8 @@ class OC_GROUP_LDAP extends OC_Group_Backend { return array(); } if(empty($this->_groups)) { - $ldap_groups = OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn')); - $this->_groups = OC_LDAP::ownCloudGroupNames($ldap_groups); + $ldap_groups = \OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(\OC_LDAP::conf('ldapGroupDisplayName'), 'dn')); + $this->_groups = \OC_LDAP::ownCloudGroupNames($ldap_groups); } return $this->_groups; } diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index ee5089924e6..e7ed4dae280 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -23,7 +23,9 @@ * */ -class OC_USER_LDAP extends OCA\user_ldap\LDAP_Access implements OCP\UserInterface { +namespace OCA\user_ldap; + +class USER_LDAP extends lib\Access implements \OCP\UserInterface { // cached settings protected $ldapUserFilter; @@ -38,10 +40,10 @@ class OC_USER_LDAP extends OCA\user_ldap\LDAP_Access implements OCP\UserInterfac protected $_users = null; public function __construct() { - $this->ldapUserFilter = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter', '(objectClass=posixAccount)'); - $this->ldapQuotaAttribute = OCP\Config::getAppValue('user_ldap', 'ldap_quota_attr', ''); - $this->ldapQuotaDefault = OCP\Config::getAppValue('user_ldap', 'ldap_quota_def', ''); - $this->ldapEmailAttribute = OCP\Config::getAppValue('user_ldap', 'ldap_email_attr', ''); + $this->ldapUserFilter = \OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter', '(objectClass=posixAccount)'); + $this->ldapQuotaAttribute = \OCP\Config::getAppValue('user_ldap', 'ldap_quota_attr', ''); + $this->ldapQuotaDefault = \OCP\Config::getAppValue('user_ldap', 'ldap_quota_def', ''); + $this->ldapEmailAttribute = \OCP\Config::getAppValue('user_ldap', 'ldap_email_attr', ''); } private function updateQuota($dn) { @@ -50,26 +52,26 @@ class OC_USER_LDAP extends OCA\user_ldap\LDAP_Access implements OCP\UserInterfac $quota = $this->ldapQuotaDefault; } if(!empty($this->ldapQuotaAttribute)) { - $aQuota = OC_LDAP::readAttribute($dn, $this->ldapQuotaAttribute); + $aQuota = \OC_LDAP::readAttribute($dn, $this->ldapQuotaAttribute); if($aQuota && (count($aQuota) > 0)) { $quota = $aQuota[0]; } } if(!is_null($quota)) { - OCP\Config::setUserValue(OC_LDAP::dn2username($dn), 'files', 'quota', OCP\Util::computerFileSize($quota)); + \OCP\Config::setUserValue(\OC_LDAP::dn2username($dn), 'files', 'quota', \OCP\Util::computerFileSize($quota)); } } private function updateEmail($dn) { $email = null; if(!empty($this->ldapEmailAttribute)) { - $aEmail = OC_LDAP::readAttribute($dn, $this->ldapEmailAttribute); + $aEmail = \OC_LDAP::readAttribute($dn, $this->ldapEmailAttribute); if($aEmail && (count($aEmail) > 0)) { $email = $aEmail[0]; } if(!is_null($email)){ - OCP\Config::setUserValue(OC_LDAP::dn2username($dn), 'settings', 'email', $email); + \OCP\Config::setUserValue(\OC_LDAP::dn2username($dn), 'settings', 'email', $email); } } } @@ -84,15 +86,15 @@ class OC_USER_LDAP extends OCA\user_ldap\LDAP_Access implements OCP\UserInterfac */ public function checkPassword($uid, $password){ //find out dn of the user name - $filter = OCP\Util::mb_str_replace('%uid', $uid, OC_LDAP::conf('ldapLoginFilter'), 'UTF-8'); - $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn'); + $filter = \OCP\Util::mb_str_replace('%uid', $uid, \OC_LDAP::conf('ldapLoginFilter'), 'UTF-8'); + $ldap_users = \OC_LDAP::fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { return false; } $dn = $ldap_users[0]; //are the credentials OK? - if(!OC_LDAP::areCredentialsValid($dn, $password)) { + if(!\OC_LDAP::areCredentialsValid($dn, $password)) { return false; } @@ -101,7 +103,7 @@ class OC_USER_LDAP extends OCA\user_ldap\LDAP_Access implements OCP\UserInterfac $this->updateEmail($dn); //give back the display name - return OC_LDAP::dn2username($dn); + return \OC_LDAP::dn2username($dn); } /** @@ -112,8 +114,8 @@ class OC_USER_LDAP extends OCA\user_ldap\LDAP_Access implements OCP\UserInterfac */ public function getUsers(){ if(is_null($this->_users)) { - $ldap_users = OC_LDAP::fetchListOfUsers($this->ldapUserFilter, array(OC_LDAP::conf('ldapUserDisplayName'), 'dn')); - $this->_users = OC_LDAP::ownCloudUserNames($ldap_users); + $ldap_users = \OC_LDAP::fetchListOfUsers($this->ldapUserFilter, array(\OC_LDAP::conf('ldapUserDisplayName'), 'dn')); + $this->_users = \OC_LDAP::ownCloudUserNames($ldap_users); } return $this->_users; } @@ -125,13 +127,13 @@ class OC_USER_LDAP extends OCA\user_ldap\LDAP_Access implements OCP\UserInterfac */ public function userExists($uid){ //getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking. - $dn = OC_LDAP::username2dn($uid); + $dn = \OC_LDAP::username2dn($uid); if(!$dn) { return false; } //if user really still exists, we will be able to read his cn - $cn = OC_LDAP::readAttribute($dn, 'cn'); + $cn = \OC_LDAP::readAttribute($dn, 'cn'); if(!$cn || empty($cn)) { return false; } From 6b320a260434712d8c558bee431dd40af58883ad Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 24 Jul 2012 10:54:56 +0200 Subject: [PATCH 12/28] provide recursiveArraySearch as Helper function and make available through API --- lib/helper.php | 28 +++++++++++++++++++++++++++- lib/public/util.php | 11 +++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/helper.php b/lib/helper.php index f328c14ac77..666bc6badfc 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -360,7 +360,7 @@ class OC_Helper { }else{ $mimeType='application/octet-stream'; } - + if($mimeType=='application/octet-stream' and function_exists('finfo_open') and function_exists('finfo_file') and $finfo=finfo_open(FILEINFO_MIME)){ $info = @strtolower(finfo_file($finfo,$path)); if($info){ @@ -679,4 +679,30 @@ class OC_Helper { } return $subject; } + + /** + * @brief performs a search in a nested array + * @param haystack the array to be searched + * @param needle the search string + * @param $index optional, only search this key name + * @return the key of the matching field, otherwise false + * + * performs a search in a nested array + * + * taken from http://www.php.net/manual/en/function.array-search.php#97645 + */ + public static function recursiveArraySearch($haystack, $needle, $index = null) { + $aIt = new RecursiveArrayIterator($haystack); + $it = new RecursiveIteratorIterator($aIt); + + while($it->valid()) { + if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) { + return $aIt->key(); + } + + $it->next(); + } + + return false; + } } diff --git a/lib/public/util.php b/lib/public/util.php index 43f9e3cee5d..75ca29f7129 100644 --- a/lib/public/util.php +++ b/lib/public/util.php @@ -320,4 +320,15 @@ class Util { public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) { return(\OC_Helper::mb_str_replace($search, $replace, $subject, $encoding, $count)); } + + /** + * @brief performs a search in a nested array + * @param haystack the array to be searched + * @param needle the search string + * @param $index optional, only search this key name + * @return the key of the matching field, otherwise false + */ + public static function recursiveArraySearch($haystack, $needle, $index = null) { + return(\OC_Helper::recursiveArraySearch($haystack, $needle, $index)); + } } From d0aebf05bf71df6f8ad11d0464e396d2be6fa744 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 24 Jul 2012 11:18:08 +0200 Subject: [PATCH 13/28] LDAP: group backend now implements the interface, does not inherit backend class --- apps/user_ldap/group_ldap.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index 06db535490a..1585b905aa9 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -23,7 +23,7 @@ namespace OCA\user_ldap; -class GROUP_LDAP extends \OC_Group_Backend { +class GROUP_LDAP implements \OCP\GroupInterface { // //group specific settings protected $ldapGroupFilter; protected $ldapGroupMemberAssocAttr; @@ -205,4 +205,17 @@ class GROUP_LDAP extends \OC_Group_Backend { public function groupExists($gid){ return in_array($gid, $this->getGroups()); } + + /** + * @brief Check if backend implements actions + * @param $actions bitwise-or'ed actions + * @returns boolean + * + * Returns the supported actions as int to be + * compared with OC_USER_BACKEND_CREATE_USER etc. + */ + public function implementsActions($actions) { + //always returns false, because possible actions are modifying actions. We do not write to LDAP, at least for now. + return false; + } } \ No newline at end of file From eefe6882f977c324b2ac9141758b64be2a9c752e Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 24 Jul 2012 11:38:56 +0200 Subject: [PATCH 14/28] method not used externally, thus not needed in interface --- lib/group/interface.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/lib/group/interface.php b/lib/group/interface.php index f86a6dd0898..7cca6061e10 100644 --- a/lib/group/interface.php +++ b/lib/group/interface.php @@ -22,16 +22,6 @@ */ interface OC_Group_Interface { - - /** - * @brief Get all supported actions - * @returns bitwise-or'ed actions - * - * Returns the supported actions as int to be - * compared with OC_USER_BACKEND_CREATE_USER etc. - */ - public function getSupportedActions(); - /** * @brief Check if backend implements actions * @param $actions bitwise-or'ed actions From 25ad1d5c3e92228e6274b5b765e3fa5d47ece04b Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 25 Jul 2012 12:37:39 +0200 Subject: [PATCH 15/28] LDAP: split up LIB_LDAP into Access for LDAP interaction functions and Connection for configuration and resource management. Adjust user_ldap, group_ldap and the app accordingly. --- apps/user_ldap/appinfo/app.php | 10 +- apps/user_ldap/group_ldap.php | 75 ++- .../{lib_ldap.php => lib/access.php} | 477 +++++++----------- apps/user_ldap/lib/connection.php | 245 +++++++++ apps/user_ldap/user_ldap.php | 46 +- 5 files changed, 480 insertions(+), 373 deletions(-) rename apps/user_ldap/{lib_ldap.php => lib/access.php} (50%) create mode 100644 apps/user_ldap/lib/connection.php diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php index b5dd718d710..537f56861c4 100644 --- a/apps/user_ldap/appinfo/app.php +++ b/apps/user_ldap/appinfo/app.php @@ -26,9 +26,15 @@ require_once('apps/user_ldap/lib_ldap.php'); OCP\App::registerAdmin('user_ldap','settings'); +$connector = new OCA\user_ldap\lib\Connection('user_ldap'); +$userBackend = new OCA\user_ldap\USER_LDAP(); +$userBackend->setConnector($connector); +$groupBackend = new OCA\user_ldap\GROUP_LDAP(); +$groupBackend->setConnector($connector); + // register user backend -OC_User::useBackend(new OCA\user_ldap\USER_LDAP()); -OC_Group::useBackend(new OCA\user_ldap\GROUP_LDAP()); +OC_User::useBackend($userBackend); +OC_Group::useBackend($groupBackend); // add settings page to navigation $entry = array( diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index 1585b905aa9..8f46a504f63 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -23,24 +23,21 @@ namespace OCA\user_ldap; -class GROUP_LDAP implements \OCP\GroupInterface { +class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { // //group specific settings - protected $ldapGroupFilter; - protected $ldapGroupMemberAssocAttr; - protected $configured = false; + protected $enabled = false; protected $_group_user = array(); protected $_user_groups = array(); protected $_group_users = array(); protected $_groups = array(); - public function __construct() { - $this->ldapGroupFilter = \OCP\Config::getAppValue('user_ldap', 'ldap_group_filter', '(objectClass=posixGroup)'); - $this->ldapGroupMemberAssocAttr = \OCP\Config::getAppValue('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember'); - - if(!empty($this->ldapGroupFilter) && !empty($this->ldapGroupMemberAssocAttr)) { - $this->configured = true; + public function setConnector(lib\Connection &$connection) { + parent::setConnector($connection); + if(empty($this->connection->ldapGroupFilter) || empty($this->connection->ldapGroupMemberAssocAttr)) { + $this->enabled = false; } + $this->enabled = true; } /** @@ -52,31 +49,31 @@ class GROUP_LDAP implements \OCP\GroupInterface { * Checks whether the user is member of a group or not. */ public function inGroup($uid, $gid) { - if(!$this->configured) { + if(!$this->enabled) { return false; } if(isset($this->_group_user[$gid][$uid])) { return $this->_group_user[$gid][$uid]; } - $dn_user = \OC_LDAP::username2dn($uid); - $dn_group = \OC_LDAP::groupname2dn($gid); + $dn_user = $this->username2dn($uid); + $dn_group = $this->groupname2dn($gid); // just in case if(!$dn_group || !$dn_user) { return false; } //usually, LDAP attributes are said to be case insensitive. But there are exceptions of course. - $members = \OC_LDAP::readAttribute($dn_group, $this->ldapGroupMemberAssocAttr); + $members = $this->readAttribute($dn_group, $this->connection->ldapGroupMemberAssocAttr); if(!$members) { return false; } //extra work if we don't get back user DNs //TODO: this can be done with one LDAP query - if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') { + if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') { $dns = array(); foreach($members as $mid) { - $filter = str_replace('%uid', $mid, \OC_LDAP::conf('ldapLoginFilter')); - $ldap_users = \OC_LDAP::fetchListOfUsers($filter, 'dn'); + $filter = str_replace('%uid', $mid, $this->connection->ldapLoginFilter); + $ldap_users = $this->fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { continue; } @@ -98,36 +95,36 @@ class GROUP_LDAP implements \OCP\GroupInterface { * if the user exists at all. */ public function getUserGroups($uid) { - if(!$this->configured) { + if(!$this->enabled) { return array(); } if(isset($this->_user_groups[$uid])) { return $this->_user_groups[$uid]; } - $userDN = \OC_LDAP::username2dn($uid); + $userDN = $this->username2dn($uid); if(!$userDN) { $this->_user_groups[$uid] = array(); return array(); } //uniqueMember takes DN, memberuid the uid, so we need to distinguish - if((strtolower($this->ldapGroupMemberAssocAttr) == 'uniquemember') - || (strtolower($this->ldapGroupMemberAssocAttr) == 'member')) { + if((strtolower($this->connection->ldapGroupMemberAssocAttr) == 'uniquemember') + || (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'member')) { $uid = $userDN; - } else if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') { - $result = \OC_LDAP::readAttribute($userDN, 'uid'); + } else if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') { + $result = $this->readAttribute($userDN, 'uid'); $uid = $result[0]; } else { // just in case $uid = $userDN; } - $filter = \OC_LDAP::combineFilterWithAnd(array( - $this->ldapGroupFilter, - $this->ldapGroupMemberAssocAttr.'='.$uid + $filter = $this->combineFilterWithAnd(array( + $this->connection->ldapGroupFilter, + $this->connection->ldapGroupMemberAssocAttr.'='.$uid )); - $groups = \OC_LDAP::fetchListOfGroups($filter, array(\OC_LDAP::conf('ldapGroupDisplayName'),'dn')); - $this->_user_groups[$uid] = array_unique(\OC_LDAP::ownCloudGroupNames($groups), SORT_LOCALE_STRING); + $groups = $this->fetchListOfGroups($filter, array($this->connection->ldapGroupDisplayName,'dn')); + $this->_user_groups[$uid] = array_unique($this->ownCloudGroupNames($groups), SORT_LOCALE_STRING); return $this->_user_groups[$uid]; } @@ -137,38 +134,38 @@ class GROUP_LDAP implements \OCP\GroupInterface { * @returns array with user ids */ public function usersInGroup($gid) { - if(!$this->configured) { + if(!$this->enabled) { return array(); } if(isset($this->_group_users[$gid])) { return $this->_group_users[$gid]; } - $groupDN = \OC_LDAP::groupname2dn($gid); + $groupDN = $this->groupname2dn($gid); if(!$groupDN) { $this->_group_users[$gid] = array(); return array(); } - $members = \OC_LDAP::readAttribute($groupDN, $this->ldapGroupMemberAssocAttr); + $members = $this->readAttribute($groupDN, $this->connection->ldapGroupMemberAssocAttr); if(!$members) { $this->_group_users[$gid] = array(); return array(); } $result = array(); - $isMemberUid = (strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid'); + $isMemberUid = (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid'); foreach($members as $member) { if($isMemberUid) { - $filter = \OCP\Util::mb_str_replace('%uid', $member, \OC_LDAP::conf('ldapLoginFilter'), 'UTF-8'); - $ldap_users = \OC_LDAP::fetchListOfUsers($filter, 'dn'); + $filter = \OCP\Util::mb_str_replace('%uid', $member, $this->connection->ldapLoginFilter, 'UTF-8'); + $ldap_users = $this->fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { continue; } - $result[] = \OC_LDAP::dn2username($ldap_users[0]); + $result[] = $this->dn2username($ldap_users[0]); continue; } else { - if($ocname = \OC_LDAP::dn2username($member)){ + if($ocname = $this->dn2username($member)){ $result[] = $ocname; } } @@ -187,12 +184,12 @@ class GROUP_LDAP implements \OCP\GroupInterface { * Returns a list with all groups */ public function getGroups() { - if(!$this->configured) { + if(!$this->enabled) { return array(); } if(empty($this->_groups)) { - $ldap_groups = \OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(\OC_LDAP::conf('ldapGroupDisplayName'), 'dn')); - $this->_groups = \OC_LDAP::ownCloudGroupNames($ldap_groups); + $ldap_groups = $this->fetchListOfGroups($this->connection->ldapGroupFilter, array($this->connection->ldapGroupDisplayName, 'dn')); + $this->_groups = $this->ownCloudGroupNames($ldap_groups); } return $this->_groups; } diff --git a/apps/user_ldap/lib_ldap.php b/apps/user_ldap/lib/access.php similarity index 50% rename from apps/user_ldap/lib_ldap.php rename to apps/user_ldap/lib/access.php index 08b09304d78..eef471f1598 100644 --- a/apps/user_ldap/lib_ldap.php +++ b/apps/user_ldap/lib/access.php @@ -1,7 +1,7 @@ connection = $connection; } - static public function destruct() { - @ldap_unbind(self::$ldapConnectionRes); + private function checkConnection() { + return ($this->connection instanceof Connection); } /** - * @brief returns a read-only configuration value - * @param $key the name of the configuration value - * @returns the value on success, otherwise null + * @brief reads a given attribute for an LDAP record identified by a DN + * @param $dn the record in question + * @param $attr the attribute that shall be retrieved + * @returns the values in an array on success, false otherwise * - * returns a read-only configuration values - * - * we cannot work with getters, because it is a static class + * Reads an attribute from an LDAP entry */ - static public function conf($key) { - if(!self::$configured) { - self::init(); + public function readAttribute($dn, $attr) { + if(!$this->checkConnection()) { + \OCP\Util::writeLog('user_ldap', 'No LDAP Connector assigned, access impossible for readAttribute.', \OCP\Util::WARN); + return false; } + $cr = $this->connection->getConnectionResource(); + $rr = ldap_read($cr, $dn, 'objectClass=*', array($attr)); + $er = ldap_first_entry($cr, $rr); + //LDAP attributes are not case sensitive + $result = \OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8'); + $attr = mb_strtolower($attr, 'UTF-8'); - $availableProperties = array( - 'ldapUserDisplayName', - 'ldapGroupDisplayName', - 'ldapLoginFilter' + if(isset($result[$attr]) && $result[$attr]['count'] > 0){ + $values = array(); + for($i=0;$i<$result[$attr]['count'];$i++) { + $values[] = $this->resemblesDN($attr) ? $this->sanitizeDN($result[$attr][$i]) : $result[$attr][$i]; + } + return $values; + } + return false; + } + + /** + * @brief checks wether the given attribute`s valua is probably a DN + * @param $attr the attribute in question + * @return if so true, otherwise false + */ + private function resemblesDN($attr) { + $resemblingAttributes = array( + 'dn', + 'uniquemember', + 'member' ); + return in_array($attr, $resemblingAttributes); + } - if(in_array($key, $availableProperties)) { - return self::$$key; - } + /** + * @brief sanitizes a DN received from the LDAP server + * @param $dn the DN in question + * @return the sanitized DN + */ + private function sanitizeDN($dn) { + //OID sometimes gives back DNs with whitespace after the comma a la "uid=foo, cn=bar, dn=..." We need to tackle this! + $dn = preg_replace('/([^\\\]),(\s+)/u','\1,',$dn); - return null; + //make comparisons and everything work + $dn = mb_strtolower($dn, 'UTF-8'); + + return $dn; } /** * gives back the database table for the query */ - static private function getMapTable($isUser) { + private function getMapTable($isUser) { if($isUser) { return '*PREFIX*ldap_user_mapping'; } else { @@ -117,8 +111,8 @@ class OC_LDAP { * * returns the LDAP DN for the given internal ownCloud name of the group */ - static public function groupname2dn($name) { - return self::ocname2dn($name, false); + public function groupname2dn($name) { + return $this->ocname2dn($name, false); } /** @@ -128,20 +122,19 @@ class OC_LDAP { * * returns the LDAP DN for the given internal ownCloud name of the user */ - static public function username2dn($name) { - $dn = self::ocname2dn($name, true); + public function username2dn($name) { + $dn = $this->ocname2dn($name, true); if($dn) { return $dn; } else { //fallback: user is not mapped - self::init(); - $filter = self::combineFilterWithAnd(array( - self::$ldapUserFilter, - self::$ldapUserDisplayName . '=' . $name, + $filter = $this->combineFilterWithAnd(array( + $this->connection->ldapUserFilter, + $this->connection->ldapUserDisplayName . '=' . $name, )); - $result = self::searchUsers($filter, 'dn'); + $result = $this->searchUsers($filter, 'dn'); if(isset($result[0]['dn'])) { - self::mapUser($result[0], $name); + $this->mapComponent($result[0], $name, true); return $result[0]; } } @@ -149,10 +142,18 @@ class OC_LDAP { return false; } - static private function ocname2dn($name, $isUser) { - $table = self::getMapTable($isUser); + /** + * @brief returns the LDAP DN for the given internal ownCloud name + * @param $name the ownCloud name in question + * @param $isUser is it a user? otherwise group + * @returns string with the LDAP DN on success, otherwise false + * + * returns the LDAP DN for the given internal ownCloud name + */ + private function ocname2dn($name, $isUser) { + $table = $this->getMapTable($isUser); - $query = OCP\DB::prepare(' + $query = \OCP\DB::prepare(' SELECT ldap_dn FROM '.$table.' WHERE owncloud_name = ? @@ -170,11 +171,11 @@ class OC_LDAP { * * returns the internal ownCloud name for the given LDAP DN of the group */ - static public function dn2groupname($dn, $ldapname = null) { - if(mb_strripos($dn, self::$ldapBaseGroups, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen(self::$ldapBaseGroups, 'UTF-8'))) { + public function dn2groupname($dn, $ldapname = null) { + if(mb_strripos($dn, $this->connection->ldapBaseGroups, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($this->connection->ldapBaseGroups, 'UTF-8'))) { return false; } - return self::dn2ocname($dn, $ldapname, false); + return $this->dn2ocname($dn, $ldapname, false); } /** @@ -185,23 +186,32 @@ class OC_LDAP { * * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN */ - static public function dn2username($dn, $ldapname = null) { - if(mb_strripos($dn, self::$ldapBaseUsers, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen(self::$ldapBaseUsers, 'UTF-8'))) { + public function dn2username($dn, $ldapname = null) { + if(mb_strripos($dn, $this->connection->ldapBaseUsers, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($this->connection->ldapBaseUsers, 'UTF-8'))) { return false; } - return self::dn2ocname($dn, $ldapname, true); + return $this->dn2ocname($dn, $ldapname, true); } - static public function dn2ocname($dn, $ldapname = null, $isUser = true) { - $dn = self::sanitizeDN($dn); - $table = self::getMapTable($isUser); + /** + * @brief returns an internal ownCloud name for the given LDAP DN + * @param $dn the dn of the user object + * @param $ldapname optional, the display name of the object + * @param $isUser optional, wether it is a user object (otherwise group assumed) + * @returns string with with the name to use in ownCloud + * + * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN + */ + public function dn2ocname($dn, $ldapname = null, $isUser = true) { + $dn = $this->sanitizeDN($dn); + $table = $this->getMapTable($isUser); if($isUser) { - $nameAttribute = self::conf('ldapUserDisplayName'); + $nameAttribute = $this->connection->ldapUserDisplayName; } else { - $nameAttribute = self::conf('ldapGroupDisplayName'); + $nameAttribute = $this->connection->ldapGroupDisplayName; } - $query = OCP\DB::prepare(' + $query = \OCP\DB::prepare(' SELECT owncloud_name FROM '.$table.' WHERE ldap_dn = ? @@ -213,22 +223,23 @@ class OC_LDAP { } if(is_null($ldapname)) { - $ldapname = self::readAttribute($dn, $nameAttribute); + $ldapname = $this->readAttribute($dn, $nameAttribute); $ldapname = $ldapname[0]; } - $ldapname = self::sanitizeUsername($ldapname); + $ldapname = $this->sanitizeUsername($ldapname); //a new user/group! Then let's try to add it. We're shooting into the blue with the user/group name, assuming that in most cases there will not be a conflict. Otherwise an error will occur and we will continue with our second shot. - if(self::mapComponent($dn, $ldapname, $isUser)) { + if($this->mapComponent($dn, $ldapname, $isUser)) { return $ldapname; } //doh! There is a conflict. We need to distinguish between users/groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this object is located. - $oc_name = self::alternateOwnCloudName($ldapname, $dn); - if(self::mapComponent($dn, $oc_name, $isUser)) { + $oc_name = $this->alternateOwnCloudName($ldapname, $dn); + if($this->mapComponent($dn, $oc_name, $isUser)) { return $oc_name; } + //TODO: do not simple die away! //and this of course should never been thrown :) throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.'); } @@ -240,8 +251,8 @@ class OC_LDAP { * * gives back the user names as they are used ownClod internally */ - static public function ownCloudUserNames($ldapUsers) { - return self::ldap2ownCloudNames($ldapUsers, true); + public function ownCloudUserNames($ldapUsers) { + return $this->ldap2ownCloudNames($ldapUsers, true); } /** @@ -251,22 +262,26 @@ class OC_LDAP { * * gives back the group names as they are used ownClod internally */ - static public function ownCloudGroupNames($ldapGroups) { - return self::ldap2ownCloudNames($ldapGroups, false); + public function ownCloudGroupNames($ldapGroups) { + return $this->ldap2ownCloudNames($ldapGroups, false); } - static private function ldap2ownCloudNames($ldapObjects, $isUsers) { + private function ldap2ownCloudNames($ldapObjects, $isUsers) { if($isUsers) { - $knownObjects = self::mappedUsers(); - $nameAttribute = self::conf('ldapUserDisplayName'); + $knownObjects = $this->mappedUsers(); + $nameAttribute = $this->connection->ldapUserDisplayName; } else { - $knownObjects = self::mappedGroups(); - $nameAttribute = self::conf('ldapGroupDisplayName'); + $knownObjects = $this->mappedGroups(); + $nameAttribute = $this->connection->ldapGroupDisplayName; } $ownCloudNames = array(); foreach($ldapObjects as $ldapObject) { - $key = self::recursiveArraySearch($knownObjects, $ldapObject['dn']); +// if(!isset($ldapObject['dn'])) { +// print("
");
+// 	die(var_dump($ldapObjects));
+// }
+			$key = \OCP\Util::recursiveArraySearch($knownObjects, $ldapObject['dn']);
 
 			//everything is fine when we know the group
 			if($key !== false) {
@@ -275,19 +290,20 @@ class OC_LDAP {
 			}
 
 			//a new group! Then let's try to add it. We're shooting into the blue with the group name, assuming that in most cases there will not be a conflict. But first make sure, that the display name contains only allowed characters.
-			$ocname = self::sanitizeUsername($ldapObject[$nameAttribute]);
-			if(self::mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
+			$ocname = $this->sanitizeUsername($ldapObject[$nameAttribute]);
+			if($this->mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
 				$ownCloudNames[] = $ocname;
 				continue;
 			}
 
 			//doh! There is a conflict. We need to distinguish between groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this entry is located.
-			$ocname = self::alternateOwnCloudName($ocname, $ldapObject['dn']);
-			if(self::mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
+			$ocname = $this->alternateOwnCloudName($ocname, $ldapObject['dn']);
+			if($this->mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
 				$ownCloudNames[] = $ocname;
 				continue;
 			}
 
+			//TODO: do not simple die away
 			//and this of course should never been thrown :)
 			throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
 		}
@@ -302,10 +318,10 @@ class OC_LDAP {
 	 *
 	 * creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
 	 */
-	static private function alternateOwnCloudName($name, $dn) {
+	private function alternateOwnCloudName($name, $dn) {
 		$ufn = ldap_dn2ufn($dn);
-		$name = $name . '@' . trim(OCP\Util::mb_substr_replace($ufn, '', 0, mb_strpos($ufn, ',', 0, 'UTF-8'), 'UTF-8'));
-		$name = self::sanitizeUsername($name);
+		$name = $name . '@' . trim(\OCP\Util::mb_substr_replace($ufn, '', 0, mb_strpos($ufn, ',', 0, 'UTF-8'), 'UTF-8'));
+		$name = $this->sanitizeUsername($name);
 		return $name;
 	}
 
@@ -315,8 +331,8 @@ class OC_LDAP {
 	 *
 	 * retrieves all known groups from the mappings table
 	 */
-	static private function mappedGroups() {
-		return self::mappedComponents(false);
+	private function mappedGroups() {
+		return $this->mappedComponents(false);
 	}
 
 	/**
@@ -325,14 +341,14 @@ class OC_LDAP {
 	 *
 	 * retrieves all known users from the mappings table
 	 */
-	static private function mappedUsers() {
-		return self::mappedComponents(true);
+	private function mappedUsers() {
+		return $this->mappedComponents(true);
 	}
 
-	static private function mappedComponents($isUsers) {
-		$table = self::getMapTable($isUsers);
+	private function mappedComponents($isUsers) {
+		$table = $this->getMapTable($isUsers);
 
-		$query = OCP\DB::prepare('
+		$query = \OCP\DB::prepare('
 			SELECT ldap_dn, owncloud_name
 			FROM '. $table
 		);
@@ -349,17 +365,17 @@ class OC_LDAP {
 	 *
 	 * inserts a new user or group into the mappings table
 	 */
-	static private function mapComponent($dn, $ocname, $isUser = true) {
-		$table = self::getMapTable($isUser);
-		$dn = self::sanitizeDN($dn);
+	private function mapComponent($dn, $ocname, $isUser = true) {
+		$table = $this->getMapTable($isUser);
+		$dn = $this->sanitizeDN($dn);
 
 		$sqlAdjustment = '';
-		$dbtype = OCP\Config::getSystemValue('dbtype');
+		$dbtype = \OCP\Config::getSystemValue('dbtype');
 		if($dbtype == 'mysql') {
 			$sqlAdjustment = 'FROM dual';
 		}
 
-		$insert = OCP\DB::prepare('
+		$insert = \OCP\DB::prepare('
 			INSERT INTO '.$table.' (ldap_dn, owncloud_name)
 				SELECT ?,?
 				'.$sqlAdjustment.'
@@ -372,7 +388,7 @@ class OC_LDAP {
 
 		$res = $insert->execute(array($dn, $ocname, $dn, $ocname));
 
-		if(OCP\DB::isError($res)) {
+		if(\OCP\DB::isError($res)) {
 			return false;
 		}
 
@@ -385,15 +401,15 @@ class OC_LDAP {
 		return true;
 	}
 
-	static public function fetchListOfUsers($filter, $attr) {
-		return self::fetchList(OC_LDAP::searchUsers($filter, $attr), (count($attr) > 1));
+	public function fetchListOfUsers($filter, $attr) {
+		return $this->fetchList($this->searchUsers($filter, $attr), (count($attr) > 1));
 	}
 
-	static public function fetchListOfGroups($filter, $attr) {
-		return self::fetchList(OC_LDAP::searchGroups($filter, $attr), (count($attr) > 1));
+	public function fetchListOfGroups($filter, $attr) {
+		return $this->fetchList($this->searchGroups($filter, $attr), (count($attr) > 1));
 	}
 
-	static private function fetchList($list, $manyAttributes) {
+	private function fetchList($list, $manyAttributes) {
 		if(is_array($list)) {
 			if($manyAttributes) {
 				return $list;
@@ -406,32 +422,6 @@ class OC_LDAP {
 		return array();
 	}
 
-	/**
-	 * @brief reads a given attribute for an LDAP record identified by a DN
-	 * @param $dn the record in question
-	 * @param $attr the attribute that shall be retrieved
-	 * @returns the values in an array on success, false otherwise
-	 *
-	 * Reads an attribute from an LDAP entry
-	 */
-	static public function readAttribute($dn, $attr) {
-		$cr = self::getConnectionResource();
-		$rr = ldap_read($cr, $dn, 'objectClass=*', array($attr));
-		$er = ldap_first_entry($cr, $rr);
-		//LDAP attributes are not case sensitive
-		$result = OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
-		$attr = mb_strtolower($attr, 'UTF-8');
-
-		if(isset($result[$attr]) && $result[$attr]['count'] > 0){
-			$values = array();
-			for($i=0;$i<$result[$attr]['count'];$i++) {
-				$values[] = self::resemblesDN($attr) ? self::sanitizeDN($result[$attr][$i]) : $result[$attr][$i];
-			}
-			return $values;
-		}
-		return false;
-	}
-
 	/**
 	 * @brief executes an LDAP search, optimized for Users
 	 * @param $filter the LDAP filter for the search
@@ -440,9 +430,8 @@ class OC_LDAP {
 	 *
 	 * Executes an LDAP search
 	 */
-	static public function searchUsers($filter, $attr = null) {
-		self::init();
-		return self::search($filter, self::$ldapBaseUsers, $attr);
+	public function searchUsers($filter, $attr = null) {
+		return $this->search($filter, $this->connection->ldapBaseUsers, $attr);
 	}
 
 	/**
@@ -453,9 +442,8 @@ class OC_LDAP {
 	 *
 	 * Executes an LDAP search
 	 */
-	static public function searchGroups($filter, $attr = null) {
-		self::init();
-		return self::search($filter, self::$ldapBaseGroups, $attr);
+	public function searchGroups($filter, $attr = null) {
+		return $this->search($filter, $this->connection->ldapBaseGroups, $attr);
 	}
 
 	/**
@@ -467,13 +455,13 @@ class OC_LDAP {
 	 *
 	 * Executes an LDAP search
 	 */
-	static private function search($filter, $base, $attr = null) {
+	private function search($filter, $base, $attr = null) {
 		if(!is_null($attr) && !is_array($attr)) {
 			$attr = array(mb_strtolower($attr, 'UTF-8'));
 		}
 
 		// See if we have a resource
-		$link_resource = self::getConnectionResource();
+		$link_resource = $this->connection->getConnectionResource();
 		if(is_resource($link_resource)) {
 			$sr = ldap_search($link_resource, $base, $filter, $attr);
 			$findings = ldap_get_entries($link_resource, $sr );
@@ -486,6 +474,7 @@ class OC_LDAP {
 		} else {
 			// Seems like we didn't find any resource.
 			// Return an empty array just like before.
+			\OCP\Util::writeLog('user_ldap', 'Could not search, because resource is missing.', \OCP\Util::DEBUG);
 			return array();
 		}
 
@@ -500,16 +489,16 @@ class OC_LDAP {
 				if(!is_array($item)) {
 					continue;
 				}
-				$item = OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8');
+				$item = \OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8');
 
 				if($multiarray) {
 					foreach($attr as $key) {
 						$key = mb_strtolower($key, 'UTF-8');
 						if(isset($item[$key])) {
 							if($key != 'dn'){
-								$selection[$i][$key] = self::resemblesDN($key) ? self::sanitizeDN($item[$key][0]) : $item[$key][0];
+								$selection[$i][$key] = $this->resemblesDN($key) ? $this->sanitizeDN($item[$key][0]) : $item[$key][0];
 							} else {
-								$selection[$i][$key] = self::sanitizeDN($item[$key]);
+								$selection[$i][$key] = $this->sanitizeDN($item[$key]);
 							}
 						}
 
@@ -520,47 +509,26 @@ class OC_LDAP {
 					$key = mb_strtolower($attr[0], 'UTF-8');
 
 					if(isset($item[$key])) {
-						if(self::resemblesDN($key)) {
-							$selection[] = self::sanitizeDN($item[$key]);
+						if($this->resemblesDN($key)) {
+							$selection[] = $this->sanitizeDN($item[$key]);
 						} else {
 							$selection[] = $item[$key];
 						}
 					}
 				}
-
 			}
 			return $selection;
 		}
-
 		return $findings;
 	}
 
-	static private function resemblesDN($attr) {
-		$resemblingAttributes = array(
-			'dn',
-			'uniquemember',
-			'member'
-		);
-		return in_array($attr, $resemblingAttributes);
-	}
-
-	static private function sanitizeDN($dn) {
-		//OID sometimes gives back DNs with whitespace after the comma a la "uid=foo, cn=bar, dn=..." We need to tackle this!
-		$dn = preg_replace('/([^\\\]),(\s+)/u','\1,',$dn);
-
-		//make comparisons and everything work
-		$dn = mb_strtolower($dn, 'UTF-8');
-
-		return $dn;
-	}
-
-	static private function sanitizeUsername($name) {
-		if(self::$ldapIgnoreNamingRules) {
+	public function sanitizeUsername($name) {
+		if($this->connection->ldapIgnoreNamingRules) {
 			return $name;
 		}
 
 		//REPLACEMENTS
-		$name = OCP\Util::mb_str_replace(' ', '_', $name, 'UTF-8');
+		$name = \OCP\Util::mb_str_replace(' ', '_', $name, 'UTF-8');
 
 		//every remaining unallowed characters will be removed
 		$name = preg_replace('/[^a-zA-Z0-9_.@-]/u', '', $name);
@@ -575,8 +543,8 @@ class OC_LDAP {
 	 *
 	 * Combines Filter arguments with AND
 	 */
-	static public function combineFilterWithAnd($filters) {
-		return self::combineFilter($filters,'&');
+	public function combineFilterWithAnd($filters) {
+		return $this->combineFilter($filters,'&');
 	}
 
 	/**
@@ -586,8 +554,8 @@ class OC_LDAP {
 	 *
 	 * Combines Filter arguments with AND
 	 */
-	static public function combineFilterWithOr($filters) {
-		return self::combineFilter($filters,'|');
+	public function combineFilterWithOr($filters) {
+		return $this->combineFilter($filters,'|');
 	}
 
 	/**
@@ -598,7 +566,7 @@ class OC_LDAP {
 	 *
 	 * Combines Filter arguments with AND
 	 */
-	static private function combineFilter($filters, $operator) {
+	private function combineFilter($filters, $operator) {
 		$combinedFilter = '('.$operator;
 		foreach($filters as $filter) {
 		    if($filter[0] != '(') {
@@ -610,112 +578,15 @@ class OC_LDAP {
 		return $combinedFilter;
 	}
 
-	/**
-	 * Returns the LDAP handler
-	 */
-	static private function getConnectionResource() {
-		if(!self::$ldapConnectionRes) {
-			self::init();
-		}
-		if(is_null(self::$ldapConnectionRes)) {
-			OCP\Util::writeLog('ldap', 'Connection could not be established', OCP\Util::INFO);
-		}
-		return self::$ldapConnectionRes;
-	}
-
-	/**
-	 * Caches the general LDAP configuration.
-	 */
-	static private function readConfiguration($force = false) {
-		if(!self::$configured || $force) {
-			self::$ldapHost              = OCP\Config::getAppValue('user_ldap', 'ldap_host', '');
-			self::$ldapPort              = OCP\Config::getAppValue('user_ldap', 'ldap_port', 389);
-			self::$ldapAgentName         = OCP\Config::getAppValue('user_ldap', 'ldap_dn','');
-			self::$ldapAgentPassword     = base64_decode(OCP\Config::getAppValue('user_ldap', 'ldap_agent_password',''));
-			self::$ldapBase              = OCP\Config::getAppValue('user_ldap', 'ldap_base', '');
-			self::$ldapBaseUsers         = OCP\Config::getAppValue('user_ldap', 'ldap_base_users',self::$ldapBase);
-			self::$ldapBaseGroups        = OCP\Config::getAppValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
-			self::$ldapTLS               = OCP\Config::getAppValue('user_ldap', 'ldap_tls',0);
-			self::$ldapNoCase            = OCP\Config::getAppValue('user_ldap', 'ldap_nocase', 0);
-			self::$ldapUserDisplayName   = mb_strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_display_name', 'uid'), 'UTF-8');
-			self::$ldapUserFilter        = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter','objectClass=person');
-			self::$ldapLoginFilter       = OCP\Config::getAppValue('user_ldap', 'ldap_login_filter', '(uid=%uid)');
-			self::$ldapGroupDisplayName  = mb_strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR), 'UTF-8');
-			self::$ldapIgnoreNamingRules = OCP\Config::getSystemValue('ldapIgnoreNamingRules', false);
-
-			if(empty(self::$ldapBaseUsers)) {
-				OCP\Util::writeLog('ldap', 'Base for Users is empty, using Base DN', OCP\Util::INFO);
-				self::$ldapBaseUsers = self::$ldapBase;
-			}
-			if(empty(self::$ldapBaseGroups)) {
-				OCP\Util::writeLog('ldap', 'Base for Groups is empty, using Base DN', OCP\Util::INFO);
-				self::$ldapBaseGroups = self::$ldapBase;
-			}
-
-			if(
-				   !empty(self::$ldapHost)
-				&& !empty(self::$ldapPort)
-				&& (
-					   (!empty(self::$ldapAgentName) && !empty(self::$ldapAgentPassword))
-					|| ( empty(self::$ldapAgentName) &&  empty(self::$ldapAgentPassword))
-				)
-				&& !empty(self::$ldapBase)
-				&& !empty(self::$ldapUserDisplayName)
-			)
-			{
-				self::$configured = true;
-			}
-		}
-	}
-
-	/**
-	 * Connects and Binds to LDAP
-	 */
-	static private function establishConnection() {
-		if(!self::$configured) {
-			OCP\Util::writeLog('ldap', 'Configuration is invalid, cannot connect', OCP\Util::INFO);
+	public function areCredentialsValid($name, $password) {
+		$testConnection = clone $this->connection;
+		$credentials = array(
+			'ldapAgentName' => $name,
+			'ldapAgentPassword' => $password
+		);
+		if(!$testConnection->setConfiguration($credentials)) {
 			return false;
 		}
-		if(!self::$ldapConnectionRes) {
-			self::$ldapConnectionRes = ldap_connect(self::$ldapHost, self::$ldapPort);
-			if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
-					if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
-						if(self::$ldapTLS) {
-							ldap_start_tls(self::$ldapConnectionRes);
-						}
-					}
-			}
-
-			$ldapLogin = @ldap_bind(self::$ldapConnectionRes, self::$ldapAgentName, self::$ldapAgentPassword );
-			if(!$ldapLogin) {
-				OCP\Util::writeLog('ldap', 'Bind failed: ' . ldap_errno(self::$ldapConnectionRes) . ': ' . ldap_error(self::$ldapConnectionRes), OCP\Util::ERROR);
-				self::$ldapConnectionRes = null;
-				return false;
-			}
-		}
+		return $testConnection->bind();
 	}
-
-	static public function areCredentialsValid($name, $password) {
-		return @ldap_bind(self::getConnectionResource(), $name, $password);
-	}
-
-	/**
-	* taken from http://www.php.net/manual/en/function.array-search.php#97645
-	* TODO: move somewhere, where its better placed since it is not LDAP specific. OC_Helper maybe?
-	*/
-	static public function recursiveArraySearch($haystack, $needle, $index = null) {
-		$aIt = new RecursiveArrayIterator($haystack);
-		$it = new RecursiveIteratorIterator($aIt);
-
-		while($it->valid()) {
-			if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) {
-				return $aIt->key();
-			}
-
-			$it->next();
-		}
-
-		return false;
-	}
-
- }
+}
\ No newline at end of file
diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php
new file mode 100644
index 00000000000..44b1c20214b
--- /dev/null
+++ b/apps/user_ldap/lib/connection.php
@@ -0,0 +1,245 @@
+.
+ *
+ */
+
+namespace OCA\user_ldap\lib;
+
+class Connection {
+	private $ldapConnectionRes = null;
+	private $configID;
+	private $configured = false;
+
+	//cached settings
+	protected $config = array(
+		'ldapHost' => null,
+		'ldapPort' => null,
+		'ldapBase' => null,
+		'ldapBaseUsers' => null,
+		'ldapBaseGroups' => null,
+		'ldapAgentName' => null,
+		'ldapAgentPassword' => null,
+		'ldapTLS' => null,
+		'ldapNoCase' => null,
+		'ldapIgnoreNamingRules' => null,
+		'ldapUserDisplayName' => null,
+		'ldapUserFilter' => null,
+		'ldapGroupFilter' => null,
+		'ldapGroupDisplayName' => null,
+		'ldapLoginFilter' => null,
+		'ldapQuotaAttribute' => null,
+		'ldapQuotaDefault' => null,
+		'ldapEmailAttribute' => null,
+	);
+
+	public function __construct($configID = 'user_ldap') {
+		$this->configID = $configID;
+	}
+
+	public function __destruct() {
+		@ldap_unbind($this->ldapConnectionRes);
+	}
+
+	public function __get($name) {
+		if(!$this->configured) {
+			$this->readConfiguration();
+		}
+
+		if(isset($this->config[$name])) {
+			return $this->config[$name];
+		}
+	}
+
+	/**
+	 * @brief initializes the LDAP backend
+	 * @param $force read the config settings no matter what
+	 *
+	 * initializes the LDAP backend
+	 */
+	public function init($force = false) {
+		$this->readConfiguration($force);
+		$this->establishConnection();
+	}
+
+	/**
+	 * Returns the LDAP handler
+	 */
+	public function getConnectionResource() {
+		if(!$this->ldapConnectionRes) {
+			$this->init();
+		}
+		if(is_null($this->ldapConnectionRes)) {
+			\OCP\Util::writeLog('user_ldap', 'Connection could not be established', \OCP\Util::ERROR);
+		}
+		return $this->ldapConnectionRes;
+	}
+
+	/**
+	 * Caches the general LDAP configuration.
+	 */
+	private function readConfiguration($force = false) {
+		\OCP\Util::writeLog('user_ldap','Checking conf state: isConfigured? '.print_r($this->configured, true).' isForce? '.print_r($force, true).' configID? '.print_r($this->configID, true), \OCP\Util::DEBUG);
+		if((!$this->configured || $force) && !is_null($this->configID)) {
+			\OCP\Util::writeLog('user_ldap','Reading the configuration', \OCP\Util::DEBUG);
+			$this->config['ldapHost']              = \OCP\Config::getAppValue($this->configID, 'ldap_host', '');
+			$this->config['ldapPort']              = \OCP\Config::getAppValue($this->configID, 'ldap_port', 389);
+			$this->config['ldapAgentName']         = \OCP\Config::getAppValue($this->configID, 'ldap_dn','');
+			$this->config['ldapAgentPassword']     = base64_decode(\OCP\Config::getAppValue($this->configID, 'ldap_agent_password',''));
+			$this->config['ldapBase']              = \OCP\Config::getAppValue($this->configID, 'ldap_base', '');
+			$this->config['ldapBaseUsers']         = \OCP\Config::getAppValue($this->configID, 'ldap_base_users',$this->config['ldapBase']);
+			$this->config['ldapBaseGroups']        = \OCP\Config::getAppValue($this->configID, 'ldap_base_groups', $this->config['ldapBase']);
+			$this->config['ldapTLS']               = \OCP\Config::getAppValue($this->configID, 'ldap_tls',0);
+			$this->config['ldapNoCase']            = \OCP\Config::getAppValue($this->configID, 'ldap_nocase', 0);
+			$this->config['ldapUserDisplayName']   = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_display_name', 'uid'), 'UTF-8');
+			$this->config['ldapUserFilter']        = \OCP\Config::getAppValue($this->configID, 'ldap_userlist_filter','objectClass=person');
+			$this->config['ldapGroupFilter']        = \OCP\Config::getAppValue($this->configID, 'ldap_group_filter','(objectClass=posixGroup)');
+			$this->config['ldapLoginFilter']       = \OCP\Config::getAppValue($this->configID, 'ldap_login_filter', '(uid=%uid)');
+			$this->config['ldapGroupDisplayName']  = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR), 'UTF-8');
+			$this->config['ldapQuotaAttribute']    = \OCP\Config::getAppValue($this->configID, 'ldap_quota_attr', '');
+			$this->config['ldapQuotaDefault']      = \OCP\Config::getAppValue($this->configID, 'ldap_quota_def', '');
+			$this->config['ldapEmailAttribute']      = \OCP\Config::getAppValue($this->configID, 'ldap_email_attr', '');
+			$this->config['ldapGroupMemberAssocAttr']      = \OCP\Config::getAppValue($this->configID, 'ldap_group_member_assoc_attribute', 'uniqueMember');
+			$this->config['ldapIgnoreNamingRules'] = \OCP\Config::getSystemValue('ldapIgnoreNamingRules', false);
+
+			$this->configured = $this->validateConfiguration();
+		}
+	}
+
+	/**
+	 * @brief set LDAP configuration with values delivered by an array, not read from configuration
+	 * @param $config array that holds the config parameters in an associated array
+	 * @param &$setParameters optional; array where the set fields will be given to
+	 * @return true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
+	 */
+	public function setConfiguration($config, &$setParameters = null) {
+		if(!is_array($config)) {
+			return false;
+		}
+
+		foreach($config as $parameter => $value) {
+		    if(isset($this->config[$parameter])) {
+				$this->config[$parameter] = $value;
+				if(is_array($setParameters)) {
+					$setParameters[] = $parameter;
+				}
+		    }
+		}
+
+		$this->configured = $this->validateConfiguration();
+
+		return $this->configured;
+	}
+
+	/**
+	 * @brief Validates the user specified configuration
+	 * @returns true if configuration seems OK, false otherwise
+	 */
+	private function validateConfiguration() {
+		//first step: "soft" checks: settings that are not really necessary, but advisable. If left empty, give an info message
+		if(empty($this->config['ldapBaseUsers'])) {
+			\OCP\Util::writeLog('user_ldap', 'Base tree for Users is empty, using Base DN', \OCP\Util::INFO);
+			$this->config['ldapBaseUsers'] = $this->config['ldapBase'];
+		}
+		if(empty($this->config['ldapBaseGroups'])) {
+			\OCP\Util::writeLog('user_ldap', 'Base tree for Groups is empty, using Base DN', \OCP\Util::INFO);
+			$this->config['ldapBaseGroups'] = $this->config['ldapBase'];
+		}
+		if(empty($this->config['ldapGroupFilter']) && empty($this->config['ldapGroupMemberAssocAttr'])) {
+			\OCP\Util::writeLog('user_ldap', 'No group filter is specified, LDAP group feature will not be used.', \OCP\Util::INFO);
+		}
+
+		//second step: critical checks. If left empty or filled wrong, set as unconfigured and give a warning.
+		$configurationOK = true;
+		if(empty($this->config['ldapHost'])) {
+			\OCP\Util::writeLog('user_ldap', 'No LDAP host given, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if(empty($this->config['ldapPort'])) {
+			\OCP\Util::writeLog('user_ldap', 'No LDAP Port given, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if((empty($this->config['ldapAgentName']) && !empty($this->config['ldapAgentPassword']))
+			|| (!empty($this->config['ldapAgentName']) && empty($this->config['ldapAgentPassword']))) {
+			\OCP\Util::writeLog('user_ldap', 'Either no password given for the user agent or a password is given, but no LDAP agent; won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		//TODO: check if ldapAgentName is in DN form
+		if(empty($this->config['ldapBase']) && (empty($this->config['ldapBaseUsers']) && empty($this->config['ldapBaseGroups']))) {
+			\OCP\Util::writeLog('user_ldap', 'No Base DN given, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if(empty($this->config['ldapUserDisplayName'])) {
+			\OCP\Util::writeLog('user_ldap', 'No user display name attribute specified, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if(empty($this->config['ldapGroupDisplayName'])) {
+			\OCP\Util::writeLog('user_ldap', 'No group display name attribute specified, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if(empty($this->config['ldapLoginFilter'])) {
+			\OCP\Util::writeLog('user_ldap', 'No login filter specified, won`t connect.', \OCP\Util::WARN);
+			$configurationOK = false;
+		}
+		if(mb_strpos($this->config['ldapLoginFilter'], '%uid', 0, 'UTF-8') === false) {
+			\OCP\Util::writeLog('user_ldap', 'Login filter does not contain %uid place holder, won`t connect.', \OCP\Util::WARN);
+			\OCP\Util::writeLog('user_ldap', 'Login filter was ' . $this->config['ldapLoginFilter'], \OCP\Util::DEBUG);
+			$configurationOK = false;
+		}
+
+		return $configurationOK;
+	}
+
+	/**
+	 * Connects and Binds to LDAP
+	 */
+	private function establishConnection() {
+		if(!$this->configured) {
+			\OCP\Util::writeLog('user_ldap', 'Configuration is invalid, cannot connect', \OCP\Util::WARN);
+			return false;
+		}
+		if(!$this->ldapConnectionRes) {
+			$this->ldapConnectionRes = ldap_connect($this->config['ldapHost'], $this->config['ldapPort']);
+			if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
+					if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
+						if($this->config['ldapTLS']) {
+							ldap_start_tls($this->ldapConnectionRes);
+						}
+					}
+			}
+
+			return $this->bind();
+		}
+	}
+
+	/**
+	 * Binds to LDAP
+	 */
+	public function bind() {
+		$ldapLogin = @ldap_bind($this->getConnectionResource(), $this->config['ldapAgentName'], $this->config['ldapAgentPassword']);
+		if(!$ldapLogin) {
+			\OCP\Util::writeLog('user_ldap', 'Bind failed: ' . ldap_errno($this->ldapConnectionRes) . ': ' . ldap_error($this->ldapConnectionRes), \OCP\Util::ERROR);
+			$this->ldapConnectionRes = null;
+			return false;
+		}
+		return true;
+	}
+
+}
\ No newline at end of file
diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index e7ed4dae280..5a7e308f006 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -27,51 +27,38 @@ namespace OCA\user_ldap;
 
 class USER_LDAP extends lib\Access implements \OCP\UserInterface {
 
-	// cached settings
-	protected $ldapUserFilter;
-	protected $ldapQuotaAttribute;
-	protected $ldapQuotaDefault;
-	protected $ldapEmailAttribute;
-
 	// will be retrieved from LDAP server
 	protected $ldap_dc = false;
 
 	// cache getUsers()
 	protected $_users = null;
 
-	public function __construct() {
-		$this->ldapUserFilter      = \OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter', '(objectClass=posixAccount)');
-		$this->ldapQuotaAttribute  = \OCP\Config::getAppValue('user_ldap', 'ldap_quota_attr', '');
-		$this->ldapQuotaDefault    = \OCP\Config::getAppValue('user_ldap', 'ldap_quota_def', '');
-		$this->ldapEmailAttribute  = \OCP\Config::getAppValue('user_ldap', 'ldap_email_attr', '');
-	}
-
 	private function updateQuota($dn) {
 		$quota = null;
-		if(!empty($this->ldapQuotaDefault)) {
-			$quota = $this->ldapQuotaDefault;
+		if(!empty($this->connection->ldapQuotaDefault)) {
+			$quota = $this->connection->ldapQuotaDefault;
 		}
-		if(!empty($this->ldapQuotaAttribute)) {
-			$aQuota = \OC_LDAP::readAttribute($dn, $this->ldapQuotaAttribute);
+		if(!empty($this->connection->ldapQuotaAttribute)) {
+			$aQuota = $this->readAttribute($dn, $this->connection->ldapQuotaAttribute);
 
 			if($aQuota && (count($aQuota) > 0)) {
 				$quota = $aQuota[0];
 			}
 		}
 		if(!is_null($quota)) {
-			\OCP\Config::setUserValue(\OC_LDAP::dn2username($dn), 'files', 'quota', \OCP\Util::computerFileSize($quota));
+			\OCP\Config::setUserValue($this->dn2username($dn), 'files', 'quota', \OCP\Util::computerFileSize($quota));
 		}
 	}
 
 	private function updateEmail($dn) {
 		$email = null;
-		if(!empty($this->ldapEmailAttribute)) {
-			$aEmail = \OC_LDAP::readAttribute($dn, $this->ldapEmailAttribute);
+		if(!empty($this->connection->ldapEmailAttribute)) {
+			$aEmail = $this->readAttribute($dn, $this->connection->ldapEmailAttribute);
 			if($aEmail && (count($aEmail) > 0)) {
 				$email = $aEmail[0];
 			}
 			if(!is_null($email)){
-				\OCP\Config::setUserValue(\OC_LDAP::dn2username($dn), 'settings', 'email', $email);
+				\OCP\Config::setUserValue($this->dn2username($dn), 'settings', 'email', $email);
 			}
 		}
 	}
@@ -86,15 +73,16 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface {
 	 */
 	public function checkPassword($uid, $password){
 		//find out dn of the user name
-		$filter = \OCP\Util::mb_str_replace('%uid', $uid, \OC_LDAP::conf('ldapLoginFilter'), 'UTF-8');
-		$ldap_users = \OC_LDAP::fetchListOfUsers($filter, 'dn');
+		$filter = \OCP\Util::mb_str_replace('%uid', $uid, $this->connection->ldapLoginFilter, 'UTF-8');
+		\OCP\Util::writeLog('user_ldap', 'Getting DN for login, filter '.$filter.' originating from '.$this->connection->ldapLoginFilter,\OCP\Util::DEBUG);
+		$ldap_users = $this->fetchListOfUsers($filter, 'dn');
 		if(count($ldap_users) < 1) {
 			return false;
 		}
 		$dn = $ldap_users[0];
 
 		//are the credentials OK?
-		if(!\OC_LDAP::areCredentialsValid($dn, $password)) {
+		if(!$this->areCredentialsValid($dn, $password)) {
 			return false;
 		}
 
@@ -103,7 +91,7 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface {
 		$this->updateEmail($dn);
 
 		//give back the display name
-		return \OC_LDAP::dn2username($dn);
+		return $this->dn2username($dn);
 	}
 
 	/**
@@ -114,8 +102,8 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface {
 	 */
 	public function getUsers(){
 		if(is_null($this->_users)) {
-			$ldap_users = \OC_LDAP::fetchListOfUsers($this->ldapUserFilter, array(\OC_LDAP::conf('ldapUserDisplayName'), 'dn'));
-			$this->_users = \OC_LDAP::ownCloudUserNames($ldap_users);
+			$ldap_users = $this->fetchListOfUsers($this->connection->ldapUserFilter, array($this->connection->ldapUserDisplayName, 'dn'));
+			$this->_users = $this->ownCloudUserNames($ldap_users);
 		}
 		return $this->_users;
 	}
@@ -127,13 +115,13 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface {
 	 */
 	public function userExists($uid){
 		//getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
-		$dn = \OC_LDAP::username2dn($uid);
+		$dn = $this->username2dn($uid);
 		if(!$dn) {
 			return false;
 		}
 
 		//if user really still exists, we will be able to read his cn
-		$cn = \OC_LDAP::readAttribute($dn, 'cn');
+		$cn = $this->readAttribute($dn, 'cn');
 		if(!$cn || empty($cn)) {
 			return false;
 		}

From b10f7aafb7fcf31af86795d45a8d227540dfb0fe Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 12:54:23 +0200
Subject: [PATCH 16/28] LDAP: silence warning, but handle the error

---
 apps/user_ldap/lib/access.php | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index eef471f1598..ff94b00a842 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -48,7 +48,12 @@ abstract class Access {
 			return false;
 		}
 		$cr = $this->connection->getConnectionResource();
-		$rr = ldap_read($cr, $dn, 'objectClass=*', array($attr));
+		$rr = @ldap_read($cr, $dn, 'objectClass=*', array($attr));
+		if(!is_resource($rr)) {
+			\OCP\Util::writeLog('user_ldap', 'readAttribute failed for DN '.$dn, \OCP\Util::DEBUG);
+			//in case an error occurs , e.g. object does not exist
+			return false;
+		}
 		$er = ldap_first_entry($cr, $rr);
 		//LDAP attributes are not case sensitive
 		$result = \OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');

From a6c5309e16817745e10bcfd5af29b24be99b2ae1 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 12:54:56 +0200
Subject: [PATCH 17/28] LDAP: adjust test after refactoring

---
 apps/user_ldap/tests/group_ldap.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/apps/user_ldap/tests/group_ldap.php b/apps/user_ldap/tests/group_ldap.php
index 2be6b46fb23..106459580fa 100644
--- a/apps/user_ldap/tests/group_ldap.php
+++ b/apps/user_ldap/tests/group_ldap.php
@@ -26,8 +26,8 @@ class Test_Group_Ldap extends UnitTestCase {
 	}
 
 	function testSingleBackend(){
-		OC_Group::useBackend(new OC_GROUP_LDAP());
-		$group_ldap = new OC_GROUP_LDAP();
+		OC_Group::useBackend(new OCA\user_ldap\GROUP_LDAP());
+		$group_ldap = new OCA\user_ldap\GROUP_LDAP();
 
  		$this->assertIsA(OC_Group::getGroups(),gettype(array()));
 		$this->assertIsA($group_ldap->getGroups(),gettype(array()));

From 92f447ca50e8b35f34c8020f867664c25703bd2c Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 13:09:51 +0200
Subject: [PATCH 18/28] code style

---
 apps/user_ldap/group_ldap.php | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index 8f46a504f63..bc9c95ffe08 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -109,7 +109,8 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
 
 		//uniqueMember takes DN, memberuid the uid, so we need to distinguish
 		if((strtolower($this->connection->ldapGroupMemberAssocAttr) == 'uniquemember')
-			|| (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'member')) {
+			|| (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'member')
+		  ) {
 			$uid = $userDN;
 		} else if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') {
 			$result = $this->readAttribute($userDN, 'uid');
@@ -165,7 +166,7 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
 				$result[] = $this->dn2username($ldap_users[0]);
 				continue;
 			} else {
-				if($ocname = $this->dn2username($member)){
+				if($ocname = $this->dn2username($member)) {
 					$result[] = $ocname;
 				}
 			}

From c8404a7bfa3d462ebf8208f7647f5da1e005e9c5 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 13:10:59 +0200
Subject: [PATCH 19/28] code style

---
 apps/user_ldap/group_ldap.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index bc9c95ffe08..ea2cc17733d 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -24,7 +24,6 @@
 namespace OCA\user_ldap;
 
 class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
-// 	//group specific settings
 	protected $enabled = false;
 
 	protected $_group_user = array();

From 569e52b87cb1f7c709f3aad4537350a1c71c79f3 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 13:11:42 +0200
Subject: [PATCH 20/28] remove unnecessary debug output

---
 apps/user_ldap/user_ldap.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index 5a7e308f006..dffed5ded98 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -74,7 +74,6 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface {
 	public function checkPassword($uid, $password){
 		//find out dn of the user name
 		$filter = \OCP\Util::mb_str_replace('%uid', $uid, $this->connection->ldapLoginFilter, 'UTF-8');
-		\OCP\Util::writeLog('user_ldap', 'Getting DN for login, filter '.$filter.' originating from '.$this->connection->ldapLoginFilter,\OCP\Util::DEBUG);
 		$ldap_users = $this->fetchListOfUsers($filter, 'dn');
 		if(count($ldap_users) < 1) {
 			return false;

From 15f7d838fa9cafe536ba638e42dd7008457fbff9 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 13:13:01 +0200
Subject: [PATCH 21/28] code style

---
 apps/user_ldap/user_ldap.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index dffed5ded98..a4a8921d08d 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -57,7 +57,7 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface {
 			if($aEmail && (count($aEmail) > 0)) {
 				$email = $aEmail[0];
 			}
-			if(!is_null($email)){
+			if(!is_null($email)) {
 				\OCP\Config::setUserValue($this->dn2username($dn), 'settings', 'email', $email);
 			}
 		}

From 8664729843a16528f224becd7afe3c35f62f191a Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 13:14:32 +0200
Subject: [PATCH 22/28] code style

---
 apps/user_ldap/appinfo/app.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php
index 537f56861c4..4862c3b8e3e 100644
--- a/apps/user_ldap/appinfo/app.php
+++ b/apps/user_ldap/appinfo/app.php
@@ -24,7 +24,7 @@
 require_once('apps/user_ldap/lib_ldap.php');
 // require_once('apps/user_ldap/group_ldap.php');
 
-OCP\App::registerAdmin('user_ldap','settings');
+OCP\App::registerAdmin('user_ldap', 'settings');
 
 $connector = new OCA\user_ldap\lib\Connection('user_ldap');
 $userBackend  = new OCA\user_ldap\USER_LDAP();

From edfd789a8787e5c06aab0b33581e9b211572ba23 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 13:16:31 +0200
Subject: [PATCH 23/28] LDAP: remove obsolete require_once

---
 apps/user_ldap/appinfo/app.php | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php
index 4862c3b8e3e..3c6da47d71a 100644
--- a/apps/user_ldap/appinfo/app.php
+++ b/apps/user_ldap/appinfo/app.php
@@ -21,9 +21,6 @@
 *
 */
 
-require_once('apps/user_ldap/lib_ldap.php');
-// require_once('apps/user_ldap/group_ldap.php');
-
 OCP\App::registerAdmin('user_ldap', 'settings');
 
 $connector = new OCA\user_ldap\lib\Connection('user_ldap');

From ab1d9507a97887fd6acd8592f079ab3e519d1687 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 13:18:31 +0200
Subject: [PATCH 24/28] code style

---
 apps/user_ldap/lib/access.php | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index ff94b00a842..80caa5d353f 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -59,7 +59,7 @@ abstract class Access {
 		$result = \OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
 		$attr = mb_strtolower($attr, 'UTF-8');
 
-		if(isset($result[$attr]) && $result[$attr]['count'] > 0){
+		if(isset($result[$attr]) && $result[$attr]['count'] > 0) {
 			$values = array();
 			for($i=0;$i<$result[$attr]['count'];$i++) {
 				$values[] = $this->resemblesDN($attr) ? $this->sanitizeDN($result[$attr][$i]) : $result[$attr][$i];
@@ -90,7 +90,7 @@ abstract class Access {
 	 */
 	private function sanitizeDN($dn) {
 		//OID sometimes gives back DNs with whitespace after the comma a la "uid=foo, cn=bar, dn=..." We need to tackle this!
-		$dn = preg_replace('/([^\\\]),(\s+)/u','\1,',$dn);
+		$dn = preg_replace('/([^\\\]),(\s+)/u', '\1,', $dn);
 
 		//make comparisons and everything work
 		$dn = mb_strtolower($dn, 'UTF-8');
@@ -500,7 +500,7 @@ abstract class Access {
 					foreach($attr as $key) {
 						$key = mb_strtolower($key, 'UTF-8');
 						if(isset($item[$key])) {
-							if($key != 'dn'){
+							if($key != 'dn') {
 								$selection[$i][$key] = $this->resemblesDN($key) ? $this->sanitizeDN($item[$key][0]) : $item[$key][0];
 							} else {
 								$selection[$i][$key] = $this->sanitizeDN($item[$key]);
@@ -549,7 +549,7 @@ abstract class Access {
 	 * Combines Filter arguments with AND
 	 */
 	public function combineFilterWithAnd($filters) {
-		return $this->combineFilter($filters,'&');
+		return $this->combineFilter($filters, '&');
 	}
 
 	/**
@@ -560,7 +560,7 @@ abstract class Access {
 	 * Combines Filter arguments with AND
 	 */
 	public function combineFilterWithOr($filters) {
-		return $this->combineFilter($filters,'|');
+		return $this->combineFilter($filters, '|');
 	}
 
 	/**

From 6285cc2604de9e8d2101f4936158e81bb8a9a330 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 13:19:07 +0200
Subject: [PATCH 25/28] LDAP: remove debug output

---
 apps/user_ldap/lib/access.php | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index 80caa5d353f..870f6330edd 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -282,10 +282,6 @@ abstract class Access {
 		$ownCloudNames = array();
 
 		foreach($ldapObjects as $ldapObject) {
-// if(!isset($ldapObject['dn'])) {
-// 	print("
");
-// 	die(var_dump($ldapObjects));
-// }
 			$key = \OCP\Util::recursiveArraySearch($knownObjects, $ldapObject['dn']);
 
 			//everything is fine when we know the group

From 4a2295b75b481cd88806acedfc63ee90651ee898 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 15:10:56 +0200
Subject: [PATCH 26/28] code style

---
 apps/user_ldap/group_ldap.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index ea2cc17733d..b9f4bdf1990 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -109,7 +109,7 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
 		//uniqueMember takes DN, memberuid the uid, so we need to distinguish
 		if((strtolower($this->connection->ldapGroupMemberAssocAttr) == 'uniquemember')
 			|| (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'member')
-		  ) {
+		) {
 			$uid = $userDN;
 		} else if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') {
 			$result = $this->readAttribute($userDN, 'uid');

From 71b862e5717e5026d5f88c708b20a5d1c124bf74 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon 
Date: Wed, 25 Jul 2012 15:11:58 +0200
Subject: [PATCH 27/28] LDAP: replace deprecated constant

---
 apps/user_ldap/lib/connection.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php
index 44b1c20214b..c8ba9dad70e 100644
--- a/apps/user_ldap/lib/connection.php
+++ b/apps/user_ldap/lib/connection.php
@@ -112,7 +112,7 @@ class Connection {
 			$this->config['ldapUserFilter']        = \OCP\Config::getAppValue($this->configID, 'ldap_userlist_filter','objectClass=person');
 			$this->config['ldapGroupFilter']        = \OCP\Config::getAppValue($this->configID, 'ldap_group_filter','(objectClass=posixGroup)');
 			$this->config['ldapLoginFilter']       = \OCP\Config::getAppValue($this->configID, 'ldap_login_filter', '(uid=%uid)');
-			$this->config['ldapGroupDisplayName']  = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR), 'UTF-8');
+			$this->config['ldapGroupDisplayName']  = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_group_display_name', 'uid'), 'UTF-8');
 			$this->config['ldapQuotaAttribute']    = \OCP\Config::getAppValue($this->configID, 'ldap_quota_attr', '');
 			$this->config['ldapQuotaDefault']      = \OCP\Config::getAppValue($this->configID, 'ldap_quota_def', '');
 			$this->config['ldapEmailAttribute']      = \OCP\Config::getAppValue($this->configID, 'ldap_email_attr', '');

From d17eb2983f46b1a2e72f0c3c2d7cfce40f47f653 Mon Sep 17 00:00:00 2001
From: Bart Visscher 
Date: Tue, 24 Jul 2012 18:36:13 +0200
Subject: [PATCH 28/28] OpenID: fix include path

---
 apps/user_openid/appinfo/app.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/apps/user_openid/appinfo/app.php b/apps/user_openid/appinfo/app.php
index a5fb6a0f45e..fe57b189fac 100644
--- a/apps/user_openid/appinfo/app.php
+++ b/apps/user_openid/appinfo/app.php
@@ -19,7 +19,7 @@ OCP\Util::addHeader('link',array('rel'=>'openid.delegate', 'href'=>OCP\Util::lin
 
 OCP\App::registerPersonal('user_openid','settings');
 
-require_once 'openid/user_openid.php';
+require_once 'apps/user_openid/user_openid.php';
 
 //active the openid backend
 OC_User::useBackend('openid');