First stage of new Wizard, neither feature complete nor ready

This commit is contained in:
Arthur Schiwon 2013-09-27 18:30:59 +02:00
parent 652caa1c88
commit 53db1fe5ac
10 changed files with 688 additions and 15 deletions

View File

@ -0,0 +1,83 @@
<?php
/**
* ownCloud - user_ldap
*
* @author Arthur Schiwon
* @copyright 2013 Arthur Schiwon blizzz@owncloud.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Check user and app status
OCP\JSON::checkAdminUser();
OCP\JSON::checkAppEnabled('user_ldap');
OCP\JSON::callCheck();
$l=OC_L10N::get('user_ldap');
if(!isset($_POST['action'])) {
\OCP\JSON::error(array('message' => $l->t('No action specified')));
}
$action = $_POST['action'];
if(!isset($_POST['ldap_serverconfig_chooser'])) {
\OCP\JSON::error(array('message' => $l->t('No configuration specified')));
}
$prefix = $_POST['ldap_serverconfig_chooser'];
$ldapWrapper = new OCA\user_ldap\lib\LDAP();
$configuration = new \OCA\user_ldap\lib\Configuration($prefix);
$wizard = new \OCA\user_ldap\lib\Wizard($configuration, $ldapWrapper);
switch($action) {
case 'guessPortAndTLS':
try {
$result = $wizard->$action();
if($result !== false) {
OCP\JSON::success($result->getResultArray());
exit;
}
} catch (\Exception $e) {
\OCP\JSON::error(array('message' => $e->getMessage()));
exit;
}
\OCP\JSON::error();
exit;
break;
case 'save':
$key = isset($_POST['cfgkey']) ? $_POST['cfgkey'] : false;
$val = isset($_POST['cfgval']) ? $_POST['cfgval'] : null;
if($key === false || is_null($val)) {
\OCP\JSON::error(array('message' => $l->t('No data specified')));
exit;
}
$cfg = array($key => $val);
$setParameters = array();
$configuration->setConfiguration($cfg, $setParameters);
if(!in_array($key, $setParameters)) {
\OCP\JSON::error(array('message' => $l->t($key.' Could not set configuration '.$setParameters[0])));
exit;
}
$configuration->saveConfiguration();
OCP\JSON::success();
break;
default:
//TODO: return 4xx error
break;
}

View File

@ -1,3 +1,69 @@
.table {
display: table;
}
.tablecell {
display: table-cell !important;
}
.tablerow {
display: table-row;
}
.tablerow input, .tablerow textarea {
width: 100% !important;
}
.tablerow textarea {
height: 15px;
}
.hidden {
visibility: hidden;
}
.ldapSettingsTabs {
float: right !important;
}
.ldapWizardControls {
width: 60%;
text-align: right;
}
.ldapWizardInfo {
width: 100% !important;
height: 50px;
background-color: lightyellow;
border-radius: 0.5em;
padding: 0.6em 0.5em 0.4em !important;
margin-bottom: 0.3em;
}
#ldapWizard1 .hostPortCombinator {
width: 60%;
display: table;
}
#ldapWizard1 .hostPortCombinator div span {
width: 7%;
display: table-cell;
text-align: right;
}
#ldapWizard1 .host {
width: 96.5% !important;
}
.ldapIndent {
margin-left: 50px;
}
.ldapwarning {
margin-left: 1.4em;
color: #FF3B3B;
}
#ldap fieldset p label {
width: 20%;
max-width: 200px;
@ -16,12 +82,3 @@
#ldap fieldset p input[type=checkbox] {
vertical-align: bottom;
}
.ldapIndent {
margin-left: 50px;
}
.ldapwarning {
margin-left: 1.4em;
color: #FF3B3B;
}

View File

@ -30,6 +30,7 @@ var LdapConfiguration = {
// assign the value
$('#'+configkey).val(configvalue);
});
LdapWizard.init();
}
}
);
@ -91,6 +92,7 @@ var LdapConfiguration = {
$('#ldap_serverconfig_chooser option:selected').removeAttr('selected');
var html = '<option value="'+result.configPrefix+'" selected="selected">'+$('#ldap_serverconfig_chooser option').length+'. Server</option>';
$('#ldap_serverconfig_chooser option:last').before(html);
LdapWizard.init();
} else {
OC.dialogs.alert(
result.message,
@ -122,12 +124,98 @@ var LdapConfiguration = {
}
};
var LdapWizard = {
checkPortInfoShown: false,
changeIndicators: {},
ajax: function(param, fnOnSuccess, fnOnError) {
$.post(
OC.filePath('user_ldap','ajax','wizard.php'),
param,
function(result) {
if(result.status == 'success') {
fnOnSuccess(result);
} else {
fnOnError(result);
}
}
);
},
applyChanges: function (result) {
for (id in result.changes) {
$('#'+id).val(result.changes[id]);
}
},
checkPort: function() {
host = $('#ldap_host').val();
user = $('#ldap_dn').val();
pass = $('#ldap_agent_password').val();
if(host && user && pass) {
param = 'action=guessPortAndTLS'+
'&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
LdapWizard.ajax(param,
function(result) {
LdapWizard.applyChanges(result);
if($('#ldap_port').val()) {
$('#ldap_port').removeClass('hidden');
if(LdapWizard.checkPortInfoShown) {
$('#ldapWizard1 .ldapWizardInfo').addClass('hidden');
LdapWizard.checkPortInfoShown = false;
}
}
},
function (result) {
$('#ldap_port').removeClass('hidden');
$('#ldapWizard1 .ldapWizardInfo').text(t('user_ldap',
'Please specify a port'));
$('#ldapWizard1 .ldapWizardInfo').removeClass('hidden');
LdapWizard.checkPortInfoShown = true;
}
);
}
},
init: function() {
if($('#ldap_port').val()) {
$('#ldap_port').removeClass('hidden');
}
},
save: function(inputObj) {
param = 'cfgkey='+inputObj.id+
'&cfgval='+$(inputObj).val()+
'&action=save'+
'&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
$.post(
OC.filePath('user_ldap','ajax','wizard.php'),
param,
function(result) {
if(result.status == 'success') {
if(inputObj.id == 'ldap_host'
|| inputObj.id == 'ldap_dn'
|| inputObj.id == 'ldap_agent_password') {
LdapWizard.checkPort();
}
} else {
// alert('Oooooooooooh :(');
}
}
);
}
};
$(document).ready(function() {
$('#ldapAdvancedAccordion').accordion({ heightStyle: 'content', animate: 'easeInOutCirc'});
$('#ldapSettings').tabs();
$('#ldap_submit').button();
$('#ldap_action_test_connection').button();
$('#ldap_action_delete_configuration').button();
$('.lwautosave').change(function() { LdapWizard.save(this); });
LdapConfiguration.refreshConfig();
$('#ldap_action_test_connection').click(function(event){
event.preventDefault();

View File

@ -0,0 +1,267 @@
<?php
/**
* ownCloud LDAP Wizard
*
* @author Arthur Schiwon
* @copyright 2013 Arthur Schiwon blizzz@owncloud.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\user_ldap\lib;
class Wizard extends LDAPUtility {
static protected $l;
protected $configuration;
protected $result;
/**
* @brief Constructor
* @param $configuration an instance of Configuration
* @param $ldap an instance of ILDAPWrapper
*/
public function __construct(Configuration $configuration, ILDAPWrapper $ldap) {
parent::__construct($ldap);
$this->configuration = $configuration;
if(is_null(Wizard::$l)) {
Wizard::$l = \OC_L10N::get('user_ldap');
}
$this->result = new WizardResult;
}
public function __destruct() {
if($this->result->hasChanges()) {
$this->configuration->saveConfiguration();
}
}
/**
* Tries to determine the port, requires given Host, User DN and Password
* @returns mixed WizardResult on success, false otherwise
*/
public function guessPortAndTLS() {
if(!$this->checkRequirements(array('ldapHost',
'ldapAgentName',
'ldapAgentPassword'))) {
return false;
}
$this->checkHost();
$portSettings = $this->getPortSettingsToTry();
file_put_contents('/tmp/ps', print_r($portSettings, true).PHP_EOL, FILE_APPEND);
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
if($this->connectAndBind($p, $t) === true) {
$config = array('ldapPort' => $p,
'ldapTLS' => intval($t)
);
$this->configuration->setConfiguration($config);
\OCP\Util::writeLog('user_ldap', 'Wiz: detected Port '. $p, \OCP\Util::DEBUG);
$this->result->addChange('ldap_port', $p);
$this->result->addChange('ldap_tls', intval($t));
// $this->result->addSpecific('port', $p);
return $this->result;
}
}
//custom port, undetected (we do not brute force)
return false;
}
public function guessBaseDN() {
if(!$this->checkRequirements(array('ldapHost',
'ldapAgentName',
'ldapAgentPassword',
'ldapPort',
))) {
return false;
}
$cr = $this->getConnection();
if(!$cr) {
return false;
}
}
/**
* @brief Checks, whether a port was entered in the Host configuration
* 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);
$config = array('ldapHost' => $host,
'ldapPort' => $port,
);
$this->result->addChange('ldap_host', $host);
$this->result->addChange('ldap_port', $port);
$this->configuration->setConfiguration($config);
}
}
/**
* Connects and Binds to an LDAP Server
* @param $port the port to connect with
* @param $tls whether startTLS is to be used
* @return
*/
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) {
throw new \Exception($this->l->t('Invalid Host'));
}
if(isset($hostInfo['scheme'])) {
if(isset($hostInfo['port'])) {
//problem
} else {
$host .= ':' . $port;
}
}
\OCP\Util::writeLog('user_ldap', 'Wiz: Attempting to connect ', \OCP\Util::DEBUG);
$cr = $this->ldap->connect($host, $port);
if(!is_resource($cr)) {
throw new \Exception($this->l->t('Invalid Host'));
}
\OCP\Util::writeLog('user_ldap', 'Wiz: Setting LDAP Options ', \OCP\Util::DEBUG);
//set LDAP options
if($this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3)) {
if($tls) {
$this->ldap->startTls($cr);
}
}
\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);
if($login === true) {
$this->ldap->unbind($cr);
if($ncc) {
throw new \Exception('Certificate cannot be validated.');
}
\OCP\Util::writeLog('user_ldap', 'Wiz: Bind succesfull with Port '. $port, \OCP\Util::DEBUG);
return true;
}
$errno = $this->ldap->errno($cr);
$error = ldap_error($cr);
$this->ldap->unbind($cr);
if($errno === -1 || ($errno === 2 && $ncc)) {
//host, port or TLS wrong
return false;
} else if ($errno === 2) {
return $this->connectAndBind($port, $tls, true);
}
throw new \Exception($error);
}
private function checkRequirements($reqs) {
foreach($reqs as $option) {
$value = $this->configuration->$option;
if(empty($value)) {
return false;
}
}
return true;
}
private function getConnection() {
$cr = $this->ldap->connect(
$this->configuration->ldapHost.':'.$this->configuration->ldapPort,
$this->configuration->ldapPort);
if($this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3)) {
if($this->configuration->ldapTLS === 1) {
$this->ldap->startTls($cr);
}
}
$lo = @$this->ldap->bind($cr,
$this->configuration->ldapAgentName,
$this->configuration->ldapAgentPassword);
if($lo === true) {
return $cr;
}
return false;
}
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;
}
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);
if(is_array($hostInfo)
&& isset($hostInfo['scheme'])
&& stripos($hostInfo['scheme'], 'ldaps') === false) {
$portSettings[] = array('port' => $port, 'tls' => true);
}
$portSettings[] =array('port' => $port, 'tls' => false);
}
//default ports
$portSettings = array_merge($portSettings,
$this->getDefaultLdapPortSettings());
return $portSettings;
}
}

View File

@ -0,0 +1,50 @@
<?php
/**
* ownCloud LDAP Wizard Result
*
* @author Arthur Schiwon
* @copyright 2013 Arthur Schiwon blizzz@owncloud.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\user_ldap\lib;
class WizardResult {
protected $changes = array();
protected $specifics = array();
public function addChange($key, $value) {
$this->changes[$key] = $value;
}
public function hasChanges() {
return count($this->changes) > 0;
}
public function addSpecific($key, $value) {
$this->specifics[$key] = $value;
}
public function getResultArray() {
$result = array();
$result['changes'] = $this->changes;
foreach($this->specifics as $key => $value) {
$result[$key] = $value;
}
return $result;
}
}

View File

@ -33,8 +33,28 @@ $tmpl = new OCP\Template('user_ldap', 'settings');
$prefixes = \OCA\user_ldap\lib\Helper::getServerConfigurationPrefixes();
$hosts = \OCA\user_ldap\lib\Helper::getServerConfigurationHosts();
$wizardHtml = '';
$toc = array();
$wControls = new OCP\Template('user_ldap', 'part.wizardcontrols');
$wControls = $wControls->fetchPage();
$sControls = new OCP\Template('user_ldap', 'part.settingcontrols');
$sControls = $sControls->fetchPage();
$wizard1 = new OCP\Template('user_ldap', 'part.wizard-server');
$wizard1->assign('serverConfigurationPrefixes', $prefixes);
$wizard1->assign('serverConfigurationHosts', $hosts);
$wizard1->assign('wizardControls', $wControls);
$wizardHtml .= $wizard1->fetchPage();
$toc['#ldapWizard1'] = 'Server';
$tmpl->assign('tabs', $wizardHtml);
$tmpl->assign('toc', $toc);
$tmpl->assign('serverConfigurationPrefixes', $prefixes);
$tmpl->assign('serverConfigurationHosts', $hosts);
$tmpl->assign('settingControls', $sControls);
// assign default values
$config = new \OCA\user_ldap\lib\Configuration('', false);

View File

@ -0,0 +1,12 @@
<div class="ldapSettingControls">
<input id="ldap_submit" type="submit" value="Save" />
<button id="ldap_action_test_connection" name="ldap_action_test_connection">
<?php p($l->t('Test Configuration'));?>
</button>
<a href="<?php p($theme->getDocBaseUrl()); ?>/server/5.0/admin_manual/auth_ldap.html"
target="_blank">
<img src="<?php print_unescaped(OCP\Util::imagePath('', 'actions/info.png')); ?>"
style="height:1.75ex" />
<?php p($l->t('Help'));?>
</a>
</div>

View File

@ -0,0 +1,76 @@
<fieldset id="ldapWizard1">
<p>
<select id="ldap_serverconfig_chooser" name="ldap_serverconfig_chooser">
<?php if(count($_['serverConfigurationPrefixes']) === 0 ) {
?>
<option value="" selected>1. Server</option>');
<?php
} else {
$i = 1;
$sel = ' selected';
foreach($_['serverConfigurationPrefixes'] as $prefix) {
?>
<option value="<?php p($prefix); ?>"<?php p($sel); $sel = ''; ?>><?php p($i++); ?>. Server: <?php p($_['serverConfigurationHosts'][$prefix]); ?></option>
<?php
}
}
?>
<option value="NEW"><?php p($l->t('Add Server Configuration'));?></option>
</select>
<button id="ldap_action_delete_configuration"
name="ldap_action_delete_configuration">Delete Configuration</button>
</p>
<div class="hostPortCombinator">
<div class="tablerow">
<div class="tablecell">
<div class="table">
<input type="text" class="host tablecell lwautosave" id="ldap_host"
name="ldap_host"
data-default="<?php p($_['ldap_host_default']); ?>"
placeholder="<?php p($l->t('Host'));?>"
title="<?php p($l->t('You can omit the protocol, except you require SSL. Then start with ldaps://'));?>"
/>
<span>
<input type="number" id="ldap_port" name="ldap_port"
class="hidden lwautosave"
data-default="<?php p($_['ldap_port_default']); ?>"
placeholder="<?php p($l->t('Port'));?>" />
</span>
</div>
</div>
</div>
<div class="tablerow">
<input type="text" id="ldap_dn" name="ldap_dn"
class="tablecell lwautosave"
data-default="<?php p($_['ldap_dn_default']); ?>"
placeholder="<?php p($l->t('User DN'));?>"
title="<?php p($l->t('The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty.'));?>"
/>
</div>
<div class="tablerow">
<input type="password" id="ldap_agent_password"
class="tablecell lwautosave" name="ldap_agent_password"
data-default="<?php p($_['ldap_agent_password_default']); ?>"
placeholder="<?php p($l->t('Password'));?>"
title="<?php p($l->t('For anonymous access, leave DN and Password empty.'));?>"
/>
</div>
<div class="tablerow">
<textarea id="ldap_base" name="ldap_base"
class="tablecell hidden lwautosave"
placeholder="<?php p($l->t('One Base DN per line'));?>"
title="<?php p($l->t('You can specify Base DN for users and groups in the Advanced tab'));?>"
data-default="<?php p($_['ldap_base_default']); ?>" >
</textarea>
</div>
<div class="tablerow">
<div class="tablecell ldapWizardInfo hidden">&nbsp;
</div>
</div>
</div>
<?php print_unescaped($_['wizardControls']); ?>
</fieldset>

View File

@ -0,0 +1,14 @@
<div class="ldapWizardControls">
<button id="ldap_action_back" name="ldap_action_back" class="hidden">
<?php p($l->t('Back'));?>
</button>
<button id="ldap_action_continue" name="ldap_action_continue">
<?php p($l->t('Continue'));?>
</button>
<a href="<?php p($theme->getDocBaseUrl()); ?>/server/5.0/admin_manual/auth_ldap.html"
target="_blank">
<img src="<?php print_unescaped(OCP\Util::imagePath('', 'actions/info.png')); ?>"
style="height:1.75ex" />
<?php p($l->t('Help'));?>
</a>
</div>

View File

@ -1,9 +1,12 @@
<form id="ldap" action="#" method="post">
<div id="ldapSettings" class="personalblock">
<ul>
<li><a href="#ldapSettings-1">LDAP Basic</a></li>
<li><a href="#ldapSettings-2">Advanced</a></li>
<li><a href="#ldapSettings-3">Expert</a></li>
<?php foreach($_['toc'] as $id => $title) { ?>
<li><a href="<?php p($id); ?>"><?php p($title); ?></a></li>
<?php } ?>
<li class="ldapSettingsTabs"><a href="#ldapSettings-3">Expert</a></li>
<li class="ldapSettingsTabs"><a href="#ldapSettings-2">Advanced</a></li>
<li class="ldapSettingsTabs"><a href="#ldapSettings-1">LDAP Basic</a></li>
</ul>
<?php if(OCP\App::isEnabled('user_webdavauth')) {
print_unescaped('<p class="ldapwarning">'.$l->t('<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them.').'</p>');
@ -12,6 +15,7 @@
print_unescaped('<p class="ldapwarning">'.$l->t('<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it.').'</p>');
}
?>
<?php print_unescaped($_['tabs']); ?>
<fieldset id="ldapSettings-1">
<p><label for="ldap_serverconfig_chooser"><?php p($l->t('Server configuration'));?></label>
<select id="ldap_serverconfig_chooser" name="ldap_serverconfig_chooser">
@ -60,6 +64,7 @@
<input type="text" id="ldap_group_filter" name="ldap_group_filter"
data-default="<?php p($_['ldap_group_filter_default']); ?>"
title="<?php p($l->t('Defines the filter to apply, when retrieving groups (no placeholders). Example: "objectClass=posixGroup"'));?>" /></p>
<?php print_unescaped($_['settingControls']); ?>
</fieldset>
<fieldset id="ldapSettings-2">
<div id="ldapAdvancedAccordion">
@ -93,6 +98,7 @@
<p><label for="home_folder_naming_rule"><?php p($l->t('User Home Folder Naming Rule'));?></label><input type="text" id="home_folder_naming_rule" name="home_folder_naming_rule" title="<?php p($l->t('Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute.'));?>" data-default="<?php p($_['home_folder_naming_rule_default']); ?>" /></p>
</div>
</div>
<?php print_unescaped($_['settingControls']); ?>
</fieldset>
<fieldset id="ldapSettings-3">
<p><strong><?php p($l->t('Internal Username'));?></strong></p>
@ -105,8 +111,8 @@
<p><strong><?php p($l->t('Username-LDAP User Mapping'));?></strong></p>
<p class="ldapIndent"><?php p($l->t('Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage.'));?></p>
<p class="ldapIndent"><button id="ldap_action_clear_user_mappings" name="ldap_action_clear_user_mappings"><?php p($l->t('Clear Username-LDAP User Mapping'));?></button><br/><button id="ldap_action_clear_group_mappings" name="ldap_action_clear_group_mappings"><?php p($l->t('Clear Groupname-LDAP Group Mapping'));?></button></p>
<?php print_unescaped($_['settingControls']); ?>
</fieldset>
<input id="ldap_submit" type="submit" value="Save" /> <button id="ldap_action_test_connection" name="ldap_action_test_connection"><?php p($l->t('Test Configuration'));?></button> <a href="<?php p($theme->getDocBaseUrl()); ?>/server/5.0/admin_manual/auth_ldap.html" target="_blank"><img src="<?php print_unescaped(OCP\Util::imagePath('', 'actions/info.png')); ?>" style="height:1.75ex" /> <?php p($l->t('Help'));?></a>
</div>
</form>