ok
This commit is contained in:
86
Production/SNIPE-IT/app/Providers/AppServiceProvider.php
Normal file
86
Production/SNIPE-IT/app/Providers/AppServiceProvider.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Component;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\License;
|
||||
use App\Models\User;
|
||||
use App\Models\Setting;
|
||||
use App\Models\SnipeSCIMConfig;
|
||||
use App\Observers\AccessoryObserver;
|
||||
use App\Observers\AssetObserver;
|
||||
use App\Observers\UserObserver;
|
||||
use App\Observers\ComponentObserver;
|
||||
use App\Observers\ConsumableObserver;
|
||||
use App\Observers\LicenseObserver;
|
||||
use App\Observers\SettingObserver;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
/**
|
||||
* This service provider handles setting the observers on models
|
||||
*
|
||||
* PHP version 5.5.9
|
||||
* @version v3.0
|
||||
*/
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Custom email array validation
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return void
|
||||
*/
|
||||
public function boot(UrlGenerator $url)
|
||||
{
|
||||
if (env('APP_FORCE_TLS')) {
|
||||
if (strpos(env('APP_URL'), 'https') === 0) {
|
||||
$url->forceScheme('https');
|
||||
} else {
|
||||
\Log::debug("'APP_FORCE_TLS' is set to true, but 'APP_URL' does not start with 'https://'. Will not force TLS on connections.");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - isn't it somehow 'gauche' to check the environment directly; shouldn't we be using config() somehow?
|
||||
if ( ! env('APP_ALLOW_INSECURE_HOSTS')) { // unless you set APP_ALLOW_INSECURE_HOSTS, you should PROHIBIT forging domain parts of URL via Host: headers
|
||||
$url_parts = parse_url(config('app.url'));
|
||||
if ($url_parts && array_key_exists('scheme', $url_parts) && array_key_exists('host', $url_parts)) { // check for the *required* parts of a bare-minimum URL
|
||||
\URL::forceRootUrl(config('app.url'));
|
||||
} else {
|
||||
\Log::error("Your APP_URL in your .env is misconfigured - it is: ".config('app.url').". Many things will work strangely unless you fix it.");
|
||||
}
|
||||
}
|
||||
|
||||
\Illuminate\Pagination\Paginator::useBootstrap();
|
||||
|
||||
Schema::defaultStringLength(191);
|
||||
Asset::observe(AssetObserver::class);
|
||||
User::observe(UserObserver::class);
|
||||
Accessory::observe(AccessoryObserver::class);
|
||||
Component::observe(ComponentObserver::class);
|
||||
Consumable::observe(ConsumableObserver::class);
|
||||
License::observe(LicenseObserver::class);
|
||||
Setting::observe(SettingObserver::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
// Only load rollbar if there is a rollbar key and the app is in production
|
||||
if (($this->app->environment('production')) && (config('logging.channels.rollbar.access_token'))) {
|
||||
$this->app->register(\Rollbar\Laravel\RollbarServiceProvider::class);
|
||||
}
|
||||
|
||||
$this->app->singleton('ArieTimmerman\Laravel\SCIMServer\SCIMConfig', SnipeSCIMConfig::class); // this overrides the default SCIM configuration with our own
|
||||
|
||||
}
|
||||
}
|
229
Production/SNIPE-IT/app/Providers/AuthServiceProvider.php
Normal file
229
Production/SNIPE-IT/app/Providers/AuthServiceProvider.php
Normal file
@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
use App\Models\Company;
|
||||
use App\Models\Component;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\Department;
|
||||
use App\Models\Depreciation;
|
||||
use App\Models\License;
|
||||
use App\Models\Location;
|
||||
use App\Models\Manufacturer;
|
||||
use App\Models\PredefinedKit;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\User;
|
||||
use App\Policies\AccessoryPolicy;
|
||||
use App\Policies\AssetModelPolicy;
|
||||
use App\Policies\AssetPolicy;
|
||||
use App\Policies\CategoryPolicy;
|
||||
use App\Policies\CompanyPolicy;
|
||||
use App\Policies\ComponentPolicy;
|
||||
use App\Policies\ConsumablePolicy;
|
||||
use App\Policies\CustomFieldPolicy;
|
||||
use App\Policies\CustomFieldsetPolicy;
|
||||
use App\Policies\DepartmentPolicy;
|
||||
use App\Policies\DepreciationPolicy;
|
||||
use App\Policies\LicensePolicy;
|
||||
use App\Policies\LocationPolicy;
|
||||
use App\Policies\ManufacturerPolicy;
|
||||
use App\Policies\PredefinedKitPolicy;
|
||||
use App\Policies\StatuslabelPolicy;
|
||||
use App\Policies\SupplierPolicy;
|
||||
use App\Policies\UserPolicy;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Laravel\Passport\Passport;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The policy mappings for the application.
|
||||
*
|
||||
* See SnipePermissionsPolicy for additional information.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $policies = [
|
||||
Accessory::class => AccessoryPolicy::class,
|
||||
Asset::class => AssetPolicy::class,
|
||||
AssetModel::class => AssetModelPolicy::class,
|
||||
Category::class => CategoryPolicy::class,
|
||||
Component::class => ComponentPolicy::class,
|
||||
Consumable::class => ConsumablePolicy::class,
|
||||
CustomField::class => CustomFieldPolicy::class,
|
||||
CustomFieldset::class => CustomFieldsetPolicy::class,
|
||||
Department::class => DepartmentPolicy::class,
|
||||
Depreciation::class => DepreciationPolicy::class,
|
||||
License::class => LicensePolicy::class,
|
||||
Location::class => LocationPolicy::class,
|
||||
PredefinedKit::class => PredefinedKitPolicy::class,
|
||||
Statuslabel::class => StatuslabelPolicy::class,
|
||||
Supplier::class => SupplierPolicy::class,
|
||||
User::class => UserPolicy::class,
|
||||
Manufacturer::class => ManufacturerPolicy::class,
|
||||
Company::class => CompanyPolicy::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->commands([
|
||||
\Laravel\Passport\Console\InstallCommand::class,
|
||||
\Laravel\Passport\Console\ClientCommand::class,
|
||||
\Laravel\Passport\Console\KeysCommand::class,
|
||||
]);
|
||||
|
||||
$this->registerPolicies();
|
||||
Passport::routes();
|
||||
Passport::tokensExpireIn(Carbon::now()->addYears(config('passport.expiration_years')));
|
||||
Passport::refreshTokensExpireIn(Carbon::now()->addYears(config('passport.expiration_years')));
|
||||
Passport::personalAccessTokensExpireIn(Carbon::now()->addYears(config('passport.expiration_years')));
|
||||
Passport::withCookieSerialization();
|
||||
|
||||
// --------------------------------
|
||||
// BEFORE ANYTHING ELSE
|
||||
// --------------------------------
|
||||
// If this condition is true, ANYTHING else below will be assumed
|
||||
// to be true. This can cause weird blade behavior.
|
||||
Gate::before(function ($user) {
|
||||
if ($user->isSuperUser()) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// --------------------------------
|
||||
// GENERAL GATES
|
||||
// These control general sections of the admin
|
||||
// --------------------------------
|
||||
Gate::define('admin', function ($user) {
|
||||
if ($user->hasAccess('admin')) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Gate::define('accessories.files', function ($user) {
|
||||
if ($user->hasAccess('accessories.files')) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Gate::define('components.files', function ($user) {
|
||||
if ($user->hasAccess('components.files')) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Gate::define('consumables.files', function ($user) {
|
||||
if ($user->hasAccess('consumables.files')) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Can the user import CSVs?
|
||||
Gate::define('import', function ($user) {
|
||||
if ($user->hasAccess('import')) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Gate::define('licenses.files', function ($user) {
|
||||
if ($user->hasAccess('licenses.files')) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Gate::define('assets.view.encrypted_custom_fields', function ($user) {
|
||||
if($user->hasAccess('assets.view.encrypted_custom_fields')){
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// -----------------------------------------
|
||||
// Reports
|
||||
// -----------------------------------------
|
||||
Gate::define('reports.view', function ($user) {
|
||||
if ($user->hasAccess('reports.view')) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// -----------------------------------------
|
||||
// Self
|
||||
// -----------------------------------------
|
||||
Gate::define('self.two_factor', function ($user) {
|
||||
if (($user->hasAccess('self.two_factor')) || ($user->hasAccess('admin'))) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Gate::define('self.api', function ($user) {
|
||||
return $user->hasAccess('self.api');
|
||||
});
|
||||
|
||||
Gate::define('self.edit_location', function ($user) {
|
||||
return $user->hasAccess('self.edit_location');
|
||||
});
|
||||
|
||||
Gate::define('self.checkout_assets', function ($user) {
|
||||
return $user->hasAccess('self.checkout_assets');
|
||||
});
|
||||
|
||||
Gate::define('self.view_purchase_cost', function ($user) {
|
||||
return $user->hasAccess('self.view_purchase_cost');
|
||||
});
|
||||
|
||||
// This is largely used to determine whether to display the gear icon sidenav
|
||||
// in the left-side navigation
|
||||
Gate::define('backend.interact', function ($user) {
|
||||
return $user->can('view', Statuslabel::class)
|
||||
|| $user->can('view', AssetModel::class)
|
||||
|| $user->can('view', Category::class)
|
||||
|| $user->can('view', Manufacturer::class)
|
||||
|| $user->can('view', Supplier::class)
|
||||
|| $user->can('view', Department::class)
|
||||
|| $user->can('view', Location::class)
|
||||
|| $user->can('view', Company::class)
|
||||
|| $user->can('view', Manufacturer::class)
|
||||
|| $user->can('view', CustomField::class)
|
||||
|| $user->can('view', CustomFieldset::class)
|
||||
|| $user->can('view', Depreciation::class);
|
||||
});
|
||||
|
||||
|
||||
// This determines whether or not an API user should be able to get the selectlists.
|
||||
// This can seem a little confusing, since view properties may not have been granted
|
||||
// to the logged in API user, but creating assets, licenses, etc won't work
|
||||
// if the user can't view and interact with the select lists.
|
||||
Gate::define('view.selectlists', function ($user) {
|
||||
return $user->can('update', Asset::class)
|
||||
|| $user->can('create', Asset::class)
|
||||
|| $user->can('checkout', Asset::class)
|
||||
|| $user->can('checkin', Asset::class)
|
||||
|| $user->can('audit', Asset::class)
|
||||
|| $user->can('update', License::class)
|
||||
|| $user->can('create', License::class)
|
||||
|| $user->can('update', Component::class)
|
||||
|| $user->can('create', Component::class)
|
||||
|| $user->can('update', Consumable::class)
|
||||
|| $user->can('create', Consumable::class)
|
||||
|| $user->can('update', Accessory::class)
|
||||
|| $user->can('create', Accessory::class)
|
||||
|| $user->can('update', User::class)
|
||||
|| $user->can('create', User::class);
|
||||
});
|
||||
}
|
||||
}
|
35
Production/SNIPE-IT/app/Providers/EventServiceProvider.php
Normal file
35
Production/SNIPE-IT/app/Providers/EventServiceProvider.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Listeners\CheckoutableListener;
|
||||
use App\Listeners\LogListener;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The event listener mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $listen = [
|
||||
'Illuminate\Auth\Events\Login' => [
|
||||
\App\Listeners\LogSuccessfulLogin::class,
|
||||
],
|
||||
|
||||
'Illuminate\Auth\Events\Failed' => [
|
||||
\App\Listeners\LogFailedLogin::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The subscriber classes to register.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $subscribe = [
|
||||
LogListener::class,
|
||||
CheckoutableListener::class,
|
||||
];
|
||||
}
|
31
Production/SNIPE-IT/app/Providers/MacroServiceProvider.php
Normal file
31
Production/SNIPE-IT/app/Providers/MacroServiceProvider.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class MacroServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
// require base_path() . '/resources/macros/community_types.php';
|
||||
foreach (glob(base_path('resources/macros/*.php')) as $filename) {
|
||||
require_once $filename;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
96
Production/SNIPE-IT/app/Providers/RouteServiceProvider.php
Normal file
96
Production/SNIPE-IT/app/Providers/RouteServiceProvider.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, etc.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->configureRateLimiting();
|
||||
|
||||
$this->routes(function () {
|
||||
$this->mapApiRoutes();
|
||||
|
||||
$this->mapWebRoutes();
|
||||
|
||||
require base_path('routes/scim.php');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "web" routes for the application.
|
||||
*
|
||||
* These routes all receive session state, CSRF protection, etc.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function mapWebRoutes()
|
||||
{
|
||||
Route::group([
|
||||
'middleware' => 'web',
|
||||
// 'namespace' => $this->namespace, //okay, I don't know what this means, but somehow this might be a problem for us?
|
||||
], function ($router) {
|
||||
require base_path('routes/web/hardware.php');
|
||||
require base_path('routes/web/models.php');
|
||||
require base_path('routes/web/accessories.php');
|
||||
require base_path('routes/web/licenses.php');
|
||||
require base_path('routes/web/consumables.php');
|
||||
require base_path('routes/web/fields.php');
|
||||
require base_path('routes/web/components.php');
|
||||
require base_path('routes/web/users.php');
|
||||
require base_path('routes/web/kits.php');
|
||||
require base_path('routes/web.php');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "api" routes for the application.
|
||||
*
|
||||
* These routes are typically stateless.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function mapApiRoutes()
|
||||
{
|
||||
Route::group([
|
||||
'middleware' => 'auth:api',
|
||||
// 'namespace' => $this->namespace, // this might also be a problem? I don't really know :/
|
||||
'prefix' => 'api',
|
||||
], function ($router) {
|
||||
require base_path('routes/api.php');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the rate limiters for the application.
|
||||
*
|
||||
* https://laravel.com/docs/8.x/routing#rate-limiting
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configureRateLimiting()
|
||||
{
|
||||
|
||||
// Rate limiter for API calls
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(config('app.api_throttle_per_minute'))->by(optional($request->user())->id ?: $request->ip());
|
||||
});
|
||||
|
||||
// Rate limiter for forgotten password requests
|
||||
RateLimiter::for('forgotten_password', function (Request $request) {
|
||||
return Limit::perMinute(config('auth.password_reset.max_attempts_per_min'))->by(optional($request->user())->id ?: $request->ip());
|
||||
});
|
||||
|
||||
}
|
||||
}
|
67
Production/SNIPE-IT/app/Providers/SamlServiceProvider.php
Normal file
67
Production/SNIPE-IT/app/Providers/SamlServiceProvider.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Services\Saml;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class SamlServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->app->singleton(Saml::class, Saml::class);
|
||||
|
||||
Route::group(['namespace'=> 'App\Http\Controllers'], function () {
|
||||
Route::group(['prefix'=> 'saml'], function () {
|
||||
Route::get(
|
||||
'metadata',
|
||||
[
|
||||
'as' => 'saml.metadata',
|
||||
'uses' => 'Auth\SamlController@metadata', ]
|
||||
);
|
||||
|
||||
Route::match(
|
||||
['get', 'post'],
|
||||
'acs',
|
||||
[
|
||||
'as' => 'saml.acs',
|
||||
'uses' => 'Auth\SamlController@acs', ]
|
||||
);
|
||||
|
||||
Route::get(
|
||||
'sls',
|
||||
[
|
||||
'as' => 'saml.sls',
|
||||
'uses' => 'Auth\SamlController@sls', ]
|
||||
);
|
||||
});
|
||||
|
||||
Route::get(
|
||||
'login/saml',
|
||||
[
|
||||
'as' => 'saml.login',
|
||||
'uses' => 'Auth\SamlController@login', ]
|
||||
);
|
||||
|
||||
Route::group(['prefix' => 'admin', 'middleware' => ['web', 'auth', 'authorize:superuser']], function () {
|
||||
Route::get('saml', ['as' => 'settings.saml.index', 'uses' => 'SettingsController@getSamlSettings']);
|
||||
Route::post('saml', ['as' => 'settings.saml.save', 'uses' => 'SettingsController@postSamlSettings']);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
}
|
||||
}
|
184
Production/SNIPE-IT/app/Providers/SettingsServiceProvider.php
Normal file
184
Production/SNIPE-IT/app/Providers/SettingsServiceProvider.php
Normal file
@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
/**
|
||||
* This service provider handles sharing the snipeSettings variable, and sets
|
||||
* some common upload path and image urls.
|
||||
*
|
||||
* PHP version 5.5.9
|
||||
* @version v3.0
|
||||
*/
|
||||
class SettingsServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Custom email array validation
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
|
||||
// Share common setting variables with all views.
|
||||
view()->composer('*', function ($view) {
|
||||
$view->with('snipeSettings', Setting::getSettings());
|
||||
});
|
||||
|
||||
|
||||
// Make sure the limit is actually set, is an integer and does not exceed system limits
|
||||
\App::singleton('api_limit_value', function () {
|
||||
$limit = config('app.max_results');
|
||||
$int_limit = intval(request('limit'));
|
||||
|
||||
if ((abs($int_limit) > 0) && ($int_limit <= config('app.max_results'))) {
|
||||
$limit = abs($int_limit);
|
||||
}
|
||||
|
||||
return $limit;
|
||||
});
|
||||
|
||||
// Make sure the offset is actually set and is an integer
|
||||
\App::singleton('api_offset_value', function () {
|
||||
$offset = intval(request('offset'));
|
||||
return $offset;
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Set some common variables so that they're globally available.
|
||||
* The paths should always be public (versus private uploads)
|
||||
*/
|
||||
|
||||
// Model paths and URLs
|
||||
|
||||
|
||||
\App::singleton('eula_pdf_path', function () {
|
||||
return 'eula_pdf_path/';
|
||||
});
|
||||
|
||||
\App::singleton('assets_upload_path', function () {
|
||||
return 'assets/';
|
||||
});
|
||||
|
||||
\App::singleton('accessories_upload_path', function () {
|
||||
return 'public/uploads/accessories/';
|
||||
});
|
||||
|
||||
\App::singleton('models_upload_path', function () {
|
||||
return 'models/';
|
||||
});
|
||||
|
||||
\App::singleton('models_upload_url', function () {
|
||||
return 'models/';
|
||||
});
|
||||
|
||||
// Categories
|
||||
\App::singleton('categories_upload_path', function () {
|
||||
return 'categories/';
|
||||
});
|
||||
|
||||
\App::singleton('categories_upload_url', function () {
|
||||
return 'categories/';
|
||||
});
|
||||
|
||||
// Locations
|
||||
\App::singleton('locations_upload_path', function () {
|
||||
return 'locations/';
|
||||
});
|
||||
|
||||
\App::singleton('locations_upload_url', function () {
|
||||
return 'locations/';
|
||||
});
|
||||
|
||||
// Users
|
||||
\App::singleton('users_upload_path', function () {
|
||||
return 'avatars/';
|
||||
});
|
||||
|
||||
\App::singleton('users_upload_url', function () {
|
||||
return 'users/';
|
||||
});
|
||||
|
||||
// Manufacturers
|
||||
\App::singleton('manufacturers_upload_path', function () {
|
||||
return 'manufacturers/';
|
||||
});
|
||||
|
||||
\App::singleton('manufacturers_upload_url', function () {
|
||||
return 'manufacturers/';
|
||||
});
|
||||
|
||||
// Suppliers
|
||||
\App::singleton('suppliers_upload_path', function () {
|
||||
return 'suppliers/';
|
||||
});
|
||||
|
||||
\App::singleton('suppliers_upload_url', function () {
|
||||
return 'suppliers/';
|
||||
});
|
||||
|
||||
// Departments
|
||||
\App::singleton('departments_upload_path', function () {
|
||||
return 'departments/';
|
||||
});
|
||||
|
||||
\App::singleton('departments_upload_url', function () {
|
||||
return 'departments/';
|
||||
});
|
||||
|
||||
// Company paths and URLs
|
||||
\App::singleton('companies_upload_path', function () {
|
||||
return 'companies/';
|
||||
});
|
||||
|
||||
\App::singleton('companies_upload_url', function () {
|
||||
return 'companies/';
|
||||
});
|
||||
|
||||
// Accessories paths and URLs
|
||||
\App::singleton('accessories_upload_path', function () {
|
||||
return 'accessories/';
|
||||
});
|
||||
|
||||
\App::singleton('accessories_upload_url', function () {
|
||||
return 'accessories/';
|
||||
});
|
||||
|
||||
// Consumables paths and URLs
|
||||
\App::singleton('consumables_upload_path', function () {
|
||||
return 'consumables/';
|
||||
});
|
||||
|
||||
\App::singleton('consumables_upload_url', function () {
|
||||
return 'consumables/';
|
||||
});
|
||||
|
||||
// Components paths and URLs
|
||||
\App::singleton('components_upload_path', function () {
|
||||
return 'components/';
|
||||
});
|
||||
|
||||
\App::singleton('components_upload_url', function () {
|
||||
return 'components/';
|
||||
});
|
||||
|
||||
// Set the monetary locale to the configured locale to make helper::parseFloat work.
|
||||
setlocale(LC_MONETARY, config('app.locale'));
|
||||
setlocale(LC_NUMERIC, config('app.locale'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Services\SnipeTranslator;
|
||||
use Illuminate\Translation\TranslationServiceProvider;
|
||||
|
||||
class SnipeTranslationServiceProvider extends TranslationServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//This is almost an *EXACT* carbon-copy of the TranslationServiceProvider, except with a modified Translator
|
||||
$this->registerLoader();
|
||||
|
||||
$this->app->singleton('translator', function ($app) {
|
||||
$loader = $app['translation.loader'];
|
||||
|
||||
// When registering the translator component, we'll need to set the default
|
||||
// locale as well as the fallback locale. So, we'll grab the application
|
||||
// configuration so we can easily get both of these values from there.
|
||||
$locale = $app['config']['app.locale'];
|
||||
|
||||
$trans = new SnipeTranslator($loader, $locale); //the ONLY changed line
|
||||
|
||||
$trans->setFallback($app['config']['app.fallback_locale']);
|
||||
|
||||
return $trans;
|
||||
});
|
||||
}
|
||||
}
|
343
Production/SNIPE-IT/app/Providers/ValidationServiceProvider.php
Normal file
343
Production/SNIPE-IT/app/Providers/ValidationServiceProvider.php
Normal file
@ -0,0 +1,343 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Department;
|
||||
use App\Models\Setting;
|
||||
use DB;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Validator;
|
||||
|
||||
/**
|
||||
* This service provider handles a few custom validation rules.
|
||||
*
|
||||
* PHP version 5.5.9
|
||||
* @version v3.0
|
||||
*/
|
||||
class ValidationServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Custom email array validation
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
|
||||
// Email array validator
|
||||
Validator::extend('email_array', function ($attribute, $value, $parameters, $validator) {
|
||||
$value = str_replace(' ', '', $value);
|
||||
$array = explode(',', $value);
|
||||
|
||||
foreach ($array as $email) { //loop over values
|
||||
$email_to_validate['alert_email'][] = $email;
|
||||
}
|
||||
|
||||
$rules = ['alert_email.*'=>'email'];
|
||||
$messages = [
|
||||
'alert_email.*'=>trans('validation.email_array'),
|
||||
];
|
||||
|
||||
$validator = Validator::make($email_to_validate, $rules, $messages);
|
||||
|
||||
return $validator->passes();
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Unique only if undeleted.
|
||||
*
|
||||
* This works around the use case where multiple deleted items have the same unique attribute.
|
||||
* (I think this is a bug in Laravel's validator?)
|
||||
*
|
||||
* $attribute is the FIELDNAME you're checking against
|
||||
* $value is the VALUE of the item you're checking against the existing values in the fieldname
|
||||
* $parameters[0] is the TABLE NAME you're querying
|
||||
* $parameters[1] is the ID of the item you're querying - this makes it work on saving, checkout, etc,
|
||||
* since it defaults to 0 if there is no item created yet (new item), but populates the ID if editing
|
||||
*
|
||||
* The UniqueUndeletedTrait prefills these parameters, so you can just use
|
||||
* `unique_undeleted:table,fieldname` in your rules out of the box
|
||||
*/
|
||||
Validator::extend('unique_undeleted', function ($attribute, $value, $parameters, $validator) {
|
||||
|
||||
if (count($parameters)) {
|
||||
|
||||
// This is a bit of a shim, but serial doesn't have any other rules around it other than that it's nullable
|
||||
if (($parameters[0]=='assets') && ($attribute == 'serial') && (Setting::getSettings()->unique_serial != '1')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$count = DB::table($parameters[0])
|
||||
->select('id')
|
||||
->where($attribute, '=', $value)
|
||||
->whereNull('deleted_at')
|
||||
->where('id', '!=', $parameters[1])->count();
|
||||
|
||||
return $count < 1;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Unique if undeleted for two columns
|
||||
*
|
||||
* Same as unique_undeleted but taking the combination of two columns as unique constrain.
|
||||
* This uses the Validator::replacer('two_column_unique_undeleted') below for nicer translations.
|
||||
*
|
||||
* $parameters[0] - the name of the first table we're looking at
|
||||
* $parameters[1] - the ID (this will be 0 on new creations)
|
||||
* $parameters[2] - the name of the second table we're looking at
|
||||
* $parameters[3] - the value that the request is passing for the second table we're
|
||||
* checking for uniqueness across
|
||||
*
|
||||
*/
|
||||
Validator::extend('two_column_unique_undeleted', function ($attribute, $value, $parameters, $validator) {
|
||||
if (count($parameters)) {
|
||||
$count = DB::table($parameters[0])
|
||||
->select('id')->where($attribute, '=', $value)
|
||||
->whereNull('deleted_at')
|
||||
->where('id', '!=', $parameters[1])
|
||||
->where($parameters[2], $parameters[3])->count();
|
||||
|
||||
return $count < 1;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* This is the validator replace static method that allows us to pass the $parameters of the table names
|
||||
* into the translation string in validation.two_column_unique_undeleted for two_column_unique_undeleted
|
||||
* validation messages.
|
||||
*
|
||||
* This is invoked automatically by Validator::extend('two_column_unique_undeleted') above and
|
||||
* produces a translation like: "The name value must be unique across categories and category type."
|
||||
*
|
||||
* The $parameters passed coincide with the ones the two_column_unique_undeleted custom validator above
|
||||
* uses, so $parameter[0] is the first table and so $parameter[2] is the second table.
|
||||
*/
|
||||
Validator::replacer('two_column_unique_undeleted', function($message, $attribute, $rule, $parameters) {
|
||||
$message = str_replace(':table1', $parameters[0], $message);
|
||||
$message = str_replace(':table2', $parameters[2], $message);
|
||||
|
||||
// Change underscores to spaces for a friendlier display
|
||||
$message = str_replace('_', ' ', $message);
|
||||
return $message;
|
||||
});
|
||||
|
||||
|
||||
// Prevent circular references
|
||||
//
|
||||
// Example usage in Location model where parent_id references another Location:
|
||||
//
|
||||
// protected $rules = array(
|
||||
// 'parent_id' => 'non_circular:locations,id,10'
|
||||
// );
|
||||
//
|
||||
Validator::extend('non_circular', function ($attribute, $value, $parameters, $validator) {
|
||||
if (count($parameters) < 2) {
|
||||
throw new \Exception('Required validator parameters: <table>,<primary key>[,depth]');
|
||||
}
|
||||
|
||||
// Parameters from the rule implementation ($pk will likely be 'id')
|
||||
$table = array_get($parameters, 0);
|
||||
$pk = array_get($parameters, 1);
|
||||
$depth = (int) array_get($parameters, 2, 50);
|
||||
|
||||
// Data from the edited model
|
||||
$data = $validator->getData();
|
||||
|
||||
// The primary key value from the edited model
|
||||
$data_pk = array_get($data, $pk);
|
||||
$value_pk = $value;
|
||||
|
||||
// If we’re editing an existing model and there is a parent value set…
|
||||
while ($data_pk && $value_pk) {
|
||||
|
||||
// It’s not valid for any parent id to be equal to the existing model’s id
|
||||
if ($data_pk == $value_pk) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Avoid accidental infinite loops
|
||||
if (--$depth < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the next parent id
|
||||
$value_pk = DB::table($table)->select($attribute)->where($pk, '=', $value_pk)->value($attribute);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Yo dawg. I heard you like validators.
|
||||
// This validates the custom validator regex in custom fields.
|
||||
// We're just checking that the regex won't throw an exception, not
|
||||
// that it's actually correct for what the user intended.
|
||||
|
||||
Validator::extend('valid_regex', function ($attribute, $value, $parameters, $validator) {
|
||||
|
||||
// Make sure it's not just an ANY format
|
||||
if ($value != '') {
|
||||
|
||||
// Check that the string starts with regex:
|
||||
if (strpos($value, 'regex:') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$test_string = 'My hovercraft is full of eels';
|
||||
|
||||
// We have to stip out the regex: part here to check with preg_match
|
||||
$test_pattern = str_replace('regex:', '', $value);
|
||||
|
||||
try {
|
||||
preg_match($test_pattern, $test_string);
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// This ONLY works for create/update user forms, since the Update Profile Password form doesn't
|
||||
// include any of these additional validator fields
|
||||
Validator::extend('disallow_same_pwd_as_user_fields', function ($attribute, $value, $parameters, $validator) {
|
||||
$data = $validator->getData();
|
||||
|
||||
if (array_key_exists('username', $data)) {
|
||||
if ($data['username'] == $data['password']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('email', $data)) {
|
||||
if ($data['email'] == $data['password']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('first_name', $data)) {
|
||||
if ($data['first_name'] == $data['password']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('last_name', $data)) {
|
||||
if ($data['last_name'] == $data['password']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
Validator::extend('letters', function ($attribute, $value, $parameters) {
|
||||
return preg_match('/\pL/', $value);
|
||||
});
|
||||
|
||||
Validator::extend('numbers', function ($attribute, $value, $parameters) {
|
||||
return preg_match('/\pN/', $value);
|
||||
});
|
||||
|
||||
Validator::extend('case_diff', function ($attribute, $value, $parameters) {
|
||||
return preg_match('/(\p{Ll}+.*\p{Lu})|(\p{Lu}+.*\p{Ll})/u', $value);
|
||||
});
|
||||
|
||||
Validator::extend('symbols', function ($attribute, $value, $parameters) {
|
||||
return preg_match('/\p{Z}|\p{S}|\p{P}/', $value);
|
||||
});
|
||||
|
||||
Validator::extend('cant_manage_self', function ($attribute, $value, $parameters, $validator) {
|
||||
// $value is the actual *value* of the thing that's being validated
|
||||
// $attribute is the name of the field that the validation is running on - probably manager_id in our case
|
||||
// $parameters are the optional parameters - an array for everything, split on commas. But we don't take any params here.
|
||||
// $validator gives us proper access to the rest of the actual data
|
||||
$data = $validator->getData();
|
||||
|
||||
if (array_key_exists('id', $data)) {
|
||||
if ($value && $value == $data['id']) {
|
||||
// if you definitely have an ID - you're saving an existing user - and your ID matches your manager's ID - fail.
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// no 'id' key to compare against (probably because this is a new user)
|
||||
// so it automatically passes this validation
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Validator::extend('is_unique_department', function ($attribute, $value, $parameters, $validator) {
|
||||
$data = $validator->getData();
|
||||
if ((array_key_exists('location_id', $data) && $data['location_id'] != null) && (array_key_exists('company_id', $data) && $data['company_id'] != null)) {
|
||||
$count = Department::where('name', $data['name'])
|
||||
->where('location_id', $data['location_id'])
|
||||
->where('company_id', $data['company_id'])
|
||||
->whereNotNull('company_id')
|
||||
->whereNotNull('location_id')
|
||||
->count('name');
|
||||
|
||||
return $count < 1;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Validator::extend('not_array', function ($attribute, $value, $parameters, $validator) {
|
||||
return !is_array($value);
|
||||
});
|
||||
|
||||
// This is only used in Models/CustomFieldset.php - it does automatic validation for checkboxes by making sure
|
||||
// that the submitted values actually exist in the options.
|
||||
Validator::extend('checkboxes', function ($attribute, $value, $parameters, $validator){
|
||||
$field = CustomField::where('db_column', $attribute)->first();
|
||||
$options = $field->formatFieldValuesAsArray();
|
||||
|
||||
if(is_array($value)) {
|
||||
$invalid = array_diff($value, $options);
|
||||
if(count($invalid) > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// for legacy, allows users to submit a comma separated string of options
|
||||
elseif(!is_array($value)) {
|
||||
$exploded = array_map('trim', explode(',', $value));
|
||||
$invalid = array_diff($exploded, $options);
|
||||
if(count($invalid) > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Validates that a radio button option exists
|
||||
Validator::extend('radio_buttons', function ($attribute, $value) {
|
||||
$field = CustomField::where('db_column', $attribute)->first();
|
||||
$options = $field->formatFieldValuesAsArray();
|
||||
|
||||
return in_array($value, $options);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user