summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@owncloud.com>2014-11-05 13:05:07 +0100
committerArthur Schiwon <blizzz@owncloud.com>2014-12-19 18:26:12 +0100
commitec0f80fee927ca572671ac7c733b960fb027e91f (patch)
treeb9b0bdbb7bb88557ea95b5872f1e0f9f0d10a99b
parent87e3e2925044831e5fd962207b4a6e9cd29b3f4f (diff)
downloadnextcloud-server-ec0f80fee927ca572671ac7c733b960fb027e91f.tar.gz
nextcloud-server-ec0f80fee927ca572671ac7c733b960fb027e91f.zip
Split mapping from Access and Helper classes into it's own. Fully test them, too.
remove unused methods split mapping methods off from Access class fix DB query handling move 'clear mapping' methods from static helper to new mapping class add tests test directly with DB finishing tests and fix return value from setDNbyUUID add corresponding class for groups and make abstract test class neutral. helper tests is now obsolete as the tested functions were moved to the new mapper class. add missing info to PHPDoc add unmap method fix namespaces fix test inheritance PHPDoc and a small code restructure for scrutinizer, no effective changes PostgreSQL does not accept LIMIT in DELETE queries phpdoc fixes, no code changes
-rw-r--r--apps/user_ldap/ajax/clearMappings.php20
-rw-r--r--apps/user_ldap/appinfo/app.php3
-rw-r--r--apps/user_ldap/lib/access.php280
-rw-r--r--apps/user_ldap/lib/connection.php1
-rw-r--r--apps/user_ldap/lib/helper.php27
-rw-r--r--apps/user_ldap/lib/mapping/abstractmapping.php201
-rw-r--r--apps/user_ldap/lib/mapping/groupmapping.php25
-rw-r--r--apps/user_ldap/lib/mapping/usermapping.php25
-rw-r--r--apps/user_ldap/lib/proxy.php12
-rw-r--r--apps/user_ldap/tests/helper.php31
-rw-r--r--apps/user_ldap/tests/mapping/abstractmappingtest.php194
-rw-r--r--apps/user_ldap/tests/mapping/groupmapping.php17
-rw-r--r--apps/user_ldap/tests/mapping/usermapping.php17
-rw-r--r--lib/private/db/connection.php1
-rw-r--r--lib/public/idbconnection.php1
15 files changed, 573 insertions, 282 deletions
diff --git a/apps/user_ldap/ajax/clearMappings.php b/apps/user_ldap/ajax/clearMappings.php
index 4e713c59f96..e6f3d32e84f 100644
--- a/apps/user_ldap/ajax/clearMappings.php
+++ b/apps/user_ldap/ajax/clearMappings.php
@@ -21,15 +21,27 @@
*
*/
+use OCA\User_LDAP\Mapping\UserMapping;
+use OCA\User_LDAP\Mapping\GroupMapping;
+
// Check user and app status
OCP\JSON::checkAdminUser();
OCP\JSON::checkAppEnabled('user_ldap');
OCP\JSON::callCheck();
$subject = $_POST['ldap_clear_mapping'];
-if(\OCA\user_ldap\lib\Helper::clearMapping($subject)) {
+$mapping = null;
+if($subject === 'user') {
+ $mapping = new UserMapping(\OC::$server->getDatabaseConnection());
+} else if($subject === 'group') {
+ $mapping = new GroupMapping(\OC::$server->getDatabaseConnection());
+}
+try {
+ if(is_null($mapping) || !$mapping->clear()) {
+ $l = \OC::$server->getL10N('user_ldap');
+ throw new \Exception($l->t('Failed to clear the mappings.'));
+ }
OCP\JSON::success();
-} else {
- $l = \OC::$server->getL10N('user_ldap');
- OCP\JSON::error(array('message' => $l->t('Failed to clear the mappings.')));
+} catch (\Exception $e) {
+ OCP\JSON::error(array('message' => $e->getMessage()));
}
diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php
index 8f9fbc5129b..98d5fb60183 100644
--- a/apps/user_ldap/appinfo/app.php
+++ b/apps/user_ldap/appinfo/app.php
@@ -34,6 +34,9 @@ if(count($configPrefixes) === 1) {
new \OCP\Image());
$connector = new OCA\user_ldap\lib\Connection($ldapWrapper, $configPrefixes[0]);
$ldapAccess = new OCA\user_ldap\lib\Access($connector, $ldapWrapper, $userManager);
+ $dbc = \OC::$server->getDatabaseConnection();
+ $ldapAccess->setUserMapper(new OCA\User_LDAP\Mapping\UserMapping($dbc));
+ $ldapAccess->setGroupMapper(new OCA\User_LDAP\Mapping\GroupMapping($dbc));
$userBackend = new OCA\user_ldap\USER_LDAP($ldapAccess);
$groupBackend = new OCA\user_ldap\GROUP_LDAP($ldapAccess);
} else if(count($configPrefixes) > 1) {
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index 22510302061..5d0910320bf 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -23,6 +23,8 @@
namespace OCA\user_ldap\lib;
+use OCA\User_LDAP\Mapping\AbstractMapping;
+
/**
* Class Access
* @package OCA\user_ldap\lib
@@ -47,6 +49,16 @@ class Access extends LDAPUtility implements user\IUserTools {
*/
protected $lastCookie = '';
+ /**
+ * @var AbstractMapping $userMapper
+ */
+ protected $userMapper;
+
+ /**
+ * @var AbstractMapping $userMapper
+ */
+ protected $groupMapper;
+
public function __construct(Connection $connection, ILDAPWrapper $ldap,
user\Manager $userManager) {
parent::__construct($ldap);
@@ -56,6 +68,22 @@ class Access extends LDAPUtility implements user\IUserTools {
}
/**
+ * sets the User Mapper
+ * @param AbstractMapping $mapper
+ */
+ public function setUserMapper(AbstractMapping $mapper) {
+ $this->userMapper = $mapper;
+ }
+
+ /**
+ * sets the Group Mapper
+ * @param AbstractMapping $mapper
+ */
+ public function setGroupMapper(AbstractMapping $mapper) {
+ $this->groupMapper = $mapper;
+ }
+
+ /**
* @return bool
*/
private function checkConnection() {
@@ -236,31 +264,12 @@ class Access extends LDAPUtility implements user\IUserTools {
}
/**
- * gives back the database table for the query
- * @param bool $isUser
- * @return string
- */
- private function getMapTable($isUser) {
- if($isUser) {
- return '*PREFIX*ldap_user_mapping';
- } else {
- return '*PREFIX*ldap_group_mapping';
- }
- }
-
- /**
* returns the LDAP DN for the given internal ownCloud name of the group
* @param string $name the ownCloud name in question
- * @return string with the LDAP DN on success, otherwise false
+ * @return string|false LDAP DN on success, otherwise false
*/
public function groupname2dn($name) {
- $dn = $this->ocname2dn($name, false);
-
- if($dn) {
- return $dn;
- }
-
- return false;
+ return $this->groupMapper->getDNbyName($name);
}
/**
@@ -269,50 +278,32 @@ class Access extends LDAPUtility implements user\IUserTools {
* @return string with the LDAP DN on success, otherwise false
*/
public function username2dn($name) {
- $dn = $this->ocname2dn($name, true);
+ $fdn = $this->userMapper->getDNbyName($name);
+
//Check whether the DN belongs to the Base, to avoid issues on multi-
//server setups
- if($dn && $this->isDNPartOfBase($dn, $this->connection->ldapBaseUsers)) {
- return $dn;
+ if(is_string($fdn) && $this->isDNPartOfBase($fdn, $this->connection->ldapBaseUsers)) {
+ return $fdn;
}
return false;
}
/**
- * returns the LDAP DN for the given internal ownCloud name
- * @param string $name the ownCloud name in question
- * @param boolean $isUser is it a user? otherwise group
- * @return string with the LDAP DN on success, otherwise false
- */
- private function ocname2dn($name, $isUser) {
- $table = $this->getMapTable($isUser);
-
- $query = \OCP\DB::prepare('
- SELECT `ldap_dn`
- FROM `'.$table.'`
- WHERE `owncloud_name` = ?
- ');
-
- $record = $query->execute(array($name))->fetchOne();
- return $record;
- }
-
- /**
* returns the internal ownCloud name for the given LDAP DN of the group, false on DN outside of search DN or failure
- * @param string $dn the dn of the group object
+ * @param string $fdn the dn of the group object
* @param string $ldapName optional, the display name of the object
* @return string with the name to use in ownCloud, false on DN outside of search DN
*/
- public function dn2groupname($dn, $ldapName = null) {
+ public function dn2groupname($fdn, $ldapName = null) {
//To avoid bypassing the base DN settings under certain circumstances
//with the group support, check whether the provided DN matches one of
//the given Bases
- if(!$this->isDNPartOfBase($dn, $this->connection->ldapBaseGroups)) {
+ if(!$this->isDNPartOfBase($fdn, $this->connection->ldapBaseGroups)) {
return false;
}
- return $this->dn2ocname($dn, $ldapName, false);
+ return $this->dn2ocname($fdn, $ldapName, false);
}
/**
@@ -321,15 +312,15 @@ class Access extends LDAPUtility implements user\IUserTools {
* @param string $ldapName optional, the display name of the object
* @return string with with the name to use in ownCloud
*/
- public function dn2username($dn, $ldapName = null) {
+ public function dn2username($fdn, $ldapName = null) {
//To avoid bypassing the base DN settings under certain circumstances
//with the group support, check whether the provided DN matches one of
//the given Bases
- if(!$this->isDNPartOfBase($dn, $this->connection->ldapBaseUsers)) {
+ if(!$this->isDNPartOfBase($fdn, $this->connection->ldapBaseUsers)) {
return false;
}
- return $this->dn2ocname($dn, $ldapName, true);
+ return $this->dn2ocname($fdn, $ldapName, true);
}
/**
@@ -339,50 +330,39 @@ class Access extends LDAPUtility implements user\IUserTools {
* @param bool $isUser optional, whether it is a user object (otherwise group assumed)
* @return string with with the name to use in ownCloud
*/
- public function dn2ocname($dn, $ldapName = null, $isUser = true) {
- $table = $this->getMapTable($isUser);
+ public function dn2ocname($fdn, $ldapName = null, $isUser = true) {
if($isUser) {
- $fncFindMappedName = 'findMappedUser';
+ $mapper = $this->userMapper;
$nameAttribute = $this->connection->ldapUserDisplayName;
} else {
- $fncFindMappedName = 'findMappedGroup';
+ $mapper = $this->groupMapper;
$nameAttribute = $this->connection->ldapGroupDisplayName;
}
//let's try to retrieve the ownCloud name from the mappings table
- $ocName = $this->$fncFindMappedName($dn);
- if($ocName) {
+ $ocName = $mapper->getNameByDN($fdn);
+ if(is_string($ocName)) {
return $ocName;
}
//second try: get the UUID and check if it is known. Then, update the DN and return the name.
- $uuid = $this->getUUID($dn, $isUser);
- if($uuid) {
- $query = \OCP\DB::prepare('
- SELECT `owncloud_name`
- FROM `'.$table.'`
- WHERE `directory_uuid` = ?
- ');
- $component = $query->execute(array($uuid))->fetchOne();
- if($component) {
- $query = \OCP\DB::prepare('
- UPDATE `'.$table.'`
- SET `ldap_dn` = ?
- WHERE `directory_uuid` = ?
- ');
- $query->execute(array($dn, $uuid));
- return $component;
+ $uuid = $this->getUUID($fdn, $isUser);
+ if(is_string($uuid)) {
+ $ocName = $mapper->getNameByUUID($uuid);
+ if(is_string($ocName)) {
+ $mapper->setDNbyUUID($fdn, $uuid);
+ return $ocName;
}
} else {
//If the UUID can't be detected something is foul.
- \OCP\Util::writeLog('user_ldap', 'Cannot determine UUID for '.$dn.'. Skipping.', \OCP\Util::INFO);
+ \OCP\Util::writeLog('user_ldap', 'Cannot determine UUID for '.$fdn.'. Skipping.', \OCP\Util::INFO);
return false;
}
if(is_null($ldapName)) {
- $ldapName = $this->readAttribute($dn, $nameAttribute);
+ $ldapName = $this->readAttribute($fdn, $nameAttribute);
if(!isset($ldapName[0]) && empty($ldapName[0])) {
- \OCP\Util::writeLog('user_ldap', 'No or empty name for '.$dn.'.', \OCP\Util::INFO);
+ \OCP\Util::writeLog('user_ldap', 'No or empty name for '.$fdn.'.', \OCP\Util::INFO);
return false;
}
$ldapName = $ldapName[0];
@@ -390,8 +370,8 @@ class Access extends LDAPUtility implements user\IUserTools {
if($isUser) {
$usernameAttribute = $this->connection->ldapExpertUsernameAttr;
- if(!emptY($usernameAttribute)) {
- $username = $this->readAttribute($dn, $usernameAttribute);
+ if(!empty($usernameAttribute)) {
+ $username = $this->readAttribute($fdn, $usernameAttribute);
$username = $username[0];
} else {
$username = $uuid;
@@ -409,7 +389,7 @@ class Access extends LDAPUtility implements user\IUserTools {
$this->connection->setConfiguration(array('ldapCacheTTL' => 0));
if(($isUser && !\OCP\User::userExists($intName))
|| (!$isUser && !\OC_Group::groupExists($intName))) {
- if($this->mapComponent($dn, $intName, $isUser)) {
+ if($mapper->map($fdn, $intName, $uuid)) {
$this->connection->setConfiguration(array('ldapCacheTTL' => $originalTTL));
return $intName;
}
@@ -417,12 +397,12 @@ class Access extends LDAPUtility implements user\IUserTools {
$this->connection->setConfiguration(array('ldapCacheTTL' => $originalTTL));
$altName = $this->createAltInternalOwnCloudName($intName, $isUser);
- if($this->mapComponent($dn, $altName, $isUser)) {
+ if(is_string($altName) && $mapper->map($fdn, $altName, $uuid)) {
return $altName;
}
//if everything else did not help..
- \OCP\Util::writeLog('user_ldap', 'Could not create unique name for '.$dn.'.', \OCP\Util::INFO);
+ \OCP\Util::writeLog('user_ldap', 'Could not create unique name for '.$fdn.'.', \OCP\Util::INFO);
return false;
}
@@ -449,46 +429,6 @@ class Access extends LDAPUtility implements user\IUserTools {
}
/**
- * @param string $dn
- * @return bool|string
- */
- private function findMappedUser($dn) {
- static $query = null;
- if(is_null($query)) {
- $query = \OCP\DB::prepare('
- SELECT `owncloud_name`
- FROM `'.$this->getMapTable(true).'`
- WHERE `ldap_dn` = ?'
- );
- }
- $res = $query->execute(array($dn))->fetchOne();
- if($res) {
- return $res;
- }
- return false;
- }
-
- /**
- * @param string $dn
- * @return bool|string
- */
- private function findMappedGroup($dn) {
- static $query = null;
- if(is_null($query)) {
- $query = \OCP\DB::prepare('
- SELECT `owncloud_name`
- FROM `'.$this->getMapTable(false).'`
- WHERE `ldap_dn` = ?'
- );
- }
- $res = $query->execute(array($dn))->fetchOne();
- if($res) {
- return $res;
- }
- return false;
- }
-
- /**
* @param array $ldapObjects
* @param bool $isUsers
* @return array
@@ -571,17 +511,7 @@ class Access extends LDAPUtility implements user\IUserTools {
* "Developers"
*/
private function _createAltInternalOwnCloudNameForGroups($name) {
- $query = \OCP\DB::prepare('
- SELECT `owncloud_name`
- FROM `'.$this->getMapTable(false).'`
- WHERE `owncloud_name` LIKE ?
- ');
-
- $usedNames = array();
- $res = $query->execute(array($name.'_%'));
- while($row = $res->fetchRow()) {
- $usedNames[] = $row['owncloud_name'];
- }
+ $usedNames = $this->groupMapper->getNamesBySearch($name.'_%');
if(!($usedNames) || count($usedNames) === 0) {
$lastNo = 1; //will become name_2
} else {
@@ -626,92 +556,6 @@ class Access extends LDAPUtility implements user\IUserTools {
}
/**
- * retrieves all known groups from the mappings table
- * @return array with the results
- *
- * retrieves all known groups from the mappings table
- */
- private function mappedGroups() {
- return $this->mappedComponents(false);
- }
-
- /**
- * retrieves all known users from the mappings table
- * @return array with the results
- *
- * retrieves all known users from the mappings table
- */
- private function mappedUsers() {
- return $this->mappedComponents(true);
- }
-
- /**
- * @param boolean $isUsers
- * @return array
- */
- private function mappedComponents($isUsers) {
- $table = $this->getMapTable($isUsers);
-
- $query = \OCP\DB::prepare('
- SELECT `ldap_dn`, `owncloud_name`
- FROM `'. $table . '`'
- );
-
- return $query->execute()->fetchAll();
- }
-
- /**
- * inserts a new user or group into the mappings table
- * @param string $dn the record in question
- * @param string $ocName the name to use in ownCloud
- * @param bool $isUser is it a user or a group?
- * @return bool true on success, false otherwise
- *
- * inserts a new user or group into the mappings table
- */
- private function mapComponent($dn, $ocName, $isUser = true) {
- $table = $this->getMapTable($isUser);
-
- $sqlAdjustment = '';
- $dbType = \OC::$server->getConfig()->getSystemValue('dbtype', null);
- if($dbType === 'mysql' || $dbType == 'oci') {
- $sqlAdjustment = 'FROM DUAL';
- }
-
- $insert = \OCP\DB::prepare('
- INSERT INTO `'.$table.'` (`ldap_dn`, `owncloud_name`, `directory_uuid`)
- SELECT ?,?,?
- '.$sqlAdjustment.'
- WHERE NOT EXISTS (
- SELECT 1
- FROM `'.$table.'`
- WHERE `ldap_dn` = ?
- OR `owncloud_name` = ?)
- ');
-
- //feed the DB
- $insRows = $insert->execute(array($dn, $ocName,
- $this->getUUID($dn, $isUser), $dn,
- $ocName));
-
- if(\OCP\DB::isError($insRows)) {
- return false;
- }
-
- if($insRows === 0) {
- return false;
- }
-
- if($isUser) {
- //make sure that email address is retrieved prior to login, so user
- //will be notified when something is shared with him
- $this->userManager->get($ocName)->update();
- }
-
- return true;
- }
-
- /**
* @param string $filter
* @param string|string[] $attr
* @param int $limit
@@ -1305,7 +1149,7 @@ class Access extends LDAPUtility implements user\IUserTools {
/**
* @param string $dn
* @param bool $isUser
- * @return array|bool|false
+ * @return string|bool
*/
public function getUUID($dn, $isUser = true) {
if($isUser) {
diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php
index 336ea7b3bbc..54aafb93410 100644
--- a/apps/user_ldap/lib/connection.php
+++ b/apps/user_ldap/lib/connection.php
@@ -29,6 +29,7 @@ namespace OCA\user_ldap\lib;
* @property string ldapUserFilter
* @property string ldapUserDisplayName
* @property boolean hasPagedResultSupport
+ * @property string[] ldapBaseUsers
*/
class Connection extends LDAPUtility {
private $ldapConnectionRes = null;
diff --git a/apps/user_ldap/lib/helper.php b/apps/user_ldap/lib/helper.php
index 282f4549e3b..fa36e304171 100644
--- a/apps/user_ldap/lib/helper.php
+++ b/apps/user_ldap/lib/helper.php
@@ -142,33 +142,6 @@ class Helper {
}
/**
- * Truncate's the given mapping table
- *
- * @param string $mapping either 'user' or 'group'
- * @return bool true on success, false otherwise
- */
- static public function clearMapping($mapping) {
- if($mapping === 'user') {
- $table = '`*PREFIX*ldap_user_mapping`';
- } else if ($mapping === 'group') {
- $table = '`*PREFIX*ldap_group_mapping`';
- } else {
- return false;
- }
-
- $connection = \OC_DB::getConnection();
- $sql = $connection->getDatabasePlatform()->getTruncateTableSQL($table);
- $query = \OCP\DB::prepare($sql);
- $res = $query->execute();
-
- if(\OCP\DB::isError($res)) {
- return false;
- }
-
- return true;
- }
-
- /**
* extracts the domain from a given URL
* @param string $url the URL
* @return string|false domain as string on success, false otherwise
diff --git a/apps/user_ldap/lib/mapping/abstractmapping.php b/apps/user_ldap/lib/mapping/abstractmapping.php
new file mode 100644
index 00000000000..2c45c6bb1c1
--- /dev/null
+++ b/apps/user_ldap/lib/mapping/abstractmapping.php
@@ -0,0 +1,201 @@
+<?php
+/**
+* Copyright (c) 2014 Arthur Schiwon <blizzz@owncloud.com>
+* This file is licensed under the Affero General Public License version 3 or
+* later.
+* See the COPYING-README file.
+*/
+
+namespace OCA\User_LDAP\Mapping;
+
+/**
+* Class AbstractMapping
+* @package OCA\User_LDAP\Mapping
+*/
+abstract class AbstractMapping {
+ /**
+ * @var \OCP\IDBConnection $dbc
+ */
+ protected $dbc;
+
+ /**
+ * returns the DB table name which holds the mappings
+ * @return string
+ */
+ abstract protected function getTableName();
+
+ /**
+ * @param \OCP\IDBConnection $dbc
+ */
+ public function __construct(\OCP\IDBConnection $dbc) {
+ $this->dbc = $dbc;
+ }
+
+ /**
+ * checks whether a provided string represents an exisiting table col
+ * @param string $col
+ * @return bool
+ */
+ public function isColNameValid($col) {
+ switch($col) {
+ case 'ldap_dn':
+ case 'owncloud_name':
+ case 'directory_uuid':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Gets the value of one column based on a provided value of another column
+ * @param string $fetchCol
+ * @param string $compareCol
+ * @param string $search
+ * @throws \Exception
+ * @return string|false
+ */
+ protected function getXbyY($fetchCol, $compareCol, $search) {
+ if(!$this->isColNameValid($fetchCol)) {
+ //this is used internally only, but we don't want to risk
+ //having SQL injection at all.
+ throw new \Exception('Invalid Column Name');
+ }
+ $query = $this->dbc->prepare('
+ SELECT `' . $fetchCol . '`
+ FROM `'. $this->getTableName() .'`
+ WHERE `' . $compareCol . '` = ?
+ ');
+
+ $res = $query->execute(array($search));
+ if($res !== false) {
+ return $query->fetchColumn();
+ }
+
+ return false;
+ }
+
+ /**
+ * Performs a DELETE or UPDATE query to the database.
+ * @param \Doctrine\DBAL\Driver\Statement $query
+ * @param array $parameters
+ * @return bool true if at least one row was modified, false otherwise
+ */
+ protected function modify($query, $parameters) {
+ $result = $query->execute($parameters);
+ return ($result === true && $query->rowCount() > 0);
+ }
+
+ /**
+ * Gets the LDAP DN based on the provided name.
+ * Replaces Access::ocname2dn
+ * @param string $name
+ * @return string|false
+ */
+ public function getDNByName($name) {
+ return $this->getXbyY('ldap_dn', 'owncloud_name', $name);
+ }
+
+ /**
+ * Updates the DN based on the given UUID
+ * @param string $fdn
+ * @param string $uuid
+ * @return bool
+ */
+ public function setDNbyUUID($fdn, $uuid) {
+ $query = $this->dbc->prepare('
+ UPDATE `' . $this->getTableName() . '`
+ SET `ldap_dn` = ?
+ WHERE `directory_uuid` = ?
+ ');
+
+ return $this->modify($query, array($fdn, $uuid));
+ }
+
+ /**
+ * Gets the name based on the provided LDAP DN.
+ * @param string $fdn
+ * @return string|false
+ */
+ public function getNameByDN($fdn) {
+ return $this->getXbyY('owncloud_name', 'ldap_dn', $fdn);
+ }
+
+ /**
+ * Searches mapped names by the giving string in the name column
+ * @param string $search
+ * @return string[]
+ */
+ public function getNamesBySearch($search) {
+ $query = $this->dbc->prepare('
+ SELECT `owncloud_name`
+ FROM `'. $this->getTableName() .'`
+ WHERE `owncloud_name` LIKE ?
+ ');
+
+ $res = $query->execute(array($search));
+ $names = array();
+ if($res !== false) {
+ while($row = $query->fetch()) {
+ $names[] = $row['owncloud_name'];
+ }
+ }
+ return $names;
+ }
+
+ /**
+ * Gets the name based on the provided LDAP DN.
+ * @param string $uuid
+ * @return string|false
+ */
+ public function getNameByUUID($uuid) {
+ return $this->getXbyY('owncloud_name', 'directory_uuid', $uuid);
+ }
+
+ /**
+ * attempts to map the given entry
+ * @param string $fdn fully distinguished name (from LDAP)
+ * @param string $name
+ * @param string $uuid a unique identifier as used in LDAP
+ * @return bool
+ */
+ public function map($fdn, $name, $uuid) {
+ $row = array(
+ 'ldap_dn' => $fdn,
+ 'owncloud_name' => $name,
+ 'directory_uuid' => $uuid
+ );
+
+ try {
+ $result = $this->dbc->insertIfNotExist($this->getTableName(), $row);
+ // insertIfNotExist returns values as int
+ return (bool)$result;
+ } catch (\Exception $e) {
+ return false;
+ }
+ }
+
+ /**
+ * removes a mapping based on the owncloud_name of the entry
+ * @param string $name
+ * @return bool
+ */
+ public function unmap($name) {
+ $query = $this->dbc->prepare('
+ DELETE FROM `'. $this->getTableName() .'`
+ WHERE `owncloud_name` = ?');
+
+ return $this->modify($query, array($name));
+ }
+
+ /**
+ * Truncate's the mapping table
+ * @return bool
+ */
+ public function clear() {
+ $sql = $this->dbc
+ ->getDatabasePlatform()
+ ->getTruncateTableSQL('`' . $this->getTableName() . '`');
+ return $this->dbc->prepare($sql)->execute();
+ }
+}
diff --git a/apps/user_ldap/lib/mapping/groupmapping.php b/apps/user_ldap/lib/mapping/groupmapping.php
new file mode 100644
index 00000000000..af8a4bb4623
--- /dev/null
+++ b/apps/user_ldap/lib/mapping/groupmapping.php
@@ -0,0 +1,25 @@
+<?php
+/**
+* Copyright (c) 2014 Arthur Schiwon <blizzz@owncloud.com>
+* This file is licensed under the Affero General Public License version 3 or
+* later.
+* See the COPYING-README file.
+*/
+
+namespace OCA\User_LDAP\Mapping;
+
+/**
+* Class UserMapping
+* @package OCA\User_LDAP\Mapping
+*/
+class GroupMapping extends AbstractMapping {
+
+ /**
+ * returns the DB table name which holds the mappings
+ * @return string
+ */
+ protected function getTableName() {
+ return '*PREFIX*ldap_group_mapping';
+ }
+
+}
diff --git a/apps/user_ldap/lib/mapping/usermapping.php b/apps/user_ldap/lib/mapping/usermapping.php
new file mode 100644
index 00000000000..dd24f338b96
--- /dev/null
+++ b/apps/user_ldap/lib/mapping/usermapping.php
@@ -0,0 +1,25 @@
+<?php
+/**
+* Copyright (c) 2014 Arthur Schiwon <blizzz@owncloud.com>
+* This file is licensed under the Affero General Public License version 3 or
+* later.
+* See the COPYING-README file.
+*/
+
+namespace OCA\User_LDAP\Mapping;
+
+/**
+* Class UserMapping
+* @package OCA\User_LDAP\Mapping
+*/
+class UserMapping extends AbstractMapping {
+
+ /**
+ * returns the DB table name which holds the mappings
+ * @return string
+ */
+ protected function getTableName() {
+ return '*PREFIX*ldap_user_mapping';
+ }
+
+}
diff --git a/apps/user_ldap/lib/proxy.php b/apps/user_ldap/lib/proxy.php
index 73a52a7ddd9..39d4b36c8bb 100644
--- a/apps/user_ldap/lib/proxy.php
+++ b/apps/user_ldap/lib/proxy.php
@@ -24,6 +24,8 @@
namespace OCA\user_ldap\lib;
use OCA\user_ldap\lib\Access;
+use OCA\User_LDAP\Mapping\UserMapping;
+use OCA\User_LDAP\Mapping\GroupMapping;
abstract class Proxy {
static private $accesses = array();
@@ -45,17 +47,23 @@ abstract class Proxy {
static $fs;
static $log;
static $avatarM;
+ static $userMap;
+ static $groupMap;
if(is_null($fs)) {
$ocConfig = \OC::$server->getConfig();
$fs = new FilesystemHelper();
$log = new LogWrapper();
$avatarM = \OC::$server->getAvatarManager();
+ $userMap = new UserMapping(\OC::$server->getDatabaseConnection());
+ $groupMap = new GroupMapping(\OC::$server->getDatabaseConnection());
}
$userManager =
new user\Manager($ocConfig, $fs, $log, $avatarM, new \OCP\Image());
$connector = new Connection($this->ldap, $configPrefix);
- self::$accesses[$configPrefix] =
- new Access($connector, $this->ldap, $userManager);
+ $access = new Access($connector, $this->ldap, $userManager);
+ $access->setUserMapper($userMap);
+ $access->setGroupMapper($groupMap);
+ self::$accesses[$configPrefix] = $access;
}
/**
diff --git a/apps/user_ldap/tests/helper.php b/apps/user_ldap/tests/helper.php
deleted file mode 100644
index a70a57051c8..00000000000
--- a/apps/user_ldap/tests/helper.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-/**
-* ownCloud
-*
-* @author Thomas Müller
-* @copyright 2014 Thomas Müller deepdiver@owncloud.com
-*
-*/
-
-namespace OCA\user_ldap\tests;
-
-use OCA\user_ldap\lib\Helper;
-
-class Test_Helper extends \Test\TestCase {
-
- public function testTableTruncate() {
-
- $statement = \OCP\DB::prepare('INSERT INTO `*PREFIX*ldap_user_mapping` (`ldap_dn`, `owncloud_name`, `directory_uuid`) VALUES (?, ?, ?)');
- $statement->execute(array('db01', 'oc1', '000-0000-0000'));
- $statement->execute(array('db02', 'oc2', '000-0000-0001'));
-
- $statement = \OCP\DB::prepare('SELECT count(*) FROM `*PREFIX*ldap_user_mapping`');
- $result = $statement->execute();
- $this->assertEquals(2, $result->fetchOne());
-
- Helper::clearMapping('user');
-
- $result = $statement->execute();
- $this->assertEquals(0, $result->fetchOne());
- }
-}
diff --git a/apps/user_ldap/tests/mapping/abstractmappingtest.php b/apps/user_ldap/tests/mapping/abstractmappingtest.php
new file mode 100644
index 00000000000..a5cb62253af
--- /dev/null
+++ b/apps/user_ldap/tests/mapping/abstractmappingtest.php
@@ -0,0 +1,194 @@
+<?php
+/**
+* Copyright (c) 2014 Arthur Schiwon <blizzz@owncloud.com>
+* This file is licensed under the Affero General Public License version 3 or
+* later.
+* See the COPYING-README file.
+*/
+
+namespace OCA\user_ldap\tests\mapping;
+
+abstract class AbstractMappingTest extends \Test\TestCase {
+ abstract public function getMapper(\OCP\IDBConnection $dbMock);
+
+ /**
+ * kiss test on isColNameValid
+ */
+ public function testIsColNameValid() {
+ $dbMock = $this->getMock('\OCP\IDBConnection');
+ $mapper = $this->getMapper($dbMock);
+
+ $this->assertTrue($mapper->isColNameValid('ldap_dn'));
+ $this->assertFalse($mapper->isColNameValid('foobar'));
+ }
+
+ /**
+ * returns an array of test entries with dn, name and uuid as keys
+ * @return array
+ */
+ protected function getTestData() {
+ $data = array(
+ array(
+ 'dn' => 'uid=foobar,dc=example,dc=org',
+ 'name' => 'Foobar',
+ 'uuid' => '1111-AAAA-1234-CDEF',
+ ),
+ array(
+ 'dn' => 'uid=barfoo,dc=example,dc=org',
+ 'name' => 'Barfoo',
+ 'uuid' => '2222-BBBB-1234-CDEF',
+ ),
+ array(
+ 'dn' => 'uid=barabara,dc=example,dc=org',
+ 'name' => 'BaraBara',
+ 'uuid' => '3333-CCCC-1234-CDEF',
+ )
+ );
+
+ return $data;
+ }
+
+ /**
+ * calls map() on the given mapper and asserts result for true
+ * @param \OCA\User_LDAP\Mapping\AbstractMapping $mapper
+ * @param array $data
+ */
+ protected function mapEntries($mapper, $data) {
+ foreach($data as $entry) {
+ $done = $mapper->map($entry['dn'], $entry['name'], $entry['uuid']);
+ $this->assertTrue($done);
+ }
+ }
+
+ /**
+ * initalizes environment for a test run and returns an array with
+ * test objects. Preparing environment means that all mappings are cleared
+ * first and then filled with test entries.
+ * @return array 0 = \OCA\User_LDAP\Mapping\AbstractMapping, 1 = array of
+ * users or groups
+ */
+ private function initTest() {
+ $dbc = \OC::$server->getDatabaseConnection();
+ $mapper = $this->getMapper($dbc);
+ $data = $this->getTestData();
+ // make sure DB is pristine, then fill it with test entries
+ $mapper->clear();
+ $this->mapEntries($mapper, $data);
+
+ return array($mapper, $data);
+ }
+
+ /**
+ * tests map() method with input that should result in not-mapping.
+ * Hint: successful mapping is tested inherently with mapEntries().
+ */
+ public function testMap() {
+ list($mapper, $data) = $this->initTest();
+
+ // test that mapping will not happen when it shall not
+ $paramKeys = array('', 'dn', 'name', 'uuid');
+ foreach($paramKeys as $key) {
+ $failEntry = $data[0];
+ if(!empty($key)) {
+ $failEntry[$key] = 'do-not-get-mapped';
+ }
+ $isMapped = $mapper->map($failEntry['dn'], $failEntry['name'], $failEntry['uuid']);
+ $this->assertFalse($isMapped);
+ }
+ }
+
+ /**
+ * tests unmap() for both successfuly and not successful removing of
+ * mapping entries
+ */
+ public function testUnmap() {
+ list($mapper, $data) = $this->initTest();
+
+ foreach($data as $entry) {
+ $result = $mapper->unmap($entry['name']);
+ $this->assertTrue($result);
+ }
+
+ $result = $mapper->unmap('notAnEntry');
+ $this->assertFalse($result);
+ }
+
+ /**
+ * tests getDNByName(), getNameByDN() and getNameByUUID() for successful
+ * and unsuccessful requests.
+ */
+ public function testGetMethods() {
+ list($mapper, $data) = $this->initTest();
+
+ foreach($data as $entry) {
+ $fdn = $mapper->getDNByName($entry['name']);
+ $this->assertSame($fdn, $entry['dn']);
+ }
+ $fdn = $mapper->getDNByName('nosuchname');
+ $this->assertFalse($fdn);
+
+ foreach($data as $entry) {
+ $name = $mapper->getNameByDN($entry['dn']);
+ $this->assertSame($name, $entry['name']);
+ }
+ $name = $mapper->getNameByDN('nosuchdn');
+ $this->assertFalse($name);
+
+ foreach($data as $entry) {
+ $name = $mapper->getNameByUUID($entry['uuid']);
+ $this->assertSame($name, $entry['name']);
+ }
+ $name = $mapper->getNameByUUID('nosuchuuid');
+ $this->assertFalse($name);
+ }
+
+ /**
+ * tests getNamesBySearch() for successful and unsuccessful requests.
+ */
+ public function testSearch() {
+ list($mapper,) = $this->initTest();
+
+ $names = $mapper->getNamesBySearch('%oo%');
+ $this->assertTrue(is_array($names));
+ $this->assertSame(2, count($names));
+ $this->assertTrue(in_array('Foobar', $names));
+ $this->assertTrue(in_array('Barfoo', $names));
+ $names = $mapper->getNamesBySearch('nada');
+ $this->assertTrue(is_array($names));
+ $this->assertSame(0, count($names));
+ }
+
+ /**
+ * tests setDNbyUUID() for successful and unsuccessful update.
+ */
+ public function testSetMethod() {
+ list($mapper, $data) = $this->initTest();
+
+ $newDN = 'uid=modified,dc=example,dc=org';
+ $done = $mapper->setDNbyUUID($newDN, $data[0]['uuid']);
+ $this->assertTrue($done);
+ $fdn = $mapper->getDNByName($data[0]['name']);
+ $this->assertSame($fdn, $newDN);
+
+ $newDN = 'uid=notme,dc=example,dc=org';
+ $done = $mapper->setDNbyUUID($newDN, 'iamnothere');
+ $this->assertFalse($done);
+ $name = $mapper->getNameByDN($newDN);
+ $this->assertFalse($name);
+
+ }
+
+ /**
+ * tests clear() for successful update.
+ */
+ public function testClear() {
+ list($mapper, $data) = $this->initTest();
+
+ $done = $mapper->clear();
+ $this->assertTrue($done);
+ foreach($data as $entry) {
+ $name = $mapper->getNameByUUID($entry['uuid']);
+ $this->assertFalse($name);
+ }
+ }
+}
diff --git a/apps/user_ldap/tests/mapping/groupmapping.php b/apps/user_ldap/tests/mapping/groupmapping.php
new file mode 100644
index 00000000000..11bb3f40e3a
--- /dev/null
+++ b/apps/user_ldap/tests/mapping/groupmapping.php
@@ -0,0 +1,17 @@
+<?php
+/**
+* Copyright (c) 2014 Arthur Schiwon <blizzz@owncloud.com>
+* This file is licensed under the Affero General Public License version 3 or
+* later.
+* See the COPYING-README file.
+*/
+
+namespace OCA\user_ldap\tests\mapping;
+
+use OCA\User_LDAP\Mapping\GroupMapping;
+
+class Test_GroupMapping extends AbstractMappingTest {
+ public function getMapper(\OCP\IDBConnection $dbMock) {
+ return new GroupMapping($dbMock);
+ }
+}
diff --git a/apps/user_ldap/tests/mapping/usermapping.php b/apps/user_ldap/tests/mapping/usermapping.php
new file mode 100644
index 00000000000..2debcecf397
--- /dev/null
+++ b/apps/user_ldap/tests/mapping/usermapping.php
@@ -0,0 +1,17 @@
+<?php
+/**
+* Copyright (c) 2014 Arthur Schiwon <blizzz@owncloud.com>
+* This file is licensed under the Affero General Public License version 3 or
+* later.
+* See the COPYING-README file.
+*/
+
+namespace OCA\user_ldap\tests\mapping;
+
+use OCA\User_LDAP\Mapping\UserMapping;
+
+class Test_UserMapping extends AbstractMappingTest {
+ public function getMapper(\OCP\IDBConnection $dbMock) {
+ return new UserMapping($dbMock);
+ }
+}
diff --git a/lib/private/db/connection.php b/lib/private/db/connection.php
index 9de7a719ff5..d10adee558c 100644
--- a/lib/private/db/connection.php
+++ b/lib/private/db/connection.php
@@ -142,6 +142,7 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
* Insert a row if a matching row doesn't exists.
* @param string $table. The table to insert into in the form '*PREFIX*tableName'
* @param array $input. An array of fieldname/value pairs
+ * @throws \OC\HintException
* @return bool The return value from execute()
*/
public function insertIfNotExist($table, $input) {
diff --git a/lib/public/idbconnection.php b/lib/public/idbconnection.php
index 32310fe755f..0d19b2cc71e 100644
--- a/lib/public/idbconnection.php
+++ b/lib/public/idbconnection.php
@@ -80,6 +80,7 @@ interface IDBConnection {
* Insert a row if a matching row doesn't exists.
* @param string $table The table name (will replace *PREFIX*) to perform the replace on.
* @param array $input
+ * @throws \OC\HintException
*
* The input array if in the form:
*