snipe-it/app/Models/Setting.php

408 lines
12 KiB
PHP
Raw Normal View History

2016-03-25 01:18:05 -07:00
<?php
2016-03-25 01:18:05 -07:00
namespace App\Models;
2021-06-10 13:17:44 -07:00
use Illuminate\Database\Eloquent\Factories\HasFactory;
2016-03-25 01:18:05 -07:00
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Cache;
use App\Helpers\Helper;
2016-03-25 01:18:05 -07:00
use Watson\Validating\ValidatingTrait;
/**
* Settings model.
*/
2016-03-25 01:18:05 -07:00
class Setting extends Model
{
2021-06-10 13:17:44 -07:00
use HasFactory;
use Notifiable, ValidatingTrait;
/**
* The cache property so that multiple invocations of this will only load the Settings record from disk only once
* @var self
*/
public static ?self $_cache = null;
/**
* The setup check cache key name.
*
* @var string
*/
public const SETUP_CHECK_KEY = 'snipeit_setup_check';
/**
* Whether the model should inject it's identifier to the unique
* validation rules before attempting validation. If this property
* is not set in the model it will default to true.
*
* @var bool
*/
2016-03-25 01:18:05 -07:00
protected $injectUniqueIdentifier = true;
/**
* Model rules.
*
* @var array
*/
2016-03-25 01:18:05 -07:00
protected $rules = [
'brand' => 'required|min:1|numeric',
'qr_text' => 'max:31|nullable',
'alert_email' => 'email_array|nullable',
'admin_cc_email' => 'email|nullable',
'default_currency' => 'required',
'locale' => 'required',
Merge branch 'develop' into integrations/2020-04-15-v5-merge # Conflicts: # README.md # app/Http/Controllers/AccessoriesController.php # app/Http/Controllers/Api/AssetsController.php # app/Http/Controllers/Api/LicensesController.php # app/Http/Controllers/Api/LocationsController.php # app/Http/Controllers/Api/SettingsController.php # app/Http/Controllers/Api/UsersController.php # app/Http/Controllers/AssetModelsController.php # app/Http/Controllers/Assets/AssetsController.php # app/Http/Controllers/Auth/ForgotPasswordController.php # app/Http/Controllers/CategoriesController.php # app/Http/Controllers/CompaniesController.php # app/Http/Controllers/ComponentsController.php # app/Http/Controllers/ConsumablesController.php # app/Http/Controllers/CustomFieldsetsController.php # app/Http/Controllers/DepartmentsController.php # app/Http/Controllers/LicensesController.php # app/Http/Controllers/LocationsController.php # app/Http/Controllers/ManufacturersController.php # app/Http/Controllers/SettingsController.php # app/Http/Controllers/SuppliersController.php # app/Http/Controllers/UsersController.php # app/Http/Requests/AssetRequest.php # app/Http/Requests/ImageUploadRequest.php # app/Models/LicenseSeat.php # app/Models/Location.php # app/Models/Setting.php # composer.json # composer.lock # config/database.php # config/version.php # npm-shrinkwrap.json # package.json # public/css/AdminLTE.css # public/css/AdminLTE.css.map # public/css/overrides.css # public/css/overrides.css.map # public/css/skins/skin-blue-light.css # public/css/skins/skin-blue.css # public/css/skins/skin-green-dark.min.css # public/js/app.js # public/js/bootstrap-table.js # public/js/bootstrap/js/bootstrap.js # public/js/bootstrap/js/bootstrap.min.js # public/js/build/all.js # public/js/build/vue.js # public/js/build/vue.js.map # public/js/demo.js # public/js/ekko-lightbox.js # public/js/ekko-lightbox.min.js # public/js/extensions/export/bootstrap-table-export.js # public/js/extensions/multiple-sort/bootstrap-table-multiple-sort.js # public/js/extensions/multiple-sort/bootstrap-table-multiple-sort.min.js # public/js/extensions/toolbar/bootstrap-table-toolbar.min.js # public/js/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.js # public/js/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js # public/js/plugins/timepicker/bootstrap-timepicker.js # public/js/plugins/timepicker/bootstrap-timepicker.min.js # public/js/vue.js # public/mix-manifest.json # resources/assets/js/bootstrap-js.js # resources/assets/js/bootstrap.min.js # resources/assets/js/ekko-lightbox.js # resources/assets/js/ekko-lightbox.min.js # resources/assets/js/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.js # resources/assets/js/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js # resources/assets/js/plugins/chartjs/Chart.js # resources/assets/js/plugins/timepicker/bootstrap-timepicker.js # resources/assets/js/plugins/timepicker/bootstrap-timepicker.min.js # resources/assets/less/AdminLTE.less # resources/assets/less/overrides.less # resources/assets/less/skins/_all-skins.less # resources/assets/less/skins/skin-black.less # resources/assets/less/skins/skin-blue.less # resources/assets/less/skins/skin-green.less # resources/assets/less/skins/skin-purple.less # resources/assets/less/skins/skin-red.less # resources/assets/less/skins/skin-yellow.less # resources/assets/less/variables.less # resources/js/components/importer/importer-file.vue # resources/lang/en/auth/message.php # resources/lang/en/passwords.php # resources/lang/es-CO/general.php # resources/lang/es-ES/general.php # resources/lang/es-VE/general.php # resources/less/skins/skin-black-dark.less # resources/less/skins/skin-blue-dark.less # resources/less/skins/skin-contrast.less # resources/less/skins/skin-green-dark.less # resources/less/skins/skin-orange-dark.less # resources/less/skins/skin-orange.less # resources/less/skins/skin-purple-dark.less # resources/less/skins/skin-red-dark.less # resources/less/skins/skin-yellow-dark.less # resources/views/accessories/checkin.blade.php # resources/views/accessories/checkout.blade.php # resources/views/accessories/edit.blade.php # resources/views/account/profile.blade.php # resources/views/account/view-assets.blade.php # resources/views/asset_maintenances/edit.blade.php # resources/views/auth/passwords/email.blade.php # resources/views/auth/passwords/reset.blade.php # resources/views/categories/edit.blade.php # resources/views/companies/edit.blade.php # resources/views/components/checkin.blade.php # resources/views/components/checkout.blade.php # resources/views/components/edit.blade.php # resources/views/consumables/checkout.blade.php # resources/views/consumables/edit.blade.php # resources/views/custom_fields/fields/edit.blade.php # resources/views/custom_fields/fieldsets/edit.blade.php # resources/views/dashboard.blade.php # resources/views/departments/edit.blade.php # resources/views/groups/edit.blade.php # resources/views/hardware/audit.blade.php # resources/views/hardware/bulk-checkout.blade.php # resources/views/hardware/bulk.blade.php # resources/views/hardware/checkin.blade.php # resources/views/hardware/checkout.blade.php # resources/views/hardware/edit.blade.php # resources/views/hardware/index.blade.php # resources/views/hardware/quickscan.blade.php # resources/views/hardware/view.blade.php # resources/views/importer/import.blade.php # resources/views/layouts/basic.blade.php # resources/views/layouts/default.blade.php # resources/views/layouts/edit-form.blade.php # resources/views/licenses/checkin.blade.php # resources/views/licenses/checkout.blade.php # resources/views/licenses/edit.blade.php # resources/views/locations/edit.blade.php # resources/views/manufacturers/edit.blade.php # resources/views/modals/upload-file.blade.php # resources/views/models/bulk-edit.blade.php # resources/views/models/custom_fields_form.blade.php # resources/views/models/edit.blade.php # resources/views/partials/bootstrap-table.blade.php # resources/views/partials/forms/edit/address.blade.php # resources/views/partials/forms/edit/asset-select.blade.php # resources/views/partials/forms/edit/category-select.blade.php # resources/views/partials/forms/edit/category.blade.php # resources/views/partials/forms/edit/company-select.blade.php # resources/views/partials/forms/edit/company.blade.php # resources/views/partials/forms/edit/department-select.blade.php # resources/views/partials/forms/edit/depreciation.blade.php # resources/views/partials/forms/edit/email.blade.php # resources/views/partials/forms/edit/image-upload.blade.php # resources/views/partials/forms/edit/item_number.blade.php # resources/views/partials/forms/edit/location-profile-select.blade.php # resources/views/partials/forms/edit/location-select.blade.php # resources/views/partials/forms/edit/location.blade.php # resources/views/partials/forms/edit/maintenance_type.blade.php # resources/views/partials/forms/edit/manufacturer-select.blade.php # resources/views/partials/forms/edit/manufacturer.blade.php # resources/views/partials/forms/edit/minimum_quantity.blade.php # resources/views/partials/forms/edit/model-select.blade.php # resources/views/partials/forms/edit/model_number.blade.php # resources/views/partials/forms/edit/name.blade.php # resources/views/partials/forms/edit/notes.blade.php # resources/views/partials/forms/edit/order_number.blade.php # resources/views/partials/forms/edit/phone.blade.php # resources/views/partials/forms/edit/purchase_cost.blade.php # resources/views/partials/forms/edit/purchase_date.blade.php # resources/views/partials/forms/edit/quantity.blade.php # resources/views/partials/forms/edit/serial.blade.php # resources/views/partials/forms/edit/status.blade.php # resources/views/partials/forms/edit/submit.blade.php # resources/views/partials/forms/edit/supplier-select.blade.php # resources/views/partials/forms/edit/supplier.blade.php # resources/views/partials/forms/edit/user-select.blade.php # resources/views/reports/custom.blade.php # resources/views/settings/alerts.blade.php # resources/views/settings/asset_tags.blade.php # resources/views/settings/barcodes.blade.php # resources/views/settings/branding.blade.php # resources/views/settings/general.blade.php # resources/views/settings/labels.blade.php # resources/views/settings/ldap.blade.php # resources/views/settings/localization.blade.php # resources/views/settings/security.blade.php # resources/views/setup/user.blade.php # resources/views/suppliers/edit.blade.php # resources/views/users/bulk-edit.blade.php # resources/views/users/edit.blade.php # resources/views/users/ldap.blade.php # resources/views/users/print.blade.php # resources/views/users/view.blade.php # routes/api.php # routes/web/hardware.php # webpack.mix.js
2020-04-20 23:20:34 -07:00
'labels_per_page' => 'numeric',
'labels_width' => 'numeric',
'labels_height' => 'numeric',
'labels_pmargin_left' => 'numeric|nullable',
'labels_pmargin_right' => 'numeric|nullable',
'labels_pmargin_top' => 'numeric|nullable',
'labels_pmargin_bottom' => 'numeric|nullable',
'labels_display_bgutter' => 'numeric|nullable',
'labels_display_sgutter' => 'numeric|nullable',
'labels_fontsize' => 'numeric|min:5',
'labels_pagewidth' => 'numeric|nullable',
'labels_pageheight' => 'numeric|nullable',
'login_remote_user_enabled' => 'numeric|nullable',
'login_common_disabled' => 'numeric|nullable',
'login_remote_user_custom_logout_url' => 'string|nullable',
'login_remote_user_header_name' => 'string|nullable',
'thumbnail_max_h' => 'numeric|max:500|min:25',
2020-10-08 18:43:23 -07:00
'pwd_secure_min' => 'numeric|required|min:8',
'audit_warning_days' => 'numeric|nullable',
'audit_interval' => 'numeric|nullable',
'custom_forgot_pass_url' => 'url|nullable',
'privacy_policy_link' => 'nullable|url',
2016-03-25 01:18:05 -07:00
];
protected $fillable = [
'site_name',
'email_domain',
'email_format',
'username_format',
2023-03-22 14:43:00 -07:00
'webhook_endpoint',
'webhook_channel',
'webhook_botname',
];
2016-03-25 01:18:05 -07:00
/**
* Get the app settings.
* Cache is expired on Setting model saved in EventServiceProvider.
*
* @author Wes Hulette <jwhulette@gmail.com>
*
* @since 5.0.0
*
* @return \App\Models\Setting|null
*/
public static function getSettings(): ?self
2016-03-25 01:18:05 -07:00
{
if (!self::$_cache) {
// Need for setup as no tables exist
try {
self::$_cache = self::first();
} catch (\Throwable $th) {
return null;
}
}
return self::$_cache;
}
/**
* Check to see if setup process is complete.
* Cache is expired on Setting model saved in EventServiceProvider.
*
* @return bool
*/
public static function setupCompleted(): bool
2016-06-22 12:27:41 -07:00
{
try {
$usercount = User::withTrashed()->count();
$settingsCount = self::count();
return $usercount > 0 && $settingsCount > 0;
} catch (\Throwable $th) {
\Log::debug('User table and settings table DO NOT exist or DO NOT have records');
// Catch the error if the tables dont exit
return false;
}
2016-05-14 16:09:00 -07:00
}
/**
* Get the current Laravel version.
*
* @return string
*/
public function lar_ver(): string
2016-03-25 01:18:05 -07:00
{
$app = App::getFacadeApplication();
2016-03-25 01:18:05 -07:00
return $app::VERSION;
}
/**
* Get the default EULA text.
*
* @return string|null
*/
public static function getDefaultEula(): ?string
2016-03-25 01:18:05 -07:00
{
if (self::getSettings()->default_eula_text) {
return Helper::parseEscapedMarkedown(self::getSettings()->default_eula_text);
2016-03-25 01:18:05 -07:00
}
2018-01-20 08:46:19 -08:00
return null;
2016-03-25 01:18:05 -07:00
}
/**
* Check wether to show in model dropdowns.
*
* @param string $element
*
* @return bool
*/
public function modellistCheckedValue($element): bool
{
$settings = self::getSettings();
// If the value is blank for some reason
if ($settings->modellist_displays == '') {
return false;
}
$values = explode(',', $settings->modellist_displays);
foreach ($values as $value) {
if ($value == $element) {
return true;
}
}
return false;
}
/**
* Escapes the custom CSS, and then un-escapes the greater-than symbol
* so it can work with direct descendant characters for bootstrap
* menu overrides like:.
*
* .skin-blue .sidebar-menu>li.active>a, .skin-blue .sidebar-menu>li:hover>a
*
* Important: Do not remove the e() escaping here, as we output raw in the blade.
*
* @return string escaped CSS
*
* @author A. Gianotto <snipe@snipe.net>
*/
public function show_custom_css(): string
2016-03-25 01:18:05 -07:00
{
$custom_css = self::getSettings()->custom_css;
2016-03-25 01:18:05 -07:00
$custom_css = e($custom_css);
// Needed for modifying the bootstrap nav :(
$custom_css = str_ireplace('script', 'SCRIPTS-NOT-ALLOWED-HERE', $custom_css);
$custom_css = str_replace('&gt;', '>', $custom_css);
// Allow String output (needs quotes)
$custom_css = str_replace('&quot;', '"', $custom_css);
2016-03-25 01:18:05 -07:00
return $custom_css;
}
/**
* Converts bytes into human readable file size.
*
* @param string $bytes
*
* @return string human readable file size (2,87 Мб)
*
* @author Mogilev Arseny
*/
public static function fileSizeConvert($bytes): string
2016-03-25 01:18:05 -07:00
{
$result = 0;
2016-03-25 01:18:05 -07:00
$bytes = floatval($bytes);
$arBytes = [
0 => [
'UNIT' => 'TB',
'VALUE' => pow(1024, 4),
],
1 => [
'UNIT' => 'GB',
'VALUE' => pow(1024, 3),
],
2 => [
'UNIT' => 'MB',
'VALUE' => pow(1024, 2),
],
3 => [
'UNIT' => 'KB',
'VALUE' => 1024,
],
4 => [
'UNIT' => 'B',
'VALUE' => 1,
],
];
2016-03-25 01:18:05 -07:00
foreach ($arBytes as $arItem) {
if ($bytes >= $arItem['VALUE']) {
$result = $bytes / $arItem['VALUE'];
$result = round($result, 2).$arItem['UNIT'];
break;
2016-03-25 01:18:05 -07:00
}
}
return $result;
2016-03-25 01:18:05 -07:00
}
/**
* The url for slack notifications.
* Used by Notifiable trait.
*
* @return string
*/
public function routeNotificationForSlack(): string
{
// At this point the endpoint is the same for everything.
// In the future this may want to be adapted for individual notifications.
2023-03-22 14:43:00 -07:00
return self::getSettings()->webhook_endpoint;
}
/**
* Get the mail reply to address from configuration.
*
* @return string
*/
public function routeNotificationForMail(): string
{
// At this point the endpoint is the same for everything.
// In the future this may want to be adapted for individual notifications.
return config('mail.reply_to.address');
}
/**
* Get the password complexity rule.
*
* @return string
*/
public static function passwordComplexityRulesSaving($action = 'update'): string
{
$security_rules = '';
$settings = self::getSettings();
// Check if they have uncommon password enforcement selected in settings
if ($settings->pwd_secure_uncommon == 1) {
$security_rules .= '|dumbpwd';
}
// Check for any secure password complexity rules that may have been selected
if ($settings->pwd_secure_complexity != '') {
$security_rules .= '|'.$settings->pwd_secure_complexity;
}
if ($action == 'update') {
return 'nullable|min:'.$settings->pwd_secure_min.$security_rules;
}
return 'required|min:'.$settings->pwd_secure_min.$security_rules;
}
/**
* Get the specific LDAP settings
*
* @author Wes Hulette <jwhulette@gmail.com>
*
* @since 5.0.0
*
* @return Collection
*/
public static function getLdapSettings(): Collection
{
$ldapSettings = self::select([
'ldap_enabled',
'ldap_server',
'ldap_uname',
'ldap_pword',
'ldap_basedn',
'ldap_filter',
'ldap_username_field',
'ldap_lname_field',
'ldap_fname_field',
'ldap_auth_filter_query',
'ldap_version',
'ldap_active_flag',
'ldap_emp_num',
'ldap_email',
'ldap_server_cert_ignore',
'ldap_port',
'ldap_tls',
'ldap_pw_sync',
'is_ad',
'ad_domain',
'ad_append_domain',
'ldap_client_tls_key',
2023-04-25 11:44:04 -07:00
'ldap_client_tls_cert',
'ldap_default_group',
'ldap_dept',
'ldap_emp_num',
'ldap_phone_field',
'ldap_jobtitle',
'ldap_manager',
'ldap_country',
'ldap_location',
])->first()->getAttributes();
return collect($ldapSettings);
}
/**
* Return the filename for the client-side SSL cert
*
* @var string
*/
public static function get_client_side_cert_path()
{
return storage_path().'/ldap_client_tls.cert';
}
/**
* Return the filename for the client-side SSL key
*
* @var string
*/
public static function get_client_side_key_path()
{
return storage_path().'/ldap_client_tls.key';
}
public function update_client_side_cert_files()
{
/**
* I'm not sure if it makes sense to have a cert but no key
* nor vice versa, but for now I'm just leaving it like this.
*
* Also, we could easily set this up with an event handler and
* self::saved() or something like that but there's literally only
* one place where we will do that, so I'll just explicitly call
* this method at that spot instead. It'll be easier to debug and understand.
*/
if ($this->ldap_client_tls_cert) {
file_put_contents(self::get_client_side_cert_path(), $this->ldap_client_tls_cert);
} else {
if (file_exists(self::get_client_side_cert_path())) {
unlink(self::get_client_side_cert_path());
}
}
if ($this->ldap_client_tls_key) {
file_put_contents(self::get_client_side_key_path(), $this->ldap_client_tls_key);
} else {
if (file_exists(self::get_client_side_key_path())) {
unlink(self::get_client_side_key_path());
}
}
}
2016-03-25 01:18:05 -07:00
}