Skip to content

Commit

Permalink
rewrite the simple version in a cleaner way
Browse files Browse the repository at this point in the history
  • Loading branch information
PipoCanaja committed Aug 11, 2024
1 parent 52c1de9 commit 473258f
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 28 deletions.
23 changes: 0 additions & 23 deletions app/Http/Controllers/PluginImageController.php

This file was deleted.

23 changes: 23 additions & 0 deletions app/Http/Controllers/PluginResourceController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Http\Controllers;

use App\Models\Plugin;
use Illuminate\Http\Request;
use App\Plugins\Hooks\ResourceAccessorHook;
use PluginManager;

class PluginResourceController extends Controller
{
public function getResource(Request $request, Plugin $plugin, string $path = null)
{
if (is_null($path)) {
// not much we can do for this path
abort(404);
}

// If we have a hook for resources, we call it.
return PluginManager::call(ResourceAccessorHook::class, ['request' => $request, 'path' => $path], $plugin->plugin_name)->first() ?? abort(404);
// if not, we return abort(404)
}
}
69 changes: 69 additions & 0 deletions app/Plugins/ExamplePlugin/ResourceAccessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
/*
* ExampleSettingsPlugin.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 <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2024 PipoCanaja
* @author PipoCanaja <pipocanaja@gmail.com>
*/

namespace App\Plugins\ExamplePlugin;

use App\Plugins\Hooks\ResourceAccessorHook;
use App\Models\User;
use App\Models\Device;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Str;
use Illuminate\Http\Request;

// This ResourceHook is called from a Controller, and allows any plugin to publish files, images, etc, to be downloaded

class ResourceAccessor extends ResourceAccessorHook
{
public function authorize(User $user): bool
{
// In this example, we check if the user has a custom role/permission
// return $user->can('download-reports')
return true;
}

// process the request, and returns
// - A response() as defined here : https://laravel.com/docs/responses
// - An array with the following syntax:
// ['action' => 'abort', 'abort_type' => 403], more details here : https://laravel.com/docs/errors#http-exceptions

public function processRequest(Request $request, string $path, array $settings)
{
// you are free to change the path here. You can also generate files on the fly.
$full_path = base_path('/app/Plugins/ExamplePlugin/files/' . $path);

// if you use a real file, better check if it exists and is readable, and return the proper abort instruction for the framework
if (! is_file($full_path)) {
return (['action' => 'abort', 'abort_type' => 404]);
}
if (! is_readable($full_path)) {
return (['action' => 'abort', 'abort_type' => 403]);
}

$result = response()->file($full_path); // to return an image or a file to be displayed inline
//$result = response()->download($full_path); // to force the browser to download the file

return ($result);
}
}
1 change: 1 addition & 0 deletions app/Plugins/ExamplePlugin/resources/views/page.blade.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<div style="display: flex; align-items: center; justify-content: center;"><img style="transform: scale(0.6);" src="/plugin/ExamplePlugin/resources/LibreNMS-Logo.png"></img></div>
<div class="panel panel-default">
<div class="panel-body ">
<div class="pull-left" style="margin-top: 5px;">
Expand Down
3 changes: 1 addition & 2 deletions app/Plugins/ExamplePlugin/resources/views/settings.blade.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<div style="display: flex; align-items: center; justify-content: center;"><img style="transform: scale(0.6);" src="/plugin/ExamplePlugin/resources/LibreNMS-Logo.png"></img></div>
<div style="margin: 15px;">

<div style="display: flex; align-items: center; justify-content: center;"><img style="transform: scale(0.6);" src="/plugin/images/ExamplePlugin/LibreNMS-Logo.png"></img></div>

<h4>{{ $plugin_name }} Settings:</h4>

<!-- Example of free-form settings, real plugins should use specific fields -->
Expand Down
55 changes: 55 additions & 0 deletions app/Plugins/Hooks/ResourceAccessorHook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/*
* ResourceAccessorHook.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 <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2024 PipoCanaja
* @author PipoCanaja <pipocanaja@gmail.com>
*/

namespace App\Plugins\Hooks;

use App\Models\User;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Str;
use Illuminate\Http\Request;

abstract class ResourceAccessorHook
{
public string $view = ''; // We don't use

public function authorize(User $user): bool
{
return true;
}

public function processRequest(Request $request, string $path, array $settings)
{
return (['action' => 'abort', 'abort_type' => 404]);
}

final public function handle(string $pluginName, Request $request, string $path, array $settings, Application $app)
{
return ($app->call([$this, 'processRequest'], [
'request' => $request,
'path' => $path,
'settings' => $settings,
]));
}
}
9 changes: 7 additions & 2 deletions app/Providers/PluginProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ protected function loadLocalPlugins(PluginManager $manager): void
}

$class = $this->className($plugin_name, $matches[3]);
$hook_type = $this->hookType($class);

// If we find a hook, we handle it, if not we continue with next class
if (is_null($hook_type = $this->hookType($class))) {

Check failure on line 64 in app/Providers/PluginProvider.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis (8.1)

Call to function is_null() with string will always evaluate to false.
continue;
}

// publish hooks in class
$hook_published = $manager->publishHook($plugin_name, $hook_type, $class);
Expand Down Expand Up @@ -89,7 +93,8 @@ protected function hookType(string $class): string
}
}

throw new PluginDoesNotImplementHookException($class);
// if we haven't found one
return null;

Check failure on line 97 in app/Providers/PluginProvider.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis (8.1)

Method App\Providers\PluginProvider::hookType() should return string but returns null.
}

protected function className(string $dir, string $name): string
Expand Down
2 changes: 1 addition & 1 deletion routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@
Route::redirect('plugin/view=admin', '/plugin/admin');
Route::get('plugin/p={pluginName}', 'PluginLegacyController@redirect');
Route::any('plugin/v1/{plugin:plugin_name}/{other?}', PluginLegacyController::class)->where('other', '(.*)')->name('plugin.legacy');
Route::get('plugin/{plugin:plugin_name}/resources/{path}', 'PluginResourceController@getResource')->where('path', '.*')->name('plugin.ressource');
Route::get('plugin/{plugin:plugin_name}', PluginPageController::class)->name('plugin.page');
Route::get('plugin/images/{plugin:plugin_name}/{file}', 'PluginImageController@image')->name('plugin.image');

// old route redirects
Route::permanentRedirect('poll-log', 'poller/log');
Expand Down

0 comments on commit 473258f

Please sign in to comment.