Skip to content

Commit

Permalink
Convert the inventory page to Laravel
Browse files Browse the repository at this point in the history
Fix several XSS issues (hopefully no new ones snuck in)
Small improvement to the SelectController to allow filtering by filterFields()
  • Loading branch information
murrant committed Apr 25, 2023
1 parent 2271e29 commit b6d854b
Show file tree
Hide file tree
Showing 14 changed files with 344 additions and 208 deletions.
50 changes: 50 additions & 0 deletions app/Http/Controllers/InventoryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace App\Http\Controllers;

use App\Models\EntPhysical;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;

class InventoryController extends Controller
{
public function __invoke(Request $request): View
{
$this->validate($request, [
'device' => 'nullable|int',
'descr' => 'nullable|string',
'model' => 'nullable|string',
'serial' => 'nullable|string',
]);

$device = \App\Models\Device::hasAccess($request->user())
->select(['device_id', 'hostname', 'ip', 'sysName', 'display'])
->firstWhere('device_id', $request->get('device'));

$model_filter = ['field' => 'model'];
$device_selected = '';
if ($device) {
$device_selected = ['id' => $device->device_id, 'text' => $device->displayName()];
$model_filter['device_id'] = $device->device_id;
}

return view('inventory', [
'device_selected' => $device_selected,
'filter' => [
'device' => $device?->device_id,
'descr' => $request->get('descr'),
'model' => $request->get('model'),
'serial' => $request->get('serial'),
],
'model_filter' => $model_filter,
'show_purge' => EntPhysical::whereDoesntHave('device')->exists(),
]);
}

public function purge()
{
EntPhysical::whereDoesntHave('device')->delete();

return redirect()->back();
}
}
68 changes: 68 additions & 0 deletions app/Http/Controllers/Select/InventoryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
/**
* EntPhysicalController.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* @link https://www.librenms.org
*
* @copyright 2023 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/

namespace App\Http\Controllers\Select;

use App\Models\EntPhysical;

class InventoryController extends SelectController
{
protected function rules()
{
return [
'field' => 'required|in:name,model,descr,class',
'device' => 'nullable|int',
];
}

protected function filterFields($request)
{
return [
'device_id' => 'device',
];
}
protected function searchFields($request)
{
return [$this->fieldToColumn($request->get('field'))];
}

protected function baseQuery($request)
{
$column = $this->fieldToColumn($request->get('field'));
return EntPhysical::hasAccess($request->user())
->select($column)
->orderBy($column)
->distinct();
}

private function fieldToColumn($field) {
return match ($field) {

Check failure on line 61 in app/Http/Controllers/Select/InventoryController.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis (8.1)

Match expression does not handle remaining value: mixed
'name' => 'entPhysicalName',
'model' => 'entPhysicalModelName',
'descr' => 'entPhysicalDescr',
'class' => 'entPhysicalClass',
};
}
}
21 changes: 13 additions & 8 deletions app/Http/Controllers/Select/PortFieldController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ protected function rules()
];
}

/**
* Defines fields that can be used as filters
* @param $request
* @return string[]
*/
protected function filterFields($request)
{
return [
'device_id' => 'device',
];
}

/**
* Defines search fields will be searched in order
*
Expand All @@ -61,14 +73,7 @@ protected function searchFields($request)
*/
protected function baseQuery($request)
{
/** @var \Illuminate\Database\Eloquent\Builder $query */
$query = Port::hasAccess($request->user())
return Port::hasAccess($request->user())
->select($request->get('field'))->distinct();

if ($device_id = $request->get('device')) {
$query->where('ports.device_id', $device_id);
}

return $query;
}
}
3 changes: 2 additions & 1 deletion app/Http/Controllers/Select/SelectController.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public function __invoke(Request $request)
$query = $this->baseQuery($request)->when($request->has('id'), function ($query) {
return $query->whereKey(request('id'));
});
$query = $this->search($request->get('term'), $query, $this->searchFields($request));
$this->filter($request, $query, $this->filterFields($request));
$this->search($request->get('term'), $query, $this->searchFields($request));
$this->sort($request, $query);
$paginator = $query->simplePaginate($limit);

Expand Down
96 changes: 96 additions & 0 deletions app/Http/Controllers/Table/InventoryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php
/**
* InventoryController.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* @link https://www.librenms.org
*
* @copyright 2023 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/

namespace App\Http\Controllers\Table;

use App\Models\EntPhysical;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use LibreNMS\Util\Url;

class InventoryController extends TableController
{
public function rules()
{
return [
'device' => 'nullable|int',
'descr' => 'nullable|string',
'model'=> 'nullable|string',
'serial' => 'nullable|string',
];
}

protected function filterFields($request)
{
return [
'device_id' => 'device',
];
}

protected function searchFields($request)
{
return ['entPhysicalDescr', 'entPhysicalModelName', 'entPhysicalSerialNum'];
}

protected function sortFields($request)
{
return [
'device' => 'device_id',
'name' => 'entPhysicalName',
'descr' => 'entPhysicalDescr',
'model' => 'entPhysicalModelName',
'serial' => 'entPhysicalSerialNum',
];
}

protected function baseQuery($request)
{
$query = EntPhysical::hasAccess($request->user())
->with('device')
->select(['entPhysical_id', 'device_id', 'entPhysicalDescr', 'entPhysicalName', 'entPhysicalModelName', 'entPhysicalSerialNum']);

// apply specific field filters
$this->search($request->get('descr'), $query, ['entPhysicalDescr']);
$this->search($request->get('model'), $query, ['entPhysicalModelName']);
$this->search($request->get('serial'), $query, ['entPhysicalSerialNum']);

return $query;
}

/**
* @param EntPhysical $entPhysical
* @return array|Model|Collection
*/
public function formatItem($entPhysical)
{
return [
'device' => Url::deviceLink($entPhysical?->device),

Check failure on line 89 in app/Http/Controllers/Table/InventoryController.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis (8.1)

Using nullsafe property access on non-nullable type App\Models\EntPhysical. Use -> instead.
'descr' => htmlspecialchars($entPhysical->entPhysicalDescr),
'name' => htmlspecialchars($entPhysical->entPhysicalName),
'model' => htmlspecialchars($entPhysical->entPhysicalModelName),
'serial' => htmlspecialchars($entPhysical->entPhysicalSerialNum),
];
}
}
2 changes: 1 addition & 1 deletion app/Http/Controllers/Table/TableController.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public function __invoke(Request $request)
/** @var Builder $query */
$query = $this->baseQuery($request);

$this->search($request->get('searchPhrase'), $query, $this->searchFields($request));
$this->filter($request, $query, $this->filterFields($request));
$this->search($request->get('searchPhrase'), $query, $this->searchFields($request));
$this->sort($request, $query);

$limit = $request->get('rowCount', 25);
Expand Down
2 changes: 1 addition & 1 deletion html/css/app.css

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions html/mix-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
"/js/app.js": "/js/app.js?id=5ddec7f7302f146a8dcc",
"/js/manifest.js": "/js/manifest.js?id=2951ae529be231f05a93",
"/css/vendor.css": "/css/vendor.css?id=2568831af31dbfc3128a",
"/css/app.css": "/css/app.css?id=bd093a6a2e2682bb59ef",
"/css/app.css": "/css/app.css?id=1cd88608bf4eaee000d8",
"/js/vendor.js": "/js/vendor.js?id=c5fd3d75a63757080dbb",
"/js/lang/de.js": "/js/lang/de.js?id=613b5ca9cd06ca15e384",
"/js/lang/en.js": "/js/lang/en.js?id=efa23897934359283288",
"/js/lang/fr.js": "/js/lang/fr.js?id=4540d71a19d8ca7c824b",
"/js/lang/it.js": "/js/lang/it.js?id=71c68fae57a4a3647e43",
"/js/lang/de.js": "/js/lang/de.js?id=d74df23e729c5dabfee8",
"/js/lang/en.js": "/js/lang/en.js?id=20e52084af3a0a8f4724",
"/js/lang/fr.js": "/js/lang/fr.js?id=22902d30358443ef2877",
"/js/lang/it.js": "/js/lang/it.js?id=6220e138068a7e58387f",
"/js/lang/ru.js": "/js/lang/ru.js?id=f6b7c078755312a0907c",
"/js/lang/sr.js": "/js/lang/sr.js?id=388e38b41f63e3517506",
"/js/lang/uk.js": "/js/lang/uk.js?id=72f81fcbf77df09d0c82",
"/js/lang/zh-CN.js": "/js/lang/zh-CN.js?id=4e081fbac70d969894bf",
"/js/lang/zh-TW.js": "/js/lang/zh-TW.js?id=ed26425647721a42ee9d"
"/js/lang/uk.js": "/js/lang/uk.js?id=fdfb4cfa77a3340e50f8",
"/js/lang/zh-CN.js": "/js/lang/zh-CN.js?id=cc4309e63a32a671f107",
"/js/lang/zh-TW.js": "/js/lang/zh-TW.js?id=2248687ad44f27299377"
}
100 changes: 0 additions & 100 deletions includes/html/pages/inventory.inc.php

This file was deleted.

Loading

0 comments on commit b6d854b

Please sign in to comment.