]> source.dussan.org Git - nextcloud-server.git/commitdiff
Ldap Wizard: Login filter UI, detection of username attribute, composing of login...
authorArthur Schiwon <blizzz@owncloud.com>
Tue, 8 Oct 2013 21:47:57 +0000 (23:47 +0200)
committerArthur Schiwon <blizzz@owncloud.com>
Thu, 17 Oct 2013 17:13:28 +0000 (19:13 +0200)
apps/user_ldap/ajax/wizard.php
apps/user_ldap/js/settings.js
apps/user_ldap/lib/configuration.php
apps/user_ldap/lib/wizard.php
apps/user_ldap/settings.php

index 27359b908f61e5e9eab9fe713b074b7cd62d2089..7af879c99a5b7760ef14dba241aad99789e3a7a6 100644 (file)
@@ -48,7 +48,9 @@ switch($action) {
        case 'guessBaseDN':
        case 'determineObjectClasses':
        case 'determineGroups':
+       case 'determineAttributes':
        case 'getUserListFilter':
+       case 'getUserLoginFilter':
        case 'countUsers':
                try {
                        $result = $wizard->$action();
index d3c7aeea4f7768cc7903b866b9d877c6aea9a90e..ba000c200f5c9c02ab514f3345e224038285db53 100644 (file)
@@ -210,6 +210,8 @@ var LdapWizard = {
        composeFilter: function(type) {
                if(type == 'user') {
                        action = 'getUserListFilter';
+               } else if(type == 'login') {
+                       action = 'getUserLoginFilter';
                }
 
                param = 'action='+action+
@@ -241,6 +243,32 @@ var LdapWizard = {
                );
        },
 
+       findAttributes: function() {
+               param = 'action=determineAttributes'+
+                               '&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
+
+               LdapWizard.ajax(param,
+                       function(result) {
+                               $('#ldap_loginfilter_attributes').find('option').remove();
+                               for (i in result.options['ldap_loginfilter_attributes']) {
+                                       //FIXME: move HTML into template
+                                       attr = result.options['ldap_loginfilter_attributes'][i];
+                                       $('#ldap_loginfilter_attributes').append(
+                                                               "<option value='"+attr+"'>"+attr+"</option>");
+                               }
+                               LdapWizard.applyChanges(result);
+                               $('#ldap_loginfilter_attributes').multiselect('refresh');
+                               $('#ldap_loginfilter_attributes').multiselect('enable');
+                       },
+                       function (result) {
+                               //deactivate if no attributes found
+                               $('#ldap_loginfilter_attributes').multiselect(
+                                                                       {noneSelectedText : 'No attributes found'});
+                               $('#ldap_loginfilter_attributes').multiselect('disable');
+                       }
+               );
+       },
+
        findAvailableGroups: function() {
                param = 'action=determineGroups'+
                                '&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
@@ -297,6 +325,10 @@ var LdapWizard = {
                }
        },
 
+       initLoginFilter: function() {
+               LdapWizard.findAttributes();
+       },
+
        initMultiSelect: function(object, id, caption) {
                object.multiselect({
                        header: false,
@@ -318,6 +350,8 @@ var LdapWizard = {
        onTabChange: function(event, ui) {
                if(ui.newTab[0].id === '#ldapWizard2') {
                        LdapWizard.initUserFilter();
+               } else if(ui.newTab[0].id === '#ldapWizard3') {
+                       LdapWizard.initLoginFilter();
                }
        },
 
@@ -333,6 +367,11 @@ var LdapWizard = {
                if(triggerObj.id == 'ldap_userlist_filter') {
                        LdapWizard.countUsers();
                }
+
+               if(triggerObj.id == 'ldap_loginfilter_username'
+                  || triggerObj.id == 'ldap_loginfilter_email') {
+                       LdapWizard.composeFilter('login');
+               }
        },
 
        save: function(inputObj) {
@@ -340,7 +379,13 @@ var LdapWizard = {
                        delete LdapWizard.saveBlacklist[inputObj.id];
                        return;
                }
-               LdapWizard._save(inputObj, $(inputObj).val());
+               if($(inputObj).is('input[type=checkbox]')
+                  && !$(inputObj).is(':checked')) {
+                       val = 0;
+               } else {
+                       val = $(inputObj).val();
+               }
+               LdapWizard._save(inputObj, val);
        },
 
        saveMultiSelect: function(originalObj, resultObj) {
@@ -352,7 +397,10 @@ var LdapWizard = {
                if(originalObj == 'ldap_userfilter_objectclass'
                   || originalObj == 'ldap_userfilter_groups') {
                        LdapWizard.composeFilter('user');
+               } else if(originalObj == 'ldap_loginfilter_attributes') {
+                       LdapWizard.composeFilter('login');
                }
+
        },
 
        _save: function(object, value) {
@@ -410,6 +458,9 @@ $(document).ready(function() {
        LdapWizard.initMultiSelect($('#ldap_userfilter_objectclass'),
                                                           'ldap_userfilter_objectclass',
                                                           t('user_ldap', 'Select object classes'));
+       LdapWizard.initMultiSelect($('#ldap_loginfilter_attributes'),
+                                                          'ldap_loginfilter_attributes',
+                                                          t('user_ldap', 'Select attributes'));
        $('.lwautosave').change(function() { LdapWizard.save(this); });
        $('#toggleRawUserFilter').click(LdapWizard.toggleRawUserFilter);
        LdapConfiguration.refreshConfig();
index 70c5545889501ecfb632a4b87ae75e1d42a85e89..205f9b517a250f327c34410b0a5b64e577376bd9 100644 (file)
@@ -51,6 +51,9 @@ class Configuration {
                'ldapGroupDisplayName' => null,
                'ldapGroupMemberAssocAttr' => null,
                'ldapLoginFilter' => null,
+               'ldapLoginFilterEmail' => null,
+               'ldapLoginFilterUsername' => null,
+               'ldapLoginFilterAttributes' => null,
                'ldapQuotaAttribute' => null,
                'ldapQuotaDefault' => null,
                'ldapEmailAttribute' => null,
@@ -126,6 +129,7 @@ class Configuration {
                                case 'ldapAttributesForGroupSearch':
                                case 'ldapUserFilterObjectclass':
                                case 'ldapUserFilterGroups':
+                               case 'ldapLoginFilterAttributes':
                                        $setMethod = 'setMultiLine';
                                default:
                                        $this->$setMethod($key, $val);
@@ -154,6 +158,7 @@ class Configuration {
                                        case 'ldapAttributesForGroupSearch':
                                        case 'ldapUserFilterObjectclass':
                                        case 'ldapUserFilterGroups':
+                                       case 'ldapLoginFilterAttributes':
                                                $readMethod = 'getMultiLine';
                                                break;
                                        case 'ldapIgnoreNamingRules':
@@ -194,6 +199,7 @@ class Configuration {
                                case 'ldapAttributesForGroupSearch':
                                case 'ldapUserFilterObjectclass':
                                case 'ldapUserFilterGroups':
+                               case 'ldapLoginFilterAttributes':
                                        if(is_array($value)) {
                                                $value = implode("\n", $value);
                                        }
@@ -286,6 +292,9 @@ class Configuration {
                        'ldap_userfilter_objectclass'           => '',
                        'ldap_userfilter_groups'                        => '',
                        'ldap_login_filter'                                     => 'uid=%uid',
+                       'ldap_loginfilter_email'                        => 0,
+                       'ldap_loginfilter_username'                     => 1,
+                       'ldap_loginfilter_attributes'           => '',
                        'ldap_group_filter'                                     => 'objectClass=posixGroup',
                        'ldap_display_name'                                     => 'cn',
                        'ldap_group_display_name'                       => 'cn',
@@ -329,6 +338,9 @@ class Configuration {
                        'ldap_userfilter_groups'                        => 'ldapUserFilterGroups',
                        'ldap_userlist_filter'                          => 'ldapUserFilter',
                        'ldap_login_filter'                                     => 'ldapLoginFilter',
+                       'ldap_loginfilter_email'                        => 'ldapLoginFilterEmail',
+                       'ldap_loginfilter_username'                     => 'ldapLoginFilterUsername',
+                       'ldap_loginfilter_attributes'           => 'ldapLoginFilterAttributes',
                        'ldap_group_filter'                                     => 'ldapGroupFilter',
                        'ldap_display_name'                                     => 'ldapUserDisplayName',
                        'ldap_group_display_name'                       => 'ldapGroupDisplayName',
index e85c7460748f650fe760a78f13bf94d09785fb5f..3cbca17251501352192f3c704485ad7ace6d34b6 100644 (file)
@@ -30,13 +30,13 @@ class Wizard extends LDAPUtility {
        protected $result;
        protected $resultCache = array();
 
-       const LRESULT_PROCESSED_OK = 0;
-       const LRESULT_PROCESSED_INVALID = 1;
-       const LRESULT_PROCESSED_SKIP = 2;
+       const LRESULT_PROCESSED_OK = 2;
+       const LRESULT_PROCESSED_INVALID = 3;
+       const LRESULT_PROCESSED_SKIP = 4;
 
-       const LFILTER_LOGIN      = 0;
-       const LFILTER_USER_LIST  = 1;
-       const LFILTER_GROUP_LIST = 2;
+       const LFILTER_LOGIN      = 2;
+       const LFILTER_USER_LIST  = 3;
+       const LFILTER_GROUP_LIST = 4;
 
        /**
         * @brief Constructor
@@ -87,6 +87,67 @@ class Wizard extends LDAPUtility {
                return $this->result;
        }
 
+       public function determineAttributes() {
+               if(!$this->checkRequirements(array('ldapHost',
+                                                                                  'ldapPort',
+                                                                                  'ldapAgentName',
+                                                                                  'ldapAgentPassword',
+                                                                                  'ldapBase',
+                                                                                  'ldapUserFilter',
+                                                                                  ))) {
+                       return  false;
+               }
+
+               $attributes = $this->getUserAttributes();
+
+               natcasesort($attributes);
+               $attributes = array_values($attributes);
+
+               $this->result->addOptions('ldap_loginfilter_attributes', $attributes);
+
+               $selected = $this->configuration->ldapLoginFilterAttributes;
+               if(is_array($selected) && !empty($selected)) {
+                       $this->result->addChange('ldap_loginfilter_attributes', $selected);
+               }
+
+               return $this->result;
+       }
+
+       /**
+        * @brief detects the available LDAP attributes
+        * @returns the instance's WizardResult instance
+        */
+       private function getUserAttributes() {
+               if(!$this->checkRequirements(array('ldapHost',
+                                                                                  'ldapPort',
+                                                                                  'ldapAgentName',
+                                                                                  'ldapAgentPassword',
+                                                                                  'ldapBase',
+                                                                                  'ldapUserFilter',
+                                                                                  ))) {
+                       return  false;
+               }
+               $cr = $this->getConnection();
+               if(!$cr) {
+                       throw new \Excpetion('Could not connect to LDAP');
+               }
+
+               $base = $this->configuration->ldapBase[0];
+               $filter = $this->configuration->ldapUserFilter;
+               $rr = $this->ldap->search($cr, $base, $filter, array(), 1, 1);
+               if(!$this->ldap->isResource($rr)) {
+                       return false;
+               }
+               $er = $this->ldap->firstEntry($cr, $rr);
+               $attributes = $this->ldap->getAttributes($cr, $er);
+               $pureAttributes = array();
+               for($i = 0; $i < $attributes['count']; $i++) {
+                       $pureAttributes[] = $attributes[$i];
+               }
+
+               return $pureAttributes;
+       }
+
        /**
         * @brief detects the available LDAP groups
         * @returns the instance's WizardResult instance
@@ -167,6 +228,25 @@ class Wizard extends LDAPUtility {
                return $this->result;
        }
 
+       public function getUserLoginFilter() {
+               if(!$this->checkRequirements(array('ldapHost',
+                                                                                  'ldapPort',
+                                                                                  'ldapAgentName',
+                                                                                  'ldapAgentPassword',
+                                                                                  'ldapBase',
+                                                                                  'ldapUserFilter',
+                                                                                  ))) {
+                       return false;
+               }
+               $filter = $this->composeLdapFilter(self::LFILTER_LOGIN);
+               if(!$filter) {
+                       throw new \Exception('Cannot create filter');
+               }
+
+               $this->applyFind('ldap_login_filter', $filter);
+               return $this->result;
+       }
+
        /**
         * Tries to determine the port, requires given Host, User DN and Password
         * @returns mixed WizardResult on success, false otherwise
@@ -361,10 +441,8 @@ class Wizard extends LDAPUtility {
                switch ($filterType) {
                        case self::LFILTER_USER_LIST:
                                $objcs = $this->configuration->ldapUserFilterObjectclass;
-                               \OCP\Util::writeLog('user_ldap', 'Wiz: '.print_r($objcs, true), \OCP\Util::DEBUG);
                                //glue objectclasses
                                if(is_array($objcs) && count($objcs) > 0) {
-                                       \OCP\Util::writeLog('user_ldap', 'Wiz: Processing objectclasses', \OCP\Util::DEBUG);
                                        $filter .= '(|';
                                        foreach($objcs as $objc) {
                                                $filter .= '(objectclass=' . $objc . ')';
@@ -372,13 +450,10 @@ class Wizard extends LDAPUtility {
                                        $filter .= ')';
                                        $parts++;
                                }
-                               \OCP\Util::writeLog('user_ldap', 'Wiz: Intermediate filter '.$filter, \OCP\Util::DEBUG);
                                //glue group memberships
                                if($this->configuration->hasMemberOfFilterSupport) {
                                        $cns = $this->configuration->ldapUserFilterGroups;
-                                       \OCP\Util::writeLog('user_ldap', 'Wiz: '.print_r($cns, true), \OCP\Util::DEBUG);
                                        if(is_array($cns) && count($cns) > 0) {
-                                               \OCP\Util::writeLog('user_ldap', 'Wiz: Processing groups', \OCP\Util::DEBUG);
                                                $filter .= '(|';
                                                $cr = $this->getConnection();
                                                if(!$cr) {
@@ -397,15 +472,70 @@ class Wizard extends LDAPUtility {
                                                $filter .= ')';
                                        }
                                        $parts++;
-                                       \OCP\Util::writeLog('user_ldap', 'Wiz: Intermediate filter '.$filter, \OCP\Util::DEBUG);
                                }
                                //wrap parts in AND condition
                                if($parts > 1) {
                                        $filter = '(&' . $filter . ')';
                                }
                                if(empty($filter)) {
-                                       $filter = 'objectclass=*';
+                                       $filter = '(objectclass=*)';
+                               }
+                               break;
+
+                       case self::LFILTER_LOGIN:
+                               $ulf = $this->configuration->ldapUserFilter;
+                               $loginpart = '=%uid';
+                               $filterUsername = '';
+                               $userAttributes = $this->getUserAttributes();
+                               $userAttributes = array_change_key_case(array_flip($userAttributes));
+                               $parts = 0;
+
+                               $x = $this->configuration->ldapLoginFilterUsername;
+                               if($this->configuration->ldapLoginFilterUsername === '1') {
+                                       $attr = '';
+                                       if(isset($userAttributes['uid'])) {
+                                               $attr = 'uid';
+                                       } else if(isset($userAttributes['samaccountname'])) {
+                                               $attr = 'samaccountname';
+                                       } else if(isset($userAttributes['cn'])) {
+                                               //fallback
+                                               $attr = 'cn';
+                                       }
+                                       if(!empty($attr)) {
+                                               $filterUsername = '(' . $attr . $loginpart . ')';
+                                               $parts++;
+                                       }
                                }
+
+                               $filterEmail = '';
+                               if($this->configuration->ldapLoginFilterEmail === '1') {
+                                       $filterEmail = '(|(mailPrimaryAddress=%uid)(mail=%uid))';
+                                       $parts++;
+                               }
+
+                               $filterAttributes = '';
+                               $attrsToFilter = $this->configuration->ldapLoginFilterAttributes;
+                               if(is_array($attrsToFilter) && count($attrsToFilter) > 0) {
+                                       $filterAttributes = '(|';
+                                       foreach($attrsToFilter as $attribute) {
+                                           $filterAttributes .= '(' . $attribute . $loginpart . ')';
+                                       }
+                                       $filterAttributes .= ')';
+                                       $parts++;
+                               }
+
+                               $filterLogin = '';
+                               if($parts > 1) {
+                                       $filterLogin = '(|';
+                               }
+                               $filterLogin .= $filterUsername;
+                               $filterLogin .= $filterEmail;
+                               $filterLogin .= $filterAttributes;
+                               if($parts > 1) {
+                                       $filterLogin .= ')';
+                               }
+
+                               $filter = '(&'.$ulf.$filterLogin.')';
                                break;
                }
 
index ebba1dbd3a620391ba1b7e0e46814aee3506f2c5..299e98fe09056d9a2ae9fc49c1b0db0f5040ef25 100644 (file)
@@ -57,6 +57,11 @@ $wizard2->assign('wizardControls', $wControls);
 $wizardHtml .= $wizard2->fetchPage();
 $toc['#ldapWizard2'] = 'User Filter';
 
+$wizard3 = new OCP\Template('user_ldap', 'part.wizard-loginfilter');
+$wizard3->assign('wizardControls', $wControls);
+$wizardHtml .= $wizard3->fetchPage();
+$toc['#ldapWizard3'] = 'Login Filter';
+
 $tmpl->assign('tabs', $wizardHtml);
 $tmpl->assign('toc', $toc);