Merge pull request #15492 from owncloud/ldap-wizard-overhaul
LDAP Wizard Overhaul
This commit is contained in:
commit
c6151053ba
|
@ -32,4 +32,17 @@ sort($serverConnections);
|
||||||
$lk = array_pop($serverConnections);
|
$lk = array_pop($serverConnections);
|
||||||
$ln = intval(str_replace('s', '', $lk));
|
$ln = intval(str_replace('s', '', $lk));
|
||||||
$nk = 's'.str_pad($ln+1, 2, '0', STR_PAD_LEFT);
|
$nk = 's'.str_pad($ln+1, 2, '0', STR_PAD_LEFT);
|
||||||
OCP\JSON::success(array('configPrefix' => $nk));
|
|
||||||
|
$resultData = array('configPrefix' => $nk);
|
||||||
|
|
||||||
|
if(isset($_POST['copyConfig'])) {
|
||||||
|
$originalConfig = new \OCA\user_ldap\lib\Configuration($_POST['copyConfig']);
|
||||||
|
$newConfig = new \OCA\user_ldap\lib\Configuration($nk, false);
|
||||||
|
$newConfig->setConfiguration($originalConfig->getConfiguration());
|
||||||
|
$newConfig->saveConfiguration();
|
||||||
|
} else {
|
||||||
|
$configuration = new \OCA\user_ldap\lib\Configuration($nk, false);
|
||||||
|
$resultData['defaults'] = $configuration->getDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
OCP\JSON::success($resultData);
|
||||||
|
|
|
@ -72,13 +72,11 @@ switch($action) {
|
||||||
case 'determineGroupsForGroups':
|
case 'determineGroupsForGroups':
|
||||||
case 'determineAttributes':
|
case 'determineAttributes':
|
||||||
case 'getUserListFilter':
|
case 'getUserListFilter':
|
||||||
case 'getLoginFilterMode':
|
|
||||||
case 'getUserLoginFilter':
|
case 'getUserLoginFilter':
|
||||||
case 'getUserFilterMode':
|
|
||||||
case 'getGroupFilter':
|
case 'getGroupFilter':
|
||||||
case 'getGroupFilterMode':
|
|
||||||
case 'countUsers':
|
case 'countUsers':
|
||||||
case 'countGroups':
|
case 'countGroups':
|
||||||
|
case 'countInBaseDN':
|
||||||
try {
|
try {
|
||||||
$result = $wizard->$action();
|
$result = $wizard->$action();
|
||||||
if($result !== false) {
|
if($result !== false) {
|
||||||
|
@ -93,6 +91,23 @@ switch($action) {
|
||||||
exit;
|
exit;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'testLoginName': {
|
||||||
|
try {
|
||||||
|
$loginName = $_POST['ldap_test_loginname'];
|
||||||
|
$result = $wizard->$action($loginName);
|
||||||
|
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':
|
case 'save':
|
||||||
$key = isset($_POST['cfgkey']) ? $_POST['cfgkey'] : false;
|
$key = isset($_POST['cfgkey']) ? $_POST['cfgkey'] : false;
|
||||||
$val = isset($_POST['cfgval']) ? $_POST['cfgval'] : null;
|
$val = isset($_POST['cfgval']) ? $_POST['cfgval'] : null;
|
||||||
|
@ -115,6 +130,6 @@ switch($action) {
|
||||||
OCP\JSON::success();
|
OCP\JSON::success();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//TODO: return 4xx error
|
\OCP\JSON::error(array('message' => $l->t('Action does not exist')));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.5.0
|
0.6.0
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.table {
|
.table {
|
||||||
display: table;
|
display: table;
|
||||||
width: 60%;
|
width: 85%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tablerow {
|
.tablerow {
|
||||||
|
@ -21,10 +21,18 @@
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ldapIconCopy {
|
||||||
|
background-image: url('../img/copy.svg');
|
||||||
|
}
|
||||||
|
|
||||||
.invisible {
|
.invisible {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.forceHidden {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.ldapSettingsTabs {
|
.ldapSettingsTabs {
|
||||||
float: right !important;
|
float: right !important;
|
||||||
}
|
}
|
||||||
|
@ -49,13 +57,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#ldapWizard1 .hostPortCombinator div span {
|
#ldapWizard1 .hostPortCombinator div span {
|
||||||
width: 7%;
|
width: 14.5%;
|
||||||
display: table-cell;
|
display: inline-block;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ldapWizard1 .host {
|
#ldapWizard1 .host {
|
||||||
width: 96.5% !important;
|
width: 100%;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tableCellInput {
|
.tableCellInput {
|
||||||
|
@ -77,7 +88,7 @@
|
||||||
color: #FF3B3B;
|
color: #FF3B3B;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wizSpinner {
|
.ldapSpinner {
|
||||||
height: 15px;
|
height: 15px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
}
|
}
|
||||||
|
@ -104,10 +115,51 @@
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ldapManyGroupsSupport span {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ldapManyGroupsSupport span button {
|
||||||
|
margin-top: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ldapManyGroupsSearch {
|
||||||
|
width: 425px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ldapGroupList {
|
||||||
|
height: 150px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
#ldap fieldset input, #ldap fieldset textarea {
|
#ldap fieldset input, #ldap fieldset textarea {
|
||||||
width: 60%;
|
width: 60%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ldap fieldset textarea ~ button {
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.ldapVerifyInput {
|
||||||
|
width: 150px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ldapInputColElement {
|
||||||
|
width: 35%;
|
||||||
|
display: inline-block;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ldapToggle {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.ldapInputColElement {
|
||||||
|
margin-top: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
#ldap fieldset p input[type=checkbox] {
|
#ldap fieldset p input[type=checkbox] {
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 346 B |
|
@ -0,0 +1,120 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:ns1="http://sozi.baierouge.fr"
|
||||||
|
xmlns:cc="http://web.resource.org/cc/"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="copy.svg"
|
||||||
|
viewBox="0 0 60 60"
|
||||||
|
sodipodi:version="0.32"
|
||||||
|
_SVGFile__filename="oldscale/actions/copy.svg"
|
||||||
|
version="1.0"
|
||||||
|
y="0"
|
||||||
|
x="0"
|
||||||
|
inkscape:version="0.40"
|
||||||
|
sodipodi:docbase="/home/danny/work/flat/SVG/mono/scalable/actions"
|
||||||
|
>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
bordercolor="#666666"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
inkscape:window-height="699"
|
||||||
|
inkscape:zoom="4.9119411"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:current-layer="svg1"
|
||||||
|
inkscape:cx="60.290892"
|
||||||
|
inkscape:cy="24.030855"
|
||||||
|
inkscape:window-width="1024"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
id="path1716"
|
||||||
|
style="stroke-linejoin:round;stroke:#ffffff;stroke-width:8.3605;fill:none"
|
||||||
|
transform="matrix(.97183 0 0 .97183 .87037 .23733)"
|
||||||
|
d="m7.513 4.5767c-1.3709 0-2.4745 1.1036-2.4745 2.4745v31.564c0 1.371 1.1036 2.474 2.4745 2.474h29.783c1.371 0 2.474-1.103 2.474-2.474v-31.564c0-1.3707-1.103-2.4743-2.474-2.4743h-29.783z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
id="rect1101"
|
||||||
|
style="stroke-linejoin:round;fill-rule:evenodd;stroke:#000000;stroke-width:3.2156;fill:#ffffff"
|
||||||
|
transform="matrix(.97183 0 0 .97183 .87037 .23733)"
|
||||||
|
d="m7.513 4.5767c-1.3709 0-2.4745 1.1036-2.4745 2.4745v31.564c0 1.371 1.1036 2.474 2.4745 2.474h29.783c1.371 0 2.474-1.103 2.474-2.474v-31.564c0-1.3707-1.103-2.4743-2.474-2.4743h-29.783z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
id="path1094"
|
||||||
|
style="stroke-linejoin:round;stroke:#ffffff;stroke-width:8.3605;fill:none"
|
||||||
|
transform="matrix(.97183 0 0 .97183 .87037 .23733)"
|
||||||
|
d="m22.652 20.161c-1.37 0-2.474 1.104-2.474 2.475v31.564c0 1.371 1.104 2.474 2.474 2.474h29.783c1.371 0 2.475-1.103 2.475-2.474v-31.564c0-1.371-1.104-2.475-2.475-2.475h-29.783z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
id="rect1111"
|
||||||
|
style="stroke-linejoin:round;fill-rule:evenodd;stroke:#000000;stroke-width:3.2156;fill:#ffffff"
|
||||||
|
transform="matrix(.97183 0 0 .97183 .87037 .23733)"
|
||||||
|
d="m22.652 20.161c-1.37 0-2.474 1.104-2.474 2.475v31.564c0 1.371 1.104 2.474 2.474 2.474h29.783c1.371 0 2.475-1.103 2.475-2.474v-31.564c0-1.371-1.104-2.475-2.475-2.475h-29.783z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
id="path1718"
|
||||||
|
style="stroke-linejoin:round;stroke:#ffffff;stroke-linecap:round;stroke-width:8.125;fill:none"
|
||||||
|
d="m12.457 21.599c2.325 20.529 20.15 19.15 21.296 19.043v6.139l8.981-8.889-8.981-8.87v6.066c-1.348 0.159-13.941 1.422-21.296-13.489z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
id="path1574"
|
||||||
|
style="stroke-linejoin:round;fill-rule:evenodd;stroke:#000000;stroke-linecap:round;stroke-width:3.125;fill:#000000"
|
||||||
|
d="m12.457 21.599c2.325 20.529 20.15 19.15 21.296 19.043v6.139l8.981-8.889-8.981-8.87v6.066c-1.348 0.159-13.941 1.422-21.296-13.489z"
|
||||||
|
/>
|
||||||
|
<metadata
|
||||||
|
>
|
||||||
|
<rdf:RDF
|
||||||
|
>
|
||||||
|
<cc:Work
|
||||||
|
>
|
||||||
|
<dc:format
|
||||||
|
>image/svg+xml</dc:format
|
||||||
|
>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage"
|
||||||
|
/>
|
||||||
|
<cc:license
|
||||||
|
rdf:resource="http://creativecommons.org/licenses/publicdomain/"
|
||||||
|
/>
|
||||||
|
<dc:publisher
|
||||||
|
>
|
||||||
|
<cc:Agent
|
||||||
|
rdf:about="http://openclipart.org/"
|
||||||
|
>
|
||||||
|
<dc:title
|
||||||
|
>Openclipart</dc:title
|
||||||
|
>
|
||||||
|
</cc:Agent
|
||||||
|
>
|
||||||
|
</dc:publisher
|
||||||
|
>
|
||||||
|
</cc:Work
|
||||||
|
>
|
||||||
|
<cc:License
|
||||||
|
rdf:about="http://creativecommons.org/licenses/publicdomain/"
|
||||||
|
>
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Reproduction"
|
||||||
|
/>
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Distribution"
|
||||||
|
/>
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
|
||||||
|
/>
|
||||||
|
</cc:License
|
||||||
|
>
|
||||||
|
</rdf:RDF
|
||||||
|
>
|
||||||
|
</metadata
|
||||||
|
>
|
||||||
|
</svg
|
||||||
|
>
|
After Width: | Height: | Size: 4.2 KiB |
|
@ -1,92 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2014, Arthur Schiwon <blizzz@owncloud.com>
|
|
||||||
* This file is licensed under the Affero General Public License version 3 or later.
|
|
||||||
* See the COPYING-README file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* global LdapWizard */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* controls behaviour depend on whether the admin is experienced in LDAP or not.
|
|
||||||
*
|
|
||||||
* @class
|
|
||||||
* @param {object} wizard the LDAP Wizard object
|
|
||||||
* @param {boolean} initialState whether the admin is experienced or not
|
|
||||||
*/
|
|
||||||
function ExperiencedAdmin(wizard, initialState) {
|
|
||||||
this.wizard = wizard;
|
|
||||||
this._isExperienced = initialState;
|
|
||||||
if(this._isExperienced) {
|
|
||||||
this.hideEntryCounters();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* toggles whether the admin is an experienced one or not
|
|
||||||
*
|
|
||||||
* @param {boolean} isExperienced whether the admin is experienced or not
|
|
||||||
*/
|
|
||||||
ExperiencedAdmin.prototype.setExperienced = function(isExperienced) {
|
|
||||||
this._isExperienced = isExperienced;
|
|
||||||
if(this._isExperienced) {
|
|
||||||
this.enableRawMode();
|
|
||||||
this.hideEntryCounters();
|
|
||||||
} else {
|
|
||||||
this.showEntryCounters();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* answers whether the admin is an experienced one or not
|
|
||||||
*
|
|
||||||
* @return {boolean} whether the admin is experienced or not
|
|
||||||
*/
|
|
||||||
ExperiencedAdmin.prototype.isExperienced = function() {
|
|
||||||
return this._isExperienced;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* switches all LDAP filters from Assisted to Raw mode.
|
|
||||||
*/
|
|
||||||
ExperiencedAdmin.prototype.enableRawMode = function() {
|
|
||||||
LdapWizard._save({id: 'ldapGroupFilterMode'}, LdapWizard.filterModeRaw);
|
|
||||||
LdapWizard._save({id: 'ldapUserFilterMode' }, LdapWizard.filterModeRaw);
|
|
||||||
LdapWizard._save({id: 'ldapLoginFilterMode'}, LdapWizard.filterModeRaw);
|
|
||||||
};
|
|
||||||
|
|
||||||
ExperiencedAdmin.prototype.updateUserTab = function(mode) {
|
|
||||||
this._updateTab(mode, $('#ldap_user_count'));
|
|
||||||
};
|
|
||||||
|
|
||||||
ExperiencedAdmin.prototype.updateGroupTab = function(mode) {
|
|
||||||
this._updateTab(mode, $('#ldap_group_count'));
|
|
||||||
};
|
|
||||||
|
|
||||||
ExperiencedAdmin.prototype._updateTab = function(mode, $countEl) {
|
|
||||||
if(mode === LdapWizard.filterModeAssisted) {
|
|
||||||
$countEl.removeClass('hidden');
|
|
||||||
} else if(!this._isExperienced) {
|
|
||||||
$countEl.removeClass('hidden');
|
|
||||||
} else {
|
|
||||||
$countEl.addClass('hidden');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hide user and group counters, they will be displayed on demand only
|
|
||||||
*/
|
|
||||||
ExperiencedAdmin.prototype.hideEntryCounters = function() {
|
|
||||||
$('#ldap_user_count').addClass('hidden');
|
|
||||||
$('#ldap_group_count').addClass('hidden');
|
|
||||||
$('.ldapGetEntryCount').removeClass('hidden');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* shows user and group counters, they will be displayed on demand only
|
|
||||||
*/
|
|
||||||
ExperiencedAdmin.prototype.showEntryCounters = function() {
|
|
||||||
$('#ldap_user_count').removeClass('hidden');
|
|
||||||
$('#ldap_group_count').removeClass('hidden');
|
|
||||||
$('.ldapGetEntryCount').addClass('hidden');
|
|
||||||
};
|
|
|
@ -1,193 +0,0 @@
|
||||||
/* global LdapWizard */
|
|
||||||
|
|
||||||
function LdapFilter(target, determineModeCallback) {
|
|
||||||
this.locked = true;
|
|
||||||
this.target = false;
|
|
||||||
this.mode = LdapWizard.filterModeAssisted;
|
|
||||||
this.lazyRunCompose = false;
|
|
||||||
this.determineModeCallback = determineModeCallback;
|
|
||||||
this.foundFeatures = false;
|
|
||||||
this.activated = false;
|
|
||||||
this.countPending = false;
|
|
||||||
|
|
||||||
if( target === 'User' ||
|
|
||||||
target === 'Login' ||
|
|
||||||
target === 'Group') {
|
|
||||||
this.target = target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LdapFilter.prototype.activate = function() {
|
|
||||||
if(this.activated) {
|
|
||||||
// might be necessary, if configuration changes happened.
|
|
||||||
this.findFeatures();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.activated = true;
|
|
||||||
|
|
||||||
this.determineMode();
|
|
||||||
};
|
|
||||||
|
|
||||||
LdapFilter.prototype.compose = function(updateCount) {
|
|
||||||
var action;
|
|
||||||
|
|
||||||
if(updateCount === true) {
|
|
||||||
this.countPending = updateCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.locked) {
|
|
||||||
this.lazyRunCompose = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.mode === LdapWizard.filterModeRaw) {
|
|
||||||
//Raw filter editing, i.e. user defined filter, don't compose
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.target === 'User') {
|
|
||||||
action = 'getUserListFilter';
|
|
||||||
} else if(this.target === 'Login') {
|
|
||||||
action = 'getUserLoginFilter';
|
|
||||||
} else if(this.target === 'Group') {
|
|
||||||
action = 'getGroupFilter';
|
|
||||||
}
|
|
||||||
|
|
||||||
var param = 'action='+action+
|
|
||||||
'&ldap_serverconfig_chooser='+
|
|
||||||
encodeURIComponent($('#ldap_serverconfig_chooser').val());
|
|
||||||
|
|
||||||
var filter = this;
|
|
||||||
|
|
||||||
LdapWizard.ajax(param,
|
|
||||||
function(result) {
|
|
||||||
filter.afterComposeSuccess(result);
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
filter.countPending = false;
|
|
||||||
console.log('LDAP Wizard: could not compose filter. '+
|
|
||||||
'Please check owncloud.log');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this function is triggered after LDAP filters have been composed successfully
|
|
||||||
* @param {object} result returned by the ajax call
|
|
||||||
*/
|
|
||||||
LdapFilter.prototype.afterComposeSuccess = function(result) {
|
|
||||||
LdapWizard.applyChanges(result);
|
|
||||||
if(this.countPending) {
|
|
||||||
this.countPending = false;
|
|
||||||
this.updateCount();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
LdapFilter.prototype.determineMode = function() {
|
|
||||||
var param = 'action=get'+encodeURIComponent(this.target)+'FilterMode'+
|
|
||||||
'&ldap_serverconfig_chooser='+
|
|
||||||
encodeURIComponent($('#ldap_serverconfig_chooser').val());
|
|
||||||
|
|
||||||
var filter = this;
|
|
||||||
LdapWizard.ajax(param,
|
|
||||||
function(result) {
|
|
||||||
var property = 'ldap' + filter.target + 'FilterMode';
|
|
||||||
filter.mode = parseInt(result.changes[property], 10);
|
|
||||||
var rawContainerIsInvisible =
|
|
||||||
$('#raw'+filter.target+'FilterContainer').hasClass('invisible');
|
|
||||||
if ( filter.mode === LdapWizard.filterModeRaw
|
|
||||||
&& rawContainerIsInvisible
|
|
||||||
) {
|
|
||||||
LdapWizard['toggleRaw'+filter.target+'Filter']();
|
|
||||||
} else if ( filter.mode === LdapWizard.filterModeAssisted
|
|
||||||
&& !rawContainerIsInvisible
|
|
||||||
) {
|
|
||||||
LdapWizard['toggleRaw'+filter.target+'Filter']();
|
|
||||||
} else {
|
|
||||||
console.log('LDAP Wizard determineMode: returned mode was »' +
|
|
||||||
filter.mode + '« of type ' + typeof filter.mode);
|
|
||||||
}
|
|
||||||
filter.unlock();
|
|
||||||
filter.determineModeCallback(filter.mode);
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
//on error case get back to default i.e. Assisted
|
|
||||||
if(!$('#raw'+filter.target+'FilterContainer').hasClass('invisible')) {
|
|
||||||
LdapWizard['toggleRaw'+filter.target+'Filter']();
|
|
||||||
filter.mode = LdapWizard.filterModeAssisted;
|
|
||||||
}
|
|
||||||
filter.unlock();
|
|
||||||
filter.determineModeCallback(filter.mode);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
LdapFilter.prototype.setMode = function(mode) {
|
|
||||||
if(mode === LdapWizard.filterModeAssisted || mode === LdapWizard.filterModeRaw) {
|
|
||||||
this.mode = mode;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
LdapFilter.prototype.getMode = function() {
|
|
||||||
return this.mode;
|
|
||||||
};
|
|
||||||
|
|
||||||
LdapFilter.prototype.unlock = function() {
|
|
||||||
this.locked = false;
|
|
||||||
if(this.lazyRunCompose) {
|
|
||||||
this.lazyRunCompose = false;
|
|
||||||
this.compose();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resets this.foundFeatures so that LDAP queries can be fired again to retrieve
|
|
||||||
* objectClasses, groups, etc.
|
|
||||||
*/
|
|
||||||
LdapFilter.prototype.reAllowFeatureLookup = function () {
|
|
||||||
this.foundFeatures = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
LdapFilter.prototype.findFeatures = function() {
|
|
||||||
if(!this.foundFeatures && !this.locked && this.mode === LdapWizard.filterModeAssisted) {
|
|
||||||
this.foundFeatures = true;
|
|
||||||
var objcEl, avgrEl;
|
|
||||||
if(this.target === 'User') {
|
|
||||||
objcEl = 'ldap_userfilter_objectclass';
|
|
||||||
avgrEl = 'ldap_userfilter_groups';
|
|
||||||
} else if (this.target === 'Group') {
|
|
||||||
objcEl = 'ldap_groupfilter_objectclass';
|
|
||||||
avgrEl = 'ldap_groupfilter_groups';
|
|
||||||
} else if (this.target === 'Login') {
|
|
||||||
LdapWizard.findAttributes();
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LdapWizard.findObjectClasses(objcEl, this.target);
|
|
||||||
LdapWizard.findAvailableGroups(avgrEl, this.target + "s");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this function is triggered before user and group counts are executed
|
|
||||||
* resolving the passed status variable will fire up counting
|
|
||||||
*/
|
|
||||||
LdapFilter.prototype.beforeUpdateCount = function() {
|
|
||||||
var status = $.Deferred();
|
|
||||||
LdapWizard.runDetectors(this.target, function() {
|
|
||||||
status.resolve();
|
|
||||||
});
|
|
||||||
return status;
|
|
||||||
};
|
|
||||||
|
|
||||||
LdapFilter.prototype.updateCount = function(doneCallback) {
|
|
||||||
var filter = this;
|
|
||||||
$.when(this.beforeUpdateCount()).done(function() {
|
|
||||||
if(filter.target === 'User') {
|
|
||||||
LdapWizard.countUsers(doneCallback);
|
|
||||||
} else if (filter.target === 'Group') {
|
|
||||||
LdapWizard.countGroups(doneCallback);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,606 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc this class represents a server configuration. It communicates
|
||||||
|
* with the ownCloud server to ensure to always have the up to date LDAP
|
||||||
|
* configuration. It sends various events that views can listen to and
|
||||||
|
* provides methods so they can modify the configuration based upon user
|
||||||
|
* input. This model is also extended by so-called "detectors" who let the
|
||||||
|
* ownCloud server try to auto-detect settings and manipulate the
|
||||||
|
* configuration as well.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var ConfigModel = function() {};
|
||||||
|
|
||||||
|
ConfigModel.prototype = {
|
||||||
|
/** @constant {number} */
|
||||||
|
FILTER_MODE_ASSISTED: 0,
|
||||||
|
/** @constant {number} */
|
||||||
|
FILTER_MODE_RAW: 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initializes the instance. Always call it after creating the instance.
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.WizardDetectorQueue} detectorQueue
|
||||||
|
*/
|
||||||
|
init: function (detectorQueue) {
|
||||||
|
/** @type {object} holds the configuration in key-value-pairs */
|
||||||
|
this.configuration = {};
|
||||||
|
/** @type {object} holds the subscribers that listen to the events */
|
||||||
|
this.subscribers = {};
|
||||||
|
/** @type {Array} holds registered detectors */
|
||||||
|
this.detectors = [];
|
||||||
|
/** @type {boolean} whether a configuration is currently loading */
|
||||||
|
this.loadingConfig = false;
|
||||||
|
|
||||||
|
if(detectorQueue instanceof OCA.LDAP.Wizard.WizardDetectorQueue) {
|
||||||
|
/** @type {OCA.LDAP.Wizard.WizardDetectorQueue} */
|
||||||
|
this.detectorQueue = detectorQueue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* loads a specified configuration
|
||||||
|
*
|
||||||
|
* @param {string} [configID] - the configuration id (or prefix)
|
||||||
|
*/
|
||||||
|
load: function (configID) {
|
||||||
|
if(this.loadingConfig) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._resetDetectorQueue();
|
||||||
|
|
||||||
|
this.configID = configID;
|
||||||
|
var url = OC.generateUrl('apps/user_ldap/ajax/getConfiguration.php');
|
||||||
|
var params = OC.buildQueryString({ldap_serverconfig_chooser: configID});
|
||||||
|
this.loadingConfig = true;
|
||||||
|
var model = this;
|
||||||
|
$.post(url, params, function (result) { model._processLoadConfig(model, result) });
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a new LDAP configuration
|
||||||
|
*
|
||||||
|
* @param {boolean} [copyCurrent] - if true, the current configuration
|
||||||
|
* is copied, otherwise a blank one is created.
|
||||||
|
*/
|
||||||
|
newConfig: function(copyCurrent) {
|
||||||
|
this._resetDetectorQueue();
|
||||||
|
|
||||||
|
var url = OC.generateUrl('apps/user_ldap/ajax/getNewServerConfigPrefix.php');
|
||||||
|
var params = {};
|
||||||
|
if(copyCurrent === true) {
|
||||||
|
params['copyConfig'] = this.configID;
|
||||||
|
}
|
||||||
|
params = OC.buildQueryString(params);
|
||||||
|
var model = this;
|
||||||
|
copyCurrent = _.isUndefined(copyCurrent) ? false : copyCurrent;
|
||||||
|
$.post(url, params, function (result) { model._processNewConfigPrefix(model, result, copyCurrent) });
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deletes the current configuration. This method will not ask for
|
||||||
|
* confirmation, if desired it needs to be ensured by the caller.
|
||||||
|
*
|
||||||
|
* @param {string} [configID] - the configuration id (or prefix)
|
||||||
|
*/
|
||||||
|
deleteConfig: function(configID) {
|
||||||
|
var url = OC.generateUrl('apps/user_ldap/ajax/deleteConfiguration.php');
|
||||||
|
var params = OC.buildQueryString({ldap_serverconfig_chooser: configID});
|
||||||
|
var model = this;
|
||||||
|
$.post(url, params, function (result) { model._processDeleteConfig(model, result, configID) });
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback wizardCallBack
|
||||||
|
* @param {ConfigModel} [model]
|
||||||
|
* @param {OCA.LDAP.Wizard.WizardDetectorGeneric} [detector]
|
||||||
|
* @param {object} [result] - response from the ajax request
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calls an AJAX endpoint at ownCloud. This method should be called by
|
||||||
|
* detectors only!
|
||||||
|
*
|
||||||
|
* @param {string} [params] - as return by OC.buildQueryString
|
||||||
|
* @param {wizardCallBack} [callback]
|
||||||
|
* @param {OCA.LDAP.Wizard.WizardDetectorGeneric} [detector]
|
||||||
|
* @returns {jqXHR}
|
||||||
|
*/
|
||||||
|
callWizard: function(params, callback, detector) {
|
||||||
|
return this.callAjax('wizard.php', params, callback, detector);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calls an AJAX endpoint at ownCloud. This method should be called by
|
||||||
|
* detectors only!
|
||||||
|
*
|
||||||
|
* @param {string} destination - the desired end point
|
||||||
|
* @param {string} [params] - as return by OC.buildQueryString
|
||||||
|
* @param {wizardCallBack} [callback]
|
||||||
|
* @param {OCA.LDAP.Wizard.WizardDetectorGeneric} [detector]
|
||||||
|
* @returns {jqXHR}
|
||||||
|
*/
|
||||||
|
callAjax: function(destination, params, callback, detector) {
|
||||||
|
var url = OC.generateUrl('apps/user_ldap/ajax/' + destination);
|
||||||
|
var model = this;
|
||||||
|
return $.post(url, params, function (result) {
|
||||||
|
callback(model, detector,result);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setRequested Event
|
||||||
|
*
|
||||||
|
* @event ConfigModel#setRequested
|
||||||
|
* @type{object} - empty
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* modifies a configuration key. If a provided configuration key does
|
||||||
|
* not exist or the provided value equals the current setting, false is
|
||||||
|
* returned. Otherwise ownCloud server will be called to save the new
|
||||||
|
* value, an event will notify when this is done. True is returned when
|
||||||
|
* the request is sent, however it does not mean whether saving was
|
||||||
|
* successful or not.
|
||||||
|
*
|
||||||
|
* This method is supposed to be called by views, after the user did a
|
||||||
|
* change which needs to be saved.
|
||||||
|
*
|
||||||
|
* @param {string} [key]
|
||||||
|
* @param {string|number} [value]
|
||||||
|
* @returns {boolean}
|
||||||
|
* @fires {ConfigModel#setRequested}
|
||||||
|
*/
|
||||||
|
set: function(key, value) {
|
||||||
|
if(_.isUndefined(this.configuration[key])) {
|
||||||
|
console.warn('will not save undefined key: ' + key);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(this.configuration[key] === value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this._broadcast('setRequested', {});
|
||||||
|
var url = OC.generateUrl('apps/user_ldap/ajax/wizard.php');
|
||||||
|
var objParams = {
|
||||||
|
ldap_serverconfig_chooser: this.configID,
|
||||||
|
action: 'save',
|
||||||
|
cfgkey: key,
|
||||||
|
cfgval: value
|
||||||
|
};
|
||||||
|
var strParams = OC.buildQueryString(objParams);
|
||||||
|
var model = this;
|
||||||
|
$.post(url, strParams, function(result) { model._processSetResult(model, result, objParams) });
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* configUpdated Event
|
||||||
|
*
|
||||||
|
* object property is a key-value-pair of the configuration key as index
|
||||||
|
* and its value.
|
||||||
|
*
|
||||||
|
* @event ConfigModel#configUpdated
|
||||||
|
* @type{object}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the model's configuration data. This should be called only,
|
||||||
|
* when a new configuration value was received from the ownCloud server.
|
||||||
|
* This is typically done by detectors, but never by views.
|
||||||
|
*
|
||||||
|
* Cancels with false if old and new values already match.
|
||||||
|
*
|
||||||
|
* @param {string} [key]
|
||||||
|
* @param {string} [value]
|
||||||
|
* @returns {boolean}
|
||||||
|
* @fires ConfigModel#configUpdated
|
||||||
|
*/
|
||||||
|
update: function(key, value) {
|
||||||
|
if(this.configuration[key] === value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!_.isUndefined(this.configuration[key])) {
|
||||||
|
// don't write e.g. count values to the configuration
|
||||||
|
// they don't go as feature, yet
|
||||||
|
this.configuration[key] = value;
|
||||||
|
}
|
||||||
|
var configPart = {};
|
||||||
|
configPart[key] = value;
|
||||||
|
this._broadcast('configUpdated', configPart);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} FeaturePayload
|
||||||
|
* @property {string} feature
|
||||||
|
* @property {Array} data
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* informs about a detected LDAP "feature" (wider sense). For examples,
|
||||||
|
* the detected object classes for users or groups
|
||||||
|
*
|
||||||
|
* @param {FeaturePayload} payload
|
||||||
|
*/
|
||||||
|
inform: function(payload) {
|
||||||
|
this._broadcast('receivedLdapFeature', payload);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} ErrorPayload
|
||||||
|
* @property {string} message
|
||||||
|
* @property {string} relatedKey
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* broadcasts an error message, if a wizard reply ended up in an error.
|
||||||
|
* To be called by detectors.
|
||||||
|
*
|
||||||
|
* @param {ErrorPayload} payload
|
||||||
|
*/
|
||||||
|
gotServerError: function(payload) {
|
||||||
|
this._broadcast('serverError', payload);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* detectionStarted Event
|
||||||
|
*
|
||||||
|
* @event ConfigModel#detectionStarted
|
||||||
|
* @type{string} - the target configuration key that is being
|
||||||
|
* auto-detected
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lets the model broadcast the info that a detector starts to run
|
||||||
|
*
|
||||||
|
* supposed to be called by detectors only
|
||||||
|
*
|
||||||
|
* @param {string} [key]
|
||||||
|
* @fires ConfigModel#detectionStarted
|
||||||
|
*/
|
||||||
|
notifyAboutDetectionStart: function(key) {
|
||||||
|
this._broadcast('detectionStarted', key);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* detectionCompleted Event
|
||||||
|
*
|
||||||
|
* @event ConfigModel#detectionCompleted
|
||||||
|
* @type{string} - the target configuration key that was
|
||||||
|
* auto-detected
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lets the model broadcast the info that a detector run was completed
|
||||||
|
*
|
||||||
|
* supposed to be called by detectors only
|
||||||
|
*
|
||||||
|
* @param {string} [key]
|
||||||
|
* @fires ConfigModel#detectionCompleted
|
||||||
|
*/
|
||||||
|
notifyAboutDetectionCompletion: function(key) {
|
||||||
|
this._broadcast('detectionCompleted', key);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback listenerCallback
|
||||||
|
* @param {OCA.LDAP.Wizard.WizardTabGeneric|OCA.LDAP.Wizard.WizardView} [view]
|
||||||
|
* @param {object} [params]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* registers a listener to an event
|
||||||
|
*
|
||||||
|
* the idea is that only views listen.
|
||||||
|
*
|
||||||
|
* @param {string} [name] - the event name
|
||||||
|
* @param {listenerCallback} [fn]
|
||||||
|
* @param {OCA.LDAP.Wizard.WizardTabGeneric|OCA.LDAP.Wizard.WizardView} [context]
|
||||||
|
*/
|
||||||
|
on: function(name, fn, context) {
|
||||||
|
if(_.isUndefined(this.subscribers[name])) {
|
||||||
|
this.subscribers[name] = [];
|
||||||
|
}
|
||||||
|
this.subscribers[name].push({fn: fn, context: context});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* starts a configuration test on the ownCloud server
|
||||||
|
*/
|
||||||
|
requestConfigurationTest: function() {
|
||||||
|
var url = OC.generateUrl('apps/user_ldap/ajax/testConfiguration.php');
|
||||||
|
var params = OC.buildQueryString(this.configuration);
|
||||||
|
var model = this;
|
||||||
|
$.post(url, params, function(result) { model._processTestResult(model, result) });
|
||||||
|
//TODO: make sure only one test is running at a time
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the view may request a call to the wizard, for instance to fetch
|
||||||
|
* object classes or groups
|
||||||
|
*
|
||||||
|
* @param {string} featureKey
|
||||||
|
* @param {Object} [additionalParams]
|
||||||
|
*/
|
||||||
|
requestWizard: function(featureKey, additionalParams) {
|
||||||
|
var model = this;
|
||||||
|
var detectorCount = this.detectors.length;
|
||||||
|
var found = false;
|
||||||
|
for(var i = 0; i < detectorCount; i++) {
|
||||||
|
if(this.detectors[i].runsOnFeatureRequest(featureKey)) {
|
||||||
|
found = true;
|
||||||
|
(function (detector) {
|
||||||
|
model.detectorQueue.add(function() {
|
||||||
|
return detector.run(model, model.configID, additionalParams);
|
||||||
|
});
|
||||||
|
})(model.detectors[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found) {
|
||||||
|
console.warn('No detector found for feature ' + featureKey);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resets the detector queue
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_resetDetectorQueue: function() {
|
||||||
|
if(!_.isUndefined(this.detectorQueue)) {
|
||||||
|
this.detectorQueue.reset();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* detectors can be registered herewith
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.WizardDetectorGeneric} [detector]
|
||||||
|
*/
|
||||||
|
registerDetector: function(detector) {
|
||||||
|
if(detector instanceof OCA.LDAP.Wizard.WizardDetectorGeneric) {
|
||||||
|
this.detectors.push(detector);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* emits an event
|
||||||
|
*
|
||||||
|
* @param {string} [name] - the event name
|
||||||
|
* @param {*} [params]
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_broadcast: function(name, params) {
|
||||||
|
if(_.isUndefined(this.subscribers[name])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var subscribers = this.subscribers[name];
|
||||||
|
var subscriberCount = subscribers.length;
|
||||||
|
for(var i = 0; i < subscriberCount; i++) {
|
||||||
|
if(_.isUndefined(subscribers[i]['fn'])) {
|
||||||
|
console.warn('callback method is not defined. Event ' + name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
subscribers[i]['fn'](subscribers[i]['context'], params);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConfigModel#configLoaded Event
|
||||||
|
*
|
||||||
|
* @event ConfigModel#configLoaded
|
||||||
|
* @type {object} - LDAP configuration as key-value-pairs
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} ConfigLoadResponse
|
||||||
|
* @property {string} [status]
|
||||||
|
* @property {object} [configuration] - only present if status equals 'success'
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* processes the ajax response of a configuration load request
|
||||||
|
*
|
||||||
|
* @param {ConfigModel} [model]
|
||||||
|
* @param {ConfigLoadResponse} [result]
|
||||||
|
* @fires ConfigModel#configLoaded
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_processLoadConfig: function(model, result) {
|
||||||
|
model.configuration = {};
|
||||||
|
if(result['status'] === 'success') {
|
||||||
|
$.each(result['configuration'], function(key, value) {
|
||||||
|
model.configuration[key] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
model.loadingConfig = false;
|
||||||
|
model._broadcast('configLoaded', model.configuration);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} ConfigSetPayload
|
||||||
|
* @property {boolean} [isSuccess]
|
||||||
|
* @property {string} [key]
|
||||||
|
* @property {string} [value]
|
||||||
|
* @property {string} [errorMessage]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConfigModel#setCompleted Event
|
||||||
|
*
|
||||||
|
* @event ConfigModel#setCompleted
|
||||||
|
* @type {ConfigSetPayload}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} ConfigSetResponse
|
||||||
|
* @property {string} [status]
|
||||||
|
* @property {object} [message] - might be present only in error cases
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* processes the ajax response of a configuration key set request
|
||||||
|
*
|
||||||
|
* @param {ConfigModel} [model]
|
||||||
|
* @param {ConfigSetResponse} [result]
|
||||||
|
* @param {object} [params] - the original changeSet
|
||||||
|
* @fires ConfigModel#configLoaded
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_processSetResult: function(model, result, params) {
|
||||||
|
var isSuccess = (result['status'] === 'success');
|
||||||
|
if(isSuccess) {
|
||||||
|
model.configuration[params.cfgkey] = params.cfgval;
|
||||||
|
}
|
||||||
|
var payload = {
|
||||||
|
isSuccess: isSuccess,
|
||||||
|
key: params.cfgkey,
|
||||||
|
value: model.configuration[params.cfgkey],
|
||||||
|
errorMessage: _.isUndefined(result['message']) ? '' : result['message']
|
||||||
|
};
|
||||||
|
model._broadcast('setCompleted', payload);
|
||||||
|
|
||||||
|
// let detectors run
|
||||||
|
// NOTE: detector's changes will not result in new _processSetResult
|
||||||
|
// calls, … in case they interfere it is because of this ;)
|
||||||
|
if(_.isUndefined(model.detectorQueue)) {
|
||||||
|
console.warn("DetectorQueue was not set, detectors will not be fired");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var detectorCount = model.detectors.length;
|
||||||
|
for(var i = 0; i < detectorCount; i++) {
|
||||||
|
if(model.detectors[i].triggersOn(params.cfgkey)) {
|
||||||
|
(function (detector) {
|
||||||
|
model.detectorQueue.add(function() {
|
||||||
|
return detector.run(model, model.configID);
|
||||||
|
});
|
||||||
|
})(model.detectors[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} ConfigTestPayload
|
||||||
|
* @property {boolean} [isSuccess]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConfigModel#configurationTested Event
|
||||||
|
*
|
||||||
|
* @event ConfigModel#configurationTested
|
||||||
|
* @type {ConfigTestPayload}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} StatusResponse
|
||||||
|
* @property {string} [status]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* processes the ajax response of a configuration test request
|
||||||
|
*
|
||||||
|
* @param {ConfigModel} [model]
|
||||||
|
* @param {StatusResponse} [result]
|
||||||
|
* @fires ConfigModel#configurationTested
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_processTestResult: function(model, result) {
|
||||||
|
var payload = {
|
||||||
|
isSuccess: (result['status'] === 'success')
|
||||||
|
};
|
||||||
|
model._broadcast('configurationTested', payload);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} BasicConfigPayload
|
||||||
|
* @property {boolean} [isSuccess]
|
||||||
|
* @property {string} [configPrefix] - the new config ID
|
||||||
|
* @property {string} [errorMessage]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConfigModel#newConfiguration Event
|
||||||
|
*
|
||||||
|
* @event ConfigModel#newConfiguration
|
||||||
|
* @type {BasicConfigPayload}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} NewConfigResponse
|
||||||
|
* @property {string} [status]
|
||||||
|
* @property {string} [configPrefix]
|
||||||
|
* @property {object} [defaults] - default configuration values
|
||||||
|
* @property {string} [message] - might only appear with status being
|
||||||
|
* not 'success'
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* processes the ajax response of a new configuration request
|
||||||
|
*
|
||||||
|
* @param {ConfigModel} [model]
|
||||||
|
* @param {NewConfigResponse} [result]
|
||||||
|
* @param {boolean} [copyCurrent]
|
||||||
|
* @fires ConfigModel#newConfiguration
|
||||||
|
* @fires ConfigModel#configLoaded
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_processNewConfigPrefix: function(model, result, copyCurrent) {
|
||||||
|
var isSuccess = (result['status'] === 'success');
|
||||||
|
var payload = {
|
||||||
|
isSuccess: isSuccess,
|
||||||
|
configPrefix: result['configPrefix'],
|
||||||
|
errorMessage: _.isUndefined(result['message']) ? '' : result['message']
|
||||||
|
};
|
||||||
|
model._broadcast('newConfiguration', payload);
|
||||||
|
|
||||||
|
if(isSuccess) {
|
||||||
|
this.configID = result['configPrefix'];
|
||||||
|
if(!copyCurrent) {
|
||||||
|
model.configuration = {};
|
||||||
|
$.each(result['defaults'], function(key, value) {
|
||||||
|
model.configuration[key] = value;
|
||||||
|
});
|
||||||
|
// view / tabs need to update with new blank config
|
||||||
|
model._broadcast('configLoaded', model.configuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConfigModel#deleteConfiguration Event
|
||||||
|
*
|
||||||
|
* @event ConfigModel#deleteConfiguration
|
||||||
|
* @type {BasicConfigPayload}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* processes the ajax response of a delete configuration request
|
||||||
|
*
|
||||||
|
* @param {ConfigModel} [model]
|
||||||
|
* @param {StatusResponse} [result]
|
||||||
|
* @param {string} [configID]
|
||||||
|
* @fires ConfigModel#deleteConfiguration
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_processDeleteConfig: function(model, result, configID) {
|
||||||
|
var isSuccess = (result['status'] === 'success');
|
||||||
|
var payload = {
|
||||||
|
isSuccess: isSuccess,
|
||||||
|
configPrefix: configID,
|
||||||
|
errorMessage: _.isUndefined(result['message']) ? '' : result['message']
|
||||||
|
};
|
||||||
|
model._broadcast('deleteConfiguration', payload);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.ConfigModel = ConfigModel;
|
||||||
|
})();
|
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
OCA.LDAP = {};
|
||||||
|
OCA.LDAP.Wizard = {};
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc minimalistic controller that basically makes the view render
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardController = function() {};
|
||||||
|
|
||||||
|
WizardController.prototype = {
|
||||||
|
/**
|
||||||
|
* initializes the instance. Always call it after creating the instance.
|
||||||
|
*/
|
||||||
|
init: function() {
|
||||||
|
this.view = false;
|
||||||
|
this.configModel = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the model instance
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} [model]
|
||||||
|
*/
|
||||||
|
setModel: function(model) {
|
||||||
|
this.configModel = model;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the view instance
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.WizardView} [view]
|
||||||
|
*/
|
||||||
|
setView: function(view) {
|
||||||
|
this.view = view;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* makes the view render i.e. ready to be used
|
||||||
|
*/
|
||||||
|
run: function() {
|
||||||
|
this.view.render();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.Controller = WizardController;
|
||||||
|
})();
|
|
@ -0,0 +1,437 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc main view class. It takes care of tab-unrelated control
|
||||||
|
* elements (status bar, control buttons) and does or requests configuration
|
||||||
|
* checks. It also manages the separate tab views.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardView = function() {};
|
||||||
|
|
||||||
|
WizardView.prototype = {
|
||||||
|
/** @constant {number} */
|
||||||
|
STATUS_ERROR: 0,
|
||||||
|
/** @constant {number} */
|
||||||
|
STATUS_INCOMPLETE: 1,
|
||||||
|
/** @constant {number} */
|
||||||
|
STATUS_SUCCESS: 2,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initializes the instance. Always call it after creating the instance.
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
this.tabs = {};
|
||||||
|
this.tabs.server = new OCA.LDAP.Wizard.WizardTabElementary();
|
||||||
|
this.$settings = $('#ldapSettings');
|
||||||
|
this.$saveSpinners = $('.ldap_saving');
|
||||||
|
this.saveProcesses = 0;
|
||||||
|
_.bindAll(this, 'onTabChange', 'onTestButtonClick');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* applies click events to the forward and backword buttons
|
||||||
|
*/
|
||||||
|
initControls: function() {
|
||||||
|
var view = this;
|
||||||
|
$('.ldap_action_continue').click(function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
view._controlContinue(view);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.ldap_action_back').click(function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
view._controlBack(view);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.ldap_action_test_connection').click(this.onTestButtonClick);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* registers a tab
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.WizardTabGeneric} tabView
|
||||||
|
* @param {string} index
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
registerTab: function(tabView, index) {
|
||||||
|
if( _.isUndefined(this.tabs[index])
|
||||||
|
&& tabView instanceof OCA.LDAP.Wizard.WizardTabGeneric
|
||||||
|
) {
|
||||||
|
this.tabs[index] = tabView;
|
||||||
|
this.tabs[index].setModel(this.configModel);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks certain config values for completeness and depending on them
|
||||||
|
* enables or disables non-elementary tabs.
|
||||||
|
*/
|
||||||
|
basicStatusCheck: function(view) {
|
||||||
|
var host = view.configModel.configuration.ldap_host;
|
||||||
|
var port = view.configModel.configuration.ldap_port;
|
||||||
|
var base = view.configModel.configuration.ldap_base;
|
||||||
|
var agent = view.configModel.configuration.ldap_dn;
|
||||||
|
var pwd = view.configModel.configuration.ldap_agent_password;
|
||||||
|
|
||||||
|
if((host && port && base) && ((!agent && !pwd) || (agent && pwd))) {
|
||||||
|
view.enableTabs();
|
||||||
|
} else {
|
||||||
|
view.disableTabs();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if the configuration is sufficient the model is being request to
|
||||||
|
* perform a configuration test. Otherwise, the status indicator is
|
||||||
|
* being updated with the status "incomplete"
|
||||||
|
*/
|
||||||
|
functionalityCheck: function() {
|
||||||
|
// this method should be called only if necessary, because it may
|
||||||
|
// cause an LDAP request!
|
||||||
|
var host = this.configModel.configuration.ldap_host;
|
||||||
|
var port = this.configModel.configuration.ldap_port;
|
||||||
|
var base = this.configModel.configuration.ldap_base;
|
||||||
|
var userFilter = this.configModel.configuration.ldap_userlist_filter;
|
||||||
|
var loginFilter = this.configModel.configuration.ldap_login_filter;
|
||||||
|
|
||||||
|
if(host && port && base && userFilter && loginFilter) {
|
||||||
|
this.configModel.requestConfigurationTest();
|
||||||
|
} else {
|
||||||
|
this._updateStatusIndicator(this.STATUS_INCOMPLETE);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* will request a functionality check if one of the related configuration
|
||||||
|
* settings was changed.
|
||||||
|
*
|
||||||
|
* @param {ConfigSetPayload|Object} [changeSet]
|
||||||
|
*/
|
||||||
|
considerFunctionalityCheck: function(changeSet) {
|
||||||
|
var testTriggers = [
|
||||||
|
'ldap_host', 'ldap_port', 'ldap_dn', 'ldap_agent_password',
|
||||||
|
'ldap_base', 'ldap_userlist_filter', 'ldap_login_filter'
|
||||||
|
];
|
||||||
|
for(var key in changeSet) {
|
||||||
|
if($.inArray(key, testTriggers) >= 0) {
|
||||||
|
this.functionalityCheck();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* keeps number of running save processes and shows a spinner if
|
||||||
|
* necessary
|
||||||
|
*
|
||||||
|
* @param {WizardView} [view]
|
||||||
|
* @listens ConfigModel#setRequested
|
||||||
|
*/
|
||||||
|
onSetRequested: function(view) {
|
||||||
|
view.saveProcesses += 1;
|
||||||
|
if(view.saveProcesses === 1) {
|
||||||
|
view.showSaveSpinner();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* keeps number of running save processes and hides the spinner if
|
||||||
|
* necessary. Also triggers checks, to adjust tabs state and status bar.
|
||||||
|
*
|
||||||
|
* @param {WizardView} [view]
|
||||||
|
* @param {ConfigSetPayload} [result]
|
||||||
|
* @listens ConfigModel#setCompleted
|
||||||
|
*/
|
||||||
|
onSetRequestDone: function(view, result) {
|
||||||
|
if(view.saveProcesses > 0) {
|
||||||
|
view.saveProcesses -= 1;
|
||||||
|
if(view.saveProcesses === 0) {
|
||||||
|
view.hideSaveSpinner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
view.basicStatusCheck(view);
|
||||||
|
var param = {};
|
||||||
|
param[result.key] = 1;
|
||||||
|
view.considerFunctionalityCheck(param);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the status indicator based on the configuration test result
|
||||||
|
*
|
||||||
|
* @param {WizardView} [view]
|
||||||
|
* @param {ConfigTestPayload} [result]
|
||||||
|
* @listens ConfigModel#configurationTested
|
||||||
|
*/
|
||||||
|
onTestCompleted: function(view, result) {
|
||||||
|
if(result.isSuccess) {
|
||||||
|
view._updateStatusIndicator(view.STATUS_SUCCESS);
|
||||||
|
} else {
|
||||||
|
view._updateStatusIndicator(view.STATUS_ERROR);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* triggers initial checks upon configuration loading to update status
|
||||||
|
* controls
|
||||||
|
*
|
||||||
|
* @param {WizardView} [view]
|
||||||
|
* @listens ConfigModel#configLoaded
|
||||||
|
*/
|
||||||
|
onConfigLoaded: function(view) {
|
||||||
|
view.basicStatusCheck(view);
|
||||||
|
view.functionalityCheck();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reacts on attempts to switch to a different tab
|
||||||
|
*
|
||||||
|
* @param {object} event
|
||||||
|
* @param {object} ui
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
onTabChange: function(event, ui) {
|
||||||
|
if(this.saveProcesses > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newTabID = ui.newTab[0].id;
|
||||||
|
if(newTabID === '#ldapWizard1') {
|
||||||
|
newTabID = 'server';
|
||||||
|
}
|
||||||
|
var oldTabID = ui.oldTab[0].id;
|
||||||
|
if(oldTabID === '#ldapWizard1') {
|
||||||
|
oldTabID = 'server';
|
||||||
|
}
|
||||||
|
if(!_.isUndefined(this.tabs[newTabID])) {
|
||||||
|
this.tabs[newTabID].isActive = true;
|
||||||
|
this.tabs[newTabID].onActivate();
|
||||||
|
} else {
|
||||||
|
console.warn('Unreferenced activated tab ' + newTabID);
|
||||||
|
}
|
||||||
|
if(!_.isUndefined(this.tabs[oldTabID])) {
|
||||||
|
this.tabs[oldTabID].isActive = false;
|
||||||
|
} else {
|
||||||
|
console.warn('Unreferenced left tab ' + oldTabID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_.isUndefined(this.tabs[newTabID])) {
|
||||||
|
this._controlUpdate(this.tabs[newTabID].tabIndex);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* triggers checks upon configuration updates to keep status controls
|
||||||
|
* up to date
|
||||||
|
*
|
||||||
|
* @param {WizardView} [view]
|
||||||
|
* @param {object} [changeSet]
|
||||||
|
* @listens ConfigModel#configUpdated
|
||||||
|
*/
|
||||||
|
onConfigUpdated: function(view, changeSet) {
|
||||||
|
view.basicStatusCheck(view);
|
||||||
|
view.considerFunctionalityCheck(changeSet);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* requests a configuration test
|
||||||
|
*/
|
||||||
|
onTestButtonClick: function() {
|
||||||
|
this.configModel.requestWizard('ldap_action_test_connection', this.configModel.configuration);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the model instance and registers event listeners
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} [configModel]
|
||||||
|
*/
|
||||||
|
setModel: function(configModel) {
|
||||||
|
/** @type {OCA.LDAP.Wizard.ConfigModel} */
|
||||||
|
this.configModel = configModel;
|
||||||
|
for(var i in this.tabs) {
|
||||||
|
this.tabs[i].setModel(configModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure this is definitely run after tabs did their work, order is important here
|
||||||
|
// for now this works, because tabs are supposed to register their listeners in their
|
||||||
|
// setModel() method.
|
||||||
|
// alternative: make Elementary Tab a Publisher as well.
|
||||||
|
this.configModel.on('configLoaded', this.onConfigLoaded, this);
|
||||||
|
this.configModel.on('configUpdated', this.onConfigUpdated, this);
|
||||||
|
this.configModel.on('setRequested', this.onSetRequested, this);
|
||||||
|
this.configModel.on('setCompleted', this.onSetRequestDone, this);
|
||||||
|
this.configModel.on('configurationTested', this.onTestCompleted, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enables tab and navigation buttons
|
||||||
|
*/
|
||||||
|
enableTabs: function() {
|
||||||
|
//do not use this function directly, use basicStatusCheck instead.
|
||||||
|
if(this.saveProcesses === 0) {
|
||||||
|
$('.ldap_action_continue').removeAttr('disabled');
|
||||||
|
$('.ldap_action_back').removeAttr('disabled');
|
||||||
|
this.$settings.tabs('option', 'disabled', []);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* disables tab and navigation buttons
|
||||||
|
*/
|
||||||
|
disableTabs: function() {
|
||||||
|
$('.ldap_action_continue').attr('disabled', 'disabled');
|
||||||
|
$('.ldap_action_back').attr('disabled', 'disabled');
|
||||||
|
this.$settings.tabs('option', 'disabled', [1, 2, 3, 4, 5]);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shows a save spinner
|
||||||
|
*/
|
||||||
|
showSaveSpinner: function() {
|
||||||
|
this.$saveSpinners.removeClass('hidden');
|
||||||
|
$('#ldap *').addClass('save-cursor');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hides the save spinner
|
||||||
|
*/
|
||||||
|
hideSaveSpinner: function() {
|
||||||
|
this.$saveSpinners.addClass('hidden');
|
||||||
|
$('#ldap *').removeClass('save-cursor');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* performs a config load request to the model
|
||||||
|
*
|
||||||
|
* @param {string} [configID]
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_requestConfig: function(configID) {
|
||||||
|
this.configModel.load(configID);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bootstraps the visual appearance and event listeners, as well as the
|
||||||
|
* first config
|
||||||
|
*/
|
||||||
|
render: function () {
|
||||||
|
$('#ldapAdvancedAccordion').accordion({ heightStyle: 'content', animate: 'easeInOutCirc'});
|
||||||
|
this.$settings.tabs({});
|
||||||
|
$('.ldap_submit').button();
|
||||||
|
$('.ldap_action_test_connection').button();
|
||||||
|
$('#ldapSettings').tabs({ beforeActivate: this.onTabChange });
|
||||||
|
|
||||||
|
this.initControls();
|
||||||
|
this.disableTabs();
|
||||||
|
|
||||||
|
this._requestConfig(this.tabs.server.getConfigID());
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the status indicator / bar
|
||||||
|
*
|
||||||
|
* @param {number} [state]
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_updateStatusIndicator: function(state) {
|
||||||
|
var $indicator = $('.ldap_config_state_indicator');
|
||||||
|
var $indicatorLight = $('.ldap_config_state_indicator_sign');
|
||||||
|
|
||||||
|
switch(state) {
|
||||||
|
case this.STATUS_ERROR:
|
||||||
|
$indicator.text(t('user_ldap',
|
||||||
|
'Configuration incorrect'
|
||||||
|
));
|
||||||
|
$indicator.removeClass('ldap_grey');
|
||||||
|
$indicatorLight.addClass('error');
|
||||||
|
$indicatorLight.removeClass('success');
|
||||||
|
break;
|
||||||
|
case this.STATUS_INCOMPLETE:
|
||||||
|
$indicator.text(t('user_ldap',
|
||||||
|
'Configuration incomplete'
|
||||||
|
));
|
||||||
|
$indicator.removeClass('ldap_grey');
|
||||||
|
$indicatorLight.removeClass('error');
|
||||||
|
$indicatorLight.removeClass('success');
|
||||||
|
break;
|
||||||
|
case this.STATUS_SUCCESS:
|
||||||
|
$indicator.text(t('user_ldap', 'Configuration OK'));
|
||||||
|
$indicator.addClass('ldap_grey');
|
||||||
|
$indicatorLight.removeClass('error');
|
||||||
|
$indicatorLight.addClass('success');
|
||||||
|
if(!this.tabs.server.isActive) {
|
||||||
|
this.configModel.set('ldap_configuration_active', 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handles a click on the Back button
|
||||||
|
*
|
||||||
|
* @param {WizardView} [view]
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_controlBack: function(view) {
|
||||||
|
var curTabIndex = view.$settings.tabs('option', 'active');
|
||||||
|
if(curTabIndex == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
view.$settings.tabs('option', 'active', curTabIndex - 1);
|
||||||
|
view._controlUpdate(curTabIndex - 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handles a click on the Continue button
|
||||||
|
*
|
||||||
|
* @param {WizardView} [view]
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_controlContinue: function(view) {
|
||||||
|
var curTabIndex = view.$settings.tabs('option', 'active');
|
||||||
|
if(curTabIndex == 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
view.$settings.tabs('option', 'active', 1 + curTabIndex);
|
||||||
|
view._controlUpdate(curTabIndex + 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the controls (navigation buttons)
|
||||||
|
*
|
||||||
|
* @param {number} [nextTabIndex] - index of the tab being switched to
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_controlUpdate: function(nextTabIndex) {
|
||||||
|
if(nextTabIndex == 0) {
|
||||||
|
$('.ldap_action_back').addClass('invisible');
|
||||||
|
$('.ldap_action_continue').removeClass('invisible');
|
||||||
|
} else
|
||||||
|
if(nextTabIndex == 1) {
|
||||||
|
$('.ldap_action_back').removeClass('invisible');
|
||||||
|
$('.ldap_action_continue').removeClass('invisible');
|
||||||
|
} else
|
||||||
|
if(nextTabIndex == 2) {
|
||||||
|
$('.ldap_action_continue').removeClass('invisible');
|
||||||
|
$('.ldap_action_back').removeClass('invisible');
|
||||||
|
} else
|
||||||
|
if(nextTabIndex == 3) {
|
||||||
|
$('.ldap_action_back').removeClass('invisible');
|
||||||
|
$('.ldap_action_continue').addClass('invisible');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardView = WizardView;
|
||||||
|
})();
|
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initializes the wizard and related components and kicks it off.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var Wizard = function() {
|
||||||
|
var detectorQueue = new OCA.LDAP.Wizard.WizardDetectorQueue();
|
||||||
|
detectorQueue.init();
|
||||||
|
|
||||||
|
var detectors = [];
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorPort());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorBaseDN());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorEmailAttribute());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorUserDisplayNameAttribute());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorUserGroupAssociation());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorUserObjectClasses());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorGroupObjectClasses());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorGroupsForUsers());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorGroupsForGroups());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorFilterUser());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorFilterLogin());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorFilterGroup());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorUserCount());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorGroupCount());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorAvailableAttributes());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorTestLoginName());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorTestBaseDN());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorTestConfiguration());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorClearUserMappings());
|
||||||
|
detectors.push(new OCA.LDAP.Wizard.WizardDetectorClearGroupMappings());
|
||||||
|
|
||||||
|
var model = new OCA.LDAP.Wizard.ConfigModel();
|
||||||
|
model.init(detectorQueue);
|
||||||
|
// NOTE: order of detectors may play a role
|
||||||
|
// for example, BaseDN detector needs the port. The port is typically found
|
||||||
|
// by the Port Detector. If BaseDN detector was run first, it will not have
|
||||||
|
// all necessary information. Only after Port Detector was executed…
|
||||||
|
for (var i = 0; i <= detectors.length; i++) {
|
||||||
|
model.registerDetector(detectors[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var filterOnTypeFactory = new OCA.LDAP.Wizard.FilterOnTypeFactory();
|
||||||
|
|
||||||
|
var tabs = [];
|
||||||
|
tabs.push(new OCA.LDAP.Wizard.WizardTabUserFilter(filterOnTypeFactory, 1));
|
||||||
|
tabs.push(new OCA.LDAP.Wizard.WizardTabLoginFilter(2));
|
||||||
|
tabs.push(new OCA.LDAP.Wizard.WizardTabGroupFilter(filterOnTypeFactory, 3));
|
||||||
|
tabs.push(new OCA.LDAP.Wizard.WizardTabAdvanced());
|
||||||
|
tabs.push(new OCA.LDAP.Wizard.WizardTabExpert());
|
||||||
|
|
||||||
|
var view = new OCA.LDAP.Wizard.WizardView(model);
|
||||||
|
view.init();
|
||||||
|
view.setModel(model);
|
||||||
|
for (var j = 0; j <= tabs.length; j++) {
|
||||||
|
view.registerTab(tabs[j], '#ldapWizard' + (j + 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
var controller = new OCA.LDAP.Wizard.Controller();
|
||||||
|
controller.init();
|
||||||
|
controller.setView(view);
|
||||||
|
controller.setModel(model);
|
||||||
|
controller.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.Wizard = Wizard;
|
||||||
|
})();
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
new OCA.LDAP.Wizard.Wizard();
|
||||||
|
});
|
|
@ -0,0 +1,59 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc an Attributes Detector. It executes the auto-detection of
|
||||||
|
* available attributes by the ownCloud server, if requirements are met.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorAvailableAttributes = OCA.LDAP.Wizard.WizardDetectorGeneric.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
// given, it is not a configuration key
|
||||||
|
this.setTargetKey('ldap_loginfilter_attributes');
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* runs the detector, if port is not set.
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} model
|
||||||
|
* @param {string} configID - the configuration prefix
|
||||||
|
* @returns {boolean|jqXHR}
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
run: function(model, configID) {
|
||||||
|
model.notifyAboutDetectionStart(this.getTargetKey());
|
||||||
|
var params = OC.buildQueryString({
|
||||||
|
action: 'determineAttributes',
|
||||||
|
ldap_serverconfig_chooser: configID
|
||||||
|
});
|
||||||
|
return model.callWizard(params, this.processResult, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
processResult: function(model, detector, result) {
|
||||||
|
if(result.status === 'success') {
|
||||||
|
var payload = {
|
||||||
|
feature: 'AvailableAttributes',
|
||||||
|
data: result.options[detector.getTargetKey()]
|
||||||
|
};
|
||||||
|
model.inform(payload);
|
||||||
|
}
|
||||||
|
this._super(model, detector, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorAvailableAttributes = WizardDetectorAvailableAttributes;
|
||||||
|
})();
|
|
@ -0,0 +1,52 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc a Base DN Detector. It executes the auto-detection of the base
|
||||||
|
* DN by the ownCloud server, if requirements are met.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorBaseDN = OCA.LDAP.Wizard.WizardDetectorGeneric.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
this.setTargetKey('ldap_base');
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* runs the detector, if specified configuration settings are set and
|
||||||
|
* base DN is not set.
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} model
|
||||||
|
* @param {string} configID - the configuration prefix
|
||||||
|
* @returns {boolean|jqXHR}
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
run: function(model, configID) {
|
||||||
|
if( !model.configuration['ldap_host']
|
||||||
|
|| !model.configuration['ldap_port']
|
||||||
|
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
model.notifyAboutDetectionStart(this.getTargetKey());
|
||||||
|
var params = OC.buildQueryString({
|
||||||
|
action: 'guessBaseDN',
|
||||||
|
ldap_serverconfig_chooser: configID
|
||||||
|
});
|
||||||
|
return model.callWizard(params, this.processResult, this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorBaseDN = WizardDetectorBaseDN;
|
||||||
|
})();
|
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc requests clearing of user mappings
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorClearGroupMappings = OCA.LDAP.Wizard.WizardDetectorTestAbstract.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
// given, it is not a configuration key
|
||||||
|
this.setTargetKey('ldap_action_clear_group_mappings');
|
||||||
|
this.testName = 'ClearMappings';
|
||||||
|
this.isLegacy = true;
|
||||||
|
this.legacyDestination = 'clearMappings.php';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorClearGroupMappings = WizardDetectorClearGroupMappings;
|
||||||
|
})();
|
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc requests clearing of user mappings
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorClearUserMappings = OCA.LDAP.Wizard.WizardDetectorTestAbstract.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
// given, it is not a configuration key
|
||||||
|
this.setTargetKey('ldap_action_clear_user_mappings');
|
||||||
|
this.testName = 'ClearMappings';
|
||||||
|
this.isLegacy = true;
|
||||||
|
this.legacyDestination = 'clearMappings.php';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorClearUserMappings = WizardDetectorClearUserMappings;
|
||||||
|
})();
|
|
@ -0,0 +1,38 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc let's the wizard backend count the available users
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorEmailAttribute = OCA.LDAP.Wizard.WizardDetectorFilterSimpleRequestAbstract.subClass({
|
||||||
|
init: function() {
|
||||||
|
this.setTargetKey('ldap_user_count');
|
||||||
|
this.wizardMethod = 'detectEmailAttribute';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
run: function(model, configID) {
|
||||||
|
if(model.configuration.ldap_email_attr) {
|
||||||
|
// a value is already set. Don't overwrite and don't ask LDAP
|
||||||
|
// without reason.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this._super(model, configID);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorEmailAttribute = WizardDetectorEmailAttribute;
|
||||||
|
})();
|
|
@ -0,0 +1,52 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc abstract detector for detecting groups and object classes
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorFeatureAbstract = OCA.LDAP.Wizard.WizardDetectorGeneric.subClass({
|
||||||
|
/**
|
||||||
|
* runs the detector, if port is not set.
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} model
|
||||||
|
* @param {string} configID - the configuration prefix
|
||||||
|
* @returns {boolean|jqXHR}
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
run: function(model, configID) {
|
||||||
|
model.notifyAboutDetectionStart(this.getTargetKey());
|
||||||
|
var params = OC.buildQueryString({
|
||||||
|
action: this.wizardMethod,
|
||||||
|
ldap_serverconfig_chooser: configID
|
||||||
|
});
|
||||||
|
return model.callWizard(params, this.processResult, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
processResult: function(model, detector, result) {
|
||||||
|
if(result.status === 'success') {
|
||||||
|
var payload = {
|
||||||
|
feature: detector.featureName,
|
||||||
|
data: result.options[detector.getTargetKey()]
|
||||||
|
};
|
||||||
|
model.inform(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._super(model, detector, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorFeatureAbstract = WizardDetectorFeatureAbstract;
|
||||||
|
})();
|
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc a Port Detector. It executes the auto-detection of the port
|
||||||
|
* by the ownCloud server, if requirements are met.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorFilterGroup = OCA.LDAP.Wizard.WizardDetectorFilterSimpleRequestAbstract.subClass({
|
||||||
|
init: function() {
|
||||||
|
this.setTrigger([
|
||||||
|
'ldap_groupfilter_groups',
|
||||||
|
'ldap_groupfilter_objectclass'
|
||||||
|
]);
|
||||||
|
this.setTargetKey('ldap_group_filter');
|
||||||
|
|
||||||
|
this.wizardMethod = 'getGroupFilter';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorFilterGroup = WizardDetectorFilterGroup;
|
||||||
|
})();
|
|
@ -0,0 +1,33 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc a Port Detector. It executes the auto-detection of the port
|
||||||
|
* by the ownCloud server, if requirements are met.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorFilterLogin = OCA.LDAP.Wizard.WizardDetectorFilterSimpleRequestAbstract.subClass({
|
||||||
|
init: function() {
|
||||||
|
this.setTrigger([
|
||||||
|
'ldap_loginfilter_username',
|
||||||
|
'ldap_loginfilter_email',
|
||||||
|
'ldap_loginfilter_attributes'
|
||||||
|
]);
|
||||||
|
this.setTargetKey('ldap_login_filter');
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
|
||||||
|
this.wizardMethod = 'getUserLoginFilter';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorFilterLogin = WizardDetectorFilterLogin;
|
||||||
|
})();
|
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc a Port Detector. It executes the auto-detection of the port
|
||||||
|
* by the ownCloud server, if requirements are met.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorFilterUser = OCA.LDAP.Wizard.WizardDetectorFilterSimpleRequestAbstract.subClass({
|
||||||
|
init: function() {
|
||||||
|
this.setTrigger([
|
||||||
|
'ldap_userfilter_groups',
|
||||||
|
'ldap_userfilter_objectclass'
|
||||||
|
]);
|
||||||
|
this.setTargetKey('ldap_userlist_filter');
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
|
||||||
|
this.wizardMethod = 'getUserListFilter';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorFilterUser = WizardDetectorFilterUser;
|
||||||
|
})();
|
|
@ -0,0 +1,117 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
/**
|
||||||
|
* @classdesc a generic (abstract) Detector template. A Detector's task is
|
||||||
|
* to kick off server side detection of certain LDAP features. It is invoked
|
||||||
|
* when changes to specified configuration keys happen.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorGeneric = OCA.LDAP.Wizard.WizardObject.subClass({
|
||||||
|
/**
|
||||||
|
* initializes the instance. Always call it after creating the instance.
|
||||||
|
*/
|
||||||
|
init: function() {
|
||||||
|
this.setTrigger([]);
|
||||||
|
this.targetKey = '';
|
||||||
|
this.runsOnRequest = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the configuration keys the detector is listening on
|
||||||
|
*
|
||||||
|
* @param {string[]} triggers
|
||||||
|
*/
|
||||||
|
setTrigger: function(triggers) {
|
||||||
|
this.triggers = triggers;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tests whether the detector is triggered by the provided key
|
||||||
|
*
|
||||||
|
* @param {string} key
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
triggersOn: function(key) {
|
||||||
|
return ($.inArray(key, this.triggers) >= 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* whether the detector runs on explicit request
|
||||||
|
*
|
||||||
|
* @param {string} key
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
runsOnFeatureRequest: function(key) {
|
||||||
|
return !!(this.runsOnRequest && this.targetKey === key);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the configuration key the detector is attempting to auto-detect
|
||||||
|
*
|
||||||
|
* @param {string} key
|
||||||
|
*/
|
||||||
|
setTargetKey: function(key) {
|
||||||
|
this.targetKey = key;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the configuration key the detector is attempting to
|
||||||
|
* auto-detect
|
||||||
|
*/
|
||||||
|
getTargetKey: function() {
|
||||||
|
return this.targetKey;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* runs the detector. This method is supposed to be implemented by the
|
||||||
|
* concrete detector.
|
||||||
|
*
|
||||||
|
* Must return false if the detector decides not to run.
|
||||||
|
* Must return a jqXHR object otherwise, which is provided by the
|
||||||
|
* model's callWizard()
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} model
|
||||||
|
* @param {string} configID - the configuration prefix
|
||||||
|
* @returns {boolean|jqXHR}
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
run: function(model, configID) {
|
||||||
|
// to be implemented by subClass
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* processes the result of the ownCloud server
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} model
|
||||||
|
* @param {WizardDetectorGeneric} detector
|
||||||
|
* @param {object} result
|
||||||
|
*/
|
||||||
|
processResult: function(model, detector, result) {
|
||||||
|
model['notifyAboutDetectionCompletion'](detector.getTargetKey());
|
||||||
|
if(result.status === 'success') {
|
||||||
|
for (var id in result.changes) {
|
||||||
|
// update and not set method, as values are already stored
|
||||||
|
model['update'](id, result.changes[id]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var payload = { relatedKey: detector.targetKey };
|
||||||
|
if(!_.isUndefined(result.message)) {
|
||||||
|
payload.message = result.message;
|
||||||
|
}
|
||||||
|
model.gotServerError(payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorGeneric = WizardDetectorGeneric;
|
||||||
|
})();
|
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc a Port Detector. It executes the auto-detection of the port
|
||||||
|
* by the ownCloud server, if requirements are met.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorGroupCount = OCA.LDAP.Wizard.WizardDetectorFilterSimpleRequestAbstract.subClass({
|
||||||
|
init: function() {
|
||||||
|
this.setTargetKey('ldap_group_count');
|
||||||
|
this.wizardMethod = 'countGroups';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorGroupCount = WizardDetectorGroupCount;
|
||||||
|
})();
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc discovers object classes for the groups tab
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorGroupObjectClasses = OCA.LDAP.Wizard.WizardDetectorFeatureAbstract.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
// given, it is not a configuration key
|
||||||
|
this.setTargetKey('ldap_groupfilter_objectclass');
|
||||||
|
this.wizardMethod = 'determineGroupObjectClasses';
|
||||||
|
this.featureName = 'GroupObjectClasses';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorGroupObjectClasses = WizardDetectorGroupObjectClasses;
|
||||||
|
})();
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc detects groups for the groups tab
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorGroupsForGroups = OCA.LDAP.Wizard.WizardDetectorFeatureAbstract.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
// given, it is not a configuration key
|
||||||
|
this.setTargetKey('ldap_groupfilter_groups');
|
||||||
|
this.wizardMethod = 'determineGroupsForGroups';
|
||||||
|
this.featureName = 'GroupsForGroups';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorGroupsForGroups = WizardDetectorGroupsForGroups;
|
||||||
|
})();
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc detects groups for the users tab
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorGroupsForUsers = OCA.LDAP.Wizard.WizardDetectorFeatureAbstract.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
// given, it is not a configuration key
|
||||||
|
this.setTargetKey('ldap_userfilter_groups');
|
||||||
|
this.wizardMethod = 'determineGroupsForUsers';
|
||||||
|
this.featureName = 'GroupsForUsers';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorGroupsForUsers = WizardDetectorGroupsForUsers;
|
||||||
|
})();
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc a Port Detector. It executes the auto-detection of the port
|
||||||
|
* by the ownCloud server, if requirements are met.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorPort = OCA.LDAP.Wizard.WizardDetectorGeneric.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
this.setTargetKey('ldap_port');
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* runs the detector, if port is not set.
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} model
|
||||||
|
* @param {string} configID - the configuration prefix
|
||||||
|
* @returns {boolean|jqXHR}
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
run: function(model, configID) {
|
||||||
|
model.notifyAboutDetectionStart('ldap_port');
|
||||||
|
var params = OC.buildQueryString({
|
||||||
|
action: 'guessPortAndTLS',
|
||||||
|
ldap_serverconfig_chooser: configID
|
||||||
|
});
|
||||||
|
return model.callWizard(params, this.processResult, this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorPort = WizardDetectorPort;
|
||||||
|
})();
|
|
@ -0,0 +1,89 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
/**
|
||||||
|
* @classdesc only run detector is allowed to run at a time. Basically
|
||||||
|
* because we cannot have parallel LDAP connections per session. This
|
||||||
|
* queue is takes care of running all the detectors one after the other.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorQueue = OCA.LDAP.Wizard.WizardObject.subClass({
|
||||||
|
/**
|
||||||
|
* initializes the instance. Always call it after creating the instance.
|
||||||
|
*/
|
||||||
|
init: function() {
|
||||||
|
this.queue = [];
|
||||||
|
this.isRunning = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* empties the queue and cancels a possibly running request
|
||||||
|
*/
|
||||||
|
reset: function() {
|
||||||
|
this.queue = [];
|
||||||
|
if(!_.isUndefined(this.runningRequest)) {
|
||||||
|
this.runningRequest.abort();
|
||||||
|
delete this.runningRequest;
|
||||||
|
}
|
||||||
|
this.isRunning = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a parameter-free callback that eventually executes the run method of
|
||||||
|
* the detector.
|
||||||
|
*
|
||||||
|
* @callback detectorCallBack
|
||||||
|
* @see OCA.LDAP.Wizard.ConfigModel._processSetResult
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds a detector to the queue and attempts to trigger to run the
|
||||||
|
* next job, because it might be the first.
|
||||||
|
*
|
||||||
|
* @param {detectorCallBack} callback
|
||||||
|
*/
|
||||||
|
add: function(callback) {
|
||||||
|
this.queue.push(callback);
|
||||||
|
this.next();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the next detector if none is running. This method is also
|
||||||
|
* automatically invoked after a detector finished.
|
||||||
|
*/
|
||||||
|
next: function() {
|
||||||
|
if(this.isRunning === true || this.queue.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isRunning = true;
|
||||||
|
var callback = this.queue.shift();
|
||||||
|
var request = callback();
|
||||||
|
|
||||||
|
// we receive either false or a jqXHR object
|
||||||
|
// false in case the detector decided against executing
|
||||||
|
if(request === false) {
|
||||||
|
this.isRunning = false;
|
||||||
|
this.next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.runningRequest = request;
|
||||||
|
|
||||||
|
var detectorQueue = this;
|
||||||
|
$.when(request).then(function() {
|
||||||
|
detectorQueue.isRunning = false;
|
||||||
|
detectorQueue.next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorQueue = WizardDetectorQueue;
|
||||||
|
})();
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc a Port Detector. It executes the auto-detection of the port
|
||||||
|
* by the ownCloud server, if requirements are met.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorFilterSimpleRequestAbstract = OCA.LDAP.Wizard.WizardDetectorGeneric.subClass({
|
||||||
|
runsOnRequest: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* runs the detector, if port is not set.
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} model
|
||||||
|
* @param {string} configID - the configuration prefix
|
||||||
|
* @returns {boolean|jqXHR}
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
run: function(model, configID) {
|
||||||
|
if(_.isUndefined(this.wizardMethod)) {
|
||||||
|
console.warn('wizardMethod not set! ' + this.constructor);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
model.notifyAboutDetectionStart(this.targetKey);
|
||||||
|
var params = OC.buildQueryString({
|
||||||
|
action: this.wizardMethod,
|
||||||
|
ldap_serverconfig_chooser: configID
|
||||||
|
});
|
||||||
|
return model.callWizard(params, this.processResult, this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorFilterSimpleRequestAbstract = WizardDetectorFilterSimpleRequestAbstract;
|
||||||
|
})();
|
|
@ -0,0 +1,63 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc a Port Detector. It executes the auto-detection of the port
|
||||||
|
* by the ownCloud server, if requirements are met.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorTestAbstract = OCA.LDAP.Wizard.WizardDetectorGeneric.subClass({
|
||||||
|
isLegacy: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* runs the test
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} model
|
||||||
|
* @param {string} configID - the configuration prefix
|
||||||
|
* @param {Object} params - additional parameters needed to send to the
|
||||||
|
* wizard
|
||||||
|
* @returns {boolean|jqXHR}
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
run: function(model, configID, params) {
|
||||||
|
if(_.isUndefined(this.wizardMethod) && !this.isLegacy) {
|
||||||
|
console.warn('wizardMethod not set! ' + this.constructor);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
model.notifyAboutDetectionStart(this.getTargetKey());
|
||||||
|
params = params || {};
|
||||||
|
params = OC.buildQueryString($.extend({
|
||||||
|
action: this.wizardMethod,
|
||||||
|
ldap_serverconfig_chooser: configID
|
||||||
|
}, params));
|
||||||
|
if(!this.isLegacy) {
|
||||||
|
return model.callWizard(params, this.processResult, this);
|
||||||
|
} else {
|
||||||
|
return model.callAjax(this.legacyDestination, params, this.processResult, this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
processResult: function(model, detector, result) {
|
||||||
|
model['notifyAboutDetectionCompletion'](detector.getTargetKey());
|
||||||
|
var payload = {
|
||||||
|
feature: detector.testName,
|
||||||
|
data: result
|
||||||
|
};
|
||||||
|
model.inform(payload);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorTestAbstract = WizardDetectorTestAbstract;
|
||||||
|
})();
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc Tests, how many objects reside in the given base DN(s)
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorTestBaseDN = OCA.LDAP.Wizard.WizardDetectorTestAbstract.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
// given, it is not a configuration key
|
||||||
|
this.setTargetKey('ldap_test_base');
|
||||||
|
this.testName = 'TestBaseDN';
|
||||||
|
this.wizardMethod = 'countInBaseDN';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorTestBaseDN = WizardDetectorTestBaseDN;
|
||||||
|
})();
|
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc a Port Detector. It executes the auto-detection of the port
|
||||||
|
* by the ownCloud server, if requirements are met.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorTestConfiguration = OCA.LDAP.Wizard.WizardDetectorTestAbstract.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
// given, it is not a configuration key
|
||||||
|
this.setTargetKey('ldap_action_test_connection');
|
||||||
|
this.testName = 'TestConfiguration';
|
||||||
|
this.isLegacy = true;
|
||||||
|
this.legacyDestination = 'testConfiguration.php';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorTestConfiguration = WizardDetectorTestConfiguration;
|
||||||
|
})();
|
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc checks whether the provided log in name can be resolved into
|
||||||
|
* a DN using the current login filter
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorTestLoginName = OCA.LDAP.Wizard.WizardDetectorTestAbstract.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
// given, it is not a configuration key
|
||||||
|
this.setTargetKey('ldap_test_loginname');
|
||||||
|
this.testName = 'TestLoginName';
|
||||||
|
this.wizardMethod = 'testLoginName';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorTestLoginName = WizardDetectorTestLoginName;
|
||||||
|
})();
|
|
@ -0,0 +1,26 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc let's the wizard backend count the available users
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorUserCount = OCA.LDAP.Wizard.WizardDetectorFilterSimpleRequestAbstract.subClass({
|
||||||
|
init: function() {
|
||||||
|
this.setTargetKey('ldap_user_count');
|
||||||
|
this.wizardMethod = 'countUsers';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorUserCount = WizardDetectorUserCount;
|
||||||
|
})();
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc let's the wizard backend count the available users
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorUserDisplayNameAttribute = OCA.LDAP.Wizard.WizardDetectorFilterSimpleRequestAbstract.subClass({
|
||||||
|
init: function() {
|
||||||
|
this.setTargetKey('ldap_user_count');
|
||||||
|
this.wizardMethod = 'detectUserDisplayNameAttribute';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
run: function(model, configID) {
|
||||||
|
// default value has capital N. Detected values are always lowercase
|
||||||
|
if(model.configuration.ldap_display_name && model.configuration.ldap_display_name !== 'displayName') {
|
||||||
|
// a value is already set. Don't overwrite and don't ask LDAP
|
||||||
|
// without reason.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this._super(model, configID);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorUserDisplayNameAttribute = WizardDetectorUserDisplayNameAttribute;
|
||||||
|
})();
|
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc let's the wizard backend count the available users
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorUserGroupAssociation = OCA.LDAP.Wizard.WizardDetectorFilterSimpleRequestAbstract.subClass({
|
||||||
|
init: function() {
|
||||||
|
this.setTargetKey('ldap_group_count');
|
||||||
|
this.wizardMethod = 'determineGroupMemberAssoc';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
run: function(model, configID) {
|
||||||
|
// TODO: might be better with configuration marker as uniqueMember
|
||||||
|
// is a valid value (although probably less common then member and memberUid).
|
||||||
|
if(model.configuration.ldap_group_member_assoc_attribute && model.configuration.ldap_group_member_assoc_attribute !== 'uniqueMember') {
|
||||||
|
// a value is already set. Don't overwrite and don't ask LDAP
|
||||||
|
// without reason.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this._super(model, configID);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorUserGroupAssociation = WizardDetectorUserGroupAssociation;
|
||||||
|
})();
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc discovers object classes for the users tab
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardDetectorUserObjectClasses = OCA.LDAP.Wizard.WizardDetectorFeatureAbstract.subClass({
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function() {
|
||||||
|
// given, it is not a configuration key
|
||||||
|
this.setTargetKey('ldap_userfilter_objectclass');
|
||||||
|
this.wizardMethod = 'determineUserObjectClasses';
|
||||||
|
this.featureName = 'UserObjectClasses';
|
||||||
|
this.runsOnRequest = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardDetectorUserObjectClasses = WizardDetectorUserObjectClasses;
|
||||||
|
})();
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc filters a select box when a text element is typed in
|
||||||
|
*/
|
||||||
|
var FilterOnType = OCA.LDAP.Wizard.WizardObject.subClass({
|
||||||
|
/**
|
||||||
|
* initializes a type filter on a text input for a select element
|
||||||
|
*
|
||||||
|
* @param {jQuery} $select
|
||||||
|
* @param {jQuery} $textInput
|
||||||
|
*/
|
||||||
|
init: function($select, $textInput) {
|
||||||
|
this.$select = $select;
|
||||||
|
this.$textInput = $textInput;
|
||||||
|
this.updateOptions();
|
||||||
|
this.lastSearch = '';
|
||||||
|
|
||||||
|
var fity = this;
|
||||||
|
$textInput.bind('change keyup', function () {
|
||||||
|
if(fity.runID) {
|
||||||
|
window.clearTimeout(fity.runID);
|
||||||
|
}
|
||||||
|
fity.runID = window.setTimeout(function() {
|
||||||
|
fity.filter(fity);
|
||||||
|
}, 250);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the options will be read in again. Should be called after a
|
||||||
|
* configuration switch.
|
||||||
|
*/
|
||||||
|
updateOptions: function() {
|
||||||
|
var options = [];
|
||||||
|
this.$select.find('option').each(function() {
|
||||||
|
options.push({
|
||||||
|
value: $(this).val(),
|
||||||
|
normalized: $(this).val().toLowerCase()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
this._options = options;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the actual search or filter method
|
||||||
|
*
|
||||||
|
* @param {FilterOnType} fity
|
||||||
|
*/
|
||||||
|
filter: function(fity) {
|
||||||
|
var filterVal = fity.$textInput.val().toLowerCase();
|
||||||
|
if(filterVal === fity.lastSearch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fity.lastSearch = filterVal;
|
||||||
|
fity.$select.empty();
|
||||||
|
$.each(fity._options, function() {
|
||||||
|
if(!filterVal || this.normalized.indexOf(filterVal) > -1) {
|
||||||
|
fity.$select.append($('<option>').val(this.value).text(this.value));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
delete(fity.runID);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.FilterOnType = FilterOnType;
|
||||||
|
})();
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc creates instances of OCA.LDAP.Wizard.FilterOnType upon request
|
||||||
|
*/
|
||||||
|
var FilterOnTypeFactory = OCA.LDAP.Wizard.WizardObject.subClass({
|
||||||
|
/**
|
||||||
|
* initializes a type filter on a text input for a select element
|
||||||
|
*
|
||||||
|
* @param {jQuery} $select
|
||||||
|
* @param {jQuery} $textInput
|
||||||
|
*/
|
||||||
|
get: function($select, $textInput) {
|
||||||
|
return new OCA.LDAP.Wizard.FilterOnType($select, $textInput);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.FilterOnTypeFactory = FilterOnTypeFactory;
|
||||||
|
})();
|
|
@ -0,0 +1,60 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var initializing = false;
|
||||||
|
var superPattern = /xyz/.test(function() { xyz; }) ? /\b_super\b/ : /.*/;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc a base class that allows inheritance
|
||||||
|
*
|
||||||
|
* @abstrcact
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var WizardObject = function(){};
|
||||||
|
WizardObject.subClass = function(properties) {
|
||||||
|
var _super = this.prototype;
|
||||||
|
|
||||||
|
initializing = true;
|
||||||
|
var proto = new this();
|
||||||
|
initializing = false;
|
||||||
|
|
||||||
|
for (var name in properties) {
|
||||||
|
proto[name] =
|
||||||
|
typeof properties[name] === "function" &&
|
||||||
|
typeof _super[name] === 'function' &&
|
||||||
|
superPattern.test(properties[name]) ?
|
||||||
|
(function (name, fn) {
|
||||||
|
return function () {
|
||||||
|
var tmp = this._super;
|
||||||
|
this._super = _super[name];
|
||||||
|
var ret = fn.apply(this, arguments);
|
||||||
|
this._super = tmp;
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
})(name, properties[name]) :
|
||||||
|
properties[name];
|
||||||
|
};
|
||||||
|
|
||||||
|
function Class() {
|
||||||
|
if(!initializing && this.init) {
|
||||||
|
this.init.apply(this, arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Class.prototype = proto;
|
||||||
|
Class.constructor = Class;
|
||||||
|
Class.subClass = arguments.callee;
|
||||||
|
return Class;
|
||||||
|
};
|
||||||
|
|
||||||
|
WizardObject.constructor = WizardObject;
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardObject = WizardObject;
|
||||||
|
})();
|
|
@ -0,0 +1,378 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc This class represents the view belonging to the server tab
|
||||||
|
* in the LDAP wizard.
|
||||||
|
*/
|
||||||
|
var WizardTabAbstractFilter = OCA.LDAP.Wizard.WizardTabGeneric.subClass({
|
||||||
|
/**
|
||||||
|
* @property {number} number that needs to exceeded to use complex group
|
||||||
|
* selection element
|
||||||
|
*/
|
||||||
|
_groupElementSwitchThreshold: 40,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {boolean} - tells whether multiselect or complex element is
|
||||||
|
* used for selecting groups
|
||||||
|
*/
|
||||||
|
isComplexGroupChooser: false,
|
||||||
|
|
||||||
|
/** @property {string} */
|
||||||
|
tabID: '',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initializes the instance. Always call it after initialization.
|
||||||
|
* concrete view must set managed items first, and then call the parent
|
||||||
|
* init.
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.FilterOnTypeFactory} fotf
|
||||||
|
* @param {number} [tabIndex]
|
||||||
|
* @param {string} [tabID]
|
||||||
|
*/
|
||||||
|
init: function (fotf, tabIndex, tabID) {
|
||||||
|
this._super(tabIndex, tabID);
|
||||||
|
|
||||||
|
/** @type {OCA.LDAP.Wizard.FilterOnTypeFactory} */
|
||||||
|
this.foTFactory = fotf;
|
||||||
|
this._initMultiSelect(
|
||||||
|
this.getGroupsItem().$element,
|
||||||
|
t('user_ldap', 'Select groups')
|
||||||
|
);
|
||||||
|
this._initMultiSelect(
|
||||||
|
this.getObjectClassItem().$element,
|
||||||
|
t('user_ldap', 'Select object classes')
|
||||||
|
);
|
||||||
|
this.filterName = this.getFilterItem().keyName;
|
||||||
|
this._initFilterModeSwitcher(
|
||||||
|
this.getToggleItem().$element,
|
||||||
|
this.getRawFilterContainerItem().$element,
|
||||||
|
[ this.getObjectClassItem().$element ],
|
||||||
|
this.getFilterModeKey(),
|
||||||
|
{
|
||||||
|
status: 'disabled',
|
||||||
|
$element: this.getGroupsItem().$element
|
||||||
|
}
|
||||||
|
);
|
||||||
|
_.bindAll(this, 'onCountButtonClick', 'onSelectGroup', 'onDeselectGroup');
|
||||||
|
this.getCountItem().$relatedElements.click(this.onCountButtonClick);
|
||||||
|
if(this.manyGroupsSupport) {
|
||||||
|
var $selectBtn = $(this.tabID).find('.ldapGroupListSelect');
|
||||||
|
$selectBtn.click(this.onSelectGroup);
|
||||||
|
var $deselectBtn = $(this.tabID).find('.ldapGroupListDeselect');
|
||||||
|
$deselectBtn.click(this.onDeselectGroup);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns managed item for the object class chooser. must be
|
||||||
|
* implemented by concrete view
|
||||||
|
*/
|
||||||
|
getObjectClassItem: function () {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns managed item for the group chooser. must be
|
||||||
|
* implemented by concrete view
|
||||||
|
*/
|
||||||
|
getGroupsItem: function () {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns managed item for the effective filter. must be
|
||||||
|
* implemented by concrete view
|
||||||
|
*/
|
||||||
|
getFilterItem: function () {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns managed item for the toggle element. must be
|
||||||
|
* implemented by concrete view
|
||||||
|
*/
|
||||||
|
getToggleItem: function () {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns managed item for the raw filter container. must be
|
||||||
|
* implemented by concrete view
|
||||||
|
*/
|
||||||
|
getRawFilterContainerItem: function () {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns managed item for the count control. must be
|
||||||
|
* implemented by concrete view
|
||||||
|
*/
|
||||||
|
getCountItem: function () {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns name of the filter mode key. must be implemented by concrete
|
||||||
|
* view
|
||||||
|
*/
|
||||||
|
getFilterModeKey: function () {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the config model for this view and subscribes to some events.
|
||||||
|
* Also binds the config chooser to the model
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} configModel
|
||||||
|
*/
|
||||||
|
setModel: function(configModel) {
|
||||||
|
this._super(configModel);
|
||||||
|
this.configModel.on('configLoaded', this.onConfigSwitch, this);
|
||||||
|
this.configModel.on('receivedLdapFeature', this.onFeatureReceived, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
_setFilterModeAssisted: function () {
|
||||||
|
this._super();
|
||||||
|
if(this.isComplexGroupChooser) {
|
||||||
|
this.enableElement(this.getGroupsItem().$relatedElements);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
_setFilterModeRaw: function () {
|
||||||
|
this._super();
|
||||||
|
if(this.manyGroupsSupport) {
|
||||||
|
this.disableElement(this.getGroupsItem().$relatedElements);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the selected user object classes
|
||||||
|
*
|
||||||
|
* @param {Array} classes
|
||||||
|
*/
|
||||||
|
setObjectClass: function(classes) {
|
||||||
|
this.setElementValue(this.getObjectClassItem().$element, classes);
|
||||||
|
this.getObjectClassItem().$element.multiselect('refresh');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the selected groups
|
||||||
|
*
|
||||||
|
* @param {Array} groups
|
||||||
|
*/
|
||||||
|
setGroups: function(groups) {
|
||||||
|
if(!this.isComplexGroupChooser) {
|
||||||
|
this.setElementValue(this.getGroupsItem().$element, groups);
|
||||||
|
this.getGroupsItem().$element.multiselect('refresh');
|
||||||
|
} else {
|
||||||
|
var $element = $(this.tabID).find('.ldapGroupListSelected');
|
||||||
|
this.equipMultiSelect($element, groups);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the filter
|
||||||
|
*
|
||||||
|
* @param {string} filter
|
||||||
|
*/
|
||||||
|
setFilter: function(filter) {
|
||||||
|
this.setElementValue(this.getFilterItem().$element, filter);
|
||||||
|
this.$filterModeRawContainer.siblings('.ldapReadOnlyFilterContainer').find('.ldapFilterReadOnlyElement').text(filter);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the user count string
|
||||||
|
*
|
||||||
|
* @param {string} countInfo
|
||||||
|
*/
|
||||||
|
setCount: function(countInfo) {
|
||||||
|
this.setElementValue(this.getCountItem().$element, countInfo);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
considerFeatureRequests: function() {
|
||||||
|
if(!this.isActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(this.getObjectClassItem().$element.find('option').length === 0) {
|
||||||
|
this.disableElement(this.getObjectClassItem().$element);
|
||||||
|
this.disableElement(this.getGroupsItem().$element);
|
||||||
|
if(this.parsedFilterMode === this.configModel.FILTER_MODE_ASSISTED) {
|
||||||
|
this.configModel.requestWizard(this.getObjectClassItem().keyName);
|
||||||
|
this.configModel.requestWizard(this.getGroupsItem().keyName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates (creates, if necessary) filterOnType instances
|
||||||
|
*
|
||||||
|
* @param {string} [only] - if only one search index should be updated
|
||||||
|
*/
|
||||||
|
updateFilterOnType: function(only) {
|
||||||
|
if(_.isUndefined(this.filterOnType)) {
|
||||||
|
this.filterOnType = [];
|
||||||
|
|
||||||
|
var $availableGroups = $(this.tabID).find('.ldapGroupListAvailable');
|
||||||
|
this.filterOnType.push(this.foTFactory.get(
|
||||||
|
$availableGroups, $(this.tabID).find('.ldapManyGroupsSearch')
|
||||||
|
));
|
||||||
|
var $selectedGroups = $(this.tabID).find('.ldapGroupListSelected');
|
||||||
|
this.filterOnType.push(this.foTFactory.get(
|
||||||
|
$selectedGroups, $(this.tabID).find('.ldapManyGroupsSearch')
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
if(_.isUndefined || only.toLowerCase() === 'available') {
|
||||||
|
this.filterOnType[0].updateOptions();
|
||||||
|
}
|
||||||
|
if(_.isUndefined || only.toLowerCase() === 'selected') {
|
||||||
|
this.filterOnType[1].updateOptions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
onActivate: function() {
|
||||||
|
this.considerFeatureRequests();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resets the view when a configuration switch happened.
|
||||||
|
*
|
||||||
|
* @param {WizardTabAbstractFilter} view
|
||||||
|
* @param {Object} configuration
|
||||||
|
*/
|
||||||
|
onConfigSwitch: function(view, configuration) {
|
||||||
|
view.getObjectClassItem().$element.find('option').remove();
|
||||||
|
view.getGroupsItem().$element.find('option').remove();
|
||||||
|
view.getCountItem().$element.text('');
|
||||||
|
$(view.tabID).find('.ldapGroupListAvailable').empty();
|
||||||
|
$(view.tabID).find('.ldapGroupListSelected').empty();
|
||||||
|
view.updateFilterOnType();
|
||||||
|
$(view.tabID).find('.ldapManyGroupsSearch').val('');
|
||||||
|
|
||||||
|
if(view.isComplexGroupChooser) {
|
||||||
|
view.isComplexGroupChooser = false;
|
||||||
|
view.getGroupsItem().$element.multiselect({classes: view.multiSelectPluginClass});
|
||||||
|
$(view.tabID).find(".ldapManyGroupsSupport").addClass('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
view.onConfigLoaded(view, configuration);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
onConfigLoaded: function(view, configuration) {
|
||||||
|
for(var key in view.managedItems){
|
||||||
|
if(!_.isUndefined(configuration[key])) {
|
||||||
|
var value = configuration[key];
|
||||||
|
var methodName = view.managedItems[key].setMethod;
|
||||||
|
if(!_.isUndefined(view[methodName])) {
|
||||||
|
view[methodName](value);
|
||||||
|
// we reimplement it here to update the filter index
|
||||||
|
// for groups. Maybe we can isolate it?
|
||||||
|
if(methodName === 'setGroups') {
|
||||||
|
view.updateFilterOnType('selected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if UserObjectClasses are found, the corresponding element will be
|
||||||
|
* updated
|
||||||
|
*
|
||||||
|
* @param {WizardTabAbstractFilter} view
|
||||||
|
* @param {FeaturePayload} payload
|
||||||
|
*/
|
||||||
|
onFeatureReceived: function(view, payload) {
|
||||||
|
if(payload.feature === view.getObjectClassItem().featureName) {
|
||||||
|
view.equipMultiSelect(view.getObjectClassItem().$element, payload.data);
|
||||||
|
if( !view.getFilterItem().$element.val()
|
||||||
|
&& view.parsedFilterMode === view.configModel.FILTER_MODE_ASSISTED
|
||||||
|
) {
|
||||||
|
view.configModel.requestWizard(view.getFilterItem().keyName)
|
||||||
|
}
|
||||||
|
} else if (payload.feature === view.getGroupsItem().featureName) {
|
||||||
|
if(view.manyGroupsSupport && payload.data.length > view._groupElementSwitchThreshold) {
|
||||||
|
// we need to fill the left list box, excluding the values
|
||||||
|
// that are already selected
|
||||||
|
var $element = $(view.tabID).find('.ldapGroupListAvailable');
|
||||||
|
var selected = view.configModel.configuration[view.getGroupsItem().keyName];
|
||||||
|
var available = $(payload.data).not(selected).get();
|
||||||
|
view.equipMultiSelect($element, available);
|
||||||
|
view.updateFilterOnType('available');
|
||||||
|
$(view.tabID).find(".ldapManyGroupsSupport").removeClass('hidden');
|
||||||
|
view.getGroupsItem().$element.multiselect({classes: view.multiSelectPluginClass + ' forceHidden'});
|
||||||
|
view.isComplexGroupChooser = true;
|
||||||
|
} else {
|
||||||
|
view.isComplexGroupChooser = false;
|
||||||
|
view.equipMultiSelect(view.getGroupsItem().$element, payload.data);
|
||||||
|
view.getGroupsItem().$element.multiselect({classes: view.multiSelectPluginClass});
|
||||||
|
$(view.tabID).find(".ldapManyGroupsSupport").addClass('hidden');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* request to count the users with the current filter
|
||||||
|
*
|
||||||
|
* @param {Event} event
|
||||||
|
*/
|
||||||
|
onCountButtonClick: function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
// let's clear the field
|
||||||
|
this.getCountItem().$element.text('');
|
||||||
|
this.configModel.requestWizard(this.getCountItem().keyName);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* saves groups when using the complex UI
|
||||||
|
*
|
||||||
|
* @param {Array} groups
|
||||||
|
* @returns {boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_saveGroups: function(groups) {
|
||||||
|
var toSave = '';
|
||||||
|
$(groups).each(function() { toSave = toSave + "\n" + this; } );
|
||||||
|
this.configModel.set(this.getGroupsItem().keyName, $.trim(toSave));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acts on adding groups to the filter
|
||||||
|
*/
|
||||||
|
onSelectGroup: function() {
|
||||||
|
var $available = $(this.tabID).find('.ldapGroupListAvailable');
|
||||||
|
var $selected = $(this.tabID).find('.ldapGroupListSelected');
|
||||||
|
var selected = $.map($selected.find('option'), function(e) { return e.value; });
|
||||||
|
|
||||||
|
this._saveGroups(selected.concat($available.val()));
|
||||||
|
$available.find('option:selected').prependTo($selected);
|
||||||
|
this.updateFilterOnType();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acts on removing groups to the filter
|
||||||
|
*/
|
||||||
|
onDeselectGroup: function() {
|
||||||
|
var $available = $(this.tabID).find('.ldapGroupListAvailable');
|
||||||
|
var $selected = $(this.tabID).find('.ldapGroupListSelected');
|
||||||
|
var selected = $.map($selected.find('option:not(:selected)'), function(e) { return e.value; });
|
||||||
|
|
||||||
|
this._saveGroups(selected);
|
||||||
|
$selected.find('option:selected').appendTo($available);
|
||||||
|
this.updateFilterOnType();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardTabAbstractFilter = WizardTabAbstractFilter;
|
||||||
|
})();
|
|
@ -0,0 +1,330 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc This class represents the view belonging to the advanced tab
|
||||||
|
* in the LDAP wizard.
|
||||||
|
*/
|
||||||
|
var WizardTabAdvanced = OCA.LDAP.Wizard.WizardTabGeneric.subClass({
|
||||||
|
/**
|
||||||
|
* initializes the instance. Always call it after initialization.
|
||||||
|
*
|
||||||
|
* @param tabIndex
|
||||||
|
* @param tabID
|
||||||
|
*/
|
||||||
|
init: function (tabIndex, tabID) {
|
||||||
|
this._super(tabIndex, tabID);
|
||||||
|
|
||||||
|
var items = {
|
||||||
|
// Connection settings
|
||||||
|
ldap_configuration_active: {
|
||||||
|
$element: $('#ldap_configuration_active'),
|
||||||
|
setMethod: 'setConfigurationState'
|
||||||
|
},
|
||||||
|
ldap_backup_host: {
|
||||||
|
$element: $('#ldap_backup_host'),
|
||||||
|
setMethod: 'setBackupHost'
|
||||||
|
},
|
||||||
|
ldap_backup_port: {
|
||||||
|
$element: $('#ldap_backup_port'),
|
||||||
|
setMethod: 'setBackupPort'
|
||||||
|
},
|
||||||
|
ldap_override_main_server: {
|
||||||
|
$element: $('#ldap_override_main_server'),
|
||||||
|
setMethod: 'setOverrideMainServerState'
|
||||||
|
},
|
||||||
|
ldap_nocase: {
|
||||||
|
$element: $('#ldap_nocase'),
|
||||||
|
setMethod: 'setNoCase'
|
||||||
|
},
|
||||||
|
ldap_turn_off_cert_check: {
|
||||||
|
$element: $('#ldap_turn_off_cert_check'),
|
||||||
|
setMethod: 'setCertCheckDisabled'
|
||||||
|
},
|
||||||
|
ldap_cache_ttl: {
|
||||||
|
$element: $('#ldap_cache_ttl'),
|
||||||
|
setMethod: 'setCacheTTL'
|
||||||
|
},
|
||||||
|
|
||||||
|
//Directory Settings
|
||||||
|
ldap_display_name: {
|
||||||
|
$element: $('#ldap_display_name'),
|
||||||
|
setMethod: 'setUserDisplayName'
|
||||||
|
},
|
||||||
|
ldap_base_users: {
|
||||||
|
$element: $('#ldap_base_users'),
|
||||||
|
setMethod: 'setBaseDNUsers'
|
||||||
|
},
|
||||||
|
ldap_attributes_for_user_search: {
|
||||||
|
$element: $('#ldap_attributes_for_user_search'),
|
||||||
|
setMethod: 'setSearchAttributesUsers'
|
||||||
|
},
|
||||||
|
ldap_group_display_name: {
|
||||||
|
$element: $('#ldap_group_display_name'),
|
||||||
|
setMethod: 'setGroupDisplayName'
|
||||||
|
},
|
||||||
|
ldap_base_groups: {
|
||||||
|
$element: $('#ldap_base_groups'),
|
||||||
|
setMethod: 'setBaseDNGroups'
|
||||||
|
},
|
||||||
|
ldap_attributes_for_group_search: {
|
||||||
|
$element: $('#ldap_attributes_for_group_search'),
|
||||||
|
setMethod: 'setSearchAttributesGroups'
|
||||||
|
},
|
||||||
|
ldap_group_member_assoc_attribute: {
|
||||||
|
$element: $('#ldap_group_member_assoc_attribute'),
|
||||||
|
setMethod: 'setGroupMemberAssociationAttribute'
|
||||||
|
},
|
||||||
|
ldap_nested_groups: {
|
||||||
|
$element: $('#ldap_nested_groups'),
|
||||||
|
setMethod: 'setUseNestedGroups'
|
||||||
|
},
|
||||||
|
ldap_paging_size: {
|
||||||
|
$element: $('#ldap_paging_size'),
|
||||||
|
setMethod: 'setPagingSize'
|
||||||
|
},
|
||||||
|
|
||||||
|
//Special Attributes
|
||||||
|
ldap_quota_attr: {
|
||||||
|
$element: $('#ldap_quota_attr'),
|
||||||
|
setMethod: 'setQuotaAttribute'
|
||||||
|
},
|
||||||
|
ldap_quota_def: {
|
||||||
|
$element: $('#ldap_quota_def'),
|
||||||
|
setMethod: 'setQuotaDefault'
|
||||||
|
},
|
||||||
|
ldap_email_attr: {
|
||||||
|
$element: $('#ldap_email_attr'),
|
||||||
|
setMethod: 'setEmailAttribute'
|
||||||
|
},
|
||||||
|
home_folder_naming_rule: {
|
||||||
|
$element: $('#home_folder_naming_rule'),
|
||||||
|
setMethod: 'setHomeFolderAttribute'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.setManagedItems(items);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the config model for this view and subscribes to some events.
|
||||||
|
* Also binds the config chooser to the model
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} configModel
|
||||||
|
*/
|
||||||
|
setModel: function(configModel) {
|
||||||
|
this._super(configModel);
|
||||||
|
this.configModel.on('configLoaded', this.onConfigLoaded, this);
|
||||||
|
this.configModel.on('receivedLdapFeature', this.onResultReceived, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the experienced admin check box
|
||||||
|
*
|
||||||
|
* @param {string} isConfigActive contains an int
|
||||||
|
*/
|
||||||
|
setConfigurationState: function(isConfigActive) {
|
||||||
|
this.setElementValue(
|
||||||
|
this.managedItems.ldap_configuration_active.$element, isConfigActive
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the backup host configuration text field
|
||||||
|
*
|
||||||
|
* @param {string} host
|
||||||
|
*/
|
||||||
|
setBackupHost: function(host) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_backup_host.$element, host);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the backup port configuration text field
|
||||||
|
*
|
||||||
|
* @param {string} port
|
||||||
|
*/
|
||||||
|
setBackupPort: function(port) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_backup_port.$element, port);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets whether the main server should be overridden or not
|
||||||
|
*
|
||||||
|
* @param {string} doOverride contains an int
|
||||||
|
*/
|
||||||
|
setOverrideMainServerState: function(doOverride) {
|
||||||
|
this.setElementValue(
|
||||||
|
this.managedItems.ldap_override_main_server.$element, doOverride
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* whether the server is case insensitive. This setting does not play
|
||||||
|
* a role anymore (probably never had).
|
||||||
|
*
|
||||||
|
* @param {string} noCase contains an int
|
||||||
|
*/
|
||||||
|
setNoCase: function(noCase) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_nocase.$element, noCase);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets whether the SSL/TLS certification check shout be disabled
|
||||||
|
*
|
||||||
|
* @param {string} doCertCheck contains an int
|
||||||
|
*/
|
||||||
|
setCertCheckDisabled: function(doCertCheck) {
|
||||||
|
this.setElementValue(
|
||||||
|
this.managedItems.ldap_turn_off_cert_check.$element, doCertCheck
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the time-to-live of the LDAP cache (in seconds)
|
||||||
|
*
|
||||||
|
* @param {string} cacheTTL contains an int
|
||||||
|
*/
|
||||||
|
setCacheTTL: function(cacheTTL) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_cache_ttl.$element, cacheTTL);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the user display name attribute
|
||||||
|
*
|
||||||
|
* @param {string} attribute
|
||||||
|
*/
|
||||||
|
setUserDisplayName: function(attribute) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_display_name.$element, attribute);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the Base DN for users
|
||||||
|
*
|
||||||
|
* @param {string} base
|
||||||
|
*/
|
||||||
|
setBaseDNUsers: function(base) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_base_users.$element, base);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the attributes for user searches
|
||||||
|
*
|
||||||
|
* @param {string} attributes
|
||||||
|
*/
|
||||||
|
setSearchAttributesUsers: function(attributes) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_attributes_for_user_search.$element, attributes);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the display name attribute for groups
|
||||||
|
*
|
||||||
|
* @param {string} attribute
|
||||||
|
*/
|
||||||
|
setGroupDisplayName: function(attribute) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_group_display_name.$element, attribute);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the Base DN for groups
|
||||||
|
*
|
||||||
|
* @param {string} base
|
||||||
|
*/
|
||||||
|
setBaseDNGroups: function(base) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_base_groups.$element, base);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the attributes for group search
|
||||||
|
*
|
||||||
|
* @param {string} attributes
|
||||||
|
*/
|
||||||
|
setSearchAttributesGroups: function(attributes) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_attributes_for_group_search.$element, attributes);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the attribute for the association of users and groups
|
||||||
|
*
|
||||||
|
* @param {string} attribute
|
||||||
|
*/
|
||||||
|
setGroupMemberAssociationAttribute: function(attribute) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_group_member_assoc_attribute.$element, attribute);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enabled or disables the use of nested groups (groups in groups in
|
||||||
|
* groups…)
|
||||||
|
*
|
||||||
|
* @param {string} useNestedGroups contains an int
|
||||||
|
*/
|
||||||
|
setUseNestedGroups: function(useNestedGroups) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_nested_groups.$element, useNestedGroups);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the size of pages for paged search
|
||||||
|
*
|
||||||
|
* @param {string} size contains an int
|
||||||
|
*/
|
||||||
|
setPagingSize: function(size) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_paging_size.$element, size);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the email attribute
|
||||||
|
*
|
||||||
|
* @param {string} attribute
|
||||||
|
*/
|
||||||
|
setEmailAttribute: function(attribute) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_email_attr.$element, attribute);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the quota attribute
|
||||||
|
*
|
||||||
|
* @param {string} attribute
|
||||||
|
*/
|
||||||
|
setQuotaAttribute: function(attribute) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_quota_attr.$element, attribute);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the default quota for LDAP users
|
||||||
|
*
|
||||||
|
* @param {string} quota contains an int
|
||||||
|
*/
|
||||||
|
setQuotaDefault: function(quota) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_quota_def.$element, quota);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the attribute for the ownCloud user specific home folder location
|
||||||
|
*
|
||||||
|
* @param {string} attribute
|
||||||
|
*/
|
||||||
|
setHomeFolderAttribute: function(attribute) {
|
||||||
|
this.setElementValue(this.managedItems.home_folder_naming_rule.$element, attribute);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deals with the result of the Test Connection test
|
||||||
|
*
|
||||||
|
* @param {WizardTabAdvanced} view
|
||||||
|
* @param {FeaturePayload} payload
|
||||||
|
*/
|
||||||
|
onResultReceived: function(view, payload) {
|
||||||
|
if(payload.feature === 'TestConfiguration') {
|
||||||
|
OC.Notification.showTemporary(payload.data.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardTabAdvanced = WizardTabAdvanced;
|
||||||
|
})();
|
|
@ -0,0 +1,347 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc This class represents the view belonging to the server tab
|
||||||
|
* in the LDAP wizard.
|
||||||
|
*/
|
||||||
|
var WizardTabElementary = OCA.LDAP.Wizard.WizardTabGeneric.subClass({
|
||||||
|
/**
|
||||||
|
* initializes the instance. Always call it after initialization.
|
||||||
|
*
|
||||||
|
* @param tabIndex
|
||||||
|
* @param tabID
|
||||||
|
*/
|
||||||
|
init: function (tabIndex, tabID) {
|
||||||
|
tabIndex = 0;
|
||||||
|
this._super(tabIndex, tabID);
|
||||||
|
this.isActive = true;
|
||||||
|
this.configChooserID = '#ldap_serverconfig_chooser';
|
||||||
|
|
||||||
|
var items = {
|
||||||
|
ldap_host: {
|
||||||
|
$element: $('#ldap_host'),
|
||||||
|
setMethod: 'setHost'
|
||||||
|
},
|
||||||
|
ldap_port: {
|
||||||
|
$element: $('#ldap_port'),
|
||||||
|
setMethod: 'setPort',
|
||||||
|
$relatedElements: $('.ldapDetectPort')
|
||||||
|
},
|
||||||
|
ldap_dn: {
|
||||||
|
$element: $('#ldap_dn'),
|
||||||
|
setMethod: 'setAgentDN'
|
||||||
|
},
|
||||||
|
ldap_agent_password: {
|
||||||
|
$element: $('#ldap_agent_password'),
|
||||||
|
setMethod: 'setAgentPwd'
|
||||||
|
},
|
||||||
|
ldap_base: {
|
||||||
|
$element: $('#ldap_base'),
|
||||||
|
setMethod: 'setBase',
|
||||||
|
$relatedElements: $('.ldapDetectBase, .ldapTestBase'),
|
||||||
|
$detectButton: $('.ldapDetectBase'),
|
||||||
|
$testButton: $('.ldapTestBase')
|
||||||
|
},
|
||||||
|
ldap_base_test: {
|
||||||
|
$element: $('#ldap_base')
|
||||||
|
},
|
||||||
|
ldap_experienced_admin: {
|
||||||
|
$element: $('#ldap_experienced_admin'),
|
||||||
|
setMethod: 'setExperiencedAdmin'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.setManagedItems(items);
|
||||||
|
_.bindAll(this, 'onPortButtonClick', 'onBaseDNButtonClick', 'onBaseDNTestButtonClick');
|
||||||
|
this.managedItems.ldap_port.$relatedElements.click(this.onPortButtonClick);
|
||||||
|
this.managedItems.ldap_base.$detectButton.click(this.onBaseDNButtonClick);
|
||||||
|
this.managedItems.ldap_base.$testButton.click(this.onBaseDNTestButtonClick);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the config model for this view and subscribes to some events.
|
||||||
|
* Also binds the config chooser to the model
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} configModel
|
||||||
|
*/
|
||||||
|
setModel: function(configModel) {
|
||||||
|
this._super(configModel);
|
||||||
|
this.configModel.on('configLoaded', this.onConfigSwitch, this);
|
||||||
|
this.configModel.on('newConfiguration', this.onNewConfiguration, this);
|
||||||
|
this.configModel.on('deleteConfiguration', this.onDeleteConfiguration, this);
|
||||||
|
this.configModel.on('receivedLdapFeature', this.onTestResultReceived, this);
|
||||||
|
this._enableConfigChooser();
|
||||||
|
this._enableConfigButtons();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the currently selected configuration ID
|
||||||
|
*
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
getConfigID: function() {
|
||||||
|
return $(this.configChooserID).val();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the host configuration text field
|
||||||
|
*
|
||||||
|
* @param {string} host
|
||||||
|
*/
|
||||||
|
setHost: function(host) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_host.$element, host);
|
||||||
|
if(host) {
|
||||||
|
this.enableElement(this.managedItems.ldap_port.$relatedElements);
|
||||||
|
} else {
|
||||||
|
this.disableElement(this.managedItems.ldap_port.$relatedElements);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the port configuration text field
|
||||||
|
*
|
||||||
|
* @param {string} port
|
||||||
|
*/
|
||||||
|
setPort: function(port) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_port.$element, port);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the user (agent) DN text field
|
||||||
|
*
|
||||||
|
* @param {string} agentDN
|
||||||
|
*/
|
||||||
|
setAgentDN: function(agentDN) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_dn.$element, agentDN);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the user (agent) password field
|
||||||
|
*
|
||||||
|
* @param {string} agentPwd
|
||||||
|
*/
|
||||||
|
setAgentPwd: function(agentPwd) {
|
||||||
|
this.setElementValue(
|
||||||
|
this.managedItems.ldap_agent_password.$element, agentPwd
|
||||||
|
);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* updates the base DN text area
|
||||||
|
*
|
||||||
|
* @param {string} bases
|
||||||
|
*/
|
||||||
|
setBase: function(bases) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_base.$element, bases);
|
||||||
|
if(!bases) {
|
||||||
|
this.disableElement(this.managedItems.ldap_base.$testButton);
|
||||||
|
} else {
|
||||||
|
this.enableElement(this.managedItems.ldap_base.$testButton);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the experienced admin check box
|
||||||
|
*
|
||||||
|
* @param {string} xpAdminMode contains an int
|
||||||
|
*/
|
||||||
|
setExperiencedAdmin: function(xpAdminMode) {
|
||||||
|
this.setElementValue(
|
||||||
|
this.managedItems.ldap_experienced_admin.$element, xpAdminMode
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
overrideErrorMessage: function(message, key) {
|
||||||
|
switch(key) {
|
||||||
|
case 'ldap_port':
|
||||||
|
if (message === 'Invalid credentials') {
|
||||||
|
return t('user_ldap', 'Please check the credentials, they seem to be wrong.');
|
||||||
|
} else {
|
||||||
|
return t('user_ldap', 'Please specify the port, it could not be auto-detected.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'ldap_base':
|
||||||
|
if( message === 'Server is unwilling to perform'
|
||||||
|
|| message === 'Could not connect to LDAP'
|
||||||
|
) {
|
||||||
|
return t('user_ldap', 'Base DN could not be auto-detected, please revise credentials, host and port.');
|
||||||
|
}
|
||||||
|
return t('user_ldap', 'Could not detect Base DN, please enter it manually.');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resets the view when a configuration switch happened.
|
||||||
|
*
|
||||||
|
* @param {WizardTabElementary} view
|
||||||
|
* @param {Object} configuration
|
||||||
|
*/
|
||||||
|
onConfigSwitch: function(view, configuration) {
|
||||||
|
view.disableElement(view.managedItems.ldap_port.$relatedElements);
|
||||||
|
|
||||||
|
view.onConfigLoaded(view, configuration);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the configuration chooser when a new configuration was added
|
||||||
|
* which also means it is being switched to. The configuration fields
|
||||||
|
* are updated on a different step.
|
||||||
|
*
|
||||||
|
* @param {WizardTabElementary} view
|
||||||
|
* @param {Object} result
|
||||||
|
*/
|
||||||
|
onNewConfiguration: function(view, result) {
|
||||||
|
if(result.isSuccess === true) {
|
||||||
|
$(view.configChooserID + ' option:selected').removeAttr('selected');
|
||||||
|
var html = '<option value="'+result.configPrefix+'" selected="selected">'+t('user_ldap','{nthServer}. Server', {nthServer: $(view.configChooserID + ' option').length + 1})+'</option>';
|
||||||
|
$(view.configChooserID + ' option:last').after(html);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the configuration chooser upon the deletion of a
|
||||||
|
* configuration and, if necessary, loads an existing one.
|
||||||
|
*
|
||||||
|
* @param view
|
||||||
|
* @param result
|
||||||
|
*/
|
||||||
|
onDeleteConfiguration: function(view, result) {
|
||||||
|
if(result.isSuccess === true) {
|
||||||
|
if(view.getConfigID() === result.configPrefix) {
|
||||||
|
// if the deleted value is still the selected one (99% of
|
||||||
|
// the cases), remove it from the list and load the topmost
|
||||||
|
$(view.configChooserID + ' option:selected').remove();
|
||||||
|
$(view.configChooserID + ' option:first').select();
|
||||||
|
if($(view.configChooserID + ' option').length < 2) {
|
||||||
|
view.configModel.newConfig(false);
|
||||||
|
} else {
|
||||||
|
view.configModel.load(view.getConfigID());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// otherwise just remove the entry
|
||||||
|
$(view.configChooserID + ' option[value=' + result.configPrefix + ']').remove();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
OC.Notification.showTemporary(result.errorMessage);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base DN test results will arrive here
|
||||||
|
*
|
||||||
|
* @param {WizardTabElementary} view
|
||||||
|
* @param {FeaturePayload} payload
|
||||||
|
*/
|
||||||
|
onTestResultReceived: function(view, payload) {
|
||||||
|
if(payload.feature === 'TestBaseDN') {
|
||||||
|
var message;
|
||||||
|
if(payload.data.status === 'success') {
|
||||||
|
var objectsFound = parseInt(payload.data.changes.ldap_test_base, 10);
|
||||||
|
if(objectsFound < 1) {
|
||||||
|
message = t('user_ldap', 'No object found in the given Base DN. Please revise.');
|
||||||
|
} else if(objectsFound > 1000) {
|
||||||
|
message = t('user_ldap', 'More then 1.000 directory entries available.');
|
||||||
|
} else {
|
||||||
|
message = t('user_ldap', objectsFound + ' entries available within the provided Base DN');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message = t('user_ldap', 'An error occurred. Please check the Base DN, as well as connection settings and credentials.');
|
||||||
|
if(payload.data.message) {
|
||||||
|
console.warn(payload.data.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OC.Notification.showTemporary(message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* request to count the users with the current filter
|
||||||
|
*
|
||||||
|
* @param {Event} event
|
||||||
|
*/
|
||||||
|
onPortButtonClick: function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.configModel.requestWizard('ldap_port');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* request to count the users with the current filter
|
||||||
|
*
|
||||||
|
* @param {Event} event
|
||||||
|
*/
|
||||||
|
onBaseDNButtonClick: function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.configModel.requestWizard('ldap_base');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* request to count the users with the current filter
|
||||||
|
*
|
||||||
|
* @param {Event} event
|
||||||
|
*/
|
||||||
|
onBaseDNTestButtonClick: function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.configModel.requestWizard('ldap_test_base');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* registers the change event on the configuration chooser and makes
|
||||||
|
* the model load a newly selected configuration
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_enableConfigChooser: function() {
|
||||||
|
var view = this;
|
||||||
|
$(this.configChooserID).change(function(){
|
||||||
|
var value = $(view.configChooserID + ' option:selected:first').attr('value');
|
||||||
|
view.configModel.load(value);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds actions to the action buttons for configuration management
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_enableConfigButtons: function() {
|
||||||
|
var view = this;
|
||||||
|
$('#ldap_action_delete_configuration').click(function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
OC.dialogs.confirm(
|
||||||
|
t('user_ldap', 'Do you really want to delete the current Server Configuration?'),
|
||||||
|
t('user_ldap', 'Confirm Deletion'),
|
||||||
|
function(doDelete) {
|
||||||
|
if(doDelete) {
|
||||||
|
view.configModel.deleteConfig(view.getConfigID());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#ldap_action_add_configuration').click(function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
view.configModel.newConfig(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#ldap_action_copy_configuration').click(function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
view.configModel.newConfig(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardTabElementary = WizardTabElementary;
|
||||||
|
})();
|
|
@ -0,0 +1,130 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc This class represents the view belonging to the expert tab
|
||||||
|
* in the LDAP wizard.
|
||||||
|
*/
|
||||||
|
var WizardTabExpert = OCA.LDAP.Wizard.WizardTabGeneric.subClass({
|
||||||
|
/**
|
||||||
|
* initializes the instance. Always call it after initialization.
|
||||||
|
*
|
||||||
|
* @param tabIndex
|
||||||
|
* @param tabID
|
||||||
|
*/
|
||||||
|
init: function (tabIndex, tabID) {
|
||||||
|
this._super(tabIndex, tabID);
|
||||||
|
|
||||||
|
var items = {
|
||||||
|
ldap_expert_username_attr: {
|
||||||
|
$element: $('#ldap_expert_username_attr'),
|
||||||
|
setMethod: 'setUsernameAttribute'
|
||||||
|
},
|
||||||
|
ldap_expert_uuid_user_attr: {
|
||||||
|
$element: $('#ldap_expert_uuid_user_attr'),
|
||||||
|
setMethod: 'setUserUUIDAttribute'
|
||||||
|
},
|
||||||
|
ldap_expert_uuid_group_attr: {
|
||||||
|
$element: $('#ldap_expert_uuid_group_attr'),
|
||||||
|
setMethod: 'setGroupUUIDAttribute'
|
||||||
|
},
|
||||||
|
|
||||||
|
//Buttons
|
||||||
|
ldap_action_clear_user_mappings: {
|
||||||
|
$element: $('#ldap_action_clear_user_mappings')
|
||||||
|
},
|
||||||
|
ldap_action_clear_group_mappings: {
|
||||||
|
$element: $('#ldap_action_clear_group_mappings')
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
this.setManagedItems(items);
|
||||||
|
_.bindAll(this, 'onClearUserMappingsClick', 'onClearGroupMappingsClick');
|
||||||
|
this.managedItems.ldap_action_clear_user_mappings.$element.click(this.onClearUserMappingsClick);
|
||||||
|
this.managedItems.ldap_action_clear_group_mappings.$element.click(this.onClearGroupMappingsClick);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the config model for this view and subscribes to some events.
|
||||||
|
* Also binds the config chooser to the model
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} configModel
|
||||||
|
*/
|
||||||
|
setModel: function(configModel) {
|
||||||
|
this._super(configModel);
|
||||||
|
this.configModel.on('configLoaded', this.onConfigLoaded, this);
|
||||||
|
this.configModel.on('receivedLdapFeature', this.onResultReceived, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the attribute to be used to create an ownCloud ID (username)
|
||||||
|
*
|
||||||
|
* @param {string} attribute
|
||||||
|
*/
|
||||||
|
setUsernameAttribute: function(attribute) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_expert_username_attr.$element, attribute);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the attribute that provides an unique identifier per LDAP user
|
||||||
|
* entry
|
||||||
|
*
|
||||||
|
* @param {string} attribute
|
||||||
|
*/
|
||||||
|
setUserUUIDAttribute: function(attribute) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_expert_uuid_user_attr.$element, attribute);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the attribute that provides an unique identifier per LDAP group
|
||||||
|
* entry
|
||||||
|
*
|
||||||
|
* @param {string} attribute
|
||||||
|
*/
|
||||||
|
setGroupUUIDAttribute: function(attribute) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_expert_uuid_group_attr.$element, attribute);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* requests clearing of all user mappings
|
||||||
|
*/
|
||||||
|
onClearUserMappingsClick: function() {
|
||||||
|
this.configModel.requestWizard('ldap_action_clear_user_mappings', {ldap_clear_mapping: 'user'});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* requests clearing of all group mappings
|
||||||
|
*/
|
||||||
|
onClearGroupMappingsClick: function() {
|
||||||
|
this.configModel.requestWizard('ldap_action_clear_group_mappings', {ldap_clear_mapping: 'group'});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deals with the result of the Test Connection test
|
||||||
|
*
|
||||||
|
* @param {WizardTabAdvanced} view
|
||||||
|
* @param {FeaturePayload} payload
|
||||||
|
*/
|
||||||
|
onResultReceived: function(view, payload) {
|
||||||
|
if(payload.feature === 'ClearMappings') {
|
||||||
|
var message;
|
||||||
|
if(payload.data.status === 'success') {
|
||||||
|
message = t('user_ldap', 'Mappings cleared successfully!');
|
||||||
|
} else {
|
||||||
|
message = t('user_ldap', 'Error while clearing the mappings.');
|
||||||
|
}
|
||||||
|
OC.Notification.showTemporary(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardTabExpert = WizardTabExpert;
|
||||||
|
})();
|
|
@ -0,0 +1,547 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc An abstract tab view
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
var WizardTabGeneric = OCA.LDAP.Wizard.WizardObject.subClass({
|
||||||
|
isActive: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {string} - class that identifies a multiselect-plugin
|
||||||
|
* control.
|
||||||
|
*/
|
||||||
|
multiSelectPluginClass: 'multiSelectPlugin',
|
||||||
|
|
||||||
|
/** @inheritdoc */
|
||||||
|
init: function(tabIndex, tabID) {
|
||||||
|
this.tabIndex = tabIndex;
|
||||||
|
this.tabID = tabID;
|
||||||
|
this.spinner = $('.ldapSpinner').first().clone().removeClass('hidden');
|
||||||
|
_.bindAll(this, '_toggleRawFilterMode', '_toggleRawFilterModeConfirmation');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the configuration items that are managed by that view.
|
||||||
|
*
|
||||||
|
* The parameter contains key-value pairs the key being the
|
||||||
|
* configuration keys and the value being its setter method.
|
||||||
|
*
|
||||||
|
* @param {object} managedItems
|
||||||
|
*/
|
||||||
|
setManagedItems: function(managedItems) {
|
||||||
|
this.managedItems = managedItems;
|
||||||
|
this._enableAutoSave();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the config model. The concrete view likely wants to subscribe
|
||||||
|
* to events as well.
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} configModel
|
||||||
|
*/
|
||||||
|
setModel: function(configModel) {
|
||||||
|
this.configModel = configModel;
|
||||||
|
this.parsedFilterMode = this.configModel.FILTER_MODE_ASSISTED;
|
||||||
|
this.configModel.on('detectionStarted', this.onDetectionStarted, this);
|
||||||
|
this.configModel.on('detectionCompleted', this.onDetectionCompleted, this);
|
||||||
|
this.configModel.on('serverError', this.onServerError, this);
|
||||||
|
this.configModel.on('setCompleted', this.onItemSaved, this);
|
||||||
|
this.configModel.on('configUpdated', this.onConfigLoaded, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the method can be used to display a different error/information
|
||||||
|
* message than provided by the ownCloud server response. The concrete
|
||||||
|
* Tab View may optionally implement it. Returning an empty string will
|
||||||
|
* avoid any notification.
|
||||||
|
*
|
||||||
|
* @param {string} message
|
||||||
|
* @param {string} key
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
overrideErrorMessage: function(message, key) {
|
||||||
|
return message;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this is called by the main view, if the tab is being switched to.
|
||||||
|
* The concrete tab view can implement this if necessary.
|
||||||
|
*/
|
||||||
|
onActivate: function() { },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the tab when the model loaded a configuration and notified
|
||||||
|
* this view.
|
||||||
|
*
|
||||||
|
* @param {WizardTabGeneric} view - this instance
|
||||||
|
* @param {Object} configuration
|
||||||
|
*/
|
||||||
|
onConfigLoaded: function(view, configuration) {
|
||||||
|
for(var key in view.managedItems){
|
||||||
|
if(!_.isUndefined(configuration[key])) {
|
||||||
|
var value = configuration[key];
|
||||||
|
var methodName = view.managedItems[key].setMethod;
|
||||||
|
if(!_.isUndefined(view[methodName])) {
|
||||||
|
view[methodName](value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reacts on a set action on the model and updates the tab with the
|
||||||
|
* valid value.
|
||||||
|
*
|
||||||
|
* @param {WizardTabGeneric} view
|
||||||
|
* @param {Object} result
|
||||||
|
*/
|
||||||
|
onItemSaved: function(view, result) {
|
||||||
|
if(!_.isUndefined(view.managedItems[result.key])) {
|
||||||
|
var methodName = view.managedItems[result.key].setMethod;
|
||||||
|
view[methodName](result.value);
|
||||||
|
if(!result.isSuccess) {
|
||||||
|
OC.Notification.showTemporary(t('user_ldap', 'Saving failed. Please make sure the database is in Operation. Reload before continuing.'));
|
||||||
|
console.warn(result.errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* displays server error messages.
|
||||||
|
*
|
||||||
|
* @param view
|
||||||
|
* @param payload
|
||||||
|
*/
|
||||||
|
onServerError: function(view, payload) {
|
||||||
|
if ( !_.isUndefined(view.managedItems[payload.relatedKey])) {
|
||||||
|
var message = view.overrideErrorMessage(payload.message, payload.relatedKey);
|
||||||
|
if(message) {
|
||||||
|
OC.Notification.showTemporary(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* disables affected, managed fields if a detector is running against them
|
||||||
|
*
|
||||||
|
* @param {WizardTabGeneric} view
|
||||||
|
* @param {string} key
|
||||||
|
*/
|
||||||
|
onDetectionStarted: function(view, key) {
|
||||||
|
if(!_.isUndefined(view.managedItems[key])) {
|
||||||
|
view.disableElement(view.managedItems[key].$element);
|
||||||
|
if(!_.isUndefined(view.managedItems[key].$relatedElements)){
|
||||||
|
view.disableElement(view.managedItems[key].$relatedElements);
|
||||||
|
}
|
||||||
|
view.attachSpinner(view.managedItems[key].$element.attr('id'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enables affected, managed fields after a detector was run against them
|
||||||
|
*
|
||||||
|
* @param {WizardTabGeneric} view
|
||||||
|
* @param {string} key
|
||||||
|
*/
|
||||||
|
onDetectionCompleted: function(view, key) {
|
||||||
|
if(!_.isUndefined(view.managedItems[key])) {
|
||||||
|
view.enableElement(view.managedItems[key].$element);
|
||||||
|
if(!_.isUndefined(view.managedItems[key].$relatedElements)){
|
||||||
|
view.enableElement(view.managedItems[key].$relatedElements);
|
||||||
|
}
|
||||||
|
view.removeSpinner(view.managedItems[key].$element.attr('id'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the value to an HTML element. Checkboxes, text areas and (text)
|
||||||
|
* input fields are supported.
|
||||||
|
*
|
||||||
|
* @param {jQuery} $element - the target element
|
||||||
|
* @param {string|number|Array} value
|
||||||
|
*/
|
||||||
|
setElementValue: function($element, value) {
|
||||||
|
// deal with check box
|
||||||
|
if ($element.is('input[type=checkbox]')) {
|
||||||
|
this._setCheckBox($element, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// deal with text area
|
||||||
|
if ($element.is('textarea') && $.isArray(value)) {
|
||||||
|
value = value.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($element.is('span')) {
|
||||||
|
$element.text(value);
|
||||||
|
} else {
|
||||||
|
$element.val(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replaces options on a multiselect element
|
||||||
|
*
|
||||||
|
* @param {jQuery} $element - the multiselect element
|
||||||
|
* @param {Array} options
|
||||||
|
*/
|
||||||
|
equipMultiSelect: function($element, options) {
|
||||||
|
$element.empty();
|
||||||
|
for (var i in options) {
|
||||||
|
var name = options[i];
|
||||||
|
$element.append($('<option>').val(name).text(name).attr('title', name));
|
||||||
|
}
|
||||||
|
if(!$element.hasClass('ldapGroupList')) {
|
||||||
|
$element.multiselect('refresh');
|
||||||
|
this.enableElement($element);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enables the specified HTML element
|
||||||
|
*
|
||||||
|
* @param {jQuery} $element
|
||||||
|
*/
|
||||||
|
enableElement: function($element) {
|
||||||
|
var isMS = $element.is('select[multiple]');
|
||||||
|
var hasOptions = isMS ? ($element.find('option').length > 0) : false;
|
||||||
|
|
||||||
|
if($element.hasClass(this.multiSelectPluginClass) && hasOptions) {
|
||||||
|
$element.multiselect("enable");
|
||||||
|
} else if(!isMS || (isMS && hasOptions)) {
|
||||||
|
$element.prop('disabled', false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* disables the specified HTML element
|
||||||
|
*
|
||||||
|
* @param {jQuery} $element
|
||||||
|
*/
|
||||||
|
disableElement: function($element) {
|
||||||
|
if($element.hasClass(this.multiSelectPluginClass)) {
|
||||||
|
$element.multiselect("disable");
|
||||||
|
} else {
|
||||||
|
$element.prop('disabled', 'disabled');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* attaches a spinner icon to the HTML element specified by ID
|
||||||
|
*
|
||||||
|
* @param {string} elementID
|
||||||
|
*/
|
||||||
|
attachSpinner: function(elementID) {
|
||||||
|
if($('#' + elementID + ' + .ldapSpinner').length == 0) {
|
||||||
|
var spinner = this.spinner.clone();
|
||||||
|
var $element = $('#' + elementID);
|
||||||
|
$(spinner).insertAfter($element);
|
||||||
|
// and special treatment for multiselects:
|
||||||
|
if ($element.is('select[multiple]')) {
|
||||||
|
$('#' + elementID + " + img + button").css('display', 'none');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removes the spinner icon from the HTML element specified by ID
|
||||||
|
*
|
||||||
|
* @param {string} elementID
|
||||||
|
*/
|
||||||
|
removeSpinner: function(elementID) {
|
||||||
|
$('#' + elementID+' + .ldapSpinner').remove();
|
||||||
|
// and special treatment for multiselects:
|
||||||
|
$('#' + elementID + " + button").css('display', 'inline');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* whether the wizard works in experienced admin mode
|
||||||
|
*
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isExperiencedMode: function() {
|
||||||
|
return parseInt(this.configModel.configuration.ldap_experienced_admin, 10) === 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets up auto-save functionality to the managed items
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_enableAutoSave: function() {
|
||||||
|
var view = this;
|
||||||
|
|
||||||
|
for(var id in this.managedItems) {
|
||||||
|
if(_.isUndefined(this.managedItems[id].$element)
|
||||||
|
|| _.isUndefined(this.managedItems[id].setMethod)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var $element = this.managedItems[id].$element;
|
||||||
|
if (!$element.is('select[multiple]')) {
|
||||||
|
$element.change(function() {
|
||||||
|
view._requestSave($(this));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initializes a multiSelect element
|
||||||
|
*
|
||||||
|
* @param {jQuery} $element
|
||||||
|
* @param {string} caption
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_initMultiSelect: function($element, caption) {
|
||||||
|
var view = this;
|
||||||
|
$element.multiselect({
|
||||||
|
header: false,
|
||||||
|
selectedList: 9,
|
||||||
|
noneSelectedText: caption,
|
||||||
|
classes: this.multiSelectPluginClass,
|
||||||
|
close: function() {
|
||||||
|
view._requestSave($element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} viewSaveInfo
|
||||||
|
* @property {function} val
|
||||||
|
* @property {function} attr
|
||||||
|
* @property {function} is
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* requests a save operation from the model for a given value
|
||||||
|
* represented by a HTML element and its ID.
|
||||||
|
*
|
||||||
|
* @param {jQuery|viewSaveInfo} $element
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_requestSave: function($element) {
|
||||||
|
var value = '';
|
||||||
|
if($element.is('input[type=checkbox]')
|
||||||
|
&& !$element.is(':checked')) {
|
||||||
|
value = 0;
|
||||||
|
} else if ($element.is('select[multiple]')) {
|
||||||
|
var entries = $element.multiselect("getChecked");
|
||||||
|
for(var i = 0; i < entries.length; i++) {
|
||||||
|
value = value + "\n" + entries[i].value;
|
||||||
|
}
|
||||||
|
value = $.trim(value);
|
||||||
|
} else {
|
||||||
|
value = $element.val();
|
||||||
|
}
|
||||||
|
this.configModel.set($element.attr('id'), value);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates a checkbox element according to the provided value
|
||||||
|
*
|
||||||
|
* @param {jQuery} $element
|
||||||
|
* @param {string|number} value
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_setCheckBox: function($element, value) {
|
||||||
|
if(parseInt(value, 10) === 1) {
|
||||||
|
$element.attr('checked', 'checked');
|
||||||
|
} else {
|
||||||
|
$element.removeAttr('checked');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this is called when the filter mode is switched to assisted. The
|
||||||
|
* concrete tab view should implement this, to load LDAP features
|
||||||
|
* (e.g. object classes, groups, attributes…), if necessary.
|
||||||
|
*/
|
||||||
|
considerFeatureRequests: function() {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this is called when the filter mode is switched to Assisted. The
|
||||||
|
* concrete tab view should request the compilation of the respective
|
||||||
|
* filter.
|
||||||
|
*/
|
||||||
|
requestCompileFilter: function() {
|
||||||
|
this.configModel.requestWizard(this.filterName);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the filter mode according to the provided configuration value
|
||||||
|
*
|
||||||
|
* @param {string} mode
|
||||||
|
*/
|
||||||
|
setFilterMode: function(mode) {
|
||||||
|
if(parseInt(mode, 10) === this.configModel.FILTER_MODE_ASSISTED) {
|
||||||
|
this.parsedFilterMode = this.configModel.FILTER_MODE_ASSISTED;
|
||||||
|
this.considerFeatureRequests();
|
||||||
|
this._setFilterModeAssisted();
|
||||||
|
if(this.isActive) {
|
||||||
|
// filter compilation should happen only, if the mode was
|
||||||
|
// switched manually, but not when initiating the view
|
||||||
|
this.requestCompileFilter();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._setFilterModeRaw();
|
||||||
|
this.parsedFilterMode = this.configModel.FILTER_MODE_RAW;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the UI so that it represents the assisted mode setting
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_setFilterModeAssisted: function() {
|
||||||
|
var view = this;
|
||||||
|
this.$filterModeRawContainer.addClass('invisible');
|
||||||
|
var filter = this.$filterModeRawContainer.find('.ldapFilterInputElement').val();
|
||||||
|
this.$filterModeRawContainer.siblings('.ldapReadOnlyFilterContainer').find('.ldapFilterReadOnlyElement').text(filter);
|
||||||
|
this.$filterModeRawContainer.siblings('.ldapReadOnlyFilterContainer').removeClass('hidden');
|
||||||
|
$.each(this.filterModeDisableableElements, function(i, $element) {
|
||||||
|
view.enableElement($element);
|
||||||
|
});
|
||||||
|
if(!_.isUndefined(this.filterModeStateElement)) {
|
||||||
|
if (this.filterModeStateElement.status === 'enabled') {
|
||||||
|
this.enableElement(this.filterModeStateElement.$element);
|
||||||
|
} else {
|
||||||
|
this.filterModeStateElement.status = 'disabled';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the UI so that it represents the raw mode setting
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_setFilterModeRaw: function() {
|
||||||
|
var view = this;
|
||||||
|
this.$filterModeRawContainer.removeClass('invisible');
|
||||||
|
this.$filterModeRawContainer.siblings('.ldapReadOnlyFilterContainer').addClass('hidden');
|
||||||
|
$.each(this.filterModeDisableableElements, function (i, $element) {
|
||||||
|
view.disableElement($element);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!_.isUndefined(this.filterModeStateElement)) {
|
||||||
|
if(this.filterModeStateElement.$element.multiselect().attr('disabled') === 'disabled') {
|
||||||
|
this.filterModeStateElement.status = 'disabled';
|
||||||
|
} else {
|
||||||
|
this.filterModeStateElement.status = 'enabled';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!_.isUndefined(this.filterModeStateElement)) {
|
||||||
|
this.disableElement(this.filterModeStateElement.$element);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback toggleConfirmCallback
|
||||||
|
* @param {boolean} isConfirmed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shows a confirmation dialogue before switching from raw to assisted
|
||||||
|
* mode if experienced mode is enabled.
|
||||||
|
*
|
||||||
|
* @param {toggleConfirmCallback} toggleFnc
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_toggleRawFilterModeConfirmation: function(toggleFnc) {
|
||||||
|
if( !this.isExperiencedMode()
|
||||||
|
|| this.parsedFilterMode === this.configModel.FILTER_MODE_ASSISTED
|
||||||
|
) {
|
||||||
|
toggleFnc(true);
|
||||||
|
} else {
|
||||||
|
OCdialogs.confirm(
|
||||||
|
t('user_ldap', 'Switching the mode will enable automatic LDAP queries. Depending on your LDAP size they may take a while. Do you still want to switch the mode?'),
|
||||||
|
t('user_ldap', 'Mode switch'),
|
||||||
|
toggleFnc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* toggles the visibility of a raw filter container and so also the
|
||||||
|
* state of the multi-select controls. The model is requested to save
|
||||||
|
* the state.
|
||||||
|
*/
|
||||||
|
_toggleRawFilterMode: function() {
|
||||||
|
var view = this;
|
||||||
|
this._toggleRawFilterModeConfirmation(function(isConfirmed) {
|
||||||
|
if(!isConfirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/** var {number} */
|
||||||
|
var mode;
|
||||||
|
if (view.parsedFilterMode === view.configModel.FILTER_MODE_ASSISTED) {
|
||||||
|
mode = view.configModel.FILTER_MODE_RAW;
|
||||||
|
} else {
|
||||||
|
mode = view.configModel.FILTER_MODE_ASSISTED;
|
||||||
|
}
|
||||||
|
view.setFilterMode(mode);
|
||||||
|
/** @var {viewSaveInfo} */
|
||||||
|
var saveInfo = {
|
||||||
|
val: function () {
|
||||||
|
return mode;
|
||||||
|
},
|
||||||
|
attr: function () {
|
||||||
|
return view.filterModeKey;
|
||||||
|
},
|
||||||
|
is: function () {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
view._requestSave(saveInfo);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} filterModeStateElementObj
|
||||||
|
* @property {string} status - either "enabled" or "disabled"
|
||||||
|
* @property {jQuery} $element
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initializes a raw filter mode switcher
|
||||||
|
*
|
||||||
|
* @param {jQuery} $switcher - the element receiving the click
|
||||||
|
* @param {jQuery} $filterModeRawContainer - contains the raw filter
|
||||||
|
* input elements
|
||||||
|
* @param {jQuery[]} filterModeDisableableElements - an array of elements
|
||||||
|
* not belonging to the raw filter part that shall be en/disabled.
|
||||||
|
* @param {string} filterModeKey - the setting key that save the state
|
||||||
|
* of the mode
|
||||||
|
* @param {filterModeStateElementObj} [filterModeStateElement] - one element
|
||||||
|
* which status (enabled or not) is tracked by a setting
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_initFilterModeSwitcher: function(
|
||||||
|
$switcher,
|
||||||
|
$filterModeRawContainer,
|
||||||
|
filterModeDisableableElements,
|
||||||
|
filterModeKey,
|
||||||
|
filterModeStateElement
|
||||||
|
) {
|
||||||
|
this.$filterModeRawContainer = $filterModeRawContainer;
|
||||||
|
this.filterModeDisableableElements = filterModeDisableableElements;
|
||||||
|
this.filterModeStateElement = filterModeStateElement;
|
||||||
|
this.filterModeKey = filterModeKey;
|
||||||
|
$switcher.click(this._toggleRawFilterMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardTabGeneric = WizardTabGeneric;
|
||||||
|
})();
|
|
@ -0,0 +1,124 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc This class represents the view belonging to the server tab
|
||||||
|
* in the LDAP wizard.
|
||||||
|
*/
|
||||||
|
var WizardTabGroupFilter = OCA.LDAP.Wizard.WizardTabAbstractFilter.subClass({
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
init: function (fotf, tabIndex, tabID) {
|
||||||
|
tabID = '#ldapWizard4';
|
||||||
|
var items = {
|
||||||
|
ldap_groupfilter_objectclass: {
|
||||||
|
$element: $('#ldap_groupfilter_objectclass'),
|
||||||
|
setMethod: 'setObjectClass',
|
||||||
|
keyName: 'ldap_groupfilter_objectclass',
|
||||||
|
featureName: 'GroupObjectClasses'
|
||||||
|
},
|
||||||
|
ldap_group_filter_mode: {
|
||||||
|
setMethod: 'setFilterMode'
|
||||||
|
},
|
||||||
|
ldap_groupfilter_groups: {
|
||||||
|
$element: $('#ldap_groupfilter_groups'),
|
||||||
|
setMethod: 'setGroups',
|
||||||
|
keyName: 'ldap_groupfilter_groups',
|
||||||
|
featureName: 'GroupsForGroups',
|
||||||
|
$relatedElements: $(
|
||||||
|
tabID + ' .ldapGroupListAvailable,' +
|
||||||
|
tabID + ' .ldapGroupListSelected,' +
|
||||||
|
tabID + ' .ldapManyGroupsSearch'
|
||||||
|
)
|
||||||
|
},
|
||||||
|
ldap_group_filter: {
|
||||||
|
$element: $('#ldap_group_filter'),
|
||||||
|
setMethod: 'setFilter',
|
||||||
|
keyName: 'ldap_group_filter'
|
||||||
|
},
|
||||||
|
groupFilterRawToggle: {
|
||||||
|
$element: $('#toggleRawGroupFilter')
|
||||||
|
},
|
||||||
|
groupFilterRawContainer: {
|
||||||
|
$element: $('#rawGroupFilterContainer')
|
||||||
|
},
|
||||||
|
ldap_group_count: {
|
||||||
|
$element: $('#ldap_group_count'),
|
||||||
|
$relatedElements: $('.ldapGetGroupCount'),
|
||||||
|
setMethod: 'setCount',
|
||||||
|
keyName: 'ldap_group_count'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.setManagedItems(items);
|
||||||
|
this.manyGroupsSupport = true;
|
||||||
|
this._super(fotf, tabIndex, tabID);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getObjectClassItem: function () {
|
||||||
|
return this.managedItems.ldap_groupfilter_objectclass;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getGroupsItem: function () {
|
||||||
|
return this.managedItems.ldap_groupfilter_groups;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getFilterItem: function () {
|
||||||
|
return this.managedItems.ldap_group_filter;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getToggleItem: function () {
|
||||||
|
return this.managedItems.groupFilterRawToggle;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getRawFilterContainerItem: function () {
|
||||||
|
return this.managedItems.groupFilterRawContainer;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getCountItem: function () {
|
||||||
|
return this.managedItems.ldap_group_count;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
getFilterModeKey: function () {
|
||||||
|
return 'ldap_group_filter_mode';
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardTabGroupFilter = WizardTabGroupFilter;
|
||||||
|
})();
|
|
@ -0,0 +1,238 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc This class represents the view belonging to the login filter
|
||||||
|
* tab in the LDAP wizard.
|
||||||
|
*/
|
||||||
|
var WizardTabLoginFilter = OCA.LDAP.Wizard.WizardTabGeneric.subClass({
|
||||||
|
/**
|
||||||
|
* initializes the instance. Always call it after initialization.
|
||||||
|
*
|
||||||
|
* @param tabIndex
|
||||||
|
* @param tabID
|
||||||
|
*/
|
||||||
|
init: function (tabIndex, tabID) {
|
||||||
|
this._super(tabIndex, tabID);
|
||||||
|
|
||||||
|
var items = {
|
||||||
|
ldap_loginfilter_username: {
|
||||||
|
$element: $('#ldap_loginfilter_username'),
|
||||||
|
setMethod: 'setLoginAttributeUsername'
|
||||||
|
},
|
||||||
|
ldap_loginfilter_email: {
|
||||||
|
$element: $('#ldap_loginfilter_email'),
|
||||||
|
setMethod: 'setLoginAttributeEmail'
|
||||||
|
},
|
||||||
|
ldap_login_filter_mode: {
|
||||||
|
setMethod: 'setFilterMode'
|
||||||
|
},
|
||||||
|
ldap_loginfilter_attributes: {
|
||||||
|
$element: $('#ldap_loginfilter_attributes'),
|
||||||
|
setMethod: 'setLoginAttributesOther'
|
||||||
|
},
|
||||||
|
ldap_login_filter: {
|
||||||
|
$element: $('#ldap_login_filter'),
|
||||||
|
setMethod: 'setLoginFilter'
|
||||||
|
},
|
||||||
|
loginFilterRawToggle: {
|
||||||
|
$element: $('#toggleRawLoginFilter')
|
||||||
|
},
|
||||||
|
loginFilterRawContainer: {
|
||||||
|
$element: $('#rawLoginFilterContainer')
|
||||||
|
},
|
||||||
|
ldap_test_loginname: {
|
||||||
|
$element: $('#ldap_test_loginname'),
|
||||||
|
$relatedElements: $('.ldapVerifyLoginName')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.setManagedItems(items);
|
||||||
|
|
||||||
|
this.filterModeKey = 'ldapLoginFilterMode';
|
||||||
|
this._initMultiSelect(
|
||||||
|
this.managedItems.ldap_loginfilter_attributes.$element,
|
||||||
|
t('user_ldap', 'Select attributes')
|
||||||
|
);
|
||||||
|
this.filterName = 'ldap_login_filter';
|
||||||
|
this._initFilterModeSwitcher(
|
||||||
|
this.managedItems.loginFilterRawToggle.$element,
|
||||||
|
this.managedItems.loginFilterRawContainer.$element,
|
||||||
|
[
|
||||||
|
this.managedItems.ldap_loginfilter_username.$element,
|
||||||
|
this.managedItems.ldap_loginfilter_email.$element,
|
||||||
|
this.managedItems.ldap_loginfilter_attributes.$element
|
||||||
|
],
|
||||||
|
'ldap_login_filter_mode'
|
||||||
|
);
|
||||||
|
_.bindAll(this, 'onVerifyClick');
|
||||||
|
this.managedItems.ldap_test_loginname.$relatedElements.click(this.onVerifyClick);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the config model for this view and subscribes to some events.
|
||||||
|
* Also binds the config chooser to the model
|
||||||
|
*
|
||||||
|
* @param {OCA.LDAP.Wizard.ConfigModel} configModel
|
||||||
|
*/
|
||||||
|
setModel: function(configModel) {
|
||||||
|
this._super(configModel);
|
||||||
|
this.configModel.on('configLoaded', this.onConfigSwitch, this);
|
||||||
|
this.configModel.on('receivedLdapFeature', this.onFeatureReceived, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the selected attributes
|
||||||
|
*
|
||||||
|
* @param {Array} attributes
|
||||||
|
*/
|
||||||
|
setLoginAttributesOther: function(attributes) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_loginfilter_attributes.$element, attributes);
|
||||||
|
this.managedItems.ldap_loginfilter_attributes.$element.multiselect('refresh');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the login list filter
|
||||||
|
*
|
||||||
|
* @param {string} filter
|
||||||
|
*/
|
||||||
|
setLoginFilter: function(filter) {
|
||||||
|
this.setElementValue(this.managedItems.ldap_login_filter.$element, filter);
|
||||||
|
this.$filterModeRawContainer.siblings('.ldapReadOnlyFilterContainer').find('.ldapFilterReadOnlyElement').text(filter);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the username attribute check box
|
||||||
|
*
|
||||||
|
* @param {string} useUsername contains an int
|
||||||
|
*/
|
||||||
|
setLoginAttributeUsername: function(useUsername) {
|
||||||
|
this.setElementValue(
|
||||||
|
this.managedItems.ldap_loginfilter_username.$element, useUsername
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the email attribute check box
|
||||||
|
*
|
||||||
|
* @param {string} useEmail contains an int
|
||||||
|
*/
|
||||||
|
setLoginAttributeEmail: function(useEmail) {
|
||||||
|
this.setElementValue(
|
||||||
|
this.managedItems.ldap_loginfilter_email.$element, useEmail
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* presents the result of the login name test
|
||||||
|
*
|
||||||
|
* @param result
|
||||||
|
*/
|
||||||
|
handleLoginTestResult: function(result) {
|
||||||
|
var message;
|
||||||
|
var isHtml = false;
|
||||||
|
if(result.status === 'success') {
|
||||||
|
var usersFound = parseInt(result.changes.ldap_test_loginname, 10);
|
||||||
|
if(usersFound < 1) {
|
||||||
|
var filter = $('<p>').text(result.changes.ldap_test_effective_filter).html();
|
||||||
|
message = t('user_ldap', 'User not found. Please check your login attributes and username. Effective filter (to copy-and-paste for command line validation): <br/>' + filter);
|
||||||
|
console.warn(filter);
|
||||||
|
isHtml = true;
|
||||||
|
} else if(usersFound === 1) {
|
||||||
|
message = t('user_ldap', 'User found and settings verified.');
|
||||||
|
} else if(usersFound > 1) {
|
||||||
|
message = t('user_ldap', 'Settings verified, but one user found. Only the first will be able to login. Consider a more narrow filter.');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message = t('user_ldap', 'An unspecified error occurred. Please check the settings and the log.');
|
||||||
|
if(!_.isUndefined(result.message) && result.message) {
|
||||||
|
message = result.message;
|
||||||
|
}
|
||||||
|
if(message === 'Bad search filter') {
|
||||||
|
message = t('user_ldap', 'The search filter is invalid, probably due to syntax issues like uneven number of opened and closed brackets. Please revise.');
|
||||||
|
} else if(message === 'connection error') {
|
||||||
|
message = t('user_ldap', 'A connection error to LDAP / AD occurred, please check host, port and credentials.');
|
||||||
|
} else if(message === 'missing placeholder') {
|
||||||
|
message = t('user_ldap', 'The %uid placeholder is missing. It will be replaced with the login name when querying LDAP / AD.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OC.Notification.showTemporary(message, {isHTML: isHtml});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
considerFeatureRequests: function() {
|
||||||
|
if(!this.isActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(this.managedItems.ldap_loginfilter_attributes.$element.find('option').length === 0) {
|
||||||
|
this.disableElement(this.managedItems.ldap_loginfilter_attributes.$element);
|
||||||
|
if(this.parsedFilterMode === this.configModel.FILTER_MODE_ASSISTED) {
|
||||||
|
this.configModel.requestWizard('ldap_loginfilter_attributes');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
onActivate: function() {
|
||||||
|
this.considerFeatureRequests();
|
||||||
|
if(!this.managedItems.ldap_login_filter.$element.val()) {
|
||||||
|
this.configModel.requestWizard('ldap_login_filter');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resets the view when a configuration switch happened.
|
||||||
|
*
|
||||||
|
* @param {WizardTabLoginFilter} view
|
||||||
|
* @param {Object} configuration
|
||||||
|
*/
|
||||||
|
onConfigSwitch: function(view, configuration) {
|
||||||
|
view.managedItems.ldap_loginfilter_attributes.$element.find('option').remove();
|
||||||
|
|
||||||
|
view.onConfigLoaded(view, configuration);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if UserObjectClasses are found, the corresponding element will be
|
||||||
|
* updated
|
||||||
|
*
|
||||||
|
* @param {WizardTabLoginFilter} view
|
||||||
|
* @param {FeaturePayload} payload
|
||||||
|
*/
|
||||||
|
onFeatureReceived: function(view, payload) {
|
||||||
|
if(payload.feature === 'AvailableAttributes') {
|
||||||
|
view.equipMultiSelect(view.managedItems.ldap_loginfilter_attributes.$element, payload.data);
|
||||||
|
} else if(payload.feature === 'TestLoginName') {
|
||||||
|
view.handleLoginTestResult(payload.data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* request to test the provided login name
|
||||||
|
*
|
||||||
|
* @param {Event} event
|
||||||
|
*/
|
||||||
|
onVerifyClick: function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var testLogin = this.managedItems.ldap_test_loginname.$element.val();
|
||||||
|
if(!testLogin) {
|
||||||
|
OC.Notification.showTemporary(t('user_ldap', 'Please provide a login name to test against'), 3);
|
||||||
|
} else {
|
||||||
|
this.configModel.requestWizard('ldap_test_loginname', {ldap_test_loginname: testLogin});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardTabLoginFilter = WizardTabLoginFilter;
|
||||||
|
})();
|
|
@ -0,0 +1,136 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, Arthur Schiwon <blizzz@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OCA = OCA || {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc This class represents the view belonging to the server tab
|
||||||
|
* in the LDAP wizard.
|
||||||
|
*/
|
||||||
|
var WizardTabUserFilter = OCA.LDAP.Wizard.WizardTabAbstractFilter.subClass({
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
init: function (fotf, tabIndex, tabID) {
|
||||||
|
tabID = '#ldapWizard2';
|
||||||
|
var items = {
|
||||||
|
ldap_userfilter_objectclass: {
|
||||||
|
$element: $('#ldap_userfilter_objectclass'),
|
||||||
|
setMethod: 'setObjectClass',
|
||||||
|
keyName: 'ldap_userfilter_objectclass',
|
||||||
|
featureName: 'UserObjectClasses'
|
||||||
|
},
|
||||||
|
ldap_user_filter_mode: {
|
||||||
|
setMethod: 'setFilterMode'
|
||||||
|
},
|
||||||
|
ldap_userfilter_groups: {
|
||||||
|
$element: $('#ldap_userfilter_groups'),
|
||||||
|
setMethod: 'setGroups',
|
||||||
|
keyName: 'ldap_userfilter_groups',
|
||||||
|
featureName: 'GroupsForUsers',
|
||||||
|
$relatedElements: $(
|
||||||
|
tabID + ' .ldapGroupListAvailable,' +
|
||||||
|
tabID + ' .ldapGroupListSelected,' +
|
||||||
|
tabID + ' .ldapManyGroupsSearch'
|
||||||
|
)
|
||||||
|
},
|
||||||
|
ldap_userlist_filter: {
|
||||||
|
$element: $('#ldap_userlist_filter'),
|
||||||
|
setMethod: 'setFilter',
|
||||||
|
keyName: 'ldap_userlist_filter'
|
||||||
|
},
|
||||||
|
userFilterRawToggle: {
|
||||||
|
$element: $('#toggleRawUserFilter')
|
||||||
|
},
|
||||||
|
userFilterRawContainer: {
|
||||||
|
$element: $('#rawUserFilterContainer')
|
||||||
|
},
|
||||||
|
ldap_user_count: {
|
||||||
|
$element: $('#ldap_user_count'),
|
||||||
|
$relatedElements: $('.ldapGetUserCount'),
|
||||||
|
setMethod: 'setCount',
|
||||||
|
keyName: 'ldap_user_count'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.setManagedItems(items);
|
||||||
|
this.manyGroupsSupport = true;
|
||||||
|
this._super(fotf, tabIndex, tabID);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getObjectClassItem: function () {
|
||||||
|
return this.managedItems.ldap_userfilter_objectclass;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getGroupsItem: function () {
|
||||||
|
return this.managedItems.ldap_userfilter_groups;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getFilterItem: function () {
|
||||||
|
return this.managedItems.ldap_userlist_filter;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getToggleItem: function () {
|
||||||
|
return this.managedItems.userFilterRawToggle;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getRawFilterContainerItem: function () {
|
||||||
|
return this.managedItems.userFilterRawContainer;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
getCountItem: function () {
|
||||||
|
return this.managedItems.ldap_user_count;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
getFilterModeKey: function () {
|
||||||
|
return 'ldap_user_filter_mode';
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
overrideErrorMessage: function(message, key) {
|
||||||
|
if( key === 'ldap_userfilter_groups'
|
||||||
|
&& message === 'memberOf is not supported by the server'
|
||||||
|
) {
|
||||||
|
message = t('user_ldap', 'The group box was disabled, because the LDAP / AD server does not support memberOf.');
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
OCA.LDAP.Wizard.WizardTabUserFilter = WizardTabUserFilter;
|
||||||
|
})();
|
|
@ -595,6 +595,22 @@ class Access extends LDAPUtility implements user\IUserTools {
|
||||||
return $altName;
|
return $altName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fetches a list of users according to a provided loginName and utilizing
|
||||||
|
* the login filter.
|
||||||
|
*
|
||||||
|
* @param string $loginName
|
||||||
|
* @param array $attributes optional, list of attributes to read
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function fetchUsersByLoginName($loginName, $attributes = array('dn')) {
|
||||||
|
$loginName = $this->escapeFilterPart($loginName);
|
||||||
|
$filter = \OCP\Util::mb_str_replace(
|
||||||
|
'%uid', $loginName, $this->connection->ldapLoginFilter, 'UTF-8');
|
||||||
|
$users = $this->fetchListOfUsers($filter, $attributes);
|
||||||
|
return $users;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $filter
|
* @param string $filter
|
||||||
* @param string|string[] $attr
|
* @param string|string[] $attr
|
||||||
|
@ -686,6 +702,17 @@ class Access extends LDAPUtility implements user\IUserTools {
|
||||||
return $this->count($filter, $this->connection->ldapBaseGroups, $attr, $limit, $offset);
|
return $this->count($filter, $this->connection->ldapBaseGroups, $attr, $limit, $offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the number of available objects on the base DN
|
||||||
|
*
|
||||||
|
* @param int|null $limit
|
||||||
|
* @param int|null $offset
|
||||||
|
* @return int|bool
|
||||||
|
*/
|
||||||
|
public function countObjects($limit = null, $offset = null) {
|
||||||
|
return $this->count('objectclass=*', $this->connection->ldapBase, array('dn'), $limit, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieved. Results will according to the order in the array.
|
* retrieved. Results will according to the order in the array.
|
||||||
* @param int $limit optional, maximum results to be counted
|
* @param int $limit optional, maximum results to be counted
|
||||||
|
|
|
@ -201,11 +201,14 @@ class Configuration {
|
||||||
case 'ldapAgentPassword':
|
case 'ldapAgentPassword':
|
||||||
$readMethod = 'getPwd';
|
$readMethod = 'getPwd';
|
||||||
break;
|
break;
|
||||||
case 'ldapUserDisplayName':
|
|
||||||
case 'ldapGroupDisplayName':
|
case 'ldapGroupDisplayName':
|
||||||
$readMethod = 'getLcValue';
|
$readMethod = 'getLcValue';
|
||||||
break;
|
break;
|
||||||
|
case 'ldapUserDisplayName':
|
||||||
default:
|
default:
|
||||||
|
// user display name does not lower case because
|
||||||
|
// we rely on an upper case N as indicator whether to
|
||||||
|
// auto-detect it or not. FIXME
|
||||||
$readMethod = 'getValue';
|
$readMethod = 'getValue';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -374,7 +377,7 @@ class Configuration {
|
||||||
'ldap_groupfilter_groups' => '',
|
'ldap_groupfilter_groups' => '',
|
||||||
'ldap_display_name' => 'displayName',
|
'ldap_display_name' => 'displayName',
|
||||||
'ldap_group_display_name' => 'cn',
|
'ldap_group_display_name' => 'cn',
|
||||||
'ldap_tls' => 1,
|
'ldap_tls' => 0,
|
||||||
'ldap_nocase' => 0,
|
'ldap_nocase' => 0,
|
||||||
'ldap_quota_def' => '',
|
'ldap_quota_def' => '',
|
||||||
'ldap_quota_attr' => '',
|
'ldap_quota_attr' => '',
|
||||||
|
|
|
@ -75,9 +75,11 @@ class Wizard extends LDAPUtility {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* counts entries in the LDAP directory
|
* counts entries in the LDAP directory
|
||||||
|
*
|
||||||
* @param string $filter the LDAP search filter
|
* @param string $filter the LDAP search filter
|
||||||
* @param string $type a string being either 'users' or 'groups';
|
* @param string $type a string being either 'users' or 'groups';
|
||||||
* @return int|bool
|
* @return bool|int
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function countEntries($filter, $type) {
|
public function countEntries($filter, $type) {
|
||||||
$reqs = array('ldapHost', 'ldapPort', 'ldapBase');
|
$reqs = array('ldapHost', 'ldapPort', 'ldapBase');
|
||||||
|
@ -88,17 +90,36 @@ class Wizard extends LDAPUtility {
|
||||||
throw new \Exception('Requirements not met', 400);
|
throw new \Exception('Requirements not met', 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$attr = array('dn'); // default
|
||||||
|
$limit = 1001;
|
||||||
if($type === 'groups') {
|
if($type === 'groups') {
|
||||||
$result = $this->access->countGroups($filter);
|
$result = $this->access->countGroups($filter, $attr, $limit);
|
||||||
} else if($type === 'users') {
|
} else if($type === 'users') {
|
||||||
$result = $this->access->countUsers($filter);
|
$result = $this->access->countUsers($filter, $attr, $limit);
|
||||||
|
} else if ($type === 'objects') {
|
||||||
|
$result = $this->access->countObjects($limit);
|
||||||
} else {
|
} else {
|
||||||
throw new \Exception('internal error: invald object type', 500);
|
throw new \Exception('internal error: invalid object type', 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
public function countGroups() {
|
public function countGroups() {
|
||||||
$filter = $this->configuration->ldapGroupFilter;
|
$filter = $this->configuration->ldapGroupFilter;
|
||||||
|
|
||||||
|
@ -109,7 +130,7 @@ class Wizard extends LDAPUtility {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$groupsTotal = $this->countEntries($filter, 'groups');
|
$groupsTotal = $this->formatCountResult($this->countEntries($filter, 'groups'));
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
//400 can be ignored, 500 is forwarded
|
//400 can be ignored, 500 is forwarded
|
||||||
if($e->getCode() === 500) {
|
if($e->getCode() === 500) {
|
||||||
|
@ -117,7 +138,6 @@ class Wizard extends LDAPUtility {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$groupsTotal = ($groupsTotal !== false) ? $groupsTotal : 0;
|
|
||||||
$output = self::$l->n('%s group found', '%s groups found', $groupsTotal, array($groupsTotal));
|
$output = self::$l->n('%s group found', '%s groups found', $groupsTotal, array($groupsTotal));
|
||||||
$this->result->addChange('ldap_group_count', $output);
|
$this->result->addChange('ldap_group_count', $output);
|
||||||
return $this->result;
|
return $this->result;
|
||||||
|
@ -130,13 +150,28 @@ class Wizard extends LDAPUtility {
|
||||||
public function countUsers() {
|
public function countUsers() {
|
||||||
$filter = $this->access->getFilterForUserCount();
|
$filter = $this->access->getFilterForUserCount();
|
||||||
|
|
||||||
$usersTotal = $this->countEntries($filter, 'users');
|
$usersTotal = $this->formatCountResult($this->countEntries($filter, 'users'));
|
||||||
$usersTotal = ($usersTotal !== false) ? $usersTotal : 0;
|
|
||||||
$output = self::$l->n('%s user found', '%s users found', $usersTotal, array($usersTotal));
|
$output = self::$l->n('%s user found', '%s users found', $usersTotal, array($usersTotal));
|
||||||
$this->result->addChange('ldap_user_count', $output);
|
$this->result->addChange('ldap_user_count', $output);
|
||||||
return $this->result;
|
return $this->result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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');
|
||||||
|
if($total === false) {
|
||||||
|
throw new \Exception('invalid results received');
|
||||||
|
}
|
||||||
|
$this->result->addChange('ldap_test_base', $total);
|
||||||
|
return $this->result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* counts users with a specified attribute
|
* counts users with a specified attribute
|
||||||
* @param string $attr
|
* @param string $attr
|
||||||
|
@ -281,45 +316,6 @@ class Wizard extends LDAPUtility {
|
||||||
return $this->result;
|
return $this->result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* return the state of the Group Filter Mode
|
|
||||||
* @return WizardResult
|
|
||||||
*/
|
|
||||||
public function getGroupFilterMode() {
|
|
||||||
$this->getFilterMode('ldapGroupFilterMode');
|
|
||||||
return $this->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return the state of the Login Filter Mode
|
|
||||||
* @return WizardResult
|
|
||||||
*/
|
|
||||||
public function getLoginFilterMode() {
|
|
||||||
$this->getFilterMode('ldapLoginFilterMode');
|
|
||||||
return $this->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return the state of the User Filter Mode
|
|
||||||
* @return WizardResult
|
|
||||||
*/
|
|
||||||
public function getUserFilterMode() {
|
|
||||||
$this->getFilterMode('ldapUserFilterMode');
|
|
||||||
return $this->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return the state of the mode of the specified filter
|
|
||||||
* @param string $confKey contains the access key of the Configuration
|
|
||||||
*/
|
|
||||||
private function getFilterMode($confKey) {
|
|
||||||
$mode = $this->configuration->$confKey;
|
|
||||||
if(is_null($mode)) {
|
|
||||||
$mode = $this->LFILTER_MODE_ASSISTED;
|
|
||||||
}
|
|
||||||
$this->result->addChange($confKey, $mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* detects the available LDAP attributes
|
* detects the available LDAP attributes
|
||||||
* @return array|false The instance's WizardResult instance
|
* @return array|false The instance's WizardResult instance
|
||||||
|
@ -467,8 +463,7 @@ class Wizard extends LDAPUtility {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$this->configuration->setConfiguration(array('ldapGroupMemberAssocAttr' => $attribute));
|
$this->configuration->setConfiguration(array('ldapGroupMemberAssocAttr' => $attribute));
|
||||||
//so it will be saved on destruct
|
$this->result->addChange('ldap_group_member_assoc_attribute', $attribute);
|
||||||
$this->result->markChange();
|
|
||||||
|
|
||||||
return $this->result;
|
return $this->result;
|
||||||
}
|
}
|
||||||
|
@ -603,6 +598,41 @@ class Wizard extends LDAPUtility {
|
||||||
return $this->result;
|
return $this->result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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');
|
||||||
|
}
|
||||||
|
|
||||||
|
$users = $this->access->fetchUsersByLoginName($loginName);
|
||||||
|
if($this->ldap->errno($cr) !== 0) {
|
||||||
|
throw new \Exception($this->ldap->error($cr));
|
||||||
|
}
|
||||||
|
$filter = \OCP\Util::mb_str_replace(
|
||||||
|
'%uid', $loginName, $this->access->connection->ldapLoginFilter, 'UTF-8');
|
||||||
|
$this->result->addChange('ldap_test_loginname', count($users));
|
||||||
|
$this->result->addChange('ldap_test_effective_filter', $filter);
|
||||||
|
return $this->result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to determine the port, requires given Host, User DN and Password
|
* Tries to determine the port, requires given Host, User DN and Password
|
||||||
* @return WizardResult|false WizardResult on success, false otherwise
|
* @return WizardResult|false WizardResult on success, false otherwise
|
||||||
|
@ -674,10 +704,13 @@ class Wizard extends LDAPUtility {
|
||||||
}
|
}
|
||||||
|
|
||||||
$dparts = explode('.', $domain);
|
$dparts = explode('.', $domain);
|
||||||
$base2 = implode('dc=', $dparts);
|
while(count($dparts) > 0) {
|
||||||
if($base !== $base2 && $this->testBaseDN($base2)) {
|
$base2 = 'dc=' . implode(',dc=', $dparts);
|
||||||
$this->applyFind('ldap_base', $base2);
|
if ($base !== $base2 && $this->testBaseDN($base2)) {
|
||||||
return $this->result;
|
$this->applyFind('ldap_base', $base2);
|
||||||
|
return $this->result;
|
||||||
|
}
|
||||||
|
array_shift($dparts);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -720,7 +753,7 @@ class Wizard extends LDAPUtility {
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private function detectGroupMemberAssoc() {
|
private function detectGroupMemberAssoc() {
|
||||||
$possibleAttrs = array('uniqueMember', 'memberUid', 'member', 'unfugasdfasdfdfa');
|
$possibleAttrs = array('uniqueMember', 'memberUid', 'member');
|
||||||
$filter = $this->configuration->ldapGroupFilter;
|
$filter = $this->configuration->ldapGroupFilter;
|
||||||
if(empty($filter)) {
|
if(empty($filter)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -730,7 +763,7 @@ class Wizard extends LDAPUtility {
|
||||||
throw new \Exception('Could not connect to LDAP');
|
throw new \Exception('Could not connect to LDAP');
|
||||||
}
|
}
|
||||||
$base = $this->configuration->ldapBase[0];
|
$base = $this->configuration->ldapBase[0];
|
||||||
$rr = $this->ldap->search($cr, $base, $filter, $possibleAttrs);
|
$rr = $this->ldap->search($cr, $base, $filter, $possibleAttrs, 0, 1000);
|
||||||
if(!$this->ldap->isResource($rr)) {
|
if(!$this->ldap->isResource($rr)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1114,7 +1147,8 @@ class Wizard extends LDAPUtility {
|
||||||
//skip when the filter is a wildcard and results were found
|
//skip when the filter is a wildcard and results were found
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$rr = $this->ldap->search($cr, $base, $filter, array($attr));
|
// 20k limit for performance and reason
|
||||||
|
$rr = $this->ldap->search($cr, $base, $filter, array($attr), 0, 20000);
|
||||||
if(!$this->ldap->isResource($rr)) {
|
if(!$this->ldap->isResource($rr)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,13 +29,6 @@
|
||||||
|
|
||||||
OC_Util::checkAdminUser();
|
OC_Util::checkAdminUser();
|
||||||
|
|
||||||
OCP\Util::addScript('user_ldap', 'ldapFilter');
|
|
||||||
OCP\Util::addScript('user_ldap', 'experiencedAdmin');
|
|
||||||
OCP\Util::addScript('user_ldap', 'settings');
|
|
||||||
\OC_Util::addVendorScript('user_ldap', 'ui-multiselect/src/jquery.multiselect');
|
|
||||||
OCP\Util::addStyle('user_ldap', 'settings');
|
|
||||||
\OC_Util::addVendorStyle('user_ldap', 'ui-multiselect/jquery.multiselect');
|
|
||||||
|
|
||||||
// fill template
|
// fill template
|
||||||
$tmpl = new OCP\Template('user_ldap', 'settings');
|
$tmpl = new OCP\Template('user_ldap', 'settings');
|
||||||
|
|
||||||
|
@ -55,9 +48,9 @@ $l = \OC::$server->getL10N('user_ldap');
|
||||||
|
|
||||||
$wizTabs = array();
|
$wizTabs = array();
|
||||||
$wizTabs[] = array('tpl' => 'part.wizard-server', 'cap' => $l->t('Server'));
|
$wizTabs[] = array('tpl' => 'part.wizard-server', 'cap' => $l->t('Server'));
|
||||||
$wizTabs[] = array('tpl' => 'part.wizard-userfilter', 'cap' => $l->t('User Filter'));
|
$wizTabs[] = array('tpl' => 'part.wizard-userfilter', 'cap' => $l->t('Users'));
|
||||||
$wizTabs[] = array('tpl' => 'part.wizard-loginfilter', 'cap' => $l->t('Login Filter'));
|
$wizTabs[] = array('tpl' => 'part.wizard-loginfilter', 'cap' => $l->t('Login Attributes'));
|
||||||
$wizTabs[] = array('tpl' => 'part.wizard-groupfilter', 'cap' => $l->t('Group Filter'));
|
$wizTabs[] = array('tpl' => 'part.wizard-groupfilter', 'cap' => $l->t('Groups'));
|
||||||
$wizTabsCount = count($wizTabs);
|
$wizTabsCount = count($wizTabs);
|
||||||
for($i = 0; $i < $wizTabsCount; $i++) {
|
for($i = 0; $i < $wizTabsCount; $i++) {
|
||||||
$tab = new OCP\Template('user_ldap', $wizTabs[$i]['tpl']);
|
$tab = new OCP\Template('user_ldap', $wizTabs[$i]['tpl']);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<div class="ldapSettingControls">
|
<div class="ldapSettingControls">
|
||||||
<input class="ldap_submit" value="<?php p($l->t('Save'));?>" type="submit">
|
|
||||||
<button type="button" class="ldap_action_test_connection" name="ldap_action_test_connection">
|
<button type="button" class="ldap_action_test_connection" name="ldap_action_test_connection">
|
||||||
<?php p($l->t('Test Configuration'));?>
|
<?php p($l->t('Test Configuration'));?>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -5,31 +5,48 @@
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="ldap_groupfilter_objectclass">
|
<label for="ldap_groupfilter_objectclass">
|
||||||
<?php p($l->t('only those object classes:'));?>
|
<?php p($l->t('Only these object classes:'));?>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<select id="ldap_groupfilter_objectclass" multiple="multiple"
|
<select id="ldap_groupfilter_objectclass" multiple="multiple"
|
||||||
name="ldap_groupfilter_objectclass">
|
name="ldap_groupfilter_objectclass" class="multiSelectPlugin">
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="ldap_groupfilter_groups">
|
<label for="ldap_groupfilter_groups">
|
||||||
<?php p($l->t('only from those groups:'));?>
|
<?php p($l->t('Only from these groups:'));?>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<input type="text" class="ldapManyGroupsSupport ldapManyGroupsSearch hidden" placeholder="<?php p($l->t('Search groups'));?>" />
|
||||||
|
|
||||||
<select id="ldap_groupfilter_groups" multiple="multiple"
|
<select id="ldap_groupfilter_groups" multiple="multiple"
|
||||||
name="ldap_groupfilter_groups">
|
name="ldap_groupfilter_groups" class="multiSelectPlugin">
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
<p class="ldapManyGroupsSupport hidden">
|
||||||
|
<label></label>
|
||||||
|
<select class="ldapGroupList ldapGroupListAvailable" multiple="multiple"
|
||||||
|
title="<?php p($l->t('Available groups'));?>"></select>
|
||||||
|
<span>
|
||||||
|
<button class="ldapGroupListSelect" type="button">></button><br/>
|
||||||
|
<button class="ldapGroupListDeselect" type="button"><</button>
|
||||||
|
</span>
|
||||||
|
<select class="ldapGroupList ldapGroupListSelected" multiple="multiple"
|
||||||
|
title="<?php p($l->t('Selected groups'));?>"></select>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label><a id='toggleRawGroupFilter'>↓ <?php p($l->t('Edit raw filter instead'));?></a></label>
|
<label><a id='toggleRawGroupFilter' class='ldapToggle'>↓ <?php p($l->t('Edit LDAP Query'));?></a></label>
|
||||||
|
</p>
|
||||||
|
<p id="ldapReadOnlyGroupFilterContainer" class="hidden ldapReadOnlyFilterContainer">
|
||||||
|
<label><?php p($l->t('LDAP Filter:'));?></label>
|
||||||
|
<span class="ldapFilterReadOnlyElement ldapInputColElement"></span>
|
||||||
</p>
|
</p>
|
||||||
<p id="rawGroupFilterContainer" class="invisible">
|
<p id="rawGroupFilterContainer" class="invisible">
|
||||||
<input type="text" id="ldap_group_filter" name="ldap_group_filter"
|
<textarea type="text" id="ldap_group_filter" name="ldap_group_filter"
|
||||||
class="lwautosave"
|
placeholder="<?php p($l->t('Edit LDAP Query'));?>"
|
||||||
placeholder="<?php p($l->t('Raw LDAP filter'));?>"
|
title="<?php p($l->t('The filter specifies which LDAP groups shall have access to the %s instance.', $theme->getName()));?>">
|
||||||
title="<?php p($l->t('The filter specifies which LDAP groups shall have access to the %s instance.', $theme->getName()));?>"
|
</textarea>
|
||||||
/>
|
|
||||||
<button class="ldapGetEntryCount hidden" name="ldapGetEntryCount" type="button">
|
<button class="ldapGetEntryCount hidden" name="ldapGetEntryCount" type="button">
|
||||||
<?php p($l->t('Test Filter'));?>
|
<?php p($l->t('Test Filter'));?>
|
||||||
</button>
|
</button>
|
||||||
|
@ -38,7 +55,10 @@
|
||||||
<div class="ldapWizardInfo invisible"> </div>
|
<div class="ldapWizardInfo invisible"> </div>
|
||||||
</p>
|
</p>
|
||||||
<p class="ldap_count">
|
<p class="ldap_count">
|
||||||
<span id="ldap_group_count">0 <?php p($l->t('groups found'));?></span>
|
<button class="ldapGetEntryCount ldapGetGroupCount" name="ldapGetEntryCount" type="button">
|
||||||
|
<?php p($l->t('Verify settings and count groups'));?>
|
||||||
|
</button>
|
||||||
|
<span id="ldap_group_count"></span>
|
||||||
</p>
|
</p>
|
||||||
<?php print_unescaped($_['wizardControls']); ?>
|
<?php print_unescaped($_['wizardControls']); ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,23 +1,25 @@
|
||||||
<fieldset id="ldapWizard3">
|
<fieldset id="ldapWizard3">
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<?php p($l->t('Users login with this attribute:'));?>
|
<?php p($l->t('When logging in, %s will find the user based on the following attributes:', $theme->getName()));?>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="ldap_loginfilter_username">
|
<label for="ldap_loginfilter_username">
|
||||||
<?php p($l->t('LDAP Username:'));?>
|
<?php p($l->t('LDAP / AD Username:'));?>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<input type="checkbox" id="ldap_loginfilter_username"
|
<input type="checkbox" id="ldap_loginfilter_username"
|
||||||
name="ldap_loginfilter_username" value="1" class="lwautosave" />
|
title="<?php p($l->t('Allows login against the LDAP / AD username, which is either uid or samaccountname and will be detected.'));?>"
|
||||||
|
name="ldap_loginfilter_username" value="1" />
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="ldap_loginfilter_email">
|
<label for="ldap_loginfilter_email">
|
||||||
<?php p($l->t('LDAP Email Address:'));?>
|
<?php p($l->t('LDAP / AD Email Address:'));?>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<input type="checkbox" id="ldap_loginfilter_email"
|
<input type="checkbox" id="ldap_loginfilter_email"
|
||||||
name="ldap_loginfilter_email" value="1" class="lwautosave" />
|
title="<?php p($l->t('Allows login against an email attribute. Mail and mailPrimaryAddress will be allowed.'));?>"
|
||||||
|
name="ldap_loginfilter_email" value="1" />
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="ldap_loginfilter_attributes">
|
<label for="ldap_loginfilter_attributes">
|
||||||
|
@ -25,23 +27,35 @@
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<select id="ldap_loginfilter_attributes" multiple="multiple"
|
<select id="ldap_loginfilter_attributes" multiple="multiple"
|
||||||
name="ldap_loginfilter_attributes">
|
name="ldap_loginfilter_attributes" class="multiSelectPlugin">
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label><a id='toggleRawLoginFilter'>↓ <?php p($l->t('Edit raw filter instead'));?></a></label>
|
<label><a id='toggleRawLoginFilter' class='ldapToggle'>↓ <?php p($l->t('Edit LDAP Query'));?></a></label>
|
||||||
|
</p>
|
||||||
|
<p id="ldapReadOnlyLoginFilterContainer" class="hidden ldapReadOnlyFilterContainer">
|
||||||
|
<label><?php p($l->t('LDAP Filter:'));?></label>
|
||||||
|
<span class="ldapFilterReadOnlyElement ldapInputColElement"></span>
|
||||||
</p>
|
</p>
|
||||||
<p id="rawLoginFilterContainer" class="invisible">
|
<p id="rawLoginFilterContainer" class="invisible">
|
||||||
<input type="text" id="ldap_login_filter" name="ldap_login_filter"
|
<textarea type="text" id="ldap_login_filter" name="ldap_login_filter"
|
||||||
class="lwautosave"
|
class="ldapFilterInputElement"
|
||||||
placeholder="<?php p($l->t('Raw LDAP filter'));?>"
|
placeholder="<?php p($l->t('Edit LDAP Query'));?>"
|
||||||
title="<?php p($l->t('Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: "uid=%%uid"'));?>"
|
title="<?php p($l->t('Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: "uid=%%uid"'));?>">
|
||||||
/>
|
</textarea>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<div class="ldapWizardInfo invisible"> </div>
|
<div class="ldapWizardInfo invisible"> </div>
|
||||||
</p>
|
</p>
|
||||||
|
<p class="ldap_verify">
|
||||||
|
<input type="text" id="ldap_test_loginname" name="ldap_test_loginname"
|
||||||
|
placeholder="<?php p($l->t('Test Loginname'));?>"
|
||||||
|
class="ldapVerifyInput"
|
||||||
|
title="Attempts to receive a DN for the given loginname and the current login filter"/>
|
||||||
|
<button class="ldapVerifyLoginName" name="ldapTestLoginSettings" type="button">
|
||||||
|
<?php p($l->t('Verify settings'));?>
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
<?php print_unescaped($_['wizardControls']); ?>
|
<?php print_unescaped($_['wizardControls']); ?>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
|
@ -22,32 +22,41 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<option value="NEW"><?php p($l->t('Add Server Configuration'));?></option>
|
|
||||||
</select>
|
</select>
|
||||||
|
<button type="button" id="ldap_action_add_configuration"
|
||||||
|
name="ldap_action_add_configuration" class="icon-add"
|
||||||
|
title="Adds a new and blank configuration"> </button>
|
||||||
|
<button type="button" id="ldap_action_copy_configuration"
|
||||||
|
name="ldap_action_copy_configuration"
|
||||||
|
class="ldapIconCopy icon-default-style"
|
||||||
|
title="Copy current configuration into new directory binding"> </button>
|
||||||
<button type="button" id="ldap_action_delete_configuration"
|
<button type="button" id="ldap_action_delete_configuration"
|
||||||
name="ldap_action_delete_configuration"><?php p($l->t('Delete Configuration'));?></button>
|
name="ldap_action_delete_configuration" class="icon-delete"
|
||||||
|
title="Delete the current configuration"> </button>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="hostPortCombinator">
|
<div class="hostPortCombinator">
|
||||||
<div class="tablerow">
|
<div class="tablerow">
|
||||||
<div class="tablecell">
|
<div class="tablecell">
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<input type="text" class="host tablecell lwautosave" id="ldap_host"
|
<input type="text" class="host" id="ldap_host"
|
||||||
name="ldap_host"
|
name="ldap_host"
|
||||||
placeholder="<?php p($l->t('Host'));?>"
|
placeholder="<?php p($l->t('Host'));?>"
|
||||||
title="<?php p($l->t('You can omit the protocol, except you require SSL. Then start with ldaps://'));?>"
|
title="<?php p($l->t('You can omit the protocol, except you require SSL. Then start with ldaps://'));?>"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
<input type="number" id="ldap_port" name="ldap_port"
|
<input type="number" id="ldap_port" name="ldap_port"
|
||||||
class="lwautosave"
|
|
||||||
placeholder="<?php p($l->t('Port'));?>" />
|
placeholder="<?php p($l->t('Port'));?>" />
|
||||||
|
<button class="ldapDetectPort" name="ldapDetectPort" type="button">
|
||||||
|
<?php p($l->t('Detect Port'));?>
|
||||||
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tablerow">
|
<div class="tablerow">
|
||||||
<input type="text" id="ldap_dn" name="ldap_dn"
|
<input type="text" id="ldap_dn" name="ldap_dn"
|
||||||
class="tablecell lwautosave"
|
class="tablecell"
|
||||||
placeholder="<?php p($l->t('User DN'));?>" autocomplete="off"
|
placeholder="<?php p($l->t('User DN'));?>" autocomplete="off"
|
||||||
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.'));?>"
|
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.'));?>"
|
||||||
/>
|
/>
|
||||||
|
@ -55,7 +64,7 @@
|
||||||
|
|
||||||
<div class="tablerow">
|
<div class="tablerow">
|
||||||
<input type="password" id="ldap_agent_password"
|
<input type="password" id="ldap_agent_password"
|
||||||
class="tablecell lwautosave" name="ldap_agent_password"
|
class="tablecell" name="ldap_agent_password"
|
||||||
placeholder="<?php p($l->t('Password'));?>" autocomplete="off"
|
placeholder="<?php p($l->t('Password'));?>" autocomplete="off"
|
||||||
title="<?php p($l->t('For anonymous access, leave DN and Password empty.'));?>"
|
title="<?php p($l->t('For anonymous access, leave DN and Password empty.'));?>"
|
||||||
/>
|
/>
|
||||||
|
@ -63,15 +72,21 @@
|
||||||
|
|
||||||
<div class="tablerow">
|
<div class="tablerow">
|
||||||
<textarea id="ldap_base" name="ldap_base"
|
<textarea id="ldap_base" name="ldap_base"
|
||||||
class="tablecell lwautosave"
|
class="tablecell"
|
||||||
placeholder="<?php p($l->t('One Base DN per line'));?>"
|
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'));?>">
|
title="<?php p($l->t('You can specify Base DN for users and groups in the Advanced tab'));?>">
|
||||||
</textarea>
|
</textarea>
|
||||||
|
<button class="ldapDetectBase" name="ldapDetectBase" type="button">
|
||||||
|
<?php p($l->t('Detect Base DN'));?>
|
||||||
|
</button>
|
||||||
|
<button class="ldapTestBase" name="ldapTestBase" type="button">
|
||||||
|
<?php p($l->t('Test Base DN'));?>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tablerow left">
|
<div class="tablerow left">
|
||||||
<input type="checkbox" id="ldap_experienced_admin" value="1"
|
<input type="checkbox" id="ldap_experienced_admin" value="1"
|
||||||
name="ldap_experienced_admin" class="tablecell lwautosave"
|
name="ldap_experienced_admin" class="tablecell"
|
||||||
title="<?php p($l->t('Avoids automatic LDAP requests. Better for bigger setups, but requires some LDAP knowledge.'));?>"
|
title="<?php p($l->t('Avoids automatic LDAP requests. Better for bigger setups, but requires some LDAP knowledge.'));?>"
|
||||||
/>
|
/>
|
||||||
<label for="ldap_experienced_admin" class="tablecell">
|
<label for="ldap_experienced_admin" class="tablecell">
|
||||||
|
|
|
@ -5,40 +5,61 @@
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="ldap_userfilter_objectclass">
|
<label for="ldap_userfilter_objectclass">
|
||||||
<?php p($l->t('only those object classes:'));?>
|
<?php p($l->t('Only these object classes:'));?>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<select id="ldap_userfilter_objectclass" multiple="multiple"
|
<select id="ldap_userfilter_objectclass" multiple="multiple"
|
||||||
name="ldap_userfilter_objectclass">
|
name="ldap_userfilter_objectclass" class="multiSelectPlugin">
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<label></label>
|
||||||
|
<span class="ldapInputColElement"><?php p($l->t('The most common object classes for users are organizationalPerson, person, user, and inetOrgPerson. If you are not sure which object class to select, please consult your directory admin.'));?></span>
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="ldap_userfilter_groups">
|
<label for="ldap_userfilter_groups">
|
||||||
<?php p($l->t('only from those groups:'));?>
|
<?php p($l->t('Only from these groups:'));?>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<input type="text" class="ldapManyGroupsSupport ldapManyGroupsSearch hidden" placeholder="<?php p($l->t('Search groups'));?>" />
|
||||||
|
|
||||||
<select id="ldap_userfilter_groups" multiple="multiple"
|
<select id="ldap_userfilter_groups" multiple="multiple"
|
||||||
name="ldap_userfilter_groups">
|
name="ldap_userfilter_groups" class="multiSelectPlugin">
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p class="ldapManyGroupsSupport hidden">
|
||||||
<label><a id='toggleRawUserFilter'>↓ <?php p($l->t('Edit raw filter instead'));?></a></label>
|
<label></label>
|
||||||
|
<select class="ldapGroupList ldapGroupListAvailable" multiple="multiple"
|
||||||
|
title="<?php p($l->t('Available groups'));?>"></select>
|
||||||
|
<span>
|
||||||
|
<button class="ldapGroupListSelect" type="button">></button><br/>
|
||||||
|
<button class="ldapGroupListDeselect" type="button"><</button>
|
||||||
|
</span>
|
||||||
|
<select class="ldapGroupList ldapGroupListSelected" multiple="multiple"
|
||||||
|
title="<?php p($l->t('Selected groups'));?>"></select>
|
||||||
</p>
|
</p>
|
||||||
<p id="rawUserFilterContainer" class="invisible">
|
<p>
|
||||||
<input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter"
|
<label><a id='toggleRawUserFilter' class='ldapToggle'>↓ <?php p($l->t('Edit LDAP Query'));?></a></label>
|
||||||
class="lwautosave"
|
</p>
|
||||||
placeholder="<?php p($l->t('Raw LDAP filter'));?>"
|
<p id="ldapReadOnlyUserFilterContainer" class="hidden ldapReadOnlyFilterContainer">
|
||||||
title="<?php p($l->t('The filter specifies which LDAP users shall have access to the %s instance.', $theme->getName()));?>"
|
<label><?php p($l->t('LDAP Filter:'));?></label>
|
||||||
/>
|
<span class="ldapFilterReadOnlyElement ldapInputColElement"></span>
|
||||||
<button class="ldapGetEntryCount hidden" name="ldapGetEntryCount" type="button">
|
</p>
|
||||||
<?php p($l->t('Test Filter'));?>
|
<p id="rawUserFilterContainer">
|
||||||
</button>
|
<textarea type="text" id="ldap_userlist_filter" name="ldap_userlist_filter"
|
||||||
|
class="ldapFilterInputElement"
|
||||||
|
placeholder="<?php p($l->t('Edit LDAP Query'));?>"
|
||||||
|
title="<?php p($l->t('The filter specifies which LDAP users shall have access to the %s instance.', $theme->getName()));?>">
|
||||||
|
</textarea>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<div class="ldapWizardInfo invisible"> </div>
|
<div class="ldapWizardInfo invisible"> </div>
|
||||||
</p>
|
</p>
|
||||||
<p class="ldap_count">
|
<p class="ldap_count">
|
||||||
<span id="ldap_user_count">0 <?php p($l->t('users found'));?></span>
|
<button class="ldapGetEntryCount ldapGetUserCount" name="ldapGetEntryCount" type="button">
|
||||||
|
<?php p($l->t('Verify settings and count users'));?>
|
||||||
|
</button>
|
||||||
|
<span id="ldap_user_count"></span>
|
||||||
</p>
|
</p>
|
||||||
<?php print_unescaped($_['wizardControls']); ?>
|
<?php print_unescaped($_['wizardControls']); ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
vendor_script('user_ldap', 'ui-multiselect/src/jquery.multiselect');
|
||||||
|
|
||||||
|
vendor_style('user_ldap', 'ui-multiselect/jquery.multiselect');
|
||||||
|
|
||||||
|
script('user_ldap', [
|
||||||
|
'wizard/controller',
|
||||||
|
'wizard/configModel',
|
||||||
|
'wizard/view',
|
||||||
|
'wizard/wizardObject',
|
||||||
|
'wizard/wizardTabGeneric',
|
||||||
|
'wizard/wizardTabElementary',
|
||||||
|
'wizard/wizardTabAbstractFilter',
|
||||||
|
'wizard/wizardTabUserFilter',
|
||||||
|
'wizard/wizardTabLoginFilter',
|
||||||
|
'wizard/wizardTabGroupFilter',
|
||||||
|
'wizard/wizardTabAdvanced',
|
||||||
|
'wizard/wizardTabExpert',
|
||||||
|
'wizard/wizardDetectorQueue',
|
||||||
|
'wizard/wizardDetectorGeneric',
|
||||||
|
'wizard/wizardDetectorPort',
|
||||||
|
'wizard/wizardDetectorBaseDN',
|
||||||
|
'wizard/wizardDetectorFeatureAbstract',
|
||||||
|
'wizard/wizardDetectorUserObjectClasses',
|
||||||
|
'wizard/wizardDetectorGroupObjectClasses',
|
||||||
|
'wizard/wizardDetectorGroupsForUsers',
|
||||||
|
'wizard/wizardDetectorGroupsForGroups',
|
||||||
|
'wizard/wizardDetectorSimpleRequestAbstract',
|
||||||
|
'wizard/wizardDetectorFilterUser',
|
||||||
|
'wizard/wizardDetectorFilterLogin',
|
||||||
|
'wizard/wizardDetectorFilterGroup',
|
||||||
|
'wizard/wizardDetectorUserCount',
|
||||||
|
'wizard/wizardDetectorGroupCount',
|
||||||
|
'wizard/wizardDetectorEmailAttribute',
|
||||||
|
'wizard/wizardDetectorUserDisplayNameAttribute',
|
||||||
|
'wizard/wizardDetectorUserGroupAssociation',
|
||||||
|
'wizard/wizardDetectorAvailableAttributes',
|
||||||
|
'wizard/wizardDetectorTestAbstract',
|
||||||
|
'wizard/wizardDetectorTestLoginName',
|
||||||
|
'wizard/wizardDetectorTestBaseDN',
|
||||||
|
'wizard/wizardDetectorTestConfiguration',
|
||||||
|
'wizard/wizardDetectorClearUserMappings',
|
||||||
|
'wizard/wizardDetectorClearGroupMappings',
|
||||||
|
'wizard/wizardFilterOnType',
|
||||||
|
'wizard/wizardFilterOnTypeFactory',
|
||||||
|
'wizard/wizard'
|
||||||
|
]);
|
||||||
|
|
||||||
|
style('user_ldap', 'settings');
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
<form id="ldap" class="section" action="#" method="post">
|
<form id="ldap" class="section" action="#" method="post">
|
||||||
<h2><?php p($l->t('LDAP')); ?></h2>
|
<h2><?php p($l->t('LDAP')); ?></h2>
|
||||||
|
|
||||||
|
@ -65,5 +118,6 @@
|
||||||
<?php print_unescaped($_['settingControls']); ?>
|
<?php print_unescaped($_['settingControls']); ?>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Spinner Template -->
|
||||||
|
<img class="ldapSpinner hidden" src="<?php p(\OCP\Util::imagePath('core', 'loading.gif')); ?>">
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -108,12 +108,6 @@ class Test_User_Ldap_Direct extends \Test\TestCase {
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function prepareAccessForCheckPassword(&$access, $noDisplayName = false) {
|
private function prepareAccessForCheckPassword(&$access, $noDisplayName = false) {
|
||||||
$access->expects($this->once())
|
|
||||||
->method('escapeFilterPart')
|
|
||||||
->will($this->returnCallback(function($uid) {
|
|
||||||
return $uid;
|
|
||||||
}));
|
|
||||||
|
|
||||||
$access->connection->expects($this->any())
|
$access->connection->expects($this->any())
|
||||||
->method('__get')
|
->method('__get')
|
||||||
->will($this->returnCallback(function($name) {
|
->will($this->returnCallback(function($name) {
|
||||||
|
@ -132,6 +126,15 @@ class Test_User_Ldap_Direct extends \Test\TestCase {
|
||||||
return array();
|
return array();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
$access->expects($this->any())
|
||||||
|
->method('fetchUsersByLoginName')
|
||||||
|
->will($this->returnCallback(function($uid) {
|
||||||
|
if($uid === 'roland') {
|
||||||
|
return array(array('dn' => 'dnOfRoland,dc=test'));
|
||||||
|
}
|
||||||
|
return array();
|
||||||
|
}));
|
||||||
|
|
||||||
$retVal = 'gunslinger';
|
$retVal = 'gunslinger';
|
||||||
if($noDisplayName === true) {
|
if($noDisplayName === true) {
|
||||||
$retVal = false;
|
$retVal = false;
|
||||||
|
|
|
@ -79,14 +79,10 @@ class USER_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
|
||||||
* Check if the password is correct without logging in the user
|
* Check if the password is correct without logging in the user
|
||||||
*/
|
*/
|
||||||
public function checkPassword($uid, $password) {
|
public function checkPassword($uid, $password) {
|
||||||
$uid = $this->access->escapeFilterPart($uid);
|
|
||||||
|
|
||||||
//find out dn of the user name
|
//find out dn of the user name
|
||||||
$attrs = array($this->access->connection->ldapUserDisplayName, 'dn',
|
$attrs = array($this->access->connection->ldapUserDisplayName, 'dn',
|
||||||
'uid', 'samaccountname');
|
'uid', 'samaccountname');
|
||||||
$filter = \OCP\Util::mb_str_replace(
|
$users = $this->access->fetchUsersByLoginName($uid, $attrs);
|
||||||
'%uid', $uid, $this->access->connection->ldapLoginFilter, 'UTF-8');
|
|
||||||
$users = $this->access->fetchListOfUsers($filter, $attrs);
|
|
||||||
if(count($users) < 1) {
|
if(count($users) < 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue