2013-09-27 20:30:59 +04:00
|
|
|
<?php
|
|
|
|
/**
|
2016-07-21 17:49:16 +03:00
|
|
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
|
|
|
*
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Alexander Bergolth <leo@strike.wu.ac.at>
|
2016-05-26 20:56:05 +03:00
|
|
|
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Bart Visscher <bartv@thisnet.nl>
|
|
|
|
* @author Jean-Louis Dupond <jean-louis@dupond.be>
|
2016-07-21 17:49:16 +03:00
|
|
|
* @author Joas Schilling <coding@schilljs.com>
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
2016-05-26 20:56:05 +03:00
|
|
|
* @author Lukas Reschke <lukas@statuscode.ch>
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Morris Jobke <hey@morrisjobke.de>
|
2015-10-05 21:54:56 +03:00
|
|
|
* @author Nicolas Grekas <nicolas.grekas@gmail.com>
|
2016-07-21 19:13:36 +03:00
|
|
|
* @author Robin Appelman <robin@icewind.nl>
|
2016-01-12 17:02:16 +03:00
|
|
|
* @author Robin McCorkell <robin@mccorkell.me.uk>
|
2016-05-26 20:56:05 +03:00
|
|
|
* @author Stefan Weil <sw@weilnetz.de>
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Victor Dubiniuk <dubiniuk@owncloud.com>
|
2017-03-18 09:56:24 +03:00
|
|
|
* @author Xuanwo <xuanwo@yunify.com>
|
2013-09-27 20:30:59 +04:00
|
|
|
*
|
2015-03-26 13:44:34 +03:00
|
|
|
* @license AGPL-3.0
|
2013-09-27 20:30:59 +04:00
|
|
|
*
|
2015-03-26 13:44:34 +03:00
|
|
|
* 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.
|
2013-09-27 20:30:59 +04:00
|
|
|
*
|
2015-03-26 13:44:34 +03:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
2013-09-27 20:30:59 +04:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2015-03-26 13:44:34 +03:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
2013-09-27 20:30:59 +04:00
|
|
|
*
|
2015-03-26 13:44:34 +03:00
|
|
|
* 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/>
|
2013-09-27 20:30:59 +04:00
|
|
|
*
|
|
|
|
*/
|
2015-02-26 13:37:37 +03:00
|
|
|
|
2016-05-12 17:08:46 +03:00
|
|
|
namespace OCA\User_LDAP;
|
2013-09-27 20:30:59 +04:00
|
|
|
|
2015-06-04 17:28:48 +03:00
|
|
|
use OC\ServerNotAvailableException;
|
|
|
|
|
2013-09-27 20:30:59 +04:00
|
|
|
class Wizard extends LDAPUtility {
|
2016-05-12 17:55:58 +03:00
|
|
|
/** @var \OCP\IL10N */
|
2013-09-27 20:30:59 +04:00
|
|
|
static protected $l;
|
2014-06-25 19:36:19 +04:00
|
|
|
protected $access;
|
2013-10-08 03:19:37 +04:00
|
|
|
protected $cr;
|
2013-09-27 20:30:59 +04:00
|
|
|
protected $configuration;
|
|
|
|
protected $result;
|
2013-10-08 03:19:37 +04:00
|
|
|
protected $resultCache = array();
|
2013-09-27 20:30:59 +04:00
|
|
|
|
2013-10-09 01:47:57 +04:00
|
|
|
const LRESULT_PROCESSED_OK = 2;
|
|
|
|
const LRESULT_PROCESSED_INVALID = 3;
|
|
|
|
const LRESULT_PROCESSED_SKIP = 4;
|
2013-10-04 18:33:37 +04:00
|
|
|
|
2013-10-09 01:47:57 +04:00
|
|
|
const LFILTER_LOGIN = 2;
|
|
|
|
const LFILTER_USER_LIST = 3;
|
|
|
|
const LFILTER_GROUP_LIST = 4;
|
2013-10-08 20:27:36 +04:00
|
|
|
|
2013-11-20 02:58:08 +04:00
|
|
|
const LFILTER_MODE_ASSISTED = 2;
|
|
|
|
const LFILTER_MODE_RAW = 1;
|
|
|
|
|
2013-10-10 21:37:12 +04:00
|
|
|
const LDAP_NW_TIMEOUT = 4;
|
|
|
|
|
2013-09-27 20:30:59 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* Constructor
|
2014-05-11 17:17:27 +04:00
|
|
|
* @param Configuration $configuration an instance of Configuration
|
|
|
|
* @param ILDAPWrapper $ldap an instance of ILDAPWrapper
|
2016-05-12 17:42:57 +03:00
|
|
|
* @param Access $access
|
2013-09-27 20:30:59 +04:00
|
|
|
*/
|
2014-06-25 19:36:19 +04:00
|
|
|
public function __construct(Configuration $configuration, ILDAPWrapper $ldap, Access $access) {
|
2013-09-27 20:30:59 +04:00
|
|
|
parent::__construct($ldap);
|
|
|
|
$this->configuration = $configuration;
|
|
|
|
if(is_null(Wizard::$l)) {
|
2014-08-31 12:05:59 +04:00
|
|
|
Wizard::$l = \OC::$server->getL10N('user_ldap');
|
2013-09-27 20:30:59 +04:00
|
|
|
}
|
2014-06-25 19:36:19 +04:00
|
|
|
$this->access = $access;
|
2014-10-24 20:26:48 +04:00
|
|
|
$this->result = new WizardResult();
|
2013-09-27 20:30:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
public function __destruct() {
|
|
|
|
if($this->result->hasChanges()) {
|
|
|
|
$this->configuration->saveConfiguration();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
/**
|
2014-06-11 15:35:35 +04:00
|
|
|
* counts entries in the LDAP directory
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
*
|
2014-06-11 15:35:35 +04:00
|
|
|
* @param string $filter the LDAP search filter
|
|
|
|
* @param string $type a string being either 'users' or 'groups';
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
* @return bool|int
|
|
|
|
* @throws \Exception
|
2014-05-11 17:17:27 +04:00
|
|
|
*/
|
2014-06-11 15:35:35 +04:00
|
|
|
public function countEntries($filter, $type) {
|
|
|
|
$reqs = array('ldapHost', 'ldapPort', 'ldapBase');
|
|
|
|
if($type === 'users') {
|
|
|
|
$reqs[] = 'ldapUserFilter';
|
|
|
|
}
|
|
|
|
if(!$this->checkRequirements($reqs)) {
|
|
|
|
throw new \Exception('Requirements not met', 400);
|
2013-10-10 00:00:36 +04:00
|
|
|
}
|
|
|
|
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
$attr = array('dn'); // default
|
|
|
|
$limit = 1001;
|
2014-06-11 15:35:35 +04:00
|
|
|
if($type === 'groups') {
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
$result = $this->access->countGroups($filter, $attr, $limit);
|
2014-06-11 15:35:35 +04:00
|
|
|
} else if($type === 'users') {
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
$result = $this->access->countUsers($filter, $attr, $limit);
|
|
|
|
} else if ($type === 'objects') {
|
|
|
|
$result = $this->access->countObjects($limit);
|
2014-06-11 15:35:35 +04:00
|
|
|
} else {
|
2017-07-14 16:46:05 +03:00
|
|
|
throw new \Exception('Internal error: Invalid object type', 500);
|
2014-06-11 15:35:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
/**
|
|
|
|
* formats the return value of a count operation to the string to be
|
|
|
|
* inserted.
|
|
|
|
*
|
|
|
|
* @param bool|int $count
|
|
|
|
* @return int|string
|
|
|
|
*/
|
|
|
|
private function formatCountResult($count) {
|
|
|
|
$formatted = ($count !== false) ? $count : 0;
|
|
|
|
if($formatted > 1000) {
|
|
|
|
$formatted = '> 1000';
|
|
|
|
}
|
|
|
|
return $formatted;
|
|
|
|
}
|
|
|
|
|
2014-06-11 15:35:35 +04:00
|
|
|
public function countGroups() {
|
2013-10-10 00:00:36 +04:00
|
|
|
$filter = $this->configuration->ldapGroupFilter;
|
2014-06-11 15:35:35 +04:00
|
|
|
|
2013-10-10 00:00:36 +04:00
|
|
|
if(empty($filter)) {
|
2014-06-11 15:35:35 +04:00
|
|
|
$output = self::$l->n('%s group found', '%s groups found', 0, array(0));
|
2013-10-23 14:20:13 +04:00
|
|
|
$this->result->addChange('ldap_group_count', $output);
|
2013-10-10 00:00:36 +04:00
|
|
|
return $this->result;
|
|
|
|
}
|
2014-06-11 15:35:35 +04:00
|
|
|
|
|
|
|
try {
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
$groupsTotal = $this->formatCountResult($this->countEntries($filter, 'groups'));
|
2014-06-11 15:35:35 +04:00
|
|
|
} catch (\Exception $e) {
|
|
|
|
//400 can be ignored, 500 is forwarded
|
|
|
|
if($e->getCode() === 500) {
|
|
|
|
throw $e;
|
|
|
|
}
|
2013-10-10 00:00:36 +04:00
|
|
|
return false;
|
|
|
|
}
|
2015-01-16 21:31:15 +03:00
|
|
|
$output = self::$l->n('%s group found', '%s groups found', $groupsTotal, array($groupsTotal));
|
2013-10-23 14:20:13 +04:00
|
|
|
$this->result->addChange('ldap_group_count', $output);
|
2013-10-10 00:00:36 +04:00
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
/**
|
|
|
|
* @return WizardResult
|
|
|
|
* @throws \Exception
|
|
|
|
*/
|
2013-10-08 20:27:36 +04:00
|
|
|
public function countUsers() {
|
2014-10-28 01:39:30 +03:00
|
|
|
$filter = $this->access->getFilterForUserCount();
|
2013-10-08 20:27:36 +04:00
|
|
|
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
$usersTotal = $this->formatCountResult($this->countEntries($filter, 'users'));
|
2015-01-16 21:31:15 +03:00
|
|
|
$output = self::$l->n('%s user found', '%s users found', $usersTotal, array($usersTotal));
|
2014-06-11 15:35:35 +04:00
|
|
|
$this->result->addChange('ldap_user_count', $output);
|
2013-10-08 20:27:36 +04:00
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
/**
|
|
|
|
* counts any objects in the currently set base dn
|
|
|
|
*
|
|
|
|
* @return WizardResult
|
|
|
|
* @throws \Exception
|
|
|
|
*/
|
|
|
|
public function countInBaseDN() {
|
|
|
|
// we don't need to provide a filter in this case
|
|
|
|
$total = $this->countEntries(null, 'objects');
|
2015-04-09 22:04:33 +03:00
|
|
|
if($total === false) {
|
|
|
|
throw new \Exception('invalid results received');
|
|
|
|
}
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
$this->result->addChange('ldap_test_base', $total);
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
2014-06-25 16:04:06 +04:00
|
|
|
/**
|
|
|
|
* counts users with a specified attribute
|
|
|
|
* @param string $attr
|
2014-10-29 12:24:48 +03:00
|
|
|
* @param bool $existsCheck
|
2014-06-25 16:04:06 +04:00
|
|
|
* @return int|bool
|
|
|
|
*/
|
2014-10-29 12:24:48 +03:00
|
|
|
public function countUsersWithAttribute($attr, $existsCheck = false) {
|
2014-06-25 16:04:06 +04:00
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
'ldapUserFilter',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-06-25 19:36:19 +04:00
|
|
|
$filter = $this->access->combineFilterWithAnd(array(
|
2014-06-25 16:04:06 +04:00
|
|
|
$this->configuration->ldapUserFilter,
|
|
|
|
$attr . '=*'
|
|
|
|
));
|
|
|
|
|
2014-10-29 12:24:48 +03:00
|
|
|
$limit = ($existsCheck === false) ? null : 1;
|
|
|
|
|
|
|
|
return $this->access->countUsers($filter, array('dn'), $limit);
|
2014-06-25 16:04:06 +04:00
|
|
|
}
|
|
|
|
|
2014-10-24 20:26:48 +04:00
|
|
|
/**
|
|
|
|
* detects the display name attribute. If a setting is already present that
|
|
|
|
* returns at least one hit, the detection will be canceled.
|
|
|
|
* @return WizardResult|bool
|
2014-11-20 20:03:47 +03:00
|
|
|
* @throws \Exception
|
2014-10-24 20:26:48 +04:00
|
|
|
*/
|
|
|
|
public function detectUserDisplayNameAttribute() {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
'ldapUserFilter',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$attr = $this->configuration->ldapUserDisplayName;
|
2016-09-23 01:30:57 +03:00
|
|
|
if ($attr !== '' && $attr !== 'displayName') {
|
2014-10-24 20:26:48 +04:00
|
|
|
// most likely not the default value with upper case N,
|
|
|
|
// verify it still produces a result
|
2014-10-29 12:24:48 +03:00
|
|
|
$count = intval($this->countUsersWithAttribute($attr, true));
|
2014-10-24 20:26:48 +04:00
|
|
|
if($count > 0) {
|
|
|
|
//no change, but we sent it back to make sure the user interface
|
2016-04-12 13:52:51 +03:00
|
|
|
//is still correct, even if the ajax call was cancelled meanwhile
|
2014-10-24 20:26:48 +04:00
|
|
|
$this->result->addChange('ldap_display_name', $attr);
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// first attribute that has at least one result wins
|
|
|
|
$displayNameAttrs = array('displayname', 'cn');
|
|
|
|
foreach ($displayNameAttrs as $attr) {
|
2014-10-29 12:24:48 +03:00
|
|
|
$count = intval($this->countUsersWithAttribute($attr, true));
|
2014-10-24 20:26:48 +04:00
|
|
|
|
|
|
|
if($count > 0) {
|
|
|
|
$this->applyFind('ldap_display_name', $attr);
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-07-14 16:46:05 +03:00
|
|
|
throw new \Exception(self::$l->t('Could not detect user display name attribute. Please specify it yourself in advanced LDAP settings.'));
|
2014-10-24 20:26:48 +04:00
|
|
|
}
|
|
|
|
|
2014-06-25 16:04:06 +04:00
|
|
|
/**
|
|
|
|
* detects the most often used email attribute for users applying to the
|
|
|
|
* user list filter. If a setting is already present that returns at least
|
|
|
|
* one hit, the detection will be canceled.
|
2014-06-25 21:38:54 +04:00
|
|
|
* @return WizardResult|bool
|
2014-06-25 16:04:06 +04:00
|
|
|
*/
|
|
|
|
public function detectEmailAttribute() {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
'ldapUserFilter',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$attr = $this->configuration->ldapEmailAttribute;
|
2016-09-23 01:30:57 +03:00
|
|
|
if ($attr !== '') {
|
2014-10-29 12:24:48 +03:00
|
|
|
$count = intval($this->countUsersWithAttribute($attr, true));
|
2014-06-25 16:04:06 +04:00
|
|
|
if($count > 0) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-06-25 20:08:05 +04:00
|
|
|
$writeLog = true;
|
|
|
|
} else {
|
|
|
|
$writeLog = false;
|
2014-06-25 16:04:06 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
$emailAttributes = array('mail', 'mailPrimaryAddress');
|
|
|
|
$winner = '';
|
|
|
|
$maxUsers = 0;
|
|
|
|
foreach($emailAttributes as $attr) {
|
|
|
|
$count = $this->countUsersWithAttribute($attr);
|
|
|
|
if($count > $maxUsers) {
|
|
|
|
$maxUsers = $count;
|
|
|
|
$winner = $attr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if($winner !== '') {
|
2014-10-29 12:27:17 +03:00
|
|
|
$this->applyFind('ldap_email_attr', $winner);
|
2014-06-25 20:08:05 +04:00
|
|
|
if($writeLog) {
|
|
|
|
\OCP\Util::writeLog('user_ldap', 'The mail attribute has ' .
|
|
|
|
'automatically been reset, because the original value ' .
|
|
|
|
'did not return any results.', \OCP\Util::INFO);
|
|
|
|
}
|
2014-06-25 16:04:06 +04:00
|
|
|
}
|
|
|
|
|
2014-06-25 21:38:54 +04:00
|
|
|
return $this->result;
|
2014-06-25 16:04:06 +04:00
|
|
|
}
|
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
/**
|
|
|
|
* @return WizardResult
|
|
|
|
* @throws \Exception
|
|
|
|
*/
|
2013-10-09 01:47:57 +04:00
|
|
|
public function determineAttributes() {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
'ldapUserFilter',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$attributes = $this->getUserAttributes();
|
|
|
|
|
|
|
|
natcasesort($attributes);
|
|
|
|
$attributes = array_values($attributes);
|
|
|
|
|
|
|
|
$this->result->addOptions('ldap_loginfilter_attributes', $attributes);
|
|
|
|
|
|
|
|
$selected = $this->configuration->ldapLoginFilterAttributes;
|
|
|
|
if(is_array($selected) && !empty($selected)) {
|
|
|
|
$this->result->addChange('ldap_loginfilter_attributes', $selected);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* detects the available LDAP attributes
|
2015-01-16 21:31:15 +03:00
|
|
|
* @return array|false The instance's WizardResult instance
|
2014-05-11 17:17:27 +04:00
|
|
|
* @throws \Exception
|
2013-10-09 01:47:57 +04:00
|
|
|
*/
|
|
|
|
private function getUserAttributes() {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
'ldapUserFilter',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$cr = $this->getConnection();
|
|
|
|
if(!$cr) {
|
2013-11-01 13:19:44 +04:00
|
|
|
throw new \Exception('Could not connect to LDAP');
|
2013-10-09 01:47:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
$base = $this->configuration->ldapBase[0];
|
|
|
|
$filter = $this->configuration->ldapUserFilter;
|
|
|
|
$rr = $this->ldap->search($cr, $base, $filter, array(), 1, 1);
|
|
|
|
if(!$this->ldap->isResource($rr)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$er = $this->ldap->firstEntry($cr, $rr);
|
|
|
|
$attributes = $this->ldap->getAttributes($cr, $er);
|
|
|
|
$pureAttributes = array();
|
|
|
|
for($i = 0; $i < $attributes['count']; $i++) {
|
|
|
|
$pureAttributes[] = $attributes[$i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $pureAttributes;
|
|
|
|
}
|
|
|
|
|
2013-10-07 19:56:45 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* detects the available LDAP groups
|
2015-01-16 21:31:15 +03:00
|
|
|
* @return WizardResult|false the instance's WizardResult instance
|
2013-10-07 19:56:45 +04:00
|
|
|
*/
|
2013-10-10 00:00:36 +04:00
|
|
|
public function determineGroupsForGroups() {
|
|
|
|
return $this->determineGroups('ldap_groupfilter_groups',
|
|
|
|
'ldapGroupFilterGroups',
|
|
|
|
false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* detects the available LDAP groups
|
2015-01-16 21:31:15 +03:00
|
|
|
* @return WizardResult|false the instance's WizardResult instance
|
2013-10-10 00:00:36 +04:00
|
|
|
*/
|
|
|
|
public function determineGroupsForUsers() {
|
|
|
|
return $this->determineGroups('ldap_userfilter_groups',
|
|
|
|
'ldapUserFilterGroups');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* detects the available LDAP groups
|
2014-05-11 17:17:27 +04:00
|
|
|
* @param string $dbKey
|
|
|
|
* @param string $confKey
|
|
|
|
* @param bool $testMemberOf
|
2015-01-16 21:31:15 +03:00
|
|
|
* @return WizardResult|false the instance's WizardResult instance
|
2014-05-11 17:17:27 +04:00
|
|
|
* @throws \Exception
|
2013-10-10 00:00:36 +04:00
|
|
|
*/
|
2014-05-11 17:17:27 +04:00
|
|
|
private function determineGroups($dbKey, $confKey, $testMemberOf = true) {
|
2013-10-04 20:11:44 +04:00
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$cr = $this->getConnection();
|
|
|
|
if(!$cr) {
|
2013-11-01 13:19:44 +04:00
|
|
|
throw new \Exception('Could not connect to LDAP');
|
2013-10-04 20:11:44 +04:00
|
|
|
}
|
|
|
|
|
2015-06-03 16:23:37 +03:00
|
|
|
$this->fetchGroups($dbKey, $confKey);
|
2013-10-07 19:56:45 +04:00
|
|
|
|
2013-10-10 00:00:36 +04:00
|
|
|
if($testMemberOf) {
|
2015-06-03 16:23:37 +03:00
|
|
|
$this->configuration->hasMemberOfFilterSupport = $this->testMemberOf();
|
2013-10-10 21:37:12 +04:00
|
|
|
$this->result->markChange();
|
2013-10-10 00:00:36 +04:00
|
|
|
if(!$this->configuration->hasMemberOfFilterSupport) {
|
|
|
|
throw new \Exception('memberOf is not supported by the server');
|
|
|
|
}
|
2013-10-08 03:19:37 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
/**
|
2015-06-03 16:23:37 +03:00
|
|
|
* fetches all groups from LDAP and adds them to the result object
|
|
|
|
*
|
2014-06-11 15:35:35 +04:00
|
|
|
* @param string $dbKey
|
|
|
|
* @param string $confKey
|
2014-08-11 11:15:56 +04:00
|
|
|
* @return array $groupEntries
|
2015-06-03 16:23:37 +03:00
|
|
|
* @throws \Exception
|
2014-05-11 17:17:27 +04:00
|
|
|
*/
|
2014-06-11 15:35:35 +04:00
|
|
|
public function fetchGroups($dbKey, $confKey) {
|
|
|
|
$obclasses = array('posixGroup', 'group', 'zimbraDistributionList', 'groupOfNames');
|
|
|
|
|
|
|
|
$filterParts = array();
|
|
|
|
foreach($obclasses as $obclass) {
|
|
|
|
$filterParts[] = 'objectclass='.$obclass;
|
|
|
|
}
|
|
|
|
//we filter for everything
|
|
|
|
//- that looks like a group and
|
|
|
|
//- has the group display name set
|
2014-06-25 19:36:19 +04:00
|
|
|
$filter = $this->access->combineFilterWithOr($filterParts);
|
|
|
|
$filter = $this->access->combineFilterWithAnd(array($filter, 'cn=*'));
|
2014-06-11 15:35:35 +04:00
|
|
|
|
2014-08-11 15:50:13 +04:00
|
|
|
$groupNames = array();
|
2014-08-11 11:15:56 +04:00
|
|
|
$groupEntries = array();
|
2014-06-11 15:35:35 +04:00
|
|
|
$limit = 400;
|
|
|
|
$offset = 0;
|
|
|
|
do {
|
2014-09-26 17:36:49 +04:00
|
|
|
// we need to request dn additionally here, otherwise memberOf
|
|
|
|
// detection will fail later
|
|
|
|
$result = $this->access->searchGroups($filter, array('cn', 'dn'), $limit, $offset);
|
2014-06-11 15:35:35 +04:00
|
|
|
foreach($result as $item) {
|
2015-10-08 21:32:15 +03:00
|
|
|
if(!isset($item['cn']) && !is_array($item['cn']) && !isset($item['cn'][0])) {
|
|
|
|
// just in case - no issue known
|
|
|
|
continue;
|
|
|
|
}
|
2015-10-07 19:57:49 +03:00
|
|
|
$groupNames[] = $item['cn'][0];
|
2014-08-11 11:15:56 +04:00
|
|
|
$groupEntries[] = $item;
|
2014-06-11 15:35:35 +04:00
|
|
|
}
|
|
|
|
$offset += $limit;
|
2015-10-01 01:30:05 +03:00
|
|
|
} while ($this->access->hasMoreResults());
|
2014-06-11 15:35:35 +04:00
|
|
|
|
2014-08-11 11:15:56 +04:00
|
|
|
if(count($groupNames) > 0) {
|
|
|
|
natsort($groupNames);
|
|
|
|
$this->result->addOptions($dbKey, array_values($groupNames));
|
2014-06-11 15:35:35 +04:00
|
|
|
} else {
|
|
|
|
throw new \Exception(self::$l->t('Could not find the desired feature'));
|
|
|
|
}
|
|
|
|
|
|
|
|
$setFeatures = $this->configuration->$confKey;
|
|
|
|
if(is_array($setFeatures) && !empty($setFeatures)) {
|
|
|
|
//something is already configured? pre-select it.
|
|
|
|
$this->result->addChange($dbKey, $setFeatures);
|
|
|
|
}
|
2014-08-11 11:15:56 +04:00
|
|
|
return $groupEntries;
|
2014-06-11 15:35:35 +04:00
|
|
|
}
|
|
|
|
|
2013-10-10 03:21:05 +04:00
|
|
|
public function determineGroupMemberAssoc() {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapGroupFilter',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$attribute = $this->detectGroupMemberAssoc();
|
|
|
|
if($attribute === false) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$this->configuration->setConfiguration(array('ldapGroupMemberAssocAttr' => $attribute));
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
$this->result->addChange('ldap_group_member_assoc_attribute', $attribute);
|
2013-10-10 03:21:05 +04:00
|
|
|
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
2013-10-07 19:56:45 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* Detects the available object classes
|
2015-01-16 21:31:15 +03:00
|
|
|
* @return WizardResult|false the instance's WizardResult instance
|
2014-05-11 17:17:27 +04:00
|
|
|
* @throws \Exception
|
2013-10-07 19:56:45 +04:00
|
|
|
*/
|
2013-10-10 00:00:36 +04:00
|
|
|
public function determineGroupObjectClasses() {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$cr = $this->getConnection();
|
|
|
|
if(!$cr) {
|
2013-11-01 13:19:44 +04:00
|
|
|
throw new \Exception('Could not connect to LDAP');
|
2013-10-10 00:00:36 +04:00
|
|
|
}
|
|
|
|
|
2016-07-08 19:13:22 +03:00
|
|
|
$obclasses = array('groupOfNames', 'groupOfUniqueNames', 'group', 'posixGroup', '*');
|
2013-10-10 00:00:36 +04:00
|
|
|
$this->determineFeature($obclasses,
|
|
|
|
'objectclass',
|
|
|
|
'ldap_groupfilter_objectclass',
|
|
|
|
'ldapGroupFilterObjectclass',
|
|
|
|
false);
|
|
|
|
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* detects the available object classes
|
2014-05-11 17:17:27 +04:00
|
|
|
* @return WizardResult
|
|
|
|
* @throws \Exception
|
2013-10-10 00:00:36 +04:00
|
|
|
*/
|
|
|
|
public function determineUserObjectClasses() {
|
2013-10-04 18:33:37 +04:00
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$cr = $this->getConnection();
|
|
|
|
if(!$cr) {
|
2013-11-01 13:19:44 +04:00
|
|
|
throw new \Exception('Could not connect to LDAP');
|
2013-10-04 18:33:37 +04:00
|
|
|
}
|
|
|
|
|
2013-10-04 20:11:44 +04:00
|
|
|
$obclasses = array('inetOrgPerson', 'person', 'organizationalPerson',
|
|
|
|
'user', 'posixAccount', '*');
|
2013-10-10 00:00:36 +04:00
|
|
|
$filter = $this->configuration->ldapUserFilter;
|
|
|
|
//if filter is empty, it is probably the first time the wizard is called
|
|
|
|
//then, apply suggestions.
|
2013-10-08 03:19:37 +04:00
|
|
|
$this->determineFeature($obclasses,
|
|
|
|
'objectclass',
|
|
|
|
'ldap_userfilter_objectclass',
|
|
|
|
'ldapUserFilterObjectclass',
|
2013-10-10 00:00:36 +04:00
|
|
|
empty($filter));
|
|
|
|
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
/**
|
2015-01-16 21:31:15 +03:00
|
|
|
* @return WizardResult|false
|
2014-05-11 17:17:27 +04:00
|
|
|
* @throws \Exception
|
|
|
|
*/
|
2013-10-10 00:00:36 +04:00
|
|
|
public function getGroupFilter() {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-11-05 16:19:32 +04:00
|
|
|
//make sure the use display name is set
|
|
|
|
$displayName = $this->configuration->ldapGroupDisplayName;
|
2016-09-23 01:30:57 +03:00
|
|
|
if ($displayName === '') {
|
2013-11-05 16:19:32 +04:00
|
|
|
$d = $this->configuration->getDefaults();
|
|
|
|
$this->applyFind('ldap_group_display_name',
|
|
|
|
$d['ldap_group_display_name']);
|
|
|
|
}
|
2013-10-10 00:00:36 +04:00
|
|
|
$filter = $this->composeLdapFilter(self::LFILTER_GROUP_LIST);
|
2013-10-08 03:19:37 +04:00
|
|
|
|
2013-10-10 00:00:36 +04:00
|
|
|
$this->applyFind('ldap_group_filter', $filter);
|
2013-10-08 03:19:37 +04:00
|
|
|
return $this->result;
|
2013-10-04 20:11:44 +04:00
|
|
|
}
|
2013-10-04 18:33:37 +04:00
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
/**
|
2015-01-16 21:31:15 +03:00
|
|
|
* @return WizardResult|false
|
2014-05-11 17:17:27 +04:00
|
|
|
* @throws \Exception
|
|
|
|
*/
|
2013-10-08 20:27:36 +04:00
|
|
|
public function getUserListFilter() {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-11-05 16:19:32 +04:00
|
|
|
//make sure the use display name is set
|
|
|
|
$displayName = $this->configuration->ldapUserDisplayName;
|
2016-09-23 01:30:57 +03:00
|
|
|
if ($displayName === '') {
|
2013-11-05 16:19:32 +04:00
|
|
|
$d = $this->configuration->getDefaults();
|
|
|
|
$this->applyFind('ldap_display_name', $d['ldap_display_name']);
|
|
|
|
}
|
2013-10-08 20:27:36 +04:00
|
|
|
$filter = $this->composeLdapFilter(self::LFILTER_USER_LIST);
|
|
|
|
if(!$filter) {
|
|
|
|
throw new \Exception('Cannot create filter');
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->applyFind('ldap_userlist_filter', $filter);
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
/**
|
|
|
|
* @return bool|WizardResult
|
|
|
|
* @throws \Exception
|
|
|
|
*/
|
2013-10-09 01:47:57 +04:00
|
|
|
public function getUserLoginFilter() {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
'ldapUserFilter',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-11-11 16:36:28 +04:00
|
|
|
|
2013-10-09 01:47:57 +04:00
|
|
|
$filter = $this->composeLdapFilter(self::LFILTER_LOGIN);
|
|
|
|
if(!$filter) {
|
|
|
|
throw new \Exception('Cannot create filter');
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->applyFind('ldap_login_filter', $filter);
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
/**
|
|
|
|
* @return bool|WizardResult
|
|
|
|
* @param string $loginName
|
|
|
|
* @throws \Exception
|
|
|
|
*/
|
|
|
|
public function testLoginName($loginName) {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
'ldapBase',
|
|
|
|
'ldapLoginFilter',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$cr = $this->access->connection->getConnectionResource();
|
|
|
|
if(!$this->ldap->isResource($cr)) {
|
|
|
|
throw new \Exception('connection error');
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mb_strpos($this->access->connection->ldapLoginFilter, '%uid', 0, 'UTF-8')
|
|
|
|
=== false) {
|
|
|
|
throw new \Exception('missing placeholder');
|
|
|
|
}
|
|
|
|
|
2015-10-30 20:20:50 +03:00
|
|
|
$users = $this->access->countUsersByLoginName($loginName);
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
if($this->ldap->errno($cr) !== 0) {
|
|
|
|
throw new \Exception($this->ldap->error($cr));
|
|
|
|
}
|
2015-06-19 15:55:04 +03:00
|
|
|
$filter = str_replace('%uid', $loginName, $this->access->connection->ldapLoginFilter);
|
2015-10-30 20:20:50 +03:00
|
|
|
$this->result->addChange('ldap_test_loginname', $users);
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
$this->result->addChange('ldap_test_effective_filter', $filter);
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
2013-09-27 20:30:59 +04:00
|
|
|
/**
|
|
|
|
* Tries to determine the port, requires given Host, User DN and Password
|
2014-05-11 18:27:18 +04:00
|
|
|
* @return WizardResult|false WizardResult on success, false otherwise
|
2014-05-11 17:17:27 +04:00
|
|
|
* @throws \Exception
|
2013-09-27 20:30:59 +04:00
|
|
|
*/
|
|
|
|
public function guessPortAndTLS() {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
2013-10-04 18:33:37 +04:00
|
|
|
))) {
|
2013-09-27 20:30:59 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$this->checkHost();
|
|
|
|
$portSettings = $this->getPortSettingsToTry();
|
|
|
|
|
|
|
|
if(!is_array($portSettings)) {
|
|
|
|
throw new \Exception(print_r($portSettings, true));
|
|
|
|
}
|
|
|
|
|
|
|
|
//proceed from the best configuration and return on first success
|
|
|
|
foreach($portSettings as $setting) {
|
|
|
|
$p = $setting['port'];
|
|
|
|
$t = $setting['tls'];
|
|
|
|
\OCP\Util::writeLog('user_ldap', 'Wiz: trying port '. $p . ', TLS '. $t, \OCP\Util::DEBUG);
|
|
|
|
//connectAndBind may throw Exception, it needs to be catched by the
|
|
|
|
//callee of this method
|
2015-05-12 15:45:32 +03:00
|
|
|
|
|
|
|
try {
|
|
|
|
$settingsFound = $this->connectAndBind($p, $t);
|
|
|
|
} catch (\Exception $e) {
|
2015-10-03 01:35:24 +03:00
|
|
|
// any reply other than -1 (= cannot connect) is already okay,
|
|
|
|
// because then we found the server
|
|
|
|
// unavailable startTLS returns -11
|
|
|
|
if($e->getCode() > 0) {
|
2015-05-12 15:45:32 +03:00
|
|
|
$settingsFound = true;
|
|
|
|
} else {
|
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($settingsFound === true) {
|
|
|
|
$config = array(
|
|
|
|
'ldapPort' => $p,
|
|
|
|
'ldapTLS' => intval($t)
|
|
|
|
);
|
2013-09-27 20:30:59 +04:00
|
|
|
$this->configuration->setConfiguration($config);
|
2015-05-12 15:45:32 +03:00
|
|
|
\OCP\Util::writeLog('user_ldap', 'Wiz: detected Port ' . $p, \OCP\Util::DEBUG);
|
2013-09-27 20:30:59 +04:00
|
|
|
$this->result->addChange('ldap_port', $p);
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//custom port, undetected (we do not brute force)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-09-30 01:53:14 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* tries to determine a base dn from User DN or LDAP Host
|
2014-05-11 18:28:50 +04:00
|
|
|
* @return WizardResult|false WizardResult on success, false otherwise
|
2013-09-30 01:53:14 +04:00
|
|
|
*/
|
2013-09-27 20:30:59 +04:00
|
|
|
public function guessBaseDN() {
|
|
|
|
if(!$this->checkRequirements(array('ldapHost',
|
|
|
|
'ldapPort',
|
|
|
|
))) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-30 01:53:14 +04:00
|
|
|
|
|
|
|
//check whether a DN is given in the agent name (99.9% of all cases)
|
|
|
|
$base = null;
|
|
|
|
$i = stripos($this->configuration->ldapAgentName, 'dc=');
|
|
|
|
if($i !== false) {
|
|
|
|
$base = substr($this->configuration->ldapAgentName, $i);
|
|
|
|
if($this->testBaseDN($base)) {
|
|
|
|
$this->applyFind('ldap_base', $base);
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//this did not help :(
|
|
|
|
//Let's see whether we can parse the Host URL and convert the domain to
|
|
|
|
//a base DN
|
2016-10-10 11:18:18 +03:00
|
|
|
$helper = new Helper(\OC::$server->getConfig());
|
2014-08-21 19:59:13 +04:00
|
|
|
$domain = $helper->getDomainFromURL($this->configuration->ldapHost);
|
2013-09-30 01:53:14 +04:00
|
|
|
if(!$domain) {
|
2013-09-27 20:30:59 +04:00
|
|
|
return false;
|
|
|
|
}
|
2013-09-30 01:53:14 +04:00
|
|
|
|
|
|
|
$dparts = explode('.', $domain);
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
while(count($dparts) > 0) {
|
|
|
|
$base2 = 'dc=' . implode(',dc=', $dparts);
|
|
|
|
if ($base !== $base2 && $this->testBaseDN($base2)) {
|
|
|
|
$this->applyFind('ldap_base', $base2);
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
array_shift($dparts);
|
2013-09-30 01:53:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* sets the found value for the configuration key in the WizardResult
|
2013-09-30 01:53:14 +04:00
|
|
|
* as well as in the Configuration instance
|
2014-04-14 19:39:29 +04:00
|
|
|
* @param string $key the configuration key
|
2014-05-11 17:17:27 +04:00
|
|
|
* @param string $value the (detected) value
|
2013-09-30 01:53:14 +04:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
private function applyFind($key, $value) {
|
|
|
|
$this->result->addChange($key, $value);
|
|
|
|
$this->configuration->setConfiguration(array($key => $value));
|
2013-09-27 20:30:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* Checks, whether a port was entered in the Host configuration
|
2013-09-27 20:30:59 +04:00
|
|
|
* field. In this case the port will be stripped off, but also stored as
|
|
|
|
* setting.
|
|
|
|
*/
|
|
|
|
private function checkHost() {
|
|
|
|
$host = $this->configuration->ldapHost;
|
|
|
|
$hostInfo = parse_url($host);
|
|
|
|
|
|
|
|
//removes Port from Host
|
|
|
|
if(is_array($hostInfo) && isset($hostInfo['port'])) {
|
|
|
|
$port = $hostInfo['port'];
|
|
|
|
$host = str_replace(':'.$port, '', $host);
|
2013-09-30 01:53:14 +04:00
|
|
|
$this->applyFind('ldap_host', $host);
|
|
|
|
$this->applyFind('ldap_port', $port);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-10 03:21:05 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* tries to detect the group member association attribute which is
|
2017-03-18 09:56:24 +03:00
|
|
|
* one of 'uniqueMember', 'memberUid', 'member', 'gidNumber'
|
2014-05-11 17:17:27 +04:00
|
|
|
* @return string|false, string with the attribute name, false on error
|
|
|
|
* @throws \Exception
|
2013-10-10 03:21:05 +04:00
|
|
|
*/
|
|
|
|
private function detectGroupMemberAssoc() {
|
2017-03-18 09:56:24 +03:00
|
|
|
$possibleAttrs = array('uniqueMember', 'memberUid', 'member', 'gidNumber');
|
2013-10-10 03:21:05 +04:00
|
|
|
$filter = $this->configuration->ldapGroupFilter;
|
|
|
|
if(empty($filter)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$cr = $this->getConnection();
|
|
|
|
if(!$cr) {
|
2013-11-01 13:19:44 +04:00
|
|
|
throw new \Exception('Could not connect to LDAP');
|
2013-10-10 03:21:05 +04:00
|
|
|
}
|
|
|
|
$base = $this->configuration->ldapBase[0];
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
$rr = $this->ldap->search($cr, $base, $filter, $possibleAttrs, 0, 1000);
|
2013-10-10 03:21:05 +04:00
|
|
|
if(!$this->ldap->isResource($rr)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$er = $this->ldap->firstEntry($cr, $rr);
|
|
|
|
while(is_resource($er)) {
|
2014-05-11 17:17:27 +04:00
|
|
|
$this->ldap->getDN($cr, $er);
|
2013-10-10 03:21:05 +04:00
|
|
|
$attrs = $this->ldap->getAttributes($cr, $er);
|
|
|
|
$result = array();
|
2014-10-24 01:27:15 +04:00
|
|
|
$possibleAttrsCount = count($possibleAttrs);
|
|
|
|
for($i = 0; $i < $possibleAttrsCount; $i++) {
|
2013-10-10 03:21:05 +04:00
|
|
|
if(isset($attrs[$possibleAttrs[$i]])) {
|
|
|
|
$result[$possibleAttrs[$i]] = $attrs[$possibleAttrs[$i]]['count'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!empty($result)) {
|
|
|
|
natsort($result);
|
|
|
|
return key($result);
|
|
|
|
}
|
|
|
|
|
|
|
|
$er = $this->ldap->nextEntry($cr, $er);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-09-30 01:53:14 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* Checks whether for a given BaseDN results will be returned
|
2014-02-06 19:30:58 +04:00
|
|
|
* @param string $base the BaseDN to test
|
2013-09-30 01:53:14 +04:00
|
|
|
* @return bool true on success, false otherwise
|
2014-05-11 17:17:27 +04:00
|
|
|
* @throws \Exception
|
2013-09-30 01:53:14 +04:00
|
|
|
*/
|
|
|
|
private function testBaseDN($base) {
|
|
|
|
$cr = $this->getConnection();
|
|
|
|
if(!$cr) {
|
2013-11-01 13:19:44 +04:00
|
|
|
throw new \Exception('Could not connect to LDAP');
|
2013-09-30 01:53:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
//base is there, let's validate it. If we search for anything, we should
|
|
|
|
//get a result set > 0 on a proper base
|
|
|
|
$rr = $this->ldap->search($cr, $base, 'objectClass=*', array('dn'), 0, 1);
|
|
|
|
if(!$this->ldap->isResource($rr)) {
|
2014-02-04 22:37:40 +04:00
|
|
|
$errorNo = $this->ldap->errno($cr);
|
|
|
|
$errorMsg = $this->ldap->error($cr);
|
|
|
|
\OCP\Util::writeLog('user_ldap', 'Wiz: Could not search base '.$base.
|
|
|
|
' Error '.$errorNo.': '.$errorMsg, \OCP\Util::INFO);
|
2013-09-30 01:53:14 +04:00
|
|
|
return false;
|
2013-09-27 20:30:59 +04:00
|
|
|
}
|
2013-09-30 01:53:14 +04:00
|
|
|
$entries = $this->ldap->countEntries($cr, $rr);
|
|
|
|
return ($entries !== false) && ($entries > 0);
|
2013-09-27 20:30:59 +04:00
|
|
|
}
|
|
|
|
|
2013-10-08 13:19:55 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* Checks whether the server supports memberOf in LDAP Filter.
|
2015-06-03 16:23:37 +03:00
|
|
|
* Note: at least in OpenLDAP, availability of memberOf is dependent on
|
|
|
|
* a configured objectClass. I.e. not necessarily for all available groups
|
|
|
|
* memberOf does work.
|
|
|
|
*
|
2014-05-11 17:17:27 +04:00
|
|
|
* @return bool true if it does, false otherwise
|
|
|
|
* @throws \Exception
|
2013-10-08 13:19:55 +04:00
|
|
|
*/
|
2015-06-03 16:23:37 +03:00
|
|
|
private function testMemberOf() {
|
2013-10-08 13:19:55 +04:00
|
|
|
$cr = $this->getConnection();
|
|
|
|
if(!$cr) {
|
2013-11-01 13:19:44 +04:00
|
|
|
throw new \Exception('Could not connect to LDAP');
|
2013-10-08 13:19:55 +04:00
|
|
|
}
|
2015-06-03 16:23:37 +03:00
|
|
|
$result = $this->access->countUsers('memberOf=*', array('memberOf'), 1);
|
|
|
|
if(is_int($result) && $result > 0) {
|
|
|
|
return true;
|
2013-10-08 13:19:55 +04:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-10-08 20:27:36 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* creates an LDAP Filter from given configuration
|
2014-02-06 19:30:58 +04:00
|
|
|
* @param integer $filterType int, for which use case the filter shall be created
|
2013-10-08 20:27:36 +04:00
|
|
|
* can be any of self::LFILTER_USER_LIST, self::LFILTER_LOGIN or
|
|
|
|
* self::LFILTER_GROUP_LIST
|
2014-05-11 17:17:27 +04:00
|
|
|
* @return string|false string with the filter on success, false otherwise
|
|
|
|
* @throws \Exception
|
2013-10-08 20:27:36 +04:00
|
|
|
*/
|
|
|
|
private function composeLdapFilter($filterType) {
|
|
|
|
$filter = '';
|
|
|
|
$parts = 0;
|
|
|
|
switch ($filterType) {
|
|
|
|
case self::LFILTER_USER_LIST:
|
|
|
|
$objcs = $this->configuration->ldapUserFilterObjectclass;
|
|
|
|
//glue objectclasses
|
|
|
|
if(is_array($objcs) && count($objcs) > 0) {
|
|
|
|
$filter .= '(|';
|
|
|
|
foreach($objcs as $objc) {
|
|
|
|
$filter .= '(objectclass=' . $objc . ')';
|
|
|
|
}
|
|
|
|
$filter .= ')';
|
|
|
|
$parts++;
|
|
|
|
}
|
|
|
|
//glue group memberships
|
|
|
|
if($this->configuration->hasMemberOfFilterSupport) {
|
|
|
|
$cns = $this->configuration->ldapUserFilterGroups;
|
|
|
|
if(is_array($cns) && count($cns) > 0) {
|
|
|
|
$filter .= '(|';
|
|
|
|
$cr = $this->getConnection();
|
|
|
|
if(!$cr) {
|
2013-11-01 13:19:44 +04:00
|
|
|
throw new \Exception('Could not connect to LDAP');
|
2013-10-08 20:27:36 +04:00
|
|
|
}
|
|
|
|
$base = $this->configuration->ldapBase[0];
|
|
|
|
foreach($cns as $cn) {
|
2014-11-17 18:30:50 +03:00
|
|
|
$rr = $this->ldap->search($cr, $base, 'cn=' . $cn, array('dn', 'primaryGroupToken'));
|
2013-10-08 20:27:36 +04:00
|
|
|
if(!$this->ldap->isResource($rr)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$er = $this->ldap->firstEntry($cr, $rr);
|
2014-11-17 18:30:50 +03:00
|
|
|
$attrs = $this->ldap->getAttributes($cr, $er);
|
2013-10-08 20:27:36 +04:00
|
|
|
$dn = $this->ldap->getDN($cr, $er);
|
2017-05-10 15:06:01 +03:00
|
|
|
if ($dn === false || $dn === '') {
|
2014-11-17 18:30:50 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$filterPart = '(memberof=' . $dn . ')';
|
|
|
|
if(isset($attrs['primaryGroupToken'])) {
|
|
|
|
$pgt = $attrs['primaryGroupToken'][0];
|
|
|
|
$primaryFilterPart = '(primaryGroupID=' . $pgt .')';
|
|
|
|
$filterPart = '(|' . $filterPart . $primaryFilterPart . ')';
|
|
|
|
}
|
|
|
|
$filter .= $filterPart;
|
2013-10-08 20:27:36 +04:00
|
|
|
}
|
|
|
|
$filter .= ')';
|
|
|
|
}
|
|
|
|
$parts++;
|
|
|
|
}
|
|
|
|
//wrap parts in AND condition
|
|
|
|
if($parts > 1) {
|
|
|
|
$filter = '(&' . $filter . ')';
|
|
|
|
}
|
2016-09-23 01:30:57 +03:00
|
|
|
if ($filter === '') {
|
2013-10-09 01:47:57 +04:00
|
|
|
$filter = '(objectclass=*)';
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2013-10-10 00:00:36 +04:00
|
|
|
case self::LFILTER_GROUP_LIST:
|
|
|
|
$objcs = $this->configuration->ldapGroupFilterObjectclass;
|
|
|
|
//glue objectclasses
|
|
|
|
if(is_array($objcs) && count($objcs) > 0) {
|
|
|
|
$filter .= '(|';
|
|
|
|
foreach($objcs as $objc) {
|
|
|
|
$filter .= '(objectclass=' . $objc . ')';
|
|
|
|
}
|
|
|
|
$filter .= ')';
|
|
|
|
$parts++;
|
|
|
|
}
|
|
|
|
//glue group memberships
|
|
|
|
$cns = $this->configuration->ldapGroupFilterGroups;
|
|
|
|
if(is_array($cns) && count($cns) > 0) {
|
|
|
|
$filter .= '(|';
|
|
|
|
foreach($cns as $cn) {
|
|
|
|
$filter .= '(cn=' . $cn . ')';
|
|
|
|
}
|
|
|
|
$filter .= ')';
|
|
|
|
}
|
|
|
|
$parts++;
|
|
|
|
//wrap parts in AND condition
|
|
|
|
if($parts > 1) {
|
|
|
|
$filter = '(&' . $filter . ')';
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2013-10-09 01:47:57 +04:00
|
|
|
case self::LFILTER_LOGIN:
|
|
|
|
$ulf = $this->configuration->ldapUserFilter;
|
|
|
|
$loginpart = '=%uid';
|
|
|
|
$filterUsername = '';
|
|
|
|
$userAttributes = $this->getUserAttributes();
|
|
|
|
$userAttributes = array_change_key_case(array_flip($userAttributes));
|
|
|
|
$parts = 0;
|
|
|
|
|
|
|
|
if($this->configuration->ldapLoginFilterUsername === '1') {
|
|
|
|
$attr = '';
|
|
|
|
if(isset($userAttributes['uid'])) {
|
|
|
|
$attr = 'uid';
|
|
|
|
} else if(isset($userAttributes['samaccountname'])) {
|
|
|
|
$attr = 'samaccountname';
|
|
|
|
} else if(isset($userAttributes['cn'])) {
|
|
|
|
//fallback
|
|
|
|
$attr = 'cn';
|
|
|
|
}
|
2016-09-23 01:30:57 +03:00
|
|
|
if ($attr !== '') {
|
2013-10-09 01:47:57 +04:00
|
|
|
$filterUsername = '(' . $attr . $loginpart . ')';
|
|
|
|
$parts++;
|
|
|
|
}
|
2013-10-08 20:27:36 +04:00
|
|
|
}
|
2013-10-09 01:47:57 +04:00
|
|
|
|
|
|
|
$filterEmail = '';
|
|
|
|
if($this->configuration->ldapLoginFilterEmail === '1') {
|
|
|
|
$filterEmail = '(|(mailPrimaryAddress=%uid)(mail=%uid))';
|
|
|
|
$parts++;
|
|
|
|
}
|
|
|
|
|
|
|
|
$filterAttributes = '';
|
|
|
|
$attrsToFilter = $this->configuration->ldapLoginFilterAttributes;
|
|
|
|
if(is_array($attrsToFilter) && count($attrsToFilter) > 0) {
|
|
|
|
$filterAttributes = '(|';
|
|
|
|
foreach($attrsToFilter as $attribute) {
|
2014-05-16 00:47:28 +04:00
|
|
|
$filterAttributes .= '(' . $attribute . $loginpart . ')';
|
2013-10-09 01:47:57 +04:00
|
|
|
}
|
|
|
|
$filterAttributes .= ')';
|
|
|
|
$parts++;
|
|
|
|
}
|
|
|
|
|
|
|
|
$filterLogin = '';
|
|
|
|
if($parts > 1) {
|
|
|
|
$filterLogin = '(|';
|
|
|
|
}
|
|
|
|
$filterLogin .= $filterUsername;
|
|
|
|
$filterLogin .= $filterEmail;
|
|
|
|
$filterLogin .= $filterAttributes;
|
|
|
|
if($parts > 1) {
|
|
|
|
$filterLogin .= ')';
|
|
|
|
}
|
|
|
|
|
|
|
|
$filter = '(&'.$ulf.$filterLogin.')';
|
2013-10-08 20:27:36 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
\OCP\Util::writeLog('user_ldap', 'Wiz: Final filter '.$filter, \OCP\Util::DEBUG);
|
|
|
|
|
2013-10-10 00:00:36 +04:00
|
|
|
return $filter;
|
2013-10-08 20:27:36 +04:00
|
|
|
}
|
|
|
|
|
2013-09-27 20:30:59 +04:00
|
|
|
/**
|
|
|
|
* Connects and Binds to an LDAP Server
|
2014-05-11 17:17:27 +04:00
|
|
|
* @param int $port the port to connect with
|
|
|
|
* @param bool $tls whether startTLS is to be used
|
|
|
|
* @param bool $ncc
|
|
|
|
* @return bool
|
|
|
|
* @throws \Exception
|
2013-09-27 20:30:59 +04:00
|
|
|
*/
|
|
|
|
private function connectAndBind($port = 389, $tls = false, $ncc = false) {
|
|
|
|
if($ncc) {
|
|
|
|
//No certificate check
|
|
|
|
//FIXME: undo afterwards
|
|
|
|
putenv('LDAPTLS_REQCERT=never');
|
|
|
|
}
|
|
|
|
|
|
|
|
//connect, does not really trigger any server communication
|
|
|
|
\OCP\Util::writeLog('user_ldap', 'Wiz: Checking Host Info ', \OCP\Util::DEBUG);
|
|
|
|
$host = $this->configuration->ldapHost;
|
|
|
|
$hostInfo = parse_url($host);
|
|
|
|
if(!$hostInfo) {
|
2016-05-12 17:55:58 +03:00
|
|
|
throw new \Exception(self::$l->t('Invalid Host'));
|
2013-09-27 20:30:59 +04:00
|
|
|
}
|
|
|
|
\OCP\Util::writeLog('user_ldap', 'Wiz: Attempting to connect ', \OCP\Util::DEBUG);
|
|
|
|
$cr = $this->ldap->connect($host, $port);
|
|
|
|
if(!is_resource($cr)) {
|
2016-05-12 17:55:58 +03:00
|
|
|
throw new \Exception(self::$l->t('Invalid Host'));
|
2013-09-27 20:30:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
\OCP\Util::writeLog('user_ldap', 'Wiz: Setting LDAP Options ', \OCP\Util::DEBUG);
|
|
|
|
//set LDAP options
|
2013-12-13 20:52:43 +04:00
|
|
|
$this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3);
|
2013-12-10 20:50:45 +04:00
|
|
|
$this->ldap->setOption($cr, LDAP_OPT_REFERRALS, 0);
|
2013-12-13 20:52:43 +04:00
|
|
|
$this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT);
|
2015-06-04 17:28:48 +03:00
|
|
|
|
|
|
|
try {
|
|
|
|
if($tls) {
|
|
|
|
$isTlsWorking = @$this->ldap->startTls($cr);
|
|
|
|
if(!$isTlsWorking) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-12-13 20:52:19 +04:00
|
|
|
}
|
2013-09-27 20:30:59 +04:00
|
|
|
|
2015-06-04 17:28:48 +03:00
|
|
|
\OCP\Util::writeLog('user_ldap', 'Wiz: Attemping to Bind ', \OCP\Util::DEBUG);
|
|
|
|
//interesting part: do the bind!
|
|
|
|
$login = $this->ldap->bind($cr,
|
|
|
|
$this->configuration->ldapAgentName,
|
|
|
|
$this->configuration->ldapAgentPassword
|
|
|
|
);
|
|
|
|
$errNo = $this->ldap->errno($cr);
|
|
|
|
$error = ldap_error($cr);
|
|
|
|
$this->ldap->unbind($cr);
|
|
|
|
} catch(ServerNotAvailableException $e) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-27 20:30:59 +04:00
|
|
|
|
|
|
|
if($login === true) {
|
|
|
|
$this->ldap->unbind($cr);
|
|
|
|
if($ncc) {
|
|
|
|
throw new \Exception('Certificate cannot be validated.');
|
|
|
|
}
|
2014-05-11 17:17:27 +04:00
|
|
|
\OCP\Util::writeLog('user_ldap', 'Wiz: Bind successful to Port '. $port . ' TLS ' . intval($tls), \OCP\Util::DEBUG);
|
2013-09-27 20:30:59 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
if($errNo === -1 || ($errNo === 2 && $ncc)) {
|
2013-09-27 20:30:59 +04:00
|
|
|
//host, port or TLS wrong
|
|
|
|
return false;
|
2014-05-11 17:17:27 +04:00
|
|
|
} else if ($errNo === 2) {
|
2013-09-27 20:30:59 +04:00
|
|
|
return $this->connectAndBind($port, $tls, true);
|
|
|
|
}
|
2015-10-03 01:35:24 +03:00
|
|
|
throw new \Exception($error, $errNo);
|
2013-09-27 20:30:59 +04:00
|
|
|
}
|
|
|
|
|
2013-11-11 16:36:28 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* checks whether a valid combination of agent and password has been
|
2013-11-11 16:36:28 +04:00
|
|
|
* provided (either two values or nothing for anonymous connect)
|
2014-05-11 17:17:27 +04:00
|
|
|
* @return bool, true if everything is fine, false otherwise
|
2013-11-11 16:36:28 +04:00
|
|
|
*/
|
|
|
|
private function checkAgentRequirements() {
|
|
|
|
$agent = $this->configuration->ldapAgentName;
|
|
|
|
$pwd = $this->configuration->ldapAgentPassword;
|
|
|
|
|
2016-09-23 01:30:57 +03:00
|
|
|
return
|
|
|
|
($agent !== '' && $pwd !== '')
|
|
|
|
|| ($agent === '' && $pwd === '')
|
|
|
|
;
|
2013-11-11 16:36:28 +04:00
|
|
|
}
|
|
|
|
|
2014-02-06 19:30:58 +04:00
|
|
|
/**
|
2014-05-11 17:17:27 +04:00
|
|
|
* @param array $reqs
|
|
|
|
* @return bool
|
2014-02-06 19:30:58 +04:00
|
|
|
*/
|
2013-09-27 20:30:59 +04:00
|
|
|
private function checkRequirements($reqs) {
|
2013-11-11 16:36:28 +04:00
|
|
|
$this->checkAgentRequirements();
|
2013-09-27 20:30:59 +04:00
|
|
|
foreach($reqs as $option) {
|
|
|
|
$value = $this->configuration->$option;
|
|
|
|
if(empty($value)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-10-04 18:33:37 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* does a cumulativeSearch on LDAP to get different values of a
|
2013-10-04 18:33:37 +04:00
|
|
|
* specified attribute
|
2014-02-19 12:31:54 +04:00
|
|
|
* @param string[] $filters array, the filters that shall be used in the search
|
|
|
|
* @param string $attr the attribute of which a list of values shall be returned
|
2014-03-20 16:58:08 +04:00
|
|
|
* @param int $dnReadLimit the amount of how many DNs should be analyzed.
|
|
|
|
* The lower, the faster
|
2014-02-06 19:30:58 +04:00
|
|
|
* @param string $maxF string. if not null, this variable will have the filter that
|
2013-10-04 18:33:37 +04:00
|
|
|
* yields most result entries
|
2014-05-11 17:17:27 +04:00
|
|
|
* @return array|false an array with the values on success, false otherwise
|
2013-10-04 18:33:37 +04:00
|
|
|
*/
|
2014-06-11 15:35:35 +04:00
|
|
|
public function cumulativeSearchOnAttribute($filters, $attr, $dnReadLimit = 3, &$maxF = null) {
|
2013-10-04 18:33:37 +04:00
|
|
|
$dnRead = array();
|
|
|
|
$foundItems = array();
|
|
|
|
$maxEntries = 0;
|
2013-10-07 20:03:54 +04:00
|
|
|
if(!is_array($this->configuration->ldapBase)
|
|
|
|
|| !isset($this->configuration->ldapBase[0])) {
|
2013-10-04 18:33:37 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$base = $this->configuration->ldapBase[0];
|
|
|
|
$cr = $this->getConnection();
|
2014-03-21 01:58:57 +04:00
|
|
|
if(!$this->ldap->isResource($cr)) {
|
2013-10-04 18:33:37 +04:00
|
|
|
return false;
|
|
|
|
}
|
2014-03-21 13:10:49 +04:00
|
|
|
$lastFilter = null;
|
2014-03-21 01:57:50 +04:00
|
|
|
if(isset($filters[count($filters)-1])) {
|
|
|
|
$lastFilter = $filters[count($filters)-1];
|
|
|
|
}
|
2013-10-04 18:33:37 +04:00
|
|
|
foreach($filters as $filter) {
|
2014-06-11 15:35:35 +04:00
|
|
|
if($lastFilter === $filter && count($foundItems) > 0) {
|
2014-04-09 14:25:48 +04:00
|
|
|
//skip when the filter is a wildcard and results were found
|
2013-10-04 18:33:37 +04:00
|
|
|
continue;
|
|
|
|
}
|
LDAP Wizard Overhaul
wizard refactor
reimplement save spinners and cursor
implement Port detector
introduced detector queue, added base dn detector
disable input fields when detectors are running
introduce spinners for fields that are being updated by detector
cache jq element objects
consolidate processing of detector results in generic / abstract base class
display notification if a detector discovered a problem
don't run base dn detector if a base is configured
reset detector queue on configuration switch
implement functionality check and update of status indicator
document ConfigModel
jsdoc for controller and main view
more documentation
implement the user filter tab view
so far the multiselects get initialized (not filled yet) and the mode can be switched.
mode is also restored.
reintroduce filter switch confirmation in admin XP mode
new detector for user object classes. so we also load user object classes if necessary and are able to save and show the setting.
multiselect trigger save actions now on close only
show spinners automatically, when a detector is running
20k limit for object classes preselection test
adjust wordings, fix grammar
add group (for users tab) detector
also includes wording fixes
error presentation moved from detectors to view, where it belongs
add info label to users page
missing wording changes
show effective LDAP filter in Assisted Mode
add user filter detector
implement count button for users and limit all count actions to 1001 for performance reasons
make port field a bit bigger. not perfect though.
do not detect port automatically
implement login filter tab view
only load features in assisted mode and don't enable assisted fields while in raw mode
add tooltips on login filter checkbox options for better understanding
permanently show filter on login tab
and also compile login filter in assisted mode
test/verify button on login attributes tab, with backend changes.
only run wizard requests if your an active tab. also run compile filter requests when switching to assisted mode
underline toggle filter links to stress that they are clickable
unity user and group tab functionality in common abstract class, add group filter tab view. only detectors and template adjustments left to have group tab implementation complete
add object class and group detector for groups as well as filter composer
show ldap filter permanently on groups tab
introduce input element that can deal better with many groups, will be used with > 40
fix disabling complex group chooser while detection is running
hide complex group chooser on config switch
fix few more issues with complex chooser
make complex group chooser available on Users tab as well
detect base dn improvements/changes:
- do not look for Base DN automatically, offer a button instead
- fix for alternative way to detect a base dn (if agent dn is not given)
- do not trigger filter composers on config switch
Changes with configuration chooser controls
- "New" was removed out of the configuration list
- and split into buttons "add" and "copy"
- delete button is also now an icon
add test button for Base DN
reimplement advanced tab. The save button is gone.
reimplement expert tab
remove unused methods
implement mail attribute detector
implement user display name attribute detection
implement member group association detector
replace text input with textarea for raw filter input
finish functionality check
auto-enable good configurations, as it was before
cleanup
move save confirmation handling to base class, reduces code duplication
enable tabs only if no running save processes are left.
move onConfigLoaded to base class, avoids code duplication
simplify, save LOCs
Test Configuration button to be dealt with in main view as it is a cross-tab element
require detectorQueue in constructor
cleanup
put bootstrap into a function and thus make it testable
get rid of old stuff
2015-03-03 13:56:03 +03:00
|
|
|
// 20k limit for performance and reason
|
|
|
|
$rr = $this->ldap->search($cr, $base, $filter, array($attr), 0, 20000);
|
2013-10-04 18:33:37 +04:00
|
|
|
if(!$this->ldap->isResource($rr)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$entries = $this->ldap->countEntries($cr, $rr);
|
|
|
|
$getEntryFunc = 'firstEntry';
|
|
|
|
if(($entries !== false) && ($entries > 0)) {
|
|
|
|
if(!is_null($maxF) && $entries > $maxEntries) {
|
|
|
|
$maxEntries = $entries;
|
|
|
|
$maxF = $filter;
|
|
|
|
}
|
2014-03-20 16:58:08 +04:00
|
|
|
$dnReadCount = 0;
|
2013-10-04 18:33:37 +04:00
|
|
|
do {
|
|
|
|
$entry = $this->ldap->$getEntryFunc($cr, $rr);
|
2014-03-21 01:59:41 +04:00
|
|
|
$getEntryFunc = 'nextEntry';
|
2013-10-04 18:33:37 +04:00
|
|
|
if(!$this->ldap->isResource($entry)) {
|
|
|
|
continue 2;
|
|
|
|
}
|
2014-05-16 20:03:15 +04:00
|
|
|
$rr = $entry; //will be expected by nextEntry next round
|
2013-10-04 18:33:37 +04:00
|
|
|
$attributes = $this->ldap->getAttributes($cr, $entry);
|
|
|
|
$dn = $this->ldap->getDN($cr, $entry);
|
|
|
|
if($dn === false || in_array($dn, $dnRead)) {
|
|
|
|
continue;
|
|
|
|
}
|
2013-10-08 03:19:37 +04:00
|
|
|
$newItems = array();
|
2013-10-04 18:33:37 +04:00
|
|
|
$state = $this->getAttributeValuesFromEntry($attributes,
|
|
|
|
$attr,
|
2013-10-08 03:19:37 +04:00
|
|
|
$newItems);
|
2014-03-20 16:58:08 +04:00
|
|
|
$dnReadCount++;
|
2013-10-08 03:19:37 +04:00
|
|
|
$foundItems = array_merge($foundItems, $newItems);
|
|
|
|
$this->resultCache[$dn][$attr] = $newItems;
|
2013-10-04 18:33:37 +04:00
|
|
|
$dnRead[] = $dn;
|
2014-03-20 16:58:08 +04:00
|
|
|
} while(($state === self::LRESULT_PROCESSED_SKIP
|
|
|
|
|| $this->ldap->isResource($entry))
|
2014-03-21 01:57:50 +04:00
|
|
|
&& ($dnReadLimit === 0 || $dnReadCount < $dnReadLimit));
|
2013-10-04 18:33:37 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-08 03:19:37 +04:00
|
|
|
return array_unique($foundItems);
|
2013-10-04 18:33:37 +04:00
|
|
|
}
|
|
|
|
|
2013-10-07 19:56:45 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* determines if and which $attr are available on the LDAP server
|
2014-02-06 19:30:58 +04:00
|
|
|
* @param string[] $objectclasses the objectclasses to use as search filter
|
|
|
|
* @param string $attr the attribute to look for
|
2014-02-19 12:31:54 +04:00
|
|
|
* @param string $dbkey the dbkey of the setting the feature is connected to
|
|
|
|
* @param string $confkey the confkey counterpart for the $dbkey as used in the
|
2013-10-07 19:56:45 +04:00
|
|
|
* Configuration class
|
2014-05-13 15:29:25 +04:00
|
|
|
* @param bool $po whether the objectClass with most result entries
|
2013-10-07 19:56:45 +04:00
|
|
|
* shall be pre-selected via the result
|
2015-01-16 21:31:15 +03:00
|
|
|
* @return array|false list of found items.
|
2014-05-11 17:17:27 +04:00
|
|
|
* @throws \Exception
|
2013-10-07 19:56:45 +04:00
|
|
|
*/
|
|
|
|
private function determineFeature($objectclasses, $attr, $dbkey, $confkey, $po = false) {
|
|
|
|
$cr = $this->getConnection();
|
|
|
|
if(!$cr) {
|
2013-11-01 13:19:44 +04:00
|
|
|
throw new \Exception('Could not connect to LDAP');
|
2013-10-07 19:56:45 +04:00
|
|
|
}
|
|
|
|
$p = 'objectclass=';
|
|
|
|
foreach($objectclasses as $key => $value) {
|
|
|
|
$objectclasses[$key] = $p.$value;
|
|
|
|
}
|
|
|
|
$maxEntryObjC = '';
|
2014-03-20 16:58:08 +04:00
|
|
|
|
|
|
|
//how deep to dig?
|
|
|
|
//When looking for objectclasses, testing few entries is sufficient,
|
2014-06-11 15:35:35 +04:00
|
|
|
$dig = 3;
|
2014-03-20 16:58:08 +04:00
|
|
|
|
2013-10-07 19:56:45 +04:00
|
|
|
$availableFeatures =
|
|
|
|
$this->cumulativeSearchOnAttribute($objectclasses, $attr,
|
2014-06-11 15:35:35 +04:00
|
|
|
$dig, $maxEntryObjC);
|
2013-10-07 19:56:45 +04:00
|
|
|
if(is_array($availableFeatures)
|
|
|
|
&& count($availableFeatures) > 0) {
|
2013-10-08 13:19:55 +04:00
|
|
|
natcasesort($availableFeatures);
|
|
|
|
//natcasesort keeps indices, but we must get rid of them for proper
|
|
|
|
//sorting in the web UI. Therefore: array_values
|
|
|
|
$this->result->addOptions($dbkey, array_values($availableFeatures));
|
2013-10-07 19:56:45 +04:00
|
|
|
} else {
|
|
|
|
throw new \Exception(self::$l->t('Could not find the desired feature'));
|
|
|
|
}
|
|
|
|
|
|
|
|
$setFeatures = $this->configuration->$confkey;
|
|
|
|
if(is_array($setFeatures) && !empty($setFeatures)) {
|
|
|
|
//something is already configured? pre-select it.
|
|
|
|
$this->result->addChange($dbkey, $setFeatures);
|
2016-09-23 01:30:57 +03:00
|
|
|
} else if ($po && $maxEntryObjC !== '') {
|
2013-10-07 19:56:45 +04:00
|
|
|
//pre-select objectclass with most result entries
|
|
|
|
$maxEntryObjC = str_replace($p, '', $maxEntryObjC);
|
2013-10-10 00:00:36 +04:00
|
|
|
$this->applyFind($dbkey, $maxEntryObjC);
|
2013-10-10 21:37:12 +04:00
|
|
|
$this->result->addChange($dbkey, $maxEntryObjC);
|
2013-10-07 19:56:45 +04:00
|
|
|
}
|
|
|
|
|
2013-10-08 03:19:37 +04:00
|
|
|
return $availableFeatures;
|
2013-10-07 19:56:45 +04:00
|
|
|
}
|
|
|
|
|
2013-10-04 18:33:37 +04:00
|
|
|
/**
|
2014-05-19 19:50:53 +04:00
|
|
|
* appends a list of values fr
|
2014-05-13 15:29:25 +04:00
|
|
|
* @param resource $result the return value from ldap_get_attributes
|
2014-04-14 19:39:29 +04:00
|
|
|
* @param string $attribute the attribute values to look for
|
2014-05-13 15:29:25 +04:00
|
|
|
* @param array &$known new values will be appended here
|
2013-10-04 18:33:37 +04:00
|
|
|
* @return int, state on of the class constants LRESULT_PROCESSED_OK,
|
|
|
|
* LRESULT_PROCESSED_INVALID or LRESULT_PROCESSED_SKIP
|
|
|
|
*/
|
|
|
|
private function getAttributeValuesFromEntry($result, $attribute, &$known) {
|
|
|
|
if(!is_array($result)
|
|
|
|
|| !isset($result['count'])
|
|
|
|
|| !$result['count'] > 0) {
|
|
|
|
return self::LRESULT_PROCESSED_INVALID;
|
|
|
|
}
|
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
// strtolower on all keys for proper comparison
|
2013-10-04 18:33:37 +04:00
|
|
|
$result = \OCP\Util::mb_array_change_key_case($result);
|
|
|
|
$attribute = strtolower($attribute);
|
|
|
|
if(isset($result[$attribute])) {
|
|
|
|
foreach($result[$attribute] as $key => $val) {
|
|
|
|
if($key === 'count') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(!in_array($val, $known)) {
|
|
|
|
$known[] = $val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return self::LRESULT_PROCESSED_OK;
|
|
|
|
} else {
|
|
|
|
return self::LRESULT_PROCESSED_SKIP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
/**
|
|
|
|
* @return bool|mixed
|
|
|
|
*/
|
2013-09-27 20:30:59 +04:00
|
|
|
private function getConnection() {
|
2013-10-08 03:19:37 +04:00
|
|
|
if(!is_null($this->cr)) {
|
2013-12-03 19:37:11 +04:00
|
|
|
return $this->cr;
|
2013-10-08 03:19:37 +04:00
|
|
|
}
|
2015-10-29 18:21:02 +03:00
|
|
|
|
2015-07-28 13:14:05 +03:00
|
|
|
$cr = $this->ldap->connect(
|
|
|
|
$this->configuration->ldapHost,
|
|
|
|
$this->configuration->ldapPort
|
|
|
|
);
|
2013-09-27 20:30:59 +04:00
|
|
|
|
2013-10-10 21:37:12 +04:00
|
|
|
$this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3);
|
2014-02-05 13:29:09 +04:00
|
|
|
$this->ldap->setOption($cr, LDAP_OPT_REFERRALS, 0);
|
2013-10-10 21:37:12 +04:00
|
|
|
$this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT);
|
|
|
|
if($this->configuration->ldapTLS === 1) {
|
|
|
|
$this->ldap->startTls($cr);
|
2013-09-27 20:30:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
$lo = @$this->ldap->bind($cr,
|
|
|
|
$this->configuration->ldapAgentName,
|
|
|
|
$this->configuration->ldapAgentPassword);
|
|
|
|
if($lo === true) {
|
2013-10-08 03:19:37 +04:00
|
|
|
$this->$cr = $cr;
|
2013-09-27 20:30:59 +04:00
|
|
|
return $cr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
2013-09-27 20:30:59 +04:00
|
|
|
private function getDefaultLdapPortSettings() {
|
|
|
|
static $settings = array(
|
|
|
|
array('port' => 7636, 'tls' => false),
|
|
|
|
array('port' => 636, 'tls' => false),
|
|
|
|
array('port' => 7389, 'tls' => true),
|
|
|
|
array('port' => 389, 'tls' => true),
|
|
|
|
array('port' => 7389, 'tls' => false),
|
|
|
|
array('port' => 389, 'tls' => false),
|
|
|
|
);
|
|
|
|
return $settings;
|
|
|
|
}
|
|
|
|
|
2014-05-11 17:17:27 +04:00
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
2013-09-27 20:30:59 +04:00
|
|
|
private function getPortSettingsToTry() {
|
|
|
|
//389 ← LDAP / Unencrypted or StartTLS
|
|
|
|
//636 ← LDAPS / SSL
|
|
|
|
//7xxx ← UCS. need to be checked first, because both ports may be open
|
|
|
|
$host = $this->configuration->ldapHost;
|
|
|
|
$port = intval($this->configuration->ldapPort);
|
|
|
|
$portSettings = array();
|
|
|
|
|
|
|
|
//In case the port is already provided, we will check this first
|
|
|
|
if($port > 0) {
|
|
|
|
$hostInfo = parse_url($host);
|
2013-11-11 18:16:54 +04:00
|
|
|
if(!(is_array($hostInfo)
|
2013-09-27 20:30:59 +04:00
|
|
|
&& isset($hostInfo['scheme'])
|
2013-11-11 18:16:54 +04:00
|
|
|
&& stripos($hostInfo['scheme'], 'ldaps') !== false)) {
|
2013-09-27 20:30:59 +04:00
|
|
|
$portSettings[] = array('port' => $port, 'tls' => true);
|
|
|
|
}
|
|
|
|
$portSettings[] =array('port' => $port, 'tls' => false);
|
|
|
|
}
|
|
|
|
|
|
|
|
//default ports
|
|
|
|
$portSettings = array_merge($portSettings,
|
|
|
|
$this->getDefaultLdapPortSettings());
|
|
|
|
|
|
|
|
return $portSettings;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-05-11 18:28:50 +04:00
|
|
|
}
|