From 1de9087427a6ac0819cb9fa3b94ebea82023b739 Mon Sep 17 00:00:00 2001
From: Steffen <smb@users.noreply.github.com>
Date: Thu, 10 Jan 2019 22:20:43 +0100
Subject: [PATCH] LDAP fixes (#6533)

* Add iCheck png files to webpack config (inconsistency for css <> png) and blue.png to public folder

* php 7.3 collect() fix (undefined variable)

* Fix travis ci

* Add iCheck png files to webpack config (inconsistency for css <> png) and blue.png to public folder

* php 7.3 collect() fix (undefined variable)

* change LDAP implementation from model to (singleton) service

* Re-apply check for content in ldap_server variable before parsing

* Update LDAP implementation

* Switch iCheck to minimal as referenced in js

* Don't init on load but on first access via init (returns ldap enabled status)

* Re-Enable notifications

* Re-add missing test target php versions

* Only init() once (singleton class, so ldap variable is already set)
---
 .travis.yml                                   |   1 +
 app/Console/Commands/LdapSync.php             |  21 +++-----
 .../Controllers/Api/SettingsController.php    |  13 ++---
 app/Http/Controllers/Auth/LoginController.php |  48 +++++++++---------
 .../Users/LDAPImportController.php            |   3 +-
 app/Http/Controllers/ViewAssetsController.php |   2 +-
 app/Providers/LdapServiceProvider.php         |  29 +++++++++++
 app/{Models => Services}/LdapAd.php           |  27 ++++++----
 .../LdapAdConfiguration.php                   |  14 ++---
 config/app.php                                |   1 +
 public/css/blue.png                           | Bin 0 -> 2185 bytes
 webpack.mix.js                                |   3 ++
 12 files changed, 101 insertions(+), 61 deletions(-)
 create mode 100644 app/Providers/LdapServiceProvider.php
 rename app/{Models => Services}/LdapAd.php (96%)
 rename app/{Models => Services}/LdapAdConfiguration.php (96%)
 create mode 100755 public/css/blue.png

diff --git a/.travis.yml b/.travis.yml
index 879eac1ea..f112d4680 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -29,6 +29,7 @@ before_script:
   - mysql -e 'CREATE USER "travis'@'localhost";'
   - mysql -e 'GRANT ALL PRIVILEGES ON * . * TO "travis'@'localhost";'
   - mysql -e 'FLUSH PRIVILEGES;'
+  - cp .env.testing-ci .env
   - composer self-update
   - composer install -n --prefer-source
   - chmod -R 777 storage
diff --git a/app/Console/Commands/LdapSync.php b/app/Console/Commands/LdapSync.php
index 46f1cd5bc..dac303251 100755
--- a/app/Console/Commands/LdapSync.php
+++ b/app/Console/Commands/LdapSync.php
@@ -4,10 +4,9 @@ declare(strict_types=1);
 
 namespace App\Console\Commands;
 
-use Log;
+use App\Services\LdapAd;
+use Illuminate\Support\Facades\Log;
 use Exception;
-use App\Models\User;
-use App\Models\LdapAd;
 use App\Models\Location;
 use Illuminate\Console\Command;
 use Adldap\Models\User as AdldapUser;
@@ -48,13 +47,6 @@ class LdapSync extends Command
      */
     private $ldap;
 
-    /**
-     * LDAP settings collection.
-     *
-     * @var \Illuminate\Support\Collection
-     */
-    private $settings = null;
-
     /**
      * A default location collection.
      *
@@ -92,13 +84,16 @@ class LdapSync extends Command
 
     /**
      * Create a new command instance.
+     *
+     * @param LdapAd $ldap
      */
     public function __construct(LdapAd $ldap)
     {
+
         parent::__construct();
-        $this->ldap     = $ldap;
-        $this->settings = $this->ldap->ldapSettings;
         $this->summary  = collect();
+
+        $this->ldap = $ldap;
     }
 
     /**
@@ -333,7 +328,7 @@ class LdapSync extends Command
      */
     private function checkIfLdapIsEnabled(): void
     {
-        if (false === $this->settings['ldap_enabled']) {
+        if (!$this->ldap->init()) {
             $msg = 'LDAP intergration is not enabled. Exiting sync process.';
             $this->info($msg);
             Log::info($msg);
diff --git a/app/Http/Controllers/Api/SettingsController.php b/app/Http/Controllers/Api/SettingsController.php
index bbc819901..b08cb0641 100644
--- a/app/Http/Controllers/Api/SettingsController.php
+++ b/app/Http/Controllers/Api/SettingsController.php
@@ -2,12 +2,9 @@
 
 namespace App\Http\Controllers\Api;
 
-use DB;
-use Mail;
-use Validator;
-use Notification;
-use App\Models\Ldap;
-use App\Models\LdapAd;
+use App\Services\LdapAd;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Notification;
 use App\Models\Setting;
 use Illuminate\Http\Request;
 use App\Notifications\MailTest;
@@ -32,8 +29,8 @@ class SettingsController extends Controller
      * @return \Illuminate\Http\JsonResponse
      */
     public function ldapAdSettingsTest(LdapAd $ldap): JsonResponse
-    {   
-        if($ldap->ldapSettings['ldap_enabled'] === false) {
+    {
+        if(!$ldap->init()) {
             Log::info('LDAP is not enabled cannot test.');
             return response()->json(['message' => 'LDAP is not enabled, cannot test.'], 400);
         }
diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php
index 503cf8ac4..03d829bfb 100644
--- a/app/Http/Controllers/Auth/LoginController.php
+++ b/app/Http/Controllers/Auth/LoginController.php
@@ -2,21 +2,19 @@
 
 namespace App\Http\Controllers\Auth;
 
-use Validator;
+use App\Services\LdapAd;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Session;
+use Illuminate\Support\Facades\Validator;
 use App\Http\Controllers\Controller;
 use Illuminate\Foundation\Auth\ThrottlesLogins;
 use App\Models\Setting;
-use App\Models\Ldap;
 use App\Models\User;
-use Auth;
-use Config;
+use Illuminate\Support\Facades\Auth;
 use Illuminate\Http\Request;
-use Input;
+use Illuminate\Support\Facades\Input;
 use Redirect;
-use Log;
-use View;
-use PragmaRX\Google2FA\Google2FA;
-use App\Models\LdapAd;
+use Illuminate\Support\Facades\Log;
 
 /**
  * This controller handles authentication for the user, including local
@@ -41,23 +39,23 @@ class LoginController extends Controller
     protected $redirectTo = '/';
 
     /**
-     * An LdapAd instance
-     *
-     * @var \App\Models\LdapAd
+     * @var LdapAd
      */
-    protected $ldapAd;
+    protected $ldap;
 
     /**
      * Create a new authentication controller instance.
      *
+     * @param LdapAd $ldap
+     *
      * @return void
      */
-    public function __construct(LdapAd $ldapAd)
+    public function __construct(LdapAd $ldap)
     {
+        parent::__construct();
         $this->middleware('guest', ['except' => ['logout','postTwoFactorAuth','getTwoFactorAuth','getTwoFactorEnroll']]);
-        \Session::put('backUrl', \URL::previous());
-
-        $this->ldapAd = $ldapAd;
+        Session::put('backUrl', \URL::previous());
+        $this->ldap = $ldap;
     }
 
     function showLoginForm(Request $request)
@@ -85,12 +83,12 @@ class LoginController extends Controller
      * 
      * @return User
      * 
-     * @throws Exception
+     * @throws \Exception
      */
     private function loginViaLdap(Request $request): User
     {
         try {
-            return $this->ldapAd->ldapLogin($request->input('username'), $request->input('password'));
+            return $this->ldap->ldapLogin($request->input('username'), $request->input('password'));
         } catch (\Exception $ex) {
             LOG::debug("LDAP user login: " . $ex->getMessage());
             throw new \Exception($ex->getMessage());
@@ -146,7 +144,7 @@ class LoginController extends Controller
         $user = null;
 
         // Should we even check for LDAP users?
-        if (Setting::getSettings()->ldap_enabled=='1') {
+        if ($this->ldap->init()) {
             LOG::debug("LDAP is enabled.");
             try {
                 LOG::debug("Attempting to log user in by LDAP authentication.");
@@ -179,8 +177,8 @@ class LoginController extends Controller
         }
 
         if ($user = Auth::user()) {
-            $user->last_login = \Carbon::now();
-            \Log::debug('Last login:'.$user->last_login);
+            $user->last_login = Carbon::now();
+            Log::debug('Last login:'.$user->last_login);
             $user->save();
         }
         // Redirect to the users page
@@ -233,6 +231,8 @@ class LoginController extends Controller
     /**
      * Two factor code submission
      *
+     * @param Request $request
+     *
      * @return Redirect
      */
     public function postTwoFactorAuth(Request $request)
@@ -263,6 +263,8 @@ class LoginController extends Controller
     /**
      * Logout page.
      *
+     * @param Request $request
+     *
      * @return Redirect
      */
     public function logout(Request $request)
@@ -327,7 +329,7 @@ class LoginController extends Controller
     * Override the lockout time and duration
     *
     * @param  \Illuminate\Http\Request  $request
-    * @return \Illuminate\Http\RedirectResponse
+    * @return  bool
     */
     protected function hasTooManyLoginAttempts(Request $request)
     {
diff --git a/app/Http/Controllers/Users/LDAPImportController.php b/app/Http/Controllers/Users/LDAPImportController.php
index 5627adb7e..006046ab9 100644
--- a/app/Http/Controllers/Users/LDAPImportController.php
+++ b/app/Http/Controllers/Users/LDAPImportController.php
@@ -3,10 +3,10 @@
 namespace App\Http\Controllers\Users;
 
 use App\Models\Ldap;
+use App\Services\LdapAd;
 use Illuminate\Http\Request;
 use App\Http\Controllers\Controller;
 use Illuminate\Support\Facades\Artisan;
-use App\Models\LdapAd;
 
 class LDAPImportController extends Controller
 {
@@ -24,6 +24,7 @@ class LDAPImportController extends Controller
      */
     public function __construct(LdapAd $ldap)
     {
+        parent::__construct();
         $this->ldap = $ldap;
     }
 
diff --git a/app/Http/Controllers/ViewAssetsController.php b/app/Http/Controllers/ViewAssetsController.php
index 8022815ba..03aa03bbe 100755
--- a/app/Http/Controllers/ViewAssetsController.php
+++ b/app/Http/Controllers/ViewAssetsController.php
@@ -63,7 +63,7 @@ class ViewAssetsController extends Controller
         $assets = Asset::with('model', 'defaultLoc', 'location', 'assignedTo', 'requests')->Hardware()->RequestableAssets()->get();
         $models = AssetModel::with('category', 'requests', 'assets')->RequestableModels()->get();
 
-        return view('account/requestable-assets', compact('user', 'assets', 'models'));
+        return view('account/requestable-assets', compact('assets', 'models'));
     }
 
 
diff --git a/app/Providers/LdapServiceProvider.php b/app/Providers/LdapServiceProvider.php
new file mode 100644
index 000000000..fc1354a46
--- /dev/null
+++ b/app/Providers/LdapServiceProvider.php
@@ -0,0 +1,29 @@
+<?php namespace App\Providers;
+
+use App\Services\LdapAd;
+use Illuminate\Support\ServiceProvider;
+
+class LdapServiceProvider extends ServiceProvider
+{
+
+    /**
+     * Bootstrap the application services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        $this->app->singleton(LdapAd::class, LdapAd::class);
+    }
+
+
+    /**
+     * Register any application services.
+     *
+     * @return void
+     */
+    public function register()
+    {
+
+    }
+}
diff --git a/app/Models/LdapAd.php b/app/Services/LdapAd.php
similarity index 96%
rename from app/Models/LdapAd.php
rename to app/Services/LdapAd.php
index e3777374f..d5df03fdb 100644
--- a/app/Models/LdapAd.php
+++ b/app/Services/LdapAd.php
@@ -2,11 +2,11 @@
 
 declare(strict_types=1);
 
-namespace App\Models;
+namespace App\Services;
 
+use App\Models\User;
 use Exception;
 use Adldap\Adldap;
-use App\Traits\UserTrait;
 use Adldap\Query\Paginator;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Log;
@@ -22,8 +22,6 @@ use Adldap\Models\ModelNotFoundException;
  */
 class LdapAd extends LdapAdConfiguration
 {
-    use UserTrait;
-
     /**
      * @see https://wdmsb.wordpress.com/2014/12/03/descriptions-of-active-directory-useraccountcontrol-value/
      */
@@ -49,18 +47,29 @@ class LdapAd extends LdapAdConfiguration
     protected $ldap;
 
     /**
-     * __construct.
+     * Initialize LDAP from user settings
+     *
+     * @since 5.0.0
+     *
+     * @return bool
      */
-    public function __construct()
+    public function init() : bool
     {
+        // Already initialized
+        if($this->ldap) {
+            return true;
+        }
+
+        parent::init();
         if($this->isLdapEnabled()) {
-            parent::__construct();
             $this->ldap = new Adldap();
             $this->ldap->addProvider($this->ldapConfig);
+            return true;
         }
+        return false;
     }
 
-    /**
+        /**
      * Create a user if they successfully login to the LDAP server.
      *
      * @author Wes Hulette <jwhulette@gmail.com>
@@ -250,7 +259,7 @@ class LdapAd extends LdapAdConfiguration
      *
      * @since 5.0.0
      *
-     * @param Adldap\Models\User $user
+     * @param \Adldap\Models\User $user
      * @param Collection|null    $defaultLocation
      * @param Collection|null    $mappedLocations
      *
diff --git a/app/Models/LdapAdConfiguration.php b/app/Services/LdapAdConfiguration.php
similarity index 96%
rename from app/Models/LdapAdConfiguration.php
rename to app/Services/LdapAdConfiguration.php
index ffb4c2f44..e6267a97d 100644
--- a/app/Models/LdapAdConfiguration.php
+++ b/app/Services/LdapAdConfiguration.php
@@ -2,8 +2,9 @@
 
 declare(strict_types=1);
 
-namespace App\Models;
+namespace App\Services;
 
+use App\Models\Setting;
 use Exception;
 use Illuminate\Support\Collection;
 
@@ -38,10 +39,11 @@ class LdapAdConfiguration
     public $ldapConfig;
 
     /**
-     * __construct.
+     * Initialize LDAP from user settings
+     *
+     * @since 5.0.0
      */
-    public function __construct()
-    {
+    public function init() {
         $this->ldapSettings = $this->getSnipeItLdapSettings();
         if ($this->isLdapEnabled()) {
             $this->setSnipeItConfig();
@@ -92,7 +94,7 @@ class LdapAdConfiguration
                     }
                 }
 
-                if (($item) && ('ldap_server' === $key)) {
+                if ($item && 'ldap_server' === $key) {
                     return collect(parse_url($item));
                 }
 
@@ -246,7 +248,7 @@ class LdapAdConfiguration
      *
      * @return bool
      */
-    protected function isLdapEnabled(): bool
+    public function isLdapEnabled(): bool
     {
         return $this->ldapSettings && $this->ldapSettings->get('ldap_enabled');
     }
diff --git a/config/app.php b/config/app.php
index 3967fa002..fd4481803 100755
--- a/config/app.php
+++ b/config/app.php
@@ -277,6 +277,7 @@ return [
         * Custom service provider
         */
         App\Providers\MacroServiceProvider::class,
+        App\Providers\LdapServiceProvider::class,
 
 
     ],
diff --git a/public/css/blue.png b/public/css/blue.png
new file mode 100755
index 0000000000000000000000000000000000000000..a3e040fcce00622a17085d447f1a18c68989357e
GIT binary patch
literal 2185
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
Y=fs_N{Q3bK1_lNOPgg&ebxsLQ08a#CLjV8(

literal 0
HcmV?d00001

diff --git a/webpack.mix.js b/webpack.mix.js
index c05ee67e1..6d7d0aad2 100644
--- a/webpack.mix.js
+++ b/webpack.mix.js
@@ -29,6 +29,9 @@ mix
     "./public/css/all.css"
   );
 
+mix.copy(["./node_modules/icheck/skins/minimal/blue.png",
+          "./node_modules/icheck/skins/minimal/blue@2x.png"], "./public/css");
+
 /**
  * Copy, minify and version skins
  */
-- 
GitLab