452 lines
12 KiB
PHP
452 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
|
*
|
|
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
|
|
* @author Joas Schilling <coding@schilljs.com>
|
|
* @author Morris Jobke <hey@morrisjobke.de>
|
|
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
|
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
|
* @author Victor Dubiniuk <dubiniuk@owncloud.com>
|
|
* @author Viktor Szépe <viktor@szepe.net>
|
|
*
|
|
* @license AGPL-3.0
|
|
*
|
|
* This code is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License, version 3,
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
*
|
|
*/
|
|
|
|
namespace OCA\User_LDAP\Tests;
|
|
|
|
use OCA\User_LDAP\Access;
|
|
use OCA\User_LDAP\Configuration;
|
|
use OCA\User_LDAP\ILDAPWrapper;
|
|
use OCA\User_LDAP\Wizard;
|
|
use Test\TestCase;
|
|
|
|
/**
|
|
* Class Test_Wizard
|
|
*
|
|
* @group DB
|
|
*
|
|
* @package OCA\User_LDAP\Tests
|
|
*/
|
|
class WizardTest extends TestCase {
|
|
protected function setUp() {
|
|
parent::setUp();
|
|
//we need to make sure the consts are defined, otherwise tests will fail
|
|
//on systems without php5_ldap
|
|
$ldapConsts = array('LDAP_OPT_PROTOCOL_VERSION',
|
|
'LDAP_OPT_REFERRALS', 'LDAP_OPT_NETWORK_TIMEOUT');
|
|
foreach($ldapConsts as $const) {
|
|
if(!defined($const)) {
|
|
define($const, 42);
|
|
}
|
|
}
|
|
}
|
|
|
|
private function getWizardAndMocks() {
|
|
static $confMethods;
|
|
static $connMethods;
|
|
static $accMethods;
|
|
|
|
if(is_null($confMethods)) {
|
|
$confMethods = get_class_methods('\OCA\User_LDAP\Configuration');
|
|
$connMethods = get_class_methods('\OCA\User_LDAP\Connection');
|
|
$accMethods = get_class_methods('\OCA\User_LDAP\Access');
|
|
}
|
|
/** @var ILDAPWrapper|\PHPUnit_Framework_MockObject_MockObject $lw */
|
|
$lw = $this->createMock(ILDAPWrapper::class);
|
|
|
|
/** @var Configuration|\PHPUnit_Framework_MockObject_MockObject $conf */
|
|
$conf = $this->getMockBuilder(Configuration::class)
|
|
->setMethods($confMethods)
|
|
->setConstructorArgs([$lw, null, null])
|
|
->getMock();
|
|
|
|
/** @var Access|\PHPUnit_Framework_MockObject_MockObject $access */
|
|
$access = $this->createMock(Access::class);
|
|
|
|
return array(new Wizard($conf, $lw, $access), $conf, $lw, $access);
|
|
}
|
|
|
|
private function prepareLdapWrapperForConnections(\PHPUnit_Framework_MockObject_MockObject &$ldap) {
|
|
$ldap->expects($this->once())
|
|
->method('connect')
|
|
//dummy value, usually invalid
|
|
->will($this->returnValue(true));
|
|
|
|
$ldap->expects($this->exactly(3))
|
|
->method('setOption')
|
|
->will($this->returnValue(true));
|
|
|
|
$ldap->expects($this->once())
|
|
->method('bind')
|
|
->will($this->returnValue(true));
|
|
|
|
}
|
|
|
|
public function testCumulativeSearchOnAttributeLimited() {
|
|
list($wizard, $configuration, $ldap) = $this->getWizardAndMocks();
|
|
|
|
$configuration->expects($this->any())
|
|
->method('__get')
|
|
->will($this->returnCallback(function($name) {
|
|
if($name === 'ldapBase') {
|
|
return array('base');
|
|
}
|
|
return null;
|
|
}));
|
|
|
|
$this->prepareLdapWrapperForConnections($ldap);
|
|
|
|
$ldap->expects($this->any())
|
|
->method('isResource')
|
|
->will($this->returnValue(true));
|
|
|
|
$ldap->expects($this->exactly(2))
|
|
->method('search')
|
|
//dummy value, usually invalid
|
|
->will($this->returnValue(true));
|
|
|
|
$ldap->expects($this->exactly(2))
|
|
->method('countEntries')
|
|
//an is_resource check will follow, so we need to return a dummy resource
|
|
->will($this->returnValue(23));
|
|
|
|
//5 DNs per filter means 2x firstEntry and 8x nextEntry
|
|
$ldap->expects($this->exactly(2))
|
|
->method('firstEntry')
|
|
//dummy value, usually invalid
|
|
->will($this->returnValue(true));
|
|
|
|
$ldap->expects($this->exactly(8))
|
|
->method('nextEntry')
|
|
//dummy value, usually invalid
|
|
->will($this->returnValue(true));
|
|
|
|
$ldap->expects($this->exactly(10))
|
|
->method('getAttributes')
|
|
//dummy value, usually invalid
|
|
->will($this->returnValue(array('cn' => array('foo'), 'count' => 1)));
|
|
|
|
global $uidnumber;
|
|
$uidnumber = 1;
|
|
$ldap->expects($this->exactly(10))
|
|
->method('getDN')
|
|
//dummy value, usually invalid
|
|
->will($this->returnCallback(function($a, $b) {
|
|
global $uidnumber;
|
|
return $uidnumber++;
|
|
}));
|
|
|
|
// The following expectations are the real test
|
|
$filters = array('f1', 'f2', '*');
|
|
$wizard->cumulativeSearchOnAttribute($filters, 'cn', 5);
|
|
unset($uidnumber);
|
|
}
|
|
|
|
public function testCumulativeSearchOnAttributeUnlimited() {
|
|
list($wizard, $configuration, $ldap) = $this->getWizardAndMocks();
|
|
|
|
$configuration->expects($this->any())
|
|
->method('__get')
|
|
->will($this->returnCallback(function($name) {
|
|
if($name === 'ldapBase') {
|
|
return array('base');
|
|
}
|
|
return null;
|
|
}));
|
|
|
|
$this->prepareLdapWrapperForConnections($ldap);
|
|
|
|
$ldap->expects($this->any())
|
|
->method('isResource')
|
|
->will($this->returnCallback(function($r) {
|
|
if($r === true) {
|
|
return true;
|
|
}
|
|
if($r % 24 === 0) {
|
|
global $uidnumber;
|
|
$uidnumber++;
|
|
return false;
|
|
}
|
|
return true;
|
|
}));
|
|
|
|
$ldap->expects($this->exactly(2))
|
|
->method('search')
|
|
//dummy value, usually invalid
|
|
->will($this->returnValue(true));
|
|
|
|
$ldap->expects($this->exactly(2))
|
|
->method('countEntries')
|
|
//an is_resource check will follow, so we need to return a dummy resource
|
|
->will($this->returnValue(23));
|
|
|
|
//5 DNs per filter means 2x firstEntry and 8x nextEntry
|
|
$ldap->expects($this->exactly(2))
|
|
->method('firstEntry')
|
|
//dummy value, usually invalid
|
|
->will($this->returnCallback(function($r) {
|
|
global $uidnumber;
|
|
return $uidnumber;
|
|
}));
|
|
|
|
$ldap->expects($this->exactly(46))
|
|
->method('nextEntry')
|
|
//dummy value, usually invalid
|
|
->will($this->returnCallback(function($r) {
|
|
global $uidnumber;
|
|
return $uidnumber;
|
|
}));
|
|
|
|
$ldap->expects($this->exactly(46))
|
|
->method('getAttributes')
|
|
//dummy value, usually invalid
|
|
->will($this->returnValue(array('cn' => array('foo'), 'count' => 1)));
|
|
|
|
global $uidnumber;
|
|
$uidnumber = 1;
|
|
$ldap->expects($this->exactly(46))
|
|
->method('getDN')
|
|
//dummy value, usually invalid
|
|
->will($this->returnCallback(function($a, $b) {
|
|
global $uidnumber;
|
|
return $uidnumber++;
|
|
}));
|
|
|
|
// The following expectations are the real test
|
|
$filters = array('f1', 'f2', '*');
|
|
$wizard->cumulativeSearchOnAttribute($filters, 'cn', 0);
|
|
unset($uidnumber);
|
|
}
|
|
|
|
public function testDetectEmailAttributeAlreadySet() {
|
|
list($wizard, $configuration, $ldap, $access)
|
|
= $this->getWizardAndMocks();
|
|
|
|
$configuration->expects($this->any())
|
|
->method('__get')
|
|
->will($this->returnCallback(function ($name) {
|
|
if($name === 'ldapEmailAttribute') {
|
|
return 'myEmailAttribute';
|
|
} else {
|
|
//for requirement checks
|
|
return 'let me pass';
|
|
}
|
|
}));
|
|
|
|
$access->expects($this->once())
|
|
->method('countUsers')
|
|
->will($this->returnValue(42));
|
|
|
|
$wizard->detectEmailAttribute();
|
|
}
|
|
|
|
public function testDetectEmailAttributeOverrideSet() {
|
|
list($wizard, $configuration, $ldap, $access)
|
|
= $this->getWizardAndMocks();
|
|
|
|
$configuration->expects($this->any())
|
|
->method('__get')
|
|
->will($this->returnCallback(function ($name) {
|
|
if($name === 'ldapEmailAttribute') {
|
|
return 'myEmailAttribute';
|
|
} else {
|
|
//for requirement checks
|
|
return 'let me pass';
|
|
}
|
|
}));
|
|
|
|
$access->expects($this->exactly(3))
|
|
->method('combineFilterWithAnd')
|
|
->will($this->returnCallback(function ($filterParts) {
|
|
return str_replace('=*', '', array_pop($filterParts));
|
|
}));
|
|
|
|
$access->expects($this->exactly(3))
|
|
->method('countUsers')
|
|
->will($this->returnCallback(function ($filter) {
|
|
if($filter === 'myEmailAttribute') {
|
|
return 0;
|
|
} else if($filter === 'mail') {
|
|
return 3;
|
|
} else if($filter === 'mailPrimaryAddress') {
|
|
return 17;
|
|
}
|
|
throw new \Exception('Untested filter: ' . $filter);
|
|
}));
|
|
|
|
$result = $wizard->detectEmailAttribute()->getResultArray();
|
|
$this->assertSame('mailPrimaryAddress',
|
|
$result['changes']['ldap_email_attr']);
|
|
}
|
|
|
|
public function testDetectEmailAttributeFind() {
|
|
list($wizard, $configuration, $ldap, $access)
|
|
= $this->getWizardAndMocks();
|
|
|
|
$configuration->expects($this->any())
|
|
->method('__get')
|
|
->will($this->returnCallback(function ($name) {
|
|
if($name === 'ldapEmailAttribute') {
|
|
return '';
|
|
} else {
|
|
//for requirement checks
|
|
return 'let me pass';
|
|
}
|
|
}));
|
|
|
|
$access->expects($this->exactly(2))
|
|
->method('combineFilterWithAnd')
|
|
->will($this->returnCallback(function ($filterParts) {
|
|
return str_replace('=*', '', array_pop($filterParts));
|
|
}));
|
|
|
|
$access->expects($this->exactly(2))
|
|
->method('countUsers')
|
|
->will($this->returnCallback(function ($filter) {
|
|
if($filter === 'myEmailAttribute') {
|
|
return 0;
|
|
} else if($filter === 'mail') {
|
|
return 3;
|
|
} else if($filter === 'mailPrimaryAddress') {
|
|
return 17;
|
|
}
|
|
throw new \Exception('Untested filter: ' . $filter);
|
|
}));
|
|
|
|
$result = $wizard->detectEmailAttribute()->getResultArray();
|
|
$this->assertSame('mailPrimaryAddress',
|
|
$result['changes']['ldap_email_attr']);
|
|
}
|
|
|
|
public function testDetectEmailAttributeFindNothing() {
|
|
list($wizard, $configuration, $ldap, $access)
|
|
= $this->getWizardAndMocks();
|
|
|
|
$configuration->expects($this->any())
|
|
->method('__get')
|
|
->will($this->returnCallback(function ($name) {
|
|
if($name === 'ldapEmailAttribute') {
|
|
return 'myEmailAttribute';
|
|
} else {
|
|
//for requirement checks
|
|
return 'let me pass';
|
|
}
|
|
}));
|
|
|
|
$access->expects($this->exactly(3))
|
|
->method('combineFilterWithAnd')
|
|
->will($this->returnCallback(function ($filterParts) {
|
|
return str_replace('=*', '', array_pop($filterParts));
|
|
}));
|
|
|
|
$access->expects($this->exactly(3))
|
|
->method('countUsers')
|
|
->will($this->returnCallback(function ($filter) {
|
|
if($filter === 'myEmailAttribute') {
|
|
return 0;
|
|
} else if($filter === 'mail') {
|
|
return 0;
|
|
} else if($filter === 'mailPrimaryAddress') {
|
|
return 0;
|
|
}
|
|
throw new \Exception('Untested filter: ' . $filter);
|
|
}));
|
|
|
|
$result = $wizard->detectEmailAttribute();
|
|
$this->assertSame(false, $result->hasChanges());
|
|
}
|
|
|
|
public function testCumulativeSearchOnAttributeSkipReadDN() {
|
|
// tests that there is no infinite loop, when skipping already processed
|
|
// DNs (they can be returned multiple times for multiple filters )
|
|
list($wizard, $configuration, $ldap) = $this->getWizardAndMocks();
|
|
|
|
$configuration->expects($this->any())
|
|
->method('__get')
|
|
->will($this->returnCallback(function($name) {
|
|
if($name === 'ldapBase') {
|
|
return array('base');
|
|
}
|
|
return null;
|
|
}));
|
|
|
|
$this->prepareLdapWrapperForConnections($ldap);
|
|
|
|
$ldap->expects($this->any())
|
|
->method('isResource')
|
|
->will($this->returnCallback(function($res) {
|
|
return (bool)$res;
|
|
}));
|
|
|
|
$ldap->expects($this->any())
|
|
->method('search')
|
|
//dummy value, usually invalid
|
|
->will($this->returnValue(true));
|
|
|
|
$ldap->expects($this->any())
|
|
->method('countEntries')
|
|
//an is_resource check will follow, so we need to return a dummy resource
|
|
->will($this->returnValue(7));
|
|
|
|
//5 DNs per filter means 2x firstEntry and 8x nextEntry
|
|
$ldap->expects($this->any())
|
|
->method('firstEntry')
|
|
//dummy value, usually invalid
|
|
->will($this->returnValue(1));
|
|
|
|
global $mark;
|
|
$mark = false;
|
|
// entries return order: 1, 2, 3, 4, 4, 5, 6
|
|
$ldap->expects($this->any())
|
|
->method('nextEntry')
|
|
//dummy value, usually invalid
|
|
->will($this->returnCallback(function($a, $prev){
|
|
$current = $prev + 1;
|
|
if($current === 7) {
|
|
return false;
|
|
}
|
|
global $mark;
|
|
if($prev === 4 && !$mark) {
|
|
$mark = true;
|
|
return 4;
|
|
}
|
|
return $current;
|
|
}));
|
|
|
|
$ldap->expects($this->any())
|
|
->method('getAttributes')
|
|
//dummy value, usually invalid
|
|
->will($this->returnCallback(function($a, $entry) {
|
|
return array('cn' => array($entry), 'count' => 1);
|
|
}));
|
|
|
|
$ldap->expects($this->any())
|
|
->method('getDN')
|
|
//dummy value, usually invalid
|
|
->will($this->returnCallback(function($a, $b) {
|
|
return $b;
|
|
}));
|
|
|
|
// The following expectations are the real test
|
|
$filters = array('f1', 'f2', '*');
|
|
$resultArray = $wizard->cumulativeSearchOnAttribute($filters, 'cn', 0);
|
|
$this->assertSame(6, count($resultArray));
|
|
unset($mark);
|
|
}
|
|
|
|
}
|