From fc8637c81a89e5bf881b2d007f0cb32d5cee6238 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 7 Mar 2018 22:22:36 -0800 Subject: [PATCH 1/7] Check for associated maintenance asset This should probably never happen, but triggers on the demo sometimes because of fluctuating data seeding --- app/Http/Transformers/AssetMaintenancesTransformer.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Http/Transformers/AssetMaintenancesTransformer.php b/app/Http/Transformers/AssetMaintenancesTransformer.php index bd4afe8fc8..ab82157233 100644 --- a/app/Http/Transformers/AssetMaintenancesTransformer.php +++ b/app/Http/Transformers/AssetMaintenancesTransformer.php @@ -22,7 +22,6 @@ class AssetMaintenancesTransformer { $array = [ 'id' => (int) $assetmaintenance->id, - 'asset' => ($assetmaintenance->asset) ? [ 'id' => (int) $assetmaintenance->asset->id, 'name'=> ($assetmaintenance->asset->name) ? e($assetmaintenance->asset->name) : null, @@ -30,7 +29,7 @@ class AssetMaintenancesTransformer ] : null, 'title' => ($assetmaintenance->title) ? e($assetmaintenance->title) : null, - 'location' => ($assetmaintenance->asset->location) ? [ + 'location' => (($assetmaintenance->asset) && ($assetmaintenance->asset->location)) ? [ 'id' => (int) $assetmaintenance->asset->location->id, 'name'=> e($assetmaintenance->asset->location->name), From 06e760081c2121e417e3adc3f1d25f25c15aa642 Mon Sep 17 00:00:00 2001 From: Anh DAO-DUY Date: Fri, 9 Mar 2018 22:05:14 +0100 Subject: [PATCH 2/7] Add default_label field missing in status_labels table (Travis CI) (#5180) --- database/factories/StatusLabelFactory.php | 2 +- tests/_data/dump.sql | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/database/factories/StatusLabelFactory.php b/database/factories/StatusLabelFactory.php index bf7ed8bc6d..ac4d07d6e0 100644 --- a/database/factories/StatusLabelFactory.php +++ b/database/factories/StatusLabelFactory.php @@ -26,7 +26,7 @@ $factory->state(Statuslabel::class, 'pending', function (Faker\Generator $faker) return [ 'notes' => $faker->sentence, 'pending' => 1, - 'default_label' => 0, + 'default_label' => 1, ]; }); diff --git a/tests/_data/dump.sql b/tests/_data/dump.sql index 554621e3bf..8179172b0a 100644 --- a/tests/_data/dump.sql +++ b/tests/_data/dump.sql @@ -1287,6 +1287,7 @@ CREATE TABLE `status_labels` ( `notes` text COLLATE utf8mb4_unicode_ci, `color` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `show_in_nav` tinyint(1) NOT NULL DEFAULT '0', + `default_label` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1297,7 +1298,7 @@ CREATE TABLE `status_labels` ( LOCK TABLES `status_labels` WRITE; /*!40000 ALTER TABLE `status_labels` DISABLE KEYS */; -INSERT INTO `status_labels` VALUES (1,'Ready to Deploy',1,'1978-03-29 02:11:42','2003-04-07 04:36:05',NULL,1,0,0,'Neque sint est sit eum.',NULL,0),(2,'Pending',1,'1984-10-22 18:19:42','1971-08-30 03:41:07',NULL,0,1,0,'Consectetur provident assumenda dolore culpa perspiciatis non.',NULL,0),(3,'Archived',1,'2005-10-20 01:12:09','1971-04-28 00:41:58',NULL,0,0,1,'These assets are permanently undeployable',NULL,0),(4,'Out for Diagnostics',1,'2001-12-01 10:49:15','2004-07-26 21:14:26',NULL,0,0,0,'',NULL,0),(5,'Out for Repair',1,'2007-10-08 14:30:44','1994-01-12 01:09:58',NULL,0,0,0,'',NULL,0),(6,'Broken - Not Fixable',1,'1982-06-03 01:20:34','1982-09-19 00:27:34',NULL,0,0,0,'',NULL,0),(7,'Lost/Stolen',1,'1977-02-15 20:16:26','1987-11-14 05:17:29',NULL,0,0,0,'',NULL,0); +INSERT INTO `status_labels` VALUES (1,'Ready to Deploy',1,'1978-03-29 02:11:42','2003-04-07 04:36:05',NULL,1,0,0,'Neque sint est sit eum.',NULL,0,0),(2,'Pending',1,'1984-10-22 18:19:42','1971-08-30 03:41:07',NULL,0,1,0,'Consectetur provident assumenda dolore culpa perspiciatis non.',NULL,0,0),(3,'Archived',1,'2005-10-20 01:12:09','1971-04-28 00:41:58',NULL,0,0,1,'These assets are permanently undeployable',NULL,0,0),(4,'Out for Diagnostics',1,'2001-12-01 10:49:15','2004-07-26 21:14:26',NULL,0,0,0,'',NULL,0,0),(5,'Out for Repair',1,'2007-10-08 14:30:44','1994-01-12 01:09:58',NULL,0,0,0,'',NULL,0,0),(6,'Broken - Not Fixable',1,'1982-06-03 01:20:34','1982-09-19 00:27:34',NULL,0,0,0,'',NULL,0,0),(7,'Lost/Stolen',1,'1977-02-15 20:16:26','1987-11-14 05:17:29',NULL,0,0,0,'',NULL,0,0); /*!40000 ALTER TABLE `status_labels` ENABLE KEYS */; UNLOCK TABLES; From e15f2ac8abff8e668c47dbb1cb949a35448a162d Mon Sep 17 00:00:00 2001 From: Brady Wetherington Date: Tue, 13 Mar 2018 20:06:53 -0700 Subject: [PATCH 3/7] Support `\r`-terminated files better from the Importer (#5184) * Hoist the ini_get/ini_set auto-detect line endings code higher * Placate the irascible Codacy --- app/Http/Controllers/Api/ImportController.php | 3 +++ app/Importer/Importer.php | 7 +++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Api/ImportController.php b/app/Http/Controllers/Api/ImportController.php index 1cda09c20e..f1c273b484 100644 --- a/app/Http/Controllers/Api/ImportController.php +++ b/app/Http/Controllers/Api/ImportController.php @@ -72,6 +72,9 @@ class ImportController extends Controller $import->file_path = $file_name; $import->filesize = filesize($path.'/'.$file_name); //TODO: is there a lighter way to do this? + if (! ini_get("auto_detect_line_endings")) { + ini_set("auto_detect_line_endings", '1'); + } $reader = Reader::createFromPath("{$path}/{$file_name}"); $import->header_row = $reader->fetchOne(0); // Grab the first row to display via ajax as the user picks fields diff --git a/app/Importer/Importer.php b/app/Importer/Importer.php index e73ef1eed9..e74d3607ea 100644 --- a/app/Importer/Importer.php +++ b/app/Importer/Importer.php @@ -91,15 +91,14 @@ abstract class Importer $this->fieldMap = $this->defaultFieldMap; // By default the importer passes a url to the file. // However, for testing we also support passing a string directly + if (! ini_get("auto_detect_line_endings")) { + ini_set("auto_detect_line_endings", '1'); + } if (is_file($file)) { $this->csv = Reader::createFromPath($file); } else { $this->csv = Reader::createFromString($file); } - $this->csv->setNewLine('\r\n'); - if (! ini_get("auto_detect_line_endings")) { - ini_set("auto_detect_line_endings", '1'); - } $this->tempPassword = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20); } // Cached Values for import lookups From 53735f2026bcff7ee9357e03c95285d525a13eec Mon Sep 17 00:00:00 2001 From: David Kaatz Date: Wed, 14 Mar 2018 20:48:07 +0100 Subject: [PATCH 4/7] Authentication via REMOTE_USER (clean repull) (#5204) - Implementation in Login - Configuration - Database migration --- app/Http/Controllers/Auth/LoginController.php | 38 +++++++++++++++++-- app/Http/Controllers/SettingsController.php | 5 +++ app/Models/Setting.php | 31 ++++++++------- ..._02_22_160436_add_remote_user_settings.php | 36 ++++++++++++++++++ resources/lang/en/admin/settings/general.php | 7 ++++ resources/views/settings/security.blade.php | 31 +++++++++++++++ 6 files changed, 130 insertions(+), 18 deletions(-) create mode 100644 database/migrations/2018_02_22_160436_add_remote_user_settings.php diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index c9f497b924..f1a11d5efe 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -50,17 +50,36 @@ class LoginController extends Controller \Session::put('backUrl', \URL::previous()); } - - function showLoginForm() + function showLoginForm(Request $request) { + $this->loginViaRemoteUser($request); if (Auth::check()) { return redirect()->intended('dashboard'); } + + if (Setting::getSettings()->login_common_disabled == "1") { + return view('errors.403'); + } + return view('auth.login'); } + private function loginViaRemoteUser(Request $request) + { + $remote_user = $request->server('REMOTE_USER'); + if (Setting::getSettings()->login_remote_user_enabled == "1" && isset($remote_user) && !empty($remote_user)) { + LOG::debug("Authenticatiing via REMOTE_USER."); + try { + $user = User::where('username', '=', $remote_user)->whereNull('deleted_at')->first(); + LOG::debug("Remote user auth lookup complete"); + if(!is_null($user)) Auth::login($user, true); + } catch(Exception $e) { + LOG::error("There was an error authenticating the Remote user: " . $e->getMessage()); + } + } + } - private function login_via_ldap(Request $request) + private function loginViaLdap(Request $request) { LOG::debug("Binding user to LDAP."); $ldap_user = Ldap::findAndBindUserLdap($request->input('username'), $request->input('password')); @@ -114,6 +133,10 @@ class LoginController extends Controller */ public function login(Request $request) { + if (Setting::getSettings()->login_common_disabled == "1") { + return view('errors.403'); + } + $validator = $this->validator(Input::all()); if ($validator->fails()) { @@ -134,7 +157,7 @@ class LoginController extends Controller if (Setting::getSettings()->ldap_enabled=='1') { LOG::debug("LDAP is enabled."); try { - $user = $this->login_via_ldap($request); + $user = $this->loginViaLdap($request); Auth::login($user, true); // If the user was unable to login via LDAP, log the error and let them fall through to @@ -253,6 +276,13 @@ class LoginController extends Controller { $request->session()->forget('2fa_authed'); Auth::logout(); + + $settings = Setting::getSettings(); + $customLogoutUrl = $settings->login_remote_user_custom_logout_url ; + if ($settings->login_remote_user_enabled == '1' && $customLogoutUrl != '') { + return redirect()->away($customLogoutUrl); + } + return redirect()->route('login')->with('success', 'You have successfully logged out!'); } diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 464246a969..261655775c 100755 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -485,6 +485,11 @@ class SettingsController extends Controller $setting->pwd_secure_min = (int) $request->input('pwd_secure_min'); $setting->pwd_secure_complexity = ''; + # remote user login + $setting->login_remote_user_enabled = (int)$request->input('login_remote_user_enabled'); + $setting->login_common_disabled= (int)$request->input('login_common_disabled'); + $setting->login_remote_user_custom_logout_url = $request->input('login_remote_user_custom_logout_url'); + if ($request->has('pwd_secure_complexity')) { $setting->pwd_secure_complexity = implode('|', $request->input('pwd_secure_complexity')); } diff --git a/app/Models/Setting.php b/app/Models/Setting.php index 71dfbbaae3..4f82366808 100755 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -13,15 +13,15 @@ class Setting extends Model use ValidatingTrait; protected $rules = [ - "brand" => 'required|min:1|numeric', - "qr_text" => 'max:31|nullable', - "logo_img" => 'mimes:jpeg,bmp,png,gif', - "alert_email" => 'email_array|nullable', - "default_currency" => 'required', - "locale" => 'required', - "slack_endpoint" => 'url|required_with:slack_channel|nullable', - "slack_channel" => 'regex:/(? 'string|nullable', + 'brand' => 'required|min:1|numeric', + 'qr_text' => 'max:31|nullable', + 'logo_img' => 'mimes:jpeg,bmp,png,gif', + 'alert_email' => 'email_array|nullable', + 'default_currency' => 'required', + 'locale' => 'required', + 'slack_endpoint' => 'url|required_with:slack_channel|nullable', + 'slack_channel' => 'regex:/(? 'string|nullable', 'labels_per_page' => 'numeric', 'labels_width' => 'numeric', 'labels_height' => 'numeric', @@ -34,11 +34,14 @@ class Setting extends Model 'labels_fontsize' => 'numeric|min:5', 'labels_pagewidth' => 'numeric|nullable', 'labels_pageheight' => 'numeric|nullable', - "thumbnail_max_h" => 'numeric|max:500|min:25', - "pwd_secure_min" => "numeric|required|min:5", - "audit_warning_days" => "numeric|nullable", - "audit_interval" => "numeric|nullable", - "custom_forgot_pass_url" => "url|nullable", + 'login_remote_user_enabled' => 'numeric|nullable', + 'login_common_disabled' => 'numeric|nullable', + 'login_remote_user_custom_logout_url' => 'string|nullable', + 'thumbnail_max_h' => 'numeric|max:500|min:25', + 'pwd_secure_min' => 'numeric|required|min:5', + 'audit_warning_days' => 'numeric|nullable', + 'audit_interval' => 'numeric|nullable', + 'custom_forgot_pass_url' => 'url|nullable', ]; protected $fillable = ['site_name','email_domain','email_format','username_format']; diff --git a/database/migrations/2018_02_22_160436_add_remote_user_settings.php b/database/migrations/2018_02_22_160436_add_remote_user_settings.php new file mode 100644 index 0000000000..5756747d52 --- /dev/null +++ b/database/migrations/2018_02_22_160436_add_remote_user_settings.php @@ -0,0 +1,36 @@ +boolean('login_remote_user_enabled')->default(0); + $table->boolean('login_common_disabled')->default(0); + $table->string('login_remote_user_custom_logout_url')->default(""); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('settings', function (Blueprint $table) { + $table->dropColumn('login_remote_user_enabled'); + $table->dropColumn('login_common_disabled'); + $table->dropColumn('login_remote_user_custom_logout_url'); + }); + } +} diff --git a/resources/lang/en/admin/settings/general.php b/resources/lang/en/admin/settings/general.php index 2539aee7d3..415fed83c5 100644 --- a/resources/lang/en/admin/settings/general.php +++ b/resources/lang/en/admin/settings/general.php @@ -78,6 +78,13 @@ return array( 'load_remote_help_text' => 'This Snipe-IT install can load scripts from the outside world.', 'login_note' => 'Login Note', 'login_note_help' => 'Optionally include a few sentences on your login screen, for example to assist people who have found a lost or stolen device. This field accepts Github flavored markdown', + 'login_remote_user_text' => 'Remote User login options', + 'login_remote_user_enabled_text' => 'Enable Login with Remote User Header', + 'login_remote_user_enabled_help' => 'This option enables Authentication via the REMOTE_USER header according to the "Common Gateway Interface (rfc3875)"', + 'login_common_disabled_text' => 'Disable other authentication mechanisms', + 'login_common_disabled_help' => 'This option disables other authentication mechanisms. Just enable this option if you are sure that your REMOTE_USER login is already working', + 'login_remote_user_custom_logout_url_text' => 'Custom logout URL', + 'login_remote_user_custom_logout_url_help' => 'If filled users will get redirected to this URL after the Session of SnipeIT is closed (Logout). This is usefull to close the user sessions of your Authenticationprovider correctly.', 'logo' => 'Logo', 'full_multiple_companies_support_help_text' => 'Restricting users (including admins) assigned to companies to their company\'s assets.', 'full_multiple_companies_support_text' => 'Full Multiple Companies Support', diff --git a/resources/views/settings/security.blade.php b/resources/views/settings/security.blade.php index a7d2b65ac8..fcd2569a94 100644 --- a/resources/views/settings/security.blade.php +++ b/resources/views/settings/security.blade.php @@ -35,6 +35,37 @@
+ +
+
+ {{ Form::label('login_remote_user', trans('admin/settings/general.login_remote_user_text')) }} +
+
+ + {{ Form::checkbox('login_remote_user_enabled', '1', Input::old('login_remote_user_enabled', $setting->login_remote_user_enabled),array('class' => 'minimal')) }} + {{ Form::label('login_remote_user_enabled', trans('admin/settings/general.login_remote_user_enabled_text')) }} + {!! $errors->first('login_remote_user_enabled', ':message') !!} +

+ {{ trans('admin/settings/general.login_remote_user_enabled_help') }} +

+ + {{ Form::label('login_remote_user_custom_logout_url', trans('admin/settings/general.login_remote_user_custom_logout_url_text')) }} + {{ Form::text('login_remote_user_custom_logout_url', Input::old('login_remote_user_custom_logout_url', $setting->login_remote_user_custom_logout_url),array('class' => 'form-control')) }} + + {!! $errors->first('login_remote_user_custom_logout_url', ':message') !!} +

+ {{ trans('admin/settings/general.login_remote_user_custom_logout_url_help') }} +

+ + {{ Form::checkbox('login_common_disabled', '1', Input::old('login_common_disabled', $setting->login_common_disabled),array('class' => 'minimal')) }} + {{ Form::label('login_common_disabled', trans('admin/settings/general.login_common_disabled_text')) }} + {!! $errors->first('login_common_disabled', ':message') !!} +

+ {{ trans('admin/settings/general.login_common_disabled_help') }} +

+
+
+
From 9e7d1b3ed814a003778d39a75d85aa68770c6d1d Mon Sep 17 00:00:00 2001 From: tiagom62 Date: Thu, 15 Mar 2018 13:20:42 -0400 Subject: [PATCH 5/7] Revert removing setting hostname (#5208) --- snipeit.sh | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/snipeit.sh b/snipeit.sh index 1385c0560d..b876f9cb6a 100644 --- a/snipeit.sh +++ b/snipeit.sh @@ -28,7 +28,9 @@ clear name="snipeit" verbose="false" +hostname="$(hostname)" fqdn="$(hostname --fqdn)" +hosts=/etc/hosts spin[0]="-" spin[1]="\\" @@ -165,6 +167,11 @@ configureselinux () { fi } +sethostfile () { + echo "* Setting up hosts file." + echo >> $hosts "127.0.0.1 $hostname $fqdn" +} + if [[ -f /etc/lsb-release || -f /etc/debian_version ]]; then distro="$(lsb_release -s -i)" version="$(lsb_release -s -r)" @@ -220,8 +227,12 @@ case $distro in esac shopt -u nocasematch -echo "" -read -rsn1 -p " Press any key to continue..." +echo -n " Q. What is the FQDN of your server? ($fqdn): " +read -r fqdn +if [ -z "$fqdn" ]; then + fqdn="$(hostname --fqdn)" +fi +echo " Setting to $fqdn" echo "" ans=default @@ -271,6 +282,8 @@ case $distro in log "a2enmod rewrite" log "a2ensite $name.conf" + sethostfile + echo "* Securing MariaDB." /usr/bin/mysql_secure_installation @@ -309,6 +322,8 @@ case $distro in log "a2enmod rewrite" log "a2ensite $name.conf" + sethostfile + echo "* Securing MariaDB." /usr/bin/mysql_secure_installation @@ -351,6 +366,8 @@ case $distro in log "a2enmod rewrite" log "a2ensite $name.conf" + sethostfile + echo "* Starting MariaDB." log "service mysql start" @@ -392,6 +409,8 @@ case $distro in log "a2enmod rewrite" log "a2ensite $name.conf" + sethostfile + echo "* Starting MariaDB." log "service mysql start" @@ -443,6 +462,8 @@ case $distro in log "chkconfig mysql on" log "/sbin/service mysql start" + sethostfile + echo "* Securing MariaDB." /usr/bin/mysql_secure_installation @@ -478,6 +499,8 @@ case $distro in echo "* Configuring Apache." createvh + sethostfile + echo "* Setting MariaDB to start on boot and starting MariaDB." log "systemctl enable mariadb.service" log "systemctl start mariadb.service" @@ -514,6 +537,8 @@ case $distro in echo "* Configuring Apache." createvh + sethostfile + echo "* Setting MariaDB to start on boot and starting MariaDB." log "systemctl enable mariadb.service" log "systemctl start mariadb.service" From 8557cb5305b54cddfba01cf97fbd12d5d7bd7d73 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 22 Mar 2018 09:43:53 -0700 Subject: [PATCH 6/7] Added - make accessory manufacturer field searchable --- app/Models/Accessory.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/Models/Accessory.php b/app/Models/Accessory.php index a589c8be66..e006b24c3e 100755 --- a/app/Models/Accessory.php +++ b/app/Models/Accessory.php @@ -172,6 +172,10 @@ class Accessory extends SnipeModel $query->whereHas('company', function ($query) use ($search) { $query->where('companies.name', 'LIKE', '%'.$search.'%'); }); + })->orWhere(function ($query) use ($search) { + $query->whereHas('manufacturer', function ($query) use ($search) { + $query->where('manufacturers.name', 'LIKE', '%'.$search.'%'); + }); })->orWhere(function ($query) use ($search) { $query->whereHas('location', function ($query) use ($search) { $query->where('locations.name', 'LIKE', '%'.$search.'%'); From abac3e77586d409b17e5d87e879c75093063739a Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 22 Mar 2018 09:44:54 -0700 Subject: [PATCH 7/7] Bumped hash --- config/version.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/version.php b/config/version.php index 10fedec6cd..965614c60e 100644 --- a/config/version.php +++ b/config/version.php @@ -1,10 +1,10 @@ 'v4.1.14', - 'full_app_version' => 'v4.1.14 - build 3446-g90bff709a', - 'build_version' => '3446', + 'app_version' => 'v4.1.15', + 'full_app_version' => 'v4.1.14 - build 3464-g735840a', + 'build_version' => '3464', 'prerelease_version' => '', - 'hash_version' => 'g90bff709a', - 'full_hash' => 'v4.1.14-55-g90bff709a', + 'hash_version' => 'g735840a', + 'full_hash' => 'v4.1.14-3464-g735840a', 'branch' => 'develop', -); \ No newline at end of file +);