From 21cd46df149b7ac94d99b384143f0549e512ce4a Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 8 May 2018 17:07:29 -0600 Subject: [PATCH] many improvements --- blueprints.yaml | 59 +++++++++++++++++++++++++++ login-ldap.php | 103 ++++++++++++++++++++++++++++++++++++++++-------- login-ldap.yaml | 8 +++- 3 files changed, 152 insertions(+), 18 deletions(-) diff --git a/blueprints.yaml b/blueprints.yaml index 279851b..0cbd7cc 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -29,12 +29,14 @@ form: server_section: type: section title: LDAP Server + underline: true fields: host: type: text label: Host + size: large help: Host name of the LDAP server validate: required: true @@ -43,6 +45,7 @@ form: type: number label: Port default: 389 + size: x-small help: Port to connect to host validate: required: true @@ -51,6 +54,7 @@ form: type: number label: Version default: 3 + size: x-small help: LDAP Version 3 is most popular, only change this if you know what you are doing validate: required: true @@ -93,12 +97,14 @@ form: config_section: type: section title: LDAP Configuration + underline: true fields: user_dn: type: text label: User Search DN + size: large placeholder: uid=[username],dc=company,dc=com help: String used to authenticate a user, where [username] is directly replaced by user value entered via login validate: @@ -107,12 +113,14 @@ form: data_dn: type: text label: User Data DN + size: large placeholder: dc=company,dc=com help: String used to retrieve user data. If not provided, extra LDAP user data will not be stored in Grav user account file map_username: type: text label: Username Mapping + size: large help: LDAP Attribute(s) that contains the user's username placeholder: uid validate: @@ -121,6 +129,7 @@ form: map_fullname: type: text label: User Fullname Mapping + size: large help: LDAP Attribute(s) that contains the user's full name placeholder: givenName lastName validate: @@ -129,7 +138,57 @@ form: map_email: type: text label: User Email Mapping + size: large help: LDAP Attribute that contains the user's email placeholder: mail validate: required: true + + advanced_section: + type: section + title: Advanced Configuration + underline: true + + fields: + + save_grav_user: + type: toggle + label: Save Grav user + highlight: 0 + default: 0 + options: + 1: Enabled + 0: Disabled + validate: + type: bool + + store_ldap_data: + type: toggle + label: Store LDAP data + help: If sotring a local Grav user, you can also store LDAP data to use in Grav + highlight: 0 + default: 0 + options: + 1: Enabled + 0: Disabled + validate: + type: bool + + default_access_levels.groups: + type: selectize + size: large + label: Default Groups + '@data-options': '\Grav\User\Groups::groups' + classes: fancy + validate: + type: commalist + + default_access_levels.access.site: + type: array + label: Default Site Access + multiple: false + placeholder_key: login + placeholder_value: 'true' + validate: + type: array + required: true \ No newline at end of file diff --git a/login-ldap.php b/login-ldap.php index ab13699..2eb0054 100644 --- a/login-ldap.php +++ b/login-ldap.php @@ -66,44 +66,99 @@ class LoginLDAPPlugin extends Plugin public function userLoginAuthenticate(UserLoginEvent $event) { - $username = $event->getUser(); $credentials = $event->getCredentials(); - // This gets fired for user authentication. - $username="cn=amiller,ou=users,dc=trilbymedia,dc=com"; - $credentials="gom8Jabar"; + // Get Proper username + $user_dn = $this->config->get('plugins.login-ldap.user_dn'); + $search_dn = $this->config->get('plugins.login-ldap.search_dn'); + $username = str_replace('[username]', $credentials['username'], $user_dn); + + // Get Host info + $host = $this->config->get('plugins.login-ldap.host'); + $port = $this->config->get('plugins.login-ldap.port'); + $version = $this->config->get('plugins.login-ldap.version'); + $ssl = $this->config->get('plugins.login-ldap.ssl'); + $start_tls = $this->config->get('plugins.login-ldap.start_tls'); + $opt_referrals = $this->config->get('plugins.login-ldap.opt_referrals'); + + // Set Encryption + if ((bool) $ssl) { + $encryption = 'ssl'; + } elseif ((bool) $start_tls) { + $encryption = 'tls'; + } else { + $encryption = 'none'; + } try { $ldap = Ldap::create('ext_ldap', array( - 'host' => 'ldap.trilbymedia.com', + 'host' => $host, + 'port' => $port, + 'encryption' => $encryption, + 'options' => array( + 'protocol_version' => $version, + 'referrals' => (bool) $opt_referrals, + ), )); + // Map Info + $map_username = $this->config->get('plugins.login-ldap.map_username'); + $map_fullname = $this->config->get('plugins.login-ldap.map_fullname'); + $map_email = $this->config->get('plugins.login-ldap.map_email'); - $ldap->bind($username, $credentials); + $ldap->bind($username, $credentials['password']); - - - $query = $ldap->query('dc=trilbymedia,dc=com', 'uid=amiller'); - $results = $query->execute(); - - $userdata = ['ldap' => $results[0]->getAttributes()]; - unset($userdata['ldap']['userPassword']); + $query = $ldap->query($search_dn, $map_username .'='. $credentials['username']); + $results = $query->execute()->toArray(); // Create Grav User $grav_user = User::load($username); + // Get LDAP Data + $ldap_data = array_shift($results)->getAttributes(); + $userdata = []; + + $userdata['login'] = $this->getLDAPMappedItem($map_username, $ldap_data); + $userdata['fullname'] = $this->getLDAPMappedItem($map_fullname, $ldap_data); + $userdata['email'] = $this->getLDAPMappedItem($map_email, $ldap_data); + + // Get LDAP Data if required + if ($this->config->get('plugins.login-ldap.store_ldap_data', false)) { +// $userdata['ldap'] = $ldap_data; + foreach($ldap_data as $key => $data) { + $userdata['ldap'][$key] = array_shift($data); + } + unset($userdata['ldap']['userPassword']); + } + + $grav_user->merge($userdata); + + // Set Groups + $current_groups = $grav_user->get('groups'); + if (!$current_groups) { + $groups = $this->config->get('plugins.login-ldap.default_access_levels.groups', []); + if (count($groups) > 0) { + $data['groups'] = $groups; + $grav_user->merge($data); + } + } + + // Set Access $current_access = $grav_user->get('access'); - if (!$current_access) { - $access = $this->config->get('plugins.login.user_registration.access.site', []); + $access = $this->config->get('plugins.login-ldap.default_access_levels.access.site'); + + if (!$current_access && $access) { if (count($access) > 0) { $data['access']['site'] = $access; $grav_user->merge($data); } } - $grav_user->merge($userdata); - $grav_user->save(); + // Optional save + if ($this->config->get('plugins.login-ldap.save_grav_user', false)) { + $grav_user->save(); + } $event->setUser($grav_user); @@ -115,6 +170,8 @@ class LoginLDAPPlugin extends Plugin } catch (ConnectionException $e) { print $e->getMessage(); + $this->grav['log']->error('plugin.login-ldap: ' . $username . ' - ' . $e->getMessage()); + $event->setStatus($event::AUTHENTICATION_FAILURE); $event->stopPropagation(); @@ -138,4 +195,16 @@ class LoginLDAPPlugin extends Plugin // This gets fired on user logout. } + protected function getLDAPMappedItem($map, $ldap_data) + { + $item_bits = []; + $map_bits = explode(' ', $map); + foreach($map_bits as $bit) { + if(isset($ldap_data[$bit])) { + $item_bits[] = array_shift($ldap_data[$bit]); + } + } + $item = implode(' ', $item_bits); + return $item; + } } diff --git a/login-ldap.yaml b/login-ldap.yaml index 9f7bbcf..26b6384 100644 --- a/login-ldap.yaml +++ b/login-ldap.yaml @@ -11,4 +11,10 @@ map_username: uid map_fullname: givenName lastName map_email: mail - +save_grav_user: false +store_ldap_data: false +default_access_levels: + groups: ldap_users + access: + site: + login: 'true'