Add Laravel to LibreNMS (#8318)

* Add Laravel to LibreNMS.

* Try to set permissions during initial install and first composer update to Laravel.

* Fix composer.lock
Fix missing db config keys

* Start building v1 layout
Port ajax_setresolution, inject csrf into jquery ajax calls
Layout works, building menu
Partially done.

* Fix device group list
remove stupid count relationships

* Print messages for common boot errors.
Don't log to laravel.log file.
Log to error_log until booted, then librenms.log

* Fix up some issues with Config loading
Start of custom directives

* Custom blade directives: config, notconfig, admin

* Preflight checks
Only load config files once.

* Update the composer.lock for php 5.6

* Menu through routing

* Start of alert menu

* Better alert scopes

* reduce cruft in models

* Alerting menu more or less working :D

* Fix style

* Improved preflight

* Fix chicken-eggs!

* Remove examples

* Better alert_rule status queries
Debugbar

* fix app.env check

* User Menu

* Settings bar (dropped refresh)
Search JS

* Toastr messages

* Rename preflight

* Use hasAccess(User) on most models.
Add port counts

* Missed a Preflight -> Checks rename

* Fix some formatting

* Boot Eloquent outside of Laravel
Use Eloquent for Config and Plugins so we don't have to connect with dbFacile inside Laravel.
Move locate_binary() into Config class

* Config WIP

* Try to fix a lot of config loading issues.

* Improve menu for non-admins removing unneeded menus
url() for all in menu

* Only use eloquent if it exists

* Include APP_URL in initial .env settings

* Implement Legacy User Provider

* Helper class for using Eloquent outside of Laravel.
Allows access to DB style queries too and checking the connection status.

* Fix up tests

* Fix device groups query

* Checking Travis

* copy config.test.php earlier

* dbFacile check config before connecting
Don't use exception to check if eloquent is connected, it gets grabbed by the exception handler.
Ignore missing config.php error.

* Fix config load with database is not migrated yet.

* Remove Config::load() from early boot.

* Use laravel config settings to init db (this prefers .env settings)
Fix bgp vars not set in menu
add _ide_helper.php to .gitignore

* Restrict dependencies to versions that support php 5.6

* Update ConfigTest

* Fix a couple of installation issues

* Add unique NODE_ID to .env

* Correct handling of title image

* Fix database config not loading. Thanks @laf

* Don't prepend /

* add class_exists checks for development service providers

* Fix config value casting

* Don't use functions that may not exist

* Update dbFacile.php

* d_echo may not be defined when Config used called.

* Add SELinux configuration steps
More detailed permissions check.
Check all and give complete corrective commands in one step.

* Ignore node_modules directory

* Re-add accidetal removal
This commit is contained in:
Tony Murray 2018-05-09 08:05:17 -05:00 committed by GitHub
parent 8afafe7eb0
commit 1ad7f3138b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
132 changed files with 10430 additions and 1578 deletions

8
.env.example Normal file
View File

@ -0,0 +1,8 @@
APP_KEY=
#DB_HOST=
#DB_DATABASE=
#DB_USERNAME=
#DB_PASSWORD=
#APP_URL=

3
.gitignore vendored
View File

@ -9,6 +9,7 @@
!/.github/
!/.codeclimate.yml
!/.mention-bot
!/.env.example
# Others #
##########
@ -25,7 +26,9 @@ nbproject
patches
!/lib/yaml
/vendor
/node_modules
composer.phar
_ide_helper.php
# Docs #
########

View File

@ -28,6 +28,7 @@ before_install:
- sudo apt-get -qq update
- sudo apt-get install -y snmp fping
- mysql -e 'CREATE DATABASE librenms_phpunit_78hunjuybybh;'
- cp tests/config/config.test.php config.php
install:
- composer install --prefer-dist --no-interaction

View File

@ -25,11 +25,27 @@
namespace LibreNMS;
use Composer\Script\Event;
use Composer\Installer\PackageEvent;
use Composer\Script\Event;
class ComposerHelper
{
public static function postRootPackageInstall(Event $event)
{
if (!file_exists('.env')) {
self::setPermissions();
self::populateEnv();
}
}
public static function postInstall(Event $event)
{
if (!file_exists('.env')) {
self::setPermissions();
self::populateEnv();
}
}
public static function preUpdate(Event $event)
{
if (!getenv('FORCE')) {
@ -55,6 +71,85 @@ class ComposerHelper
}
}
/**
* Initially populate .env file
*/
private static function populateEnv()
{
if (!file_exists('.env')) {
copy('.env.example', '.env');
self::exec('php artisan key:generate');
$config = [
'db_host' => '',
'db_port' => '',
'db_name' => '',
'db_user' => '',
'db_pass' => '',
'db_socket' => '',
'base_url' => '',
'user' => '',
'group' => '',
];
@include 'config.php';
self::setEnv([
'NODE_ID' => uniqid(),
'DB_HOST' => $config['db_host'],
'DB_PORT' => $config['db_port'],
'DB_USERNAME' => $config['db_user'],
'DB_PASSWORD' => $config['db_pass'],
'DB_DATABASE' => $config['db_name'],
'DB_SOCKET' => $config['db_socket'],
'APP_URL' => $config['base_url'],
'LIBRENMS_USER' => $config['user'],
'LIBRENMS_GROUP' => $config['group'],
]);
}
}
/**
* Set a setting in .env file
*
* @param array $settings KEY => value list of settings
* @param string $file
*/
private static function setEnv($settings, $file = '.env')
{
$content = file_get_contents($file);
if (substr($content, -1) !== "\n") {
$content .= PHP_EOL;
}
foreach ($settings as $key => $value) {
// only add non-empty settings
if (empty($value)) {
continue;
}
if (strpos($content, "$key=") !== false) {
// only replace ones that aren't already set for safety and uncomment
$content = preg_replace("/#?$key=\n/", "$key=$value\n", $content);
} else {
$content .= "$key=$value\n";
}
}
file_put_contents($file, $content);
}
private static function setPermissions()
{
$permissions_cmds = [
'setfacl -R -m g::rwx rrd/ logs/ storage/ bootstrap/cache/',
'setfacl -d -m g::rwx rrd/ logs/ storage/ bootstrap/cache/',
];
self::exec($permissions_cmds);
}
/**
* Run a command or array of commands and echo the command and output
*

View File

@ -25,6 +25,10 @@
namespace LibreNMS;
use App\Models\GraphType;
use Illuminate\Database\QueryException;
use LibreNMS\DB\Eloquent;
class Config
{
/**
@ -39,16 +43,19 @@ class Config
self::loadFiles();
// Make sure the database is connected
if (dbIsConnected()) {
if (Eloquent::isConnected() || (function_exists('dbIsConnected') && dbIsConnected())) {
// pull in the database config settings
self::mergeDb();
// load graph types from the database
self::loadGraphsFromDb();
}
// Process $config to tidy up
self::processConfig();
// process $config to tidy up
self::processConfig(true);
} else {
// just process $config
self::processConfig(false);
}
return $config;
}
@ -80,7 +87,7 @@ class Config
require $install_dir . '/includes/vmware_guestid.inc.php';
// Load user config
include $install_dir . '/config.php';
@include $install_dir . '/config.php';
return $config;
}
@ -222,22 +229,45 @@ class Config
* @param string $group webui group (only set when initially created)
* @param string $sub_group webui subgroup (only set when initially created)
*/
public static function set($key, $value, $persist = false, $default = '', $descr = '', $group = '', $sub_group = '')
public static function set($key, $value, $persist = false, $default = null, $descr = null, $group = null, $sub_group = null)
{
global $config;
if ($persist) {
$res = dbUpdate(array('config_value' => $value), 'config', '`config_name`=?', array($key));
if (!$res && !dbFetchCell('SELECT 1 FROM `config` WHERE `config_name`=?', array($key))) {
$insert = array(
'config_name' => $key,
'config_value' => $value,
'config_default' => $default,
'config_descr' => $descr,
'config_group' => $group,
'config_sub_group' => $sub_group,
);
dbInsert($insert, 'config');
if (Eloquent::isConnected()) {
try {
$config_array = collect([
'config_name' => $key,
'config_value' => $value,
'config_default' => $default,
'config_descr' => $descr,
'config_group' => $group,
'config_sub_group' => $sub_group,
])->filter(function ($value) {
return !is_null($value);
})->toArray();
\App\Models\Config::updateOrCreate(['config_name' => $key], $config_array);
} catch (QueryException $e) {
// possibly table config doesn't exist yet
global $debug;
if ($debug) {
echo $e;
}
}
} else {
$res = dbUpdate(array('config_value' => $value), 'config', '`config_name`=?', array($key));
if (!$res && !dbFetchCell('SELECT 1 FROM `config` WHERE `config_name`=?', array($key))) {
$insert = array(
'config_name' => $key,
'config_value' => $value,
'config_default' => $default,
'config_descr' => $descr,
'config_group' => $group,
'config_sub_group' => $sub_group,
);
dbInsert($insert, 'config');
}
}
}
@ -292,10 +322,24 @@ class Config
{
global $config;
$db_config = array();
foreach (dbFetchRows('SELECT `config_name`,`config_value` FROM `config`') as $obj) {
self::assignArrayByPath($db_config, $obj['config_name'], $obj['config_value']);
$db_config = [];
if (Eloquent::isConnected()) {
try {
\App\Models\Config::get(['config_name', 'config_value'])
->each(function ($item) use (&$db_config) {
array_set($db_config, $item->config_name, $item->config_value);
});
} catch (QueryException $e) {
// possibly table config doesn't exist yet
}
} else {
foreach (dbFetchRows('SELECT `config_name`,`config_value` FROM `config`') as $obj) {
self::assignArrayByPath($db_config, $obj['config_name'], $obj['config_value']);
}
}
$config = array_replace_recursive($db_config, $config);
}
@ -312,9 +356,9 @@ class Config
{
// type cast value. Is this needed here?
if (filter_var($value, FILTER_VALIDATE_INT)) {
$value = (int) $value;
$value = (int)$value;
} elseif (filter_var($value, FILTER_VALIDATE_FLOAT)) {
$value = (float) $value;
$value = (float)$value;
} elseif (filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== null) {
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
}
@ -333,8 +377,20 @@ class Config
{
global $config;
if (Eloquent::isConnected()) {
try {
$graph_types = GraphType::all()->toArray();
} catch (QueryException $e) {
// possibly table config doesn't exist yet
$graph_types = [];
}
} else {
$graph_types = dbFetchRows('SELECT * FROM graph_types');
}
// load graph types from the database
foreach (dbFetchRows('SELECT * FROM graph_types') as $graph) {
foreach ($graph_types as $graph) {
$g = [];
foreach ($graph as $k => $v) {
if (strpos($k, 'graph_') == 0) {
// remove leading 'graph_' from column name
@ -353,9 +409,9 @@ class Config
* Proces the config after it has been loaded.
* Make sure certain variables have been set properly and
*
*
* @param bool $persist Save binary locations and other settings to the database.
*/
private static function processConfig()
private static function processConfig($persist = true)
{
if (!self::get('email_from')) {
self::set('email_from', '"' . self::get('project_name') . '" <' . self::get('email_user') . '@' . php_uname('n') . '>');
@ -388,7 +444,7 @@ class Config
// make sure we have full path to binaries in case PATH isn't set
foreach (array('fping', 'fping6', 'snmpgetnext', 'rrdtool') as $bin) {
if (!is_executable(self::get($bin))) {
self::set($bin, locate_binary($bin), true, $bin, "Path to $bin", 'external', 'paths');
self::set($bin, self::locateBinary($bin), $persist, $bin, "Path to $bin", 'external', 'paths');
}
}
}
@ -421,7 +477,10 @@ class Config
private static function deprecatedVariable($old, $new)
{
if (self::has($old)) {
d_echo("Copied deprecated config $old to $new\n");
global $debug;
if ($debug) {
echo "Copied deprecated config $old to $new\n";
}
self::set($new, self::get($old));
}
}
@ -463,4 +522,25 @@ class Config
return array_intersect_key($config, $keys); // return only the db settings
}
/**
* Locate the actual path of a binary
*
* @param $binary
* @return mixed
*/
public static function locateBinary($binary)
{
if (!str_contains($binary, '/')) {
$output = `whereis -b $binary`;
$list = trim(substr($output, strpos($output, ':') + 1));
$targets = explode(' ', $list);
foreach ($targets as $target) {
if (is_executable($target)) {
return $target;
}
}
}
return $binary;
}
}

79
LibreNMS/DB/Eloquent.php Normal file
View File

@ -0,0 +1,79 @@
<?php
/**
* Eloquent.php
*
* Class for managing Eloquent outside of Laravel
*
* 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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\DB;
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Events\Dispatcher;
class Eloquent
{
/** @var Capsule static reference to capsule */
private static $capsule;
public static function boot()
{
// boot Eloquent outside of Laravel
if (!defined('LARAVEL_START') && class_exists(Capsule::class)) {
$install_dir = realpath(__DIR__ . '/../../');
self::$capsule = new Capsule;
$db_config = include($install_dir . '/config/database.php');
self::$capsule->addConnection($db_config['connections'][$db_config['default']]);
self::$capsule->setEventDispatcher(new Dispatcher());
self::$capsule->setAsGlobal();
self::$capsule->bootEloquent();
}
}
public static function isConnected()
{
$conn = self::DB();
if ($conn) {
return (bool)$conn->getDatabaseName();
}
return false;
}
/**
* Access the Database Manager for Fluent style queries. Like the Laravel DB facade.
*
* @return \Illuminate\Database\Connection
*/
public static function DB()
{
// check if Laravel is booted
if (class_exists('DB')) {
return \DB::connection();
}
if (is_null(self::$capsule)) {
return null;
}
return self::$capsule->getDatabaseManager()->connection();
}
}

View File

@ -25,31 +25,37 @@
namespace LibreNMS;
use App\Models\Plugin;
class Plugins
{
private static $plugins = array();
private static $plugins;
public static function start()
{
global $config;
if (file_exists($config['plugin_dir'])) {
// $plugin_files = scandir($config['plugin_dir']);
$plugin_files = dbFetchRows("SELECT * FROM `plugins` WHERE `plugin_active` = '1'");
foreach ($plugin_files as $plugins) {
$plugin_info = pathinfo($config['plugin_dir'].'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php');
if ($plugin_info['extension'] == 'php') {
if (is_file($config['plugin_dir'].'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php')) {
self::load($config['plugin_dir'].'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php', $plugin_info['filename']);
if (is_null(self::$plugins)) {
self::$plugins = [];
$plugin_dir = Config::get('plugin_dir');
if (file_exists($plugin_dir)) {
// $plugin_files = scandir($config['plugin_dir']);
$plugin_files = Plugin::isActive()->get()->toArray();
foreach ($plugin_files as $plugins) {
$plugin_info = pathinfo($plugin_dir.'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php');
if ($plugin_info['extension'] == 'php') {
if (is_file($plugin_dir.'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php')) {
self::load($plugin_dir.'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php', $plugin_info['filename']);
}
}
}
}
return true;
} else {
return false;
return true;
}
}
return false;
}//end start()
@ -79,7 +85,9 @@ class Plugins
public static function call($hook, $params = false)
{
if (count(self::$plugins[$hook]) != 0) {
self::start();
if (!empty(self::$plugins[$hook])) {
foreach (self::$plugins[$hook] as $name) {
if (!is_array($params)) {
call_user_func(array($name, $hook));
@ -89,4 +97,10 @@ class Plugins
}
}
}//end call()
public static function count()
{
self::start();
return count(self::$plugins);
}
}//end class

View File

@ -98,7 +98,7 @@ class Programs extends BaseValidation
return Config::get($bin);
}
$located = locate_binary($bin);
$located = Config::locateBinary($bin);
if (is_executable($located)) {
return $located;
}

172
app/Checks.php Normal file
View File

@ -0,0 +1,172 @@
<?php
/**
* Checks.php
*
* Pre-flight checks at various stages of booting
*
* 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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App;
use App\Models\Device;
use App\Models\Notification;
use Auth;
use Carbon\Carbon;
use Dotenv\Dotenv;
use Kamaln7\Toastr\Facades\Toastr;
use LibreNMS\Config;
class Checks
{
public static function preBoot()
{
// check file/folder permissions
$check_folders = [
self::basePath('bootstrap/cache'),
self::basePath('storage'),
self::basePath('logs'),
];
$check_files = [
self::basePath('logs/librenms.log'), // This file is important because Laravel needs to be able to write to it
];
// check that each is writable
$check_folders = array_filter($check_folders, function ($path) {
return !is_writable($path);
});
$check_files = array_filter($check_files, function ($path) {
return file_exists($path) xor is_writable($path);
});
if (!empty($check_folders) || !empty($check_files)) {
// only operate on parent directories, not files
$check = array_unique(array_merge($check_folders, array_map('dirname', $check_files)));
// load .env, it isn't loaded
$dotenv = new Dotenv(__DIR__ . '/../');
$dotenv->load();
$user = env('LIBRENMS_USER', 'librenms');
$group = env('LIBRENMS_GROUP', $user);
// build chown message
$dirs = implode(' ', $check);
$chown_commands = [
"chown -R $user:$group $dirs",
"setfacl -R -m g::rwx $dirs",
"setfacl -d -m g::rwx $dirs",
];
//check for missing directories
$missing = array_filter($check, 'file_exists');
if (!empty($missing)) {
array_unshift($chown_commands, 'mkdir -p ' . implode(' ', $missing));
}
self::printMessage(
"Error: $dirs not writable! Run these commands as root to fix:",
$chown_commands
);
// build SELinux output
$selinux_commands = [];
foreach ($check as $dir) {
$selinux_commands[] = "semanage fcontext -a -t httpd_sys_content_t '$dir(/.*)?'";
$selinux_commands[] = "semanage fcontext -a -t httpd_sys_rw_content_t '$dir(/.*)?'";
$selinux_commands[] = "restorecon -RFvv $dir";
}
self::printMessage(
"If using SELinux you may also need:",
$selinux_commands,
true
);
}
}
/**
* Pre-boot dependency check
*/
public static function postAutoload()
{
if (!class_exists(\Illuminate\Foundation\Application::class)) {
self::printMessage(
'Error: Missing dependencies! Run the following command to fix:',
'./scripts/composer_wrapper.php install --no-dev',
true
);
}
}
/**
* Post boot Toast messages
*/
public static function postAuth()
{
$notifications = Notification::isUnread(Auth::user())->where('severity', '>', 1)->get();
foreach ($notifications as $notification) {
Toastr::error("<a href='notifications/'>$notification->body</a>", $notification->title);
}
if (Device::isUp()->whereTime('last_polled', '<=', Carbon::now()->subMinutes(15))->count() > 0) {
Toastr::warning('<a href="poll-log/filter=unpolled/">It appears as though you have some devices that haven\'t completed polling within the last 15 minutes, you may want to check that out :)</a>', 'Devices unpolled');
}
// Directory access checks
$rrd_dir = Config::get('rrd_dir');
if (!is_dir($rrd_dir)) {
Toastr::error("RRD Directory is missing ($rrd_dir). Graphing may fail.");
}
$temp_dir = Config::get('temp_dir');
if (!is_dir($temp_dir)) {
Toastr::error("Temp Directory is missing ($temp_dir). Graphing may fail.");
} elseif (!is_writable($temp_dir)) {
Toastr::error("Temp Directory is not writable ($temp_dir). Graphing may fail.");
}
}
private static function printMessage($title, $content, $exit = false)
{
$content = (array)$content;
if (PHP_SAPI == 'cli') {
$format = "%s\n\n%s\n\n";
$message = implode(PHP_EOL, $content);
} else {
$format = "<h3 style='color: firebrick;'>%s</h3><p>%s</p>";
$message = implode('<br />', $content);
}
printf($format, $title, $message);
if ($exit) {
exit(1);
}
}
private static function basePath($path = '')
{
$base_dir = realpath(__DIR__ . '/..');
return "$base_dir/$path";
}
}

40
app/Console/Kernel.php Normal file
View File

@ -0,0 +1,40 @@
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
}
/**
* Register the Closure based commands for the application.
*
* @return void
*/
protected function commands()
{
require base_path('routes/console.php');
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that should not be reported.
*
* @var array
*/
protected $dontReport = [
\Illuminate\Auth\AuthenticationException::class,
\Illuminate\Auth\Access\AuthorizationException::class,
\Symfony\Component\HttpKernel\Exception\HttpException::class,
\Illuminate\Database\Eloquent\ModelNotFoundException::class,
\Illuminate\Session\TokenMismatchException::class,
\Illuminate\Validation\ValidationException::class,
];
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
}
/**
* Convert an authentication exception into an unauthenticated response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception
* @return \Illuminate\Http\Response
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest(route('login'));
}
}

View File

@ -0,0 +1,111 @@
<?php
/**
* LegacyAuth.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Extensions;
use App\Models\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
use LibreNMS\Authentication\Auth as LegacyAuth;
use LibreNMS\Exceptions\AuthenticationException;
class LegacyUserProvider implements UserProvider
{
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
$user_array = LegacyAuth::get()->getUser($identifier);
if (empty($user_array)) {
return null;
}
$user = new User($user_array);
$user->user_id = $user_array['user_id'];
return $user;
}
/**
* Retrieve a user by their unique identifier and "remember me" token.
*
* @param mixed $identifier
* @param string $token
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
// TODO: Implement retrieveByToken() method.
}
/**
* Update the "remember me" token for the given user in storage.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $token
* @return void
*/
public function updateRememberToken(Authenticatable $user, $token)
{
// TODO: Implement updateRememberToken() method.
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
$username = $credentials['username'];
$user_id = LegacyAuth::get()->getUserid($username);
return $this->retrieveById($user_id);
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
try {
return LegacyAuth::get()->authenticate($credentials['username'], $credentials['password']);
} catch (AuthenticationException $e) {
\Toastr::error($e->getMessage());
}
return null;
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AjaxController extends Controller
{
public function setResolution(Request $request)
{
$this->validate($request, [
'width' => 'required|numeric',
'height' => 'required|numeric'
]);
// legacy session
session_start();
$_SESSION['screen_width'] = $request->width;
$_SESSION['screen_height'] = $request->height;
session_write_close();
// laravel session
session([
'screen_width' => $request->width,
'screen_height' => $request->height
]);
return $request->width . 'x' . $request->height;
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class ForgotPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset emails and
| includes a trait which assists in sending these notifications from
| your application to your users. Feel free to explore this trait.
|
*/
use SendsPasswordResetEmails;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Http\Controllers;
class LegacyController extends Controller
{
public function index($path = '')
{
ob_start();
include base_path('html/legacy_index.php');
$html = ob_get_clean();
return response($html);
}
public function api($path = '')
{
ob_start();
include base_path('html/legacy_api_v0.php');
$html = ob_get_clean();
return response($html);
}
}

68
app/Http/Kernel.php Normal file
View File

@ -0,0 +1,68 @@
<?php
namespace App\Http;
use App\Checks;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
public function bootstrap()
{
Checks::preBoot();
parent::bootstrap();
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as BaseEncrypter;
class EncryptCookies extends BaseEncrypter
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array
*/
protected $except = [
//
];
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as BaseTrimmer;
class TrimStrings extends BaseTrimmer
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array
*/
protected $except = [
'password',
'password_confirmation',
];
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
'*', // FIXME: CSRF completely disabled!
];
}

View File

@ -0,0 +1,245 @@
<?php
/**
* Menu.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Http\ViewComposers;
use App\Models\AlertRule;
use App\Models\Application;
use App\Models\BgpPeer;
use App\Models\CefSwitching;
use App\Models\Component;
use App\Models\Device;
use App\Models\DeviceGroup;
use App\Models\Notification;
use App\Models\OspfInstance;
use App\Models\Package;
use App\Models\Port;
use App\Models\Pseudowire;
use App\Models\Sensor;
use App\Models\Service;
use App\Models\User;
use App\Models\Vrf;
use App\Models\WirelessSensor;
use Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;
use LibreNMS\Config;
class MenuComposer
{
/**
* Bind data to the view.
*
* @param View $view
* @return void
*/
public function compose(View $view)
{
$vars = [];
/** @var User $user */
$user = Auth::user();
$vars['navbar'] = in_array(Config::get('site_style'), ['mono', 'dark']) ? 'navbar-inverse' : '';
$vars['project_name'] = Config::get('project_name', 'LibreNMS');
$vars['title_image'] = asset(Config::get('title_image', 'images/librenms_logo_light.svg'));
// Device menu
$vars['device_groups'] = DeviceGroup::hasAccess($user)->select('device_groups.id', 'name', 'desc')->get();
$vars['package_count'] = Package::hasAccess($user)->count();
$vars['device_types'] = Device::hasAccess($user)->select('type')->distinct()->get()->pluck('type')->filter();
if (Config::get('show_locations') && Config::get('show_locations_dropdown')) {
$vars['locations'] = Device::hasAccess($user)->select('location')->distinct()->get()->pluck('location')->filter();
} else {
$vars['locations'] = [];
}
// Service menu
if (Config::get('show_services')) {
$vars['service_status'] = Service::hasAccess($user)->groupBy('service_status')
->select('service_status', DB::raw('count(*) as count'))
->whereIn('service_status', [1, 2])
->get()
->keyBy('service_status');
$warning = $vars['service_status']->get(1);
$vars['service_warning'] = $warning ? $warning->count : 0;
$critical = $vars['service_status']->get(2);
$vars['service_critical'] = $critical ? $critical->count : 0;
}
// Port menu
$vars['port_counts'] = [
'count' => Port::hasAccess($user)->count(),
'up' => Port::hasAccess($user)->isUp()->count(),
'down' => Port::hasAccess($user)->isDown()->count(),
'shutdown' => Port::hasAccess($user)->isDisabled()->count(),
'errored' => Port::hasAccess($user)->hasErrors()->count(),
'ignored' => Port::hasAccess($user)->isIgnored()->count(),
'deleted' => Port::hasAccess($user)->isDeleted()->count(),
'pseudowire' => Config::get('enable_pseudowires') ? Pseudowire::hasAccess($user)->count() : 0,
'alerted' => 0, // not actually supported on old...
];
// Sensor menu
$sensor_menu = [];
$sensor_classes = Sensor::hasAccess($user)->select('sensor_class')->groupBy('sensor_class')->orderBy('sensor_class')->get();
foreach ($sensor_classes as $sensor_model) {
/** @var Sensor $sensor_model */
$class = $sensor_model->sensor_class;
if (in_array($class, ['fanspeed', 'humidity', 'temperature', 'signal'])) {
// First group
$group = 0;
} elseif (in_array($class, ['current', 'frequency', 'power', 'voltage'])) {
// Second group
$group = 1;
} else {
// anything else
$group = 2;
}
$sensor_menu[$group][] = $sensor_model;
}
$vars['sensor_menu'] = $sensor_menu;
// Wireless menu
$wireless_menu_order = array_keys(\LibreNMS\Device\WirelessSensor::getTypes());
$vars['wireless_menu'] = WirelessSensor::hasAccess($user)->select('sensor_class')
->groupBy('sensor_class')
->get()
->sortBy(function ($wireless_sensor) use ($wireless_menu_order) {
$pos = array_search($wireless_sensor->sensor_class, $wireless_menu_order);
return $pos === false ? 100 : $pos; // unknown at bottom
});
// Application menu
$vars['app_menu'] = Application::hasAccess($user)
->select('app_type', 'app_instance')
->groupBy('app_type', 'app_instance')
->orderBy('app_type')
->get()
->groupBy('app_type');
// Routing menu
// FIXME queries use relationships to user
$routing_menu = [];
if ($user->hasGlobalRead()) {
if (Vrf::hasAccess($user)->count()) {
$routing_menu[] = [
[
'url' => 'vrf',
'icon' => 'arrows',
'text' => 'VRFs',
]
];
}
if (OspfInstance::hasAccess($user)->count()) {
$routing_menu[] = [
[
'url' => 'ospf',
'icon' => 'circle-o-notch fa-rotate-180',
'text' => 'OSPF Devices',
]
];
}
if (Component::hasAccess($user)->where('type', 'Cisco-OTV')->count()) {
$routing_menu[] = [
[
'url' => 'cisco-otv',
'icon' => 'exchange',
'text' => 'Cisco OTV',
]
];
}
if (BgpPeer::hasAccess($user)->count()) {
$vars['show_peeringdb'] = Config::get('peeringdb.enabled', false);
$vars['bgp_alerts'] = BgpPeer::hasAccess($user)->inAlarm()->count();
$routing_menu[] = [
[
'url' => 'bgp/type=all/graph=NULL',
'icon' => 'circle-o',
'text' => 'BGP All Sessions',
],
[
'url' => 'bgp/type=external/graph=NULL',
'icon' => 'external-link',
'text' => 'BGP External',
],
[
'url' => 'bgp/type=internal/graph=NULL',
'icon' => 'external-link fa-rotate-180',
'text' => 'BGP Internal',
],
];
} else {
$vars['show_peeringdb'] = false;
$vars['bgp_alerts'] = [];
}
if (CefSwitching::hasAccess($user)->count()) {
$routing_menu[] = [
[
'url' => 'cef',
'icon' => 'exchange',
'text' => 'Cisco CEF',
]
];
}
}
$vars['routing_menu'] = $routing_menu;
// Alert menu
$alert_status = AlertRule::select('severity')
->isActive()
->hasAccess($user)
->groupBy('severity')
->pluck('severity');
if ($alert_status->contains('critical')) {
$vars['alert_menu_class'] = 'danger';
} elseif ($alert_status->contains('warning')) {
$vars['alert_menu_class'] = 'warning';
} else {
$vars['alert_menu_class'] = 'success';
}
// User menu
$vars['notification_count'] = Notification::isSticky()
->orWhere(function ($query) use ($user) {
$query->isUnread($user);
})->count();
// Search bar
$vars['typeahead_limit'] = \LibreNMS\Config::get('webui.global_search_result_limit');
$view->with($vars);
}
}

73
app/Models/Alert.php Normal file
View File

@ -0,0 +1,73 @@
<?php
/**
* app/Models/Alert.php
*
* Model for access to alerts table data
*
* 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 2016 Neil Lathwood
* @author Neil Lathwood <neil@lathwood.co.uk>
*/
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class Alert extends Model
{
public $timestamps = false;
// ---- Query scopes ----
/**
* Only select active alerts
* @param Builder $query
* @return Builder
*/
public function scopeActive($query)
{
return $query->where('state', '=', '1');
}
/**
* Only select active alerts
* @param Builder $query
* @return Builder
*/
public function scopeAcknowledged($query)
{
return $query->where('state', '=', '2');
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id');
}
public function rule()
{
return $this->belongsTo('App\Models\Rule', 'rule_id', 'id');
}
public function users()
{
return $this->belongsToMany('App\Models\User', 'devices_perms', 'device_id', 'user_id');
}
}

90
app/Models/AlertRule.php Normal file
View File

@ -0,0 +1,90 @@
<?php
/**
* app/Models/AlertRule.php
*
* Model for access to alert_rules table data
*
* 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 2016 Neil Lathwood
* @author Neil Lathwood <neil@lathwood.co.uk>
*/
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
class AlertRule extends BaseModel
{
public $timestamps = false;
// ---- Query scopes ----
/**
* @param Builder $query
* @return Builder
*/
public function scopeEnabled($query)
{
return $query->where('disabled', 0);
}
/**
* Scope for only alert rules that are currently in alarm
*
* @param Builder $query
* @return Builder
*/
public function scopeIsActive($query)
{
return $query->enabled()
->join('alerts', 'alerts.rule_id', 'alert_rules.id')
->where('alerts.state', 1);
}
/**
* Scope to filter rules for devices permitted to user
* (do not use for admin and global read-only users)
*
* @param $query
* @param User $user
* @return mixed
*/
public function scopeHasAccess($query, User $user)
{
if ($user->hasGlobalRead()) {
return $query;
}
if (!$this->isJoined($query, 'alerts')) {
$query->join('alerts', 'alerts.rule_id', 'alert_rules.id');
}
return $this->hasDeviceAccess($query, $user, 'alerts');
}
// ---- Define Relationships ----
public function alerts()
{
return $this->hasMany('App\Models\Alert', 'rule_id');
}
public function devices()
{
return $this->belongsToMany('App\Models\Device', 'alert_device_map', 'device_id', 'device_id', 'devices');
}
}

View File

@ -0,0 +1,94 @@
<?php
/**
* Applications.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
class Application extends BaseModel
{
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* The primary key column name.
*
* @var string
*/
protected $primaryKey = 'app_id';
protected static $display_name = [
'bind' => 'BIND',
'dhcp-stats' => 'DHCP Stats',
'exim-stats' => 'EXIM Stats',
'fbsd-nfs-client' => 'FreeBSD NFS Client',
'fbsd-nfs-server' => 'FreeBSD NFS Server',
'freeradius' => 'FreeRADIUS',
'gpsd' => 'GPSD',
'mysql' => 'MySQL',
'nfs-stats' => 'NFS Stats',
'nfs-v3-stats' => 'NFS v3 Stats',
'nfs-server' => 'NFS Server',
'ntp' => 'NTP',
'ntp-client' => 'NTP Client',
'ntp-server' => 'NTP Server',
'opengridscheduler' => 'Open Grid Scheduler',
'os-updates' => 'OS Updates',
'php-fpm' => 'PHP-FPM',
'pi-hole' => 'Pi-hole',
'powerdns' => 'PowerDNS',
'powerdns-dnsdist' => 'PowerDNS dnsdist',
'powerdns-recursor' => 'PowerDNS Recursor',
'sdfsinfo' => 'SDFS info',
'smart' => 'SMART',
'ups-apcups' => 'UPS apcups',
'ups-nut' => 'UPS nut',
'zfs' => 'ZFS',
];
// ---- Helper Functions ----
public function displayName()
{
return collect(self::$display_name)
->get($this->app_type, ucwords(str_replace(['_', '-'], ' ', $this->app_type)));
}
// ---- Query Scopes ----
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id');
}
}

101
app/Models/BaseModel.php Normal file
View File

@ -0,0 +1,101 @@
<?php
/**
* BaseModel.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Query\Builder;
abstract class BaseModel extends Model
{
/**
* Check if query is already joined with a table
*
* @param Builder $query
* @param string $table
* @return bool
*/
public static function isJoined($query, $table)
{
$joins = $query->getQuery()->joins;
if ($joins == null) {
return false;
}
foreach ($joins as $join) {
if ($join->table == $table) {
return true;
}
}
return false;
}
/**
* Helper function to determine if user has access based on device permissions
*
* @param Builder $query
* @param User $user
* @param string $table
* @return Builder
*/
protected function hasDeviceAccess($query, User $user, $table = null)
{
if ($user->hasGlobalRead()) {
return $query;
}
if (is_null($table)) {
$table = $this->getTable();
}
return $query->join('devices_perms', 'devices_perms.device_id', "$table.device_id")
->where('devices_perms.user_id', $user->user_id);
}
/**
* Helper function to determine if user has access based on port permissions
*
* @param Builder $query
* @param User $user
* @param string $table
* @return Builder
*/
protected function hasPortAccess($query, User $user, $table = null)
{
if ($user->hasGlobalRead()) {
return $query;
}
if (is_null($table)) {
$table = $this->getTable();
}
return $query->join('ports_perms', 'ports_perms.port_id', "$table.port_id")
->join('devices_perms', 'devices_perms.device_id', "$table.device_id")
->where(function ($query) use ($user) {
$query->where('ports_perms.user_id', $user->user_id)
->orWhere('devices_perms.user_id', $user->user_id);
});
}
}

58
app/Models/BgpPeer.php Normal file
View File

@ -0,0 +1,58 @@
<?php
/**
* BgpPeer.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
class BgpPeer extends BaseModel
{
public $timestamps = false;
protected $table = 'bgpPeers';
protected $primaryKey = 'bgpPeer_id';
// ---- Query scopes ----
public function scopeInAlarm(Builder $query)
{
return $query->where(function (Builder $query) {
$query->where('bgpPeerAdminStatus', 'start')
->orWhere('bgpPeerAdminStatus', 'running');
})->where('bgpPeerState', '!=', 'established');
}
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id');
}
}

View File

@ -0,0 +1,48 @@
<?php
/**
* CefSwitching.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
class CefSwitching extends BaseModel
{
public $timestamps = false;
protected $table = 'cef_switching';
protected $primaryKey = 'cef_switching_id';
// ---- Query Scopes ----
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id');
}
}

46
app/Models/Component.php Normal file
View File

@ -0,0 +1,46 @@
<?php
/**
* Component.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
class Component extends BaseModel
{
public $timestamps = false;
protected $table = 'component';
// ---- Query Scopes ----
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id');
}
}

76
app/Models/Config.php Normal file
View File

@ -0,0 +1,76 @@
<?php
/**
* Config.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
class Config extends BaseModel
{
public $timestamps = false;
protected $table = 'config';
public $primaryKey = 'config_name';
public $incrementing = false;
protected $fillable = [
'config_name',
'config_value',
'config_default',
'config_descr',
'config_group',
'config_sub_group',
];
protected $attributes = [
'config_default' => '',
'config_descr' => '',
'config_group' => '',
'config_sub_group' => '',
];
/**
* Get the config_value (type cast)
*
* @param string $value
* @return mixed
*/
public function getConfigValueAttribute($value)
{
if (filter_var($value, FILTER_VALIDATE_INT)) {
return (int)$value;
} elseif (filter_var($value, FILTER_VALIDATE_FLOAT)) {
return (float)$value;
} elseif (filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== null) {
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
}
return $value;
}
public function setConfigValueAttribute($value)
{
if (is_bool($value)) {
$this->attributes['config_value'] = $value ? 'true' : 'false';
} else {
$this->attributes['config_value'] = $value;
}
}
}

44
app/Models/Dashboard.php Normal file
View File

@ -0,0 +1,44 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class Dashboard extends Model
{
public $timestamps = false;
protected $primaryKey = 'dashboard_id';
protected $fillable = ['user_id', 'dashboard_name', 'access'];
// ---- Query scopes ----
/**
* @param Builder $query
* @param $user
* @return Builder|static
*/
public function scopeAllAvailable(Builder $query, $user)
{
return $query->where('user_id', $user->user_id)
->orWhere('access', '>', 0);
}
// ---- Define Reletionships ----
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function widgets()
{
return $this->hasMany('App\Models\UsersWidgets', 'dashboard_id');
}
}

238
app/Models/Device.php Normal file
View File

@ -0,0 +1,238 @@
<?php
namespace App\Models;
class Device extends BaseModel
{
public $timestamps = false;
protected $primaryKey = 'device_id';
protected $fillable = ['hostname', 'ip', 'status', 'status_reason'];
/**
* Initialize this class
*/
public static function boot()
{
parent::boot();
static::deleting(function (Device $device) {
// delete related data
$device->ports()->delete();
$device->syslogs()->delete();
$device->eventlogs()->delete();
});
}
// ---- Helper Functions ----
/**
* @return string
*/
public function logo()
{
$base_name = pathinfo($this->icon, PATHINFO_FILENAME);
$options = [
"images/logos/$base_name.svg",
"images/logos/$base_name.png",
"images/os/$base_name.svg",
"images/os/$base_name.png",
];
foreach ($options as $file) {
if (is_file(public_path()."/$file")) {
return asset($file);
}
}
return asset('images/os/generic.svg');
}
/**
* @return string
*/
public function statusColour()
{
$status = $this->status;
$ignore = $this->ignore;
$disabled = $this->disabled;
if ($disabled == 1) {
return 'teal';
} elseif ($ignore == 1) {
return 'yellow';
} elseif ($status == 0) {
return 'danger';
} else {
return 'success';
}
}
// ---- Accessors/Mutators ----
public function getIconAttribute($icon)
{
if (isset($icon)) {
return asset("images/os/$icon");
}
return asset('images/os/generic.svg');
}
public function getIpAttribute($ip)
{
if (empty($ip)) {
return null;
}
// @ suppresses warning, inet_ntop() returns false if it fails
return @inet_ntop($ip) ?: null;
}
public function setIpAttribute($ip)
{
$this->attributes['ip'] = inet_pton($ip);
}
// ---- Query scopes ----
public function scopeIsUp($query)
{
return $query->where([
['status', '=', 1],
['ignore', '=', 0],
['disabled', '=', 0]
]);
}
public function scopeIsActive($query)
{
return $query->where([
['ignore', '=', 0],
['disabled', '=', 0]
]);
}
public function scopeIsDown($query)
{
return $query->where([
['status', '=', 0],
['ignore', '=', 0],
['disabled', '=', 0]
]);
}
public function scopeIsIgnored($query)
{
return $query->where([
['ignore', '=', 1],
['disabled', '=', 0]
]);
}
public function scopeNotIgnored($query)
{
return $query->where([
['ignore', '=', 0]
]);
}
public function scopeIsDisabled($query)
{
return $query->where([
['disabled', '=', 1]
]);
}
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function alerts()
{
return $this->hasMany('App\Models\Alert', 'device_id');
}
public function applications()
{
return $this->hasMany('App\Models\Application', 'device_id');
}
public function bgppeers()
{
return $this->hasMany('App\Models\BgpPeer', 'device_id');
}
public function cefSwitching()
{
return $this->hasMany('App\Models\CefSwitching', 'device_id');
}
public function components()
{
return $this->hasMany('App\Models\Component', 'device_id');
}
public function eventlogs()
{
return $this->hasMany('App\Models\General\Eventlog', 'host', 'device_id');
}
public function groups()
{
return $this->belongsToMany('App\Models\DeviceGroup', 'device_group_device', 'device_id', 'device_group_id');
}
public function ospfInstances()
{
return $this->hasMany('App\Models\OspfInstance', 'device_id');
}
public function packages()
{
return $this->hasMany('App\Models\Package', 'device_id', 'device_id');
}
public function ports()
{
return $this->hasMany('App\Models\Port', 'device_id', 'device_id');
}
public function processors()
{
return $this->hasMany('App\Models\Processor', 'device_id');
}
public function rules()
{
return $this->belongsToMany('App\Models\AlertRule', 'alert_device_map', 'device_id', 'rule_id');
}
public function sensors()
{
return $this->hasMany('App\Models\Sensor', 'device_id');
}
public function services()
{
return $this->hasMany('App\Models\Service', 'device_id');
}
public function storage()
{
return $this->hasMany('App\Models\Storage', 'device_id');
}
public function syslogs()
{
return $this->hasMany('App\Models\General\Syslog', 'device_id', 'device_id');
}
public function users()
{
// FIXME does not include global read
return $this->belongsToMany('App\Models\User', 'devices_perms', 'device_id', 'user_id');
}
public function vrfs()
{
return $this->hasMany('App\Models\Vrf', 'device_id');
}
}

314
app/Models/DeviceGroup.php Normal file
View File

@ -0,0 +1,314 @@
<?php
/**
* DeviceGroup.php
*
* Dynamic groups of devices
*
* 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 2016 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
use App\Util;
use DB;
use Settings;
class DeviceGroup extends BaseModel
{
public $timestamps = false;
protected $appends = ['patternSql'];
protected $fillable = ['name', 'desc', 'pattern', 'params'];
protected $casts = ['params' => 'array'];
// ---- Helper Functions ----
public function updateRelations()
{
// we need an id to add relationships
if (is_null($this->id)) {
$this->save();
}
$device_ids = $this->getDeviceIdsRaw();
// update the relationships (deletes and adds as needed)
$this->devices()->sync($device_ids);
}
/**
* Get an array of the device ids from this group by re-querying the database with
* either the specified pattern or the saved pattern of this group
*
* @param string $statement Optional, will use the pattern from this group if not specified
* @param array $params array of paremeters
* @return array
*/
public function getDeviceIdsRaw($statement = null, $params = null)
{
if (is_null($statement)) {
$statement = $this->pattern;
}
if (is_null($params)) {
if (empty($this->params)) {
if (!starts_with($statement, '%')) {
// can't build sql
return [];
}
} else {
$params = $this->params;
}
}
$statement = $this->applyGroupMacros($statement);
$tables = $this->getTablesFromPattern($statement);
$query = null;
if (count($tables) == 1) {
$query = DB::table($tables[0])->select('device_id')->distinct();
} else {
$query = DB::table('devices')->select('devices.device_id')->distinct();
foreach ($tables as $table) {
// skip devices table, we used that as the base.
if ($table == 'devices') {
continue;
}
$query = $query->join($table, 'devices.device_id', '=', $table.'.device_id');
}
}
// match the device ids
if (is_null($params)) {
return $query->whereRaw($statement)->pluck('device_id')->toArray();
} else {
return $query->whereRaw($statement, $params)->pluck('device_id')->toArray();
}
}
/**
* Process Macros
*
* @param string $pattern Rule to process
* @param int $x Recursion-Anchor, do not pass
* @return string|boolean
*/
public static function applyGroupMacros($pattern, $x = 1)
{
if (!str_contains($pattern, 'macros.')) {
return $pattern;
}
foreach (Settings::get('alert.macros.group', []) as $macro => $value) {
$value = str_replace(['%', '&&', '||'], ['', 'AND', 'OR'], $value); // this might need something more complex
if (!str_contains($macro, ' ')) {
$pattern = str_replace('macros.'.$macro, '('.$value.')', $pattern);
}
}
if (str_contains($pattern, 'macros.')) {
if (++$x < 30) {
$pattern = self::applyGroupMacros($pattern, $x);
} else {
return false;
}
}
return $pattern;
}
/**
* Extract an array of tables in a pattern
*
* @param string $pattern
* @return array
*/
private function getTablesFromPattern($pattern)
{
preg_match_all('/[A-Za-z_]+(?=\.[A-Za-z_]+ )/', $pattern, $tables);
if (is_null($tables)) {
return [];
}
return array_keys(array_flip($tables[0])); // unique tables only
}
/**
* Convert a v1 device group pattern to sql that can be ingested by jQuery-QueryBuilder
*
* @param $pattern
* @return array
*/
private function convertV1Pattern($pattern)
{
$pattern = rtrim($pattern, ' &&');
$pattern = rtrim($pattern, ' ||');
$ops = ['=', '!=', '<', '<=', '>', '>='];
$parts = str_getcsv($pattern, ' '); // tokenize the pattern, respecting quoted parts
$out = "";
$count = count($parts);
for ($i = 0; $i < $count; $i++) {
$cur = $parts[$i];
if (starts_with($cur, '%')) {
// table and column or macro
$out .= substr($cur, 1).' ';
} elseif (substr($cur, -1) == '~') {
// like operator
$content = $parts[++$i]; // grab the content so we can format it
if (starts_with($cur, '!')) {
// prepend NOT
$out .= 'NOT ';
}
$out .= "LIKE('".$this->convertRegexToLike($content)."') ";
} elseif ($cur == '&&') {
$out .= 'AND ';
} elseif ($cur == '||') {
$out .= 'OR ';
} elseif (in_array($cur, $ops)) {
// pass-through operators
$out .= $cur.' ';
} else {
// user supplied input
$out .= "'".trim($cur, '"\'')."' "; // TODO: remove trim, only needed with invalid input
}
}
return rtrim($out);
}
/**
* Convert sql regex to like, many common uses can be converted
* Should only be used to convert v1 patterns
*
* @param $pattern
* @return string
*/
private function convertRegexToLike($pattern)
{
$startAnchor = starts_with($pattern, '^');
$endAnchor = ends_with($pattern, '$');
$pattern = trim($pattern, '^$');
$wildcards = ['@', '.*'];
if (str_contains($pattern, $wildcards)) {
// contains wildcard
$pattern = str_replace($wildcards, '%', $pattern);
}
// add ends appropriately
if ($startAnchor && !$endAnchor) {
$pattern .= '%';
} elseif (!$startAnchor && $endAnchor) {
$pattern = '%'.$pattern;
}
// if there are no wildcards, assume substring
if (!str_contains($pattern, '%')) {
$pattern = '%'.$pattern.'%';
}
return $pattern;
}
// ---- Accessors/Mutators ----
/**
* Returns an sql formatted string
* Mostly, this is for ingestion by JQuery-QueryBuilder
*
* @return string
*/
public function getPatternSqlAttribute()
{
$sql = $this->pattern;
// fill in parameters
foreach ((array)$this->params as $value) {
if (!is_numeric($value) && !starts_with($value, "'")) {
$value = "'".$value."'";
}
$sql = preg_replace('/\?/', $value, $sql, 1);
}
return $sql;
}
/**
* Custom mutator for params attribute
* Allows already encoded json to pass through
*
* @param array|string $params
*/
public function setParamsAttribute($params)
{
if (!Util::isJson($params)) {
$params = json_encode($params);
}
$this->attributes['params'] = $params;
}
/**
* Check if the stored pattern is v1
* Convert it to v2 for display
* Currently, it will only be updated in the database if the user saves the rule in the ui
*
* @param $pattern
* @return string
*/
public function getPatternAttribute($pattern)
{
// If this is a v1 pattern, convert it to sql
if (starts_with($pattern, '%')) {
return $this->convertV1Pattern($pattern);
}
return $pattern;
}
// ---- Query Scopes ----
public function scopeHasAccess($query, User $user)
{
if ($user->hasGlobalRead()) {
return $query;
}
if (!$this->isJoined($query, 'device_group_device')) {
$query->join('device_group_device', 'device_group_device.device_group_id', 'device_groups.id');
}
return $this->hasDeviceAccess($query, $user, 'device_group_device');
}
// ---- Define Relationships ----
public function rules()
{
return $this->belongsToMany('App\Models\AlertRule', 'alert_group_map', 'group_id', 'rule_id');
}
public function devices()
{
return $this->belongsToMany('App\Models\Device', 'device_group_device', 'device_group_id', 'device_id');
}
}

31
app/Models/GraphType.php Normal file
View File

@ -0,0 +1,31 @@
<?php
/**
* GraphTypes.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
class GraphType extends BaseModel
{
public $timestamps = false;
}

142
app/Models/Notification.php Normal file
View File

@ -0,0 +1,142 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class Notification extends Model
{
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'notifications';
/**
* The primary key column name.
*
* @var string
*/
protected $primaryKey = 'notifications_id';
// ---- Helper Functions ----
/**
* Mark this notification as read or unread
*
* @param bool $enabled
* @return bool
*/
public function markRead($enabled = true)
{
return $this->setAttrib('read', $enabled);
}
/**
* Mark this notification as sticky or unsticky
*
* @var bool $enabled
* @return bool
*/
public function markSticky($enabled = true)
{
return $this->setAttrib('sticky', $enabled);
}
/**
* @param $name
* @param $enabled
* @return bool
*/
private function setAttrib($name, $enabled)
{
if ($enabled === true) {
$read = new NotificationAttrib;
$read->user_id = \Auth::user()->user_id;
$read->key = $name;
$read->value = 1;
$this->attribs()->save($read);
return true;
} else {
return $this->attribs()->where('key', $name)->delete();
}
}
// ---- Query Scopes ----
/**
* @param Builder $query
* @return mixed
*/
public function scopeIsUnread(Builder $query, User $user)
{
return $query->whereNotExists(function ($query) use ($user) {
$query->select(DB::raw(1))
->from('notifications_attribs')
->whereRaw('notifications.notifications_id = notifications_attribs.notifications_id')
->where('notifications_attribs.user_id', $user->user_id);
});
}
/**
* Get all sticky notifications
*
* @param Builder $query
*/
public function scopeIsSticky(Builder $query)
{
$query->leftJoin('notifications_attribs', 'notifications_attribs.notifications_id', 'notifications.notifications_id')
->where(['notifications_attribs.key' => 'sticky', 'notifications_attribs.value' => 1]);
}
/**
* @param Builder $query
* @param User $user
* @return mixed
*/
public function scopeIsArchived(Builder $query, User $user)
{
return $query->leftJoin('notifications_attribs', 'notifications.notifications_id', '=', 'notifications_attribs.notifications_id')
->source()
->where('notifications_attribs.user_id', $user->user_id)
->where(['key' => 'read', 'value' => 1])
->limit();
}
/**
* @param Builder $query
* @return $this
*/
public function scopeLimit(Builder $query)
{
return $query->select('notifications.*', 'key', 'users.username');
}
/**
* @param Builder $query
* @return Builder|static
*/
public function scopeSource(Builder $query)
{
return $query->leftJoin('users', 'notifications.source', '=', 'users.user_id');
}
// ---- Define Relationships ----
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function attribs()
{
return $this->hasMany('App\Models\NotificationAttrib', 'notifications_id', 'notifications_id');
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class NotificationAttrib extends Model
{
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'notifications_attribs';
/**
* The primary key column name.
*
* @var string
*/
protected $primaryKey = 'attrib_id';
// ---- Define Relationships ----
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function notification()
{
return $this->belongsTo('App\Models\Notification', 'notifications_id');
}
}

View File

@ -0,0 +1,46 @@
<?php
/**
* OspfInstance.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
class OspfInstance extends BaseModel
{
public $timestamps = false;
protected $primaryKey = 'ospf_instance_id';
// ---- Query Scopes ----
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id');
}
}

46
app/Models/Package.php Normal file
View File

@ -0,0 +1,46 @@
<?php
/**
* Package.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
class Package extends BaseModel
{
public $timestamps = false;
protected $primaryKey = 'pkg_id';
// ---- Query Scopes ----
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->hasOne('App/Models/Device', 'device_id', 'device_id');
}
}

45
app/Models/Plugin.php Normal file
View File

@ -0,0 +1,45 @@
<?php
/**
* Plugin.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
class Plugin extends BaseModel
{
public $timestamps = false;
protected $primaryKey = 'plugin_id';
// ---- Query scopes ----
/**
* @param Builder $query
* @return Builder
*/
public function scopeIsActive($query)
{
return $query->where('plugin_active', 1);
}
}

127
app/Models/Port.php Normal file
View File

@ -0,0 +1,127 @@
<?php
namespace App\Models;
class Port extends BaseModel
{
public $timestamps = false;
protected $primaryKey = 'port_id';
// ---- Helper Functions ----
/**
* Returns a human readable label for this port
*
* @return string
*/
public function getLabel()
{
if ($this->ifName) {
return $this->ifName;
}
if ($this->ifDescr) {
return $this->ifDescr;
}
return $this->ifIndex;
}
// ---- Accessors/Mutators ----
public function getIfPhysAddressAttribute($mac)
{
if (!empty($mac)) {
return preg_replace('/(..)(..)(..)(..)(..)(..)/', '\\1:\\2:\\3:\\4:\\5:\\6', $mac);
}
return null;
}
// ---- Query scopes ----
public function scopeIsDeleted($query)
{
return $query->where([
['deleted', 1],
]);
}
public function scopeIsNotDeleted($query)
{
return $query->where([
['deleted', 0],
]);
}
public function scopeIsUp($query)
{
return $query->where([
['deleted', '=', 0],
['ignore', '=', 0],
['ifOperStatus', '=', 'up'],
]);
}
public function scopeIsDown($query)
{
return $query->where([
['deleted', '=', 0],
['ignore', '=', 0],
['ifOperStatus', '=', 'down'],
['ifAdminStatus', '=', 'up'],
]);
}
public function scopeIsIgnored($query)
{
return $query->where([
['deleted', '=', 0],
['ignore', '=', 1],
]);
}
public function scopeIsDisabled($query)
{
return $query->where([
['deleted', '=', 0],
['ignore', '=', 0],
['ifAdminStatus', '=', 'down'],
]);
}
public function scopeHasErrors($query)
{
return $query->where(function ($query) {
$query->where('ifInErrors_delta', '>', 0)
->orWhere('ifOutErrors_delta', '>', 0);
});
}
public function scopeHasAccess($query, User $user)
{
return $this->hasPortAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id', 'device_id');
}
public function users()
{
// FIXME does not include global read
return $this->belongsToMany('App\Models\User', 'ports_perms', 'port_id', 'user_id');
}
public function ipv4()
{
return $this->hasMany('App\Models\General\IPv4', 'port_id');
}
public function ipv6()
{
return $this->hasMany('App\Models\General\IPv6', 'port_id');
}
}

49
app/Models/Processor.php Normal file
View File

@ -0,0 +1,49 @@
<?php
namespace App\Models;
class Processor extends BaseModel
{
public $timestamps = false;
protected $primaryKey = 'processor_id';
// ---- Helper Functions ----
/**
* Return Processor Description, formatted for display
*
* @return string
*/
public function getFormattedDescription()
{
$bad_descr = array(
'GenuineIntel:',
'AuthenticAMD:',
'Intel(R)',
'CPU',
'(R)',
'(tm)',
);
$descr = str_replace($bad_descr, '', $this->processor_descr);
// reduce extra spaces
$descr = str_replace(' ', ' ', $descr);
return $descr;
}
// ---- Query Scopes ----
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id', 'device_id');
}
}

37
app/Models/Pseudowire.php Normal file
View File

@ -0,0 +1,37 @@
<?php
/**
* Pseudowire.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
class Pseudowire extends BaseModel
{
public $timestamps = false;
protected $primaryKey = 'pseudowire_id';
public function scopeHasAccess($query, User $user)
{
return $this->hasPortAccess($query, $user);
}
}

67
app/Models/Sensor.php Normal file
View File

@ -0,0 +1,67 @@
<?php
namespace App\Models;
class Sensor extends BaseModel
{
public $timestamps = false;
protected $primaryKey = 'sensors_id';
protected static $icons = array(
'fanspeed' => 'tachometer',
'humidity' => 'tint',
'temperature' => 'thermometer-full',
'current' => 'bolt',
'frequency' => 'line-chart',
'power' => 'power-off',
'voltage' => 'bolt',
'charge' => 'battery-half',
'dbm' => 'sun-o',
'load' => 'percent',
'runtime' => 'hourglass-half',
'state' => 'bullseye',
'signal' => 'wifi',
'snr' => 'signal',
'pressure' => 'thermometer-empty',
'cooling' => 'thermometer-full',
'airflow' => 'angle-double-right',
'delay' => 'clock-o',
'chromatic_dispersion' => 'indent',
'ber' => 'sort-amount-desc',
'quality_factor' => 'arrows',
'eer' => 'snowflake-o',
'waterflow' => 'tint',
);
// ---- Helper Functions ----
public function classDescr()
{
$nice = collect([
'ber' => 'BER',
'dbm' => 'dBm',
'eer' => 'EER',
'snr' => 'SNR',
]);
return $nice->get($this->sensor_class, ucwords(str_replace('_', ' ', $this->sensor_class)));
}
public function icon()
{
return collect(self::$icons)->get($this->sensor_class, 'heartbeat');
}
// ---- Query Scopes ----
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id');
}
}

23
app/Models/Service.php Normal file
View File

@ -0,0 +1,23 @@
<?php
namespace App\Models;
class Service extends BaseModel
{
public $timestamps = false;
protected $primaryKey = 'service_id';
// ---- Query Scopes ----
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id');
}
}

82
app/Models/User.php Normal file
View File

@ -0,0 +1,82 @@
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
protected $primaryKey = 'user_id';
protected $fillable = ['realname', 'username', 'email', 'level', 'descr', 'can_modify_passwd'];
protected $hidden = ['password', 'remember_token', 'pivot'];
// ---- Helper Functions ----
/**
* Test if this user has global read access
* these users have a level of 5, 10 or 11 (demo).
*
* @return boolean
*/
public function hasGlobalRead()
{
return $this->isAdmin() || $this->level == 5;
}
/**
* Test if the User is an admin or demo.
*
* @return boolean
*/
public function isAdmin()
{
return $this->level >= 10;
}
/**
* Check if this user has access to a device
*
* @param Device|int $device can be a device Model or device id
* @return bool
*/
public function canAccessDevice($device)
{
return $this->hasGlobalRead() || $this->devices->contains($device);
}
// ---- Define Relationships ----
public function devices()
{
if ($this->hasGlobalRead()) {
// $instance = $this->newRelatedInstance('App\Models\Device');
// return new HasAll($instance);
return Device::query();
} else {
return $this->belongsToMany('App\Models\Device', 'devices_perms', 'user_id', 'device_id');
}
}
public function ports()
{
if ($this->hasGlobalRead()) {
return Port::query();
} else {
//FIXME we should return all ports for a device if the user has been given access to the whole device.
return $this->belongsToMany('App\Models\Port', 'ports_perms', 'user_id', 'port_id');
}
}
public function dashboards()
{
return $this->hasMany('App\Models\Dashboard', 'user_id');
}
public function widgets()
{
return $this->hasMany('App\Models\UsersWidgets', 'user_id');
}
}

47
app/Models/Vrf.php Normal file
View File

@ -0,0 +1,47 @@
<?php
/**
* Vrf.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
class Vrf extends BaseModel
{
public $timestamps = false;
protected $table = 'vrfs';
protected $primaryKey = 'vrf_id';
// ---- Query Scopes ----
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id');
}
}

View File

@ -0,0 +1,62 @@
<?php
/**
* WirelessSensor.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Models;
class WirelessSensor extends BaseModel
{
public $timestamps = false;
protected $primaryKey = 'sensors_id';
// ---- Helper Functions ----
public function classDescr()
{
return collect(collect(\LibreNMS\Device\WirelessSensor::getTypes())
->get($this->sensor_class, []))
->get('short', ucwords(str_replace('_', ' ', $this->sensor_class)));
}
public function icon()
{
return collect(collect(\LibreNMS\Device\WirelessSensor::getTypes())
->get($this->sensor_class, []))
->get('icon', 'signal');
}
// ---- Query Scopes ----
public function scopeHasAccess($query, User $user)
{
return $this->hasDeviceAccess($query, $user);
}
// ---- Define Relationships ----
public function device()
{
return $this->belongsTo('App\Models\Device', 'device_id');
}
}

View File

@ -0,0 +1,83 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider;
use LibreNMS\Config;
use LibreNMS\Exceptions\DatabaseConnectException;
include_once __DIR__ . '/../../includes/dbFacile.php';
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
// connect legacy db
//FIXME this is for auth right now, remove later
try {
$db_config = config('database.connections')[config('database.default')];
dbConnect(
$db_config['host'],
$db_config['username'],
$db_config['password'],
$db_config['database'],
$db_config['port'],
$db_config['unix_socket']
);
} catch (DatabaseConnectException $e) {
// ignore failures here
}
// load config
Config::load();
// direct log output to librenms.log
Log::useFiles(Config::get('log_file', base_path('logs/librenms.log')));
// Blade directives (Yucky because of < L5.5)
Blade::directive('config', function ($key) {
return "<?php if (\LibreNMS\Config::get(($key))): ?>";
});
Blade::directive('notconfig', function ($key) {
return "<?php if (!\LibreNMS\Config::get(($key))): ?>";
});
Blade::directive('endconfig', function () {
return "<?php endif; ?>";
});
Blade::directive('admin', function () {
return "<?php if (auth()->check() && auth()->user()->isAdmin()): ?>";
});
Blade::directive('endadmin', function () {
return "<?php endif; ?>";
});
// Development service providers
if ($this->app->environment() !== 'production') {
if (class_exists(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class)) {
$this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);
}
if (config('app.debug') && class_exists(\Barryvdh\Debugbar\ServiceProvider::class)) {
$this->app->register(\Barryvdh\Debugbar\ServiceProvider::class);
}
}
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Providers;
use App\Extensions\LegacyUserProvider;
use Auth;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::provider('legacy', function ($app, array $config) {
return new LegacyUserProvider();
});
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Broadcast;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Broadcast::routes();
require base_path('routes/channels.php');
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* ComposerServiceProvider.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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* @return void
*/
public function boot()
{
View::composer('layouts.menu', 'App\Http\ViewComposers\MenuComposer');
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'App\Events\Event' => [
'App\Listeners\EventListener',
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
//
parent::boot();
}
/**
* Define the routes for the application.
*
* @return void
*/
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
//
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* @return void
*/
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}

51
artisan Normal file
View File

@ -0,0 +1,51 @@
#!/usr/bin/env php
<?php
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/
require __DIR__.'/bootstrap/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Artisan Application
|--------------------------------------------------------------------------
|
| When we run the console application, the current CLI command will be
| executed in this console and the response sent back to a terminal
| or another output device for the developers. Here goes nothing!
|
*/
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput,
new Symfony\Component\Console\Output\ConsoleOutput
);
/*
|--------------------------------------------------------------------------
| Shutdown The Application
|--------------------------------------------------------------------------
|
| Once Artisan has finished running, we will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
*/
$kernel->terminate($input, $status);
exit($status);

55
bootstrap/app.php Normal file
View File

@ -0,0 +1,55 @@
<?php
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
|--------------------------------------------------------------------------
|
| Next, we need to bind some important interfaces into the container so
| we will be able to resolve them when needed. The kernels serve the
| incoming requests to this application from both the web and CLI.
|
*/
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/
return $app;

23
bootstrap/autoload.php Normal file
View File

@ -0,0 +1,23 @@
<?php
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Composer Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so we do not have to manually load any of
| our application's PHP classes. It just feels great to relax.
|
*/
@include __DIR__ . '/../vendor/autoload.php';
if (!class_exists(\App\Checks::class)) {
require __DIR__ . '/../app/Checks.php';
}
\App\Checks::postAutoload();

2
bootstrap/cache/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -34,14 +34,25 @@
"symfony/yaml": "^2.8",
"rmccue/requests": "^1.7",
"palanik/corsslim": "^1.1",
"influxdb/influxdb-php": "^1.14"
"influxdb/influxdb-php": "^1.14",
"laravel/laravel": "5.4.*",
"oriceon/toastr-5-laravel": "dev-master",
"doctrine/inflector": "1.1.*",
"symfony/event-dispatcher": "3.*",
"symfony/css-selector": "3.*",
"doctrine/instantiator": "1.0.*",
"phpdocumentor/reflection-docblock": "3.*",
"phpunit/php-token-stream": "1.*"
},
"require-dev": {
"squizlabs/php_codesniffer": "^2.9.1",
"phpunit/phpunit": "5.*",
"jakub-onderka/php-parallel-lint": "*",
"jakub-onderka/php-console-highlighter": "*",
"fojuth/readmegen": "1.*"
"fojuth/readmegen": "1.*",
"barryvdh/laravel-ide-helper": "^2.4",
"barryvdh/laravel-debugbar": "~2.4"
},
"suggest": {
"ext-memcached": "Required if you utilize distributed polling",
@ -49,12 +60,26 @@
},
"autoload": {
"psr-4": {
"App\\": "app",
"LibreNMS\\": "LibreNMS",
"LibreNMS\\Tests\\": "tests"
}
},
"scripts": {
"pre-update-cmd": "LibreNMS\\ComposerHelper::preUpdate",
"pre-install-cmd": "LibreNMS\\ComposerHelper::preInstall"
"pre-install-cmd": "LibreNMS\\ComposerHelper::preInstall",
"post-root-package-install": "LibreNMS\\ComposerHelper::postRootPackageInstall",
"post-create-project-cmd": [
"php artisan key:generate"
],
"post-install-cmd": [
"LibreNMS\\ComposerHelper::postInstall",
"Illuminate\\Foundation\\ComposerScripts::postInstall",
"php artisan optimize"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"php artisan optimize"
]
}
}

3866
composer.lock generated

File diff suppressed because it is too large Load Diff

241
config/app.php Normal file
View File

@ -0,0 +1,241 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Application Name
|--------------------------------------------------------------------------
|
| This value is the name of your application. This value is used when the
| framework needs to place the application's name in a notification or
| any other location as required by the application or its packages.
*/
'name' => env('APP_NAME', 'LibreNMS'),
/*
|--------------------------------------------------------------------------
| Application Environment
|--------------------------------------------------------------------------
|
| This value determines the "environment" your application is currently
| running in. This may determine how you prefer to configure various
| services your application utilizes. Set this in your ".env" file.
|
*/
'env' => env('APP_ENV', 'production'),
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => env('APP_URL', 'http://localhost'),
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'UTC',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
'fallback_locale' => 'en',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
'key' => env('APP_KEY'),
'cipher' => 'AES-256-CBC',
/*
|--------------------------------------------------------------------------
| Logging Configuration
|--------------------------------------------------------------------------
|
| Here you may configure the log settings for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Settings: "single", "daily", "syslog", "errorlog"
|
*/
'log' => env('APP_LOG', 'errorlog'), // use error log until we are booted
'log_level' => env('APP_LOG_LEVEL', 'debug'),
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* Package Service Providers...
*/
Laravel\Tinker\TinkerServiceProvider::class,
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\ComposerServiceProvider::class,
/*
* Vendor Service Providers...
*/
Kamaln7\Toastr\ToastrServiceProvider::class,
],
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Notification' => Illuminate\Support\Facades\Notification::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'Debugbar' => Barryvdh\Debugbar\Facade::class,
'Toastr' => Kamaln7\Toastr\Facades\Toastr::class,
// LibreNMS
// 'LibreConfig' => \LibreNMS\Config::class,
],
];

101
config/auth.php Normal file
View File

@ -0,0 +1,101 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'legacy',
],
'api' => [
'driver' => 'token',
'provider' => 'legacy',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'legacy' => [
'driver' => 'legacy'
],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];

58
config/broadcasting.php Normal file
View File

@ -0,0 +1,58 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "pusher", "redis", "log", "null"
|
*/
'default' => env('BROADCAST_DRIVER', 'null'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over websockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
//
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];

91
config/cache.php Normal file
View File

@ -0,0 +1,91 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Cache Store
|--------------------------------------------------------------------------
|
| This option controls the default cache connection that gets used while
| using this caching library. This connection is used when another is
| not explicitly specified when executing a given caching function.
|
| Supported: "apc", "array", "database", "file", "memcached", "redis"
|
*/
'default' => env('CACHE_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Cache Stores
|--------------------------------------------------------------------------
|
| Here you may define all of the cache "stores" for your application as
| well as their drivers. You may even define multiple stores for the
| same cache driver to group types of items stored in your caches.
|
*/
'stores' => [
'apc' => [
'driver' => 'apc',
],
'array' => [
'driver' => 'array',
],
'database' => [
'driver' => 'database',
'table' => 'cache',
'connection' => null,
],
'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache/data'),
],
'memcached' => [
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
],
/*
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
|
*/
'prefix' => 'laravel',
];

124
config/database.php Normal file
View File

@ -0,0 +1,124 @@
<?php
use LibreNMS\Config;
$fallback_db_config = Config::getDatabaseSettings();
return [
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
// 'sqlite' => [
// 'driver' => 'sqlite',
// 'database' => env('DB_DATABASE', database_path('database.sqlite')),
// 'prefix' => '',
// ],
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', $fallback_db_config['db_host']),
'port' => env('DB_PORT', $fallback_db_config['db_port']),
'database' => env('DB_DATABASE', $fallback_db_config['db_name']),
'username' => env('DB_USERNAME', $fallback_db_config['db_user']),
'password' => env('DB_PASSWORD', $fallback_db_config['db_pass']),
'unix_socket' => env('DB_SOCKET', $fallback_db_config['db_socket']),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
];

192
config/debugbar.php Normal file
View File

@ -0,0 +1,192 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Debugbar Settings
|--------------------------------------------------------------------------
|
| Debugbar is enabled by default, when debug is set to true in app.php.
| You can override the value by setting enable to true or false instead of null.
|
*/
'enabled' => env('DEBUGBAR_ENABLED', null),
/*
|--------------------------------------------------------------------------
| Storage settings
|--------------------------------------------------------------------------
|
| DebugBar stores data for session/ajax requests.
| You can disable this, so the debugbar stores data in headers/session,
| but this can cause problems with large data collectors.
| By default, file storage (in the storage folder) is used. Redis and PDO
| can also be used. For PDO, run the package migrations first.
|
*/
'storage' => [
'enabled' => true,
'driver' => 'file', // redis, file, pdo, custom
'path' => storage_path('debugbar'), // For file driver
'connection' => null, // Leave null for default connection (Redis/PDO)
'provider' => '' // Instance of StorageInterface for custom driver
],
/*
|--------------------------------------------------------------------------
| Vendors
|--------------------------------------------------------------------------
|
| Vendor files are included by default, but can be set to false.
| This can also be set to 'js' or 'css', to only include javascript or css vendor files.
| Vendor files are for css: font-awesome (including fonts) and highlight.js (css files)
| and for js: jquery and and highlight.js
| So if you want syntax highlighting, set it to true.
| jQuery is set to not conflict with existing jQuery scripts.
|
*/
'include_vendors' => true,
/*
|--------------------------------------------------------------------------
| Capture Ajax Requests
|--------------------------------------------------------------------------
|
| The Debugbar can capture Ajax requests and display them. If you don't want this (ie. because of errors),
| you can use this option to disable sending the data through the headers.
|
| Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools.
*/
'capture_ajax' => true,
'add_ajax_timing' => false,
/*
|--------------------------------------------------------------------------
| Custom Error Handler for Deprecated warnings
|--------------------------------------------------------------------------
|
| When enabled, the Debugbar shows deprecated warnings for Symfony components
| in the Messages tab.
|
*/
'error_handler' => false,
/*
|--------------------------------------------------------------------------
| Clockwork integration
|--------------------------------------------------------------------------
|
| The Debugbar can emulate the Clockwork headers, so you can use the Chrome
| Extension, without the server-side code. It uses Debugbar collectors instead.
|
*/
'clockwork' => false,
/*
|--------------------------------------------------------------------------
| DataCollectors
|--------------------------------------------------------------------------
|
| Enable/disable DataCollectors
|
*/
'collectors' => [
'phpinfo' => true, // Php version
'messages' => true, // Messages
'time' => true, // Time Datalogger
'memory' => true, // Memory usage
'exceptions' => true, // Exception displayer
'log' => true, // Logs from Monolog (merged in messages if enabled)
'db' => true, // Show database (PDO) queries and bindings
'views' => true, // Views with their data
'route' => true, // Current route information
'auth' => true, // Display Laravel authentication status
'gate' => true, // Display Laravel Gate checks
'session' => true, // Display session data
'symfony_request' => true, // Only one can be enabled..
'mail' => true, // Catch mail messages
'laravel' => false, // Laravel version and environment
'events' => false, // All events fired
'default_request' => false, // Regular or special Symfony request logger
'logs' => false, // Add the latest log messages
'files' => false, // Show the included files
'config' => false, // Display config settings
],
/*
|--------------------------------------------------------------------------
| Extra options
|--------------------------------------------------------------------------
|
| Configure some DataCollectors
|
*/
'options' => [
'auth' => [
'show_name' => true, // Also show the users name/email in the debugbar
],
'db' => [
'with_params' => true, // Render SQL with the parameters substituted
'backtrace' => true, // Use a backtrace to find the origin of the query in your files.
'timeline' => false, // Add the queries to the timeline
'explain' => [ // Show EXPLAIN output on queries
'enabled' => false,
'types' => ['SELECT'], // ['SELECT', 'INSERT', 'UPDATE', 'DELETE']; for MySQL 5.6.3+
],
'hints' => true, // Show hints for common mistakes
],
'mail' => [
'full_log' => false
],
'views' => [
'data' => false, //Note: Can slow down the application, because the data can be quite large..
],
'route' => [
'label' => true // show complete route on bar
],
'logs' => [
'file' => null
],
],
/*
|--------------------------------------------------------------------------
| Inject Debugbar in Response
|--------------------------------------------------------------------------
|
| Usually, the debugbar is added just before </body>, by listening to the
| Response after the App is done. If you disable this, you have to add them
| in your template yourself. See http://phpdebugbar.com/docs/rendering.html
|
*/
'inject' => true,
/*
|--------------------------------------------------------------------------
| DebugBar route prefix
|--------------------------------------------------------------------------
|
| Sometimes you want to set route prefix to be used by DebugBar to load
| its resources from. Usually the need comes from misconfigured web server or
| from trying to overcome bugs like this: http://trac.nginx.org/nginx/ticket/97
|
*/
'route_prefix' => '_debugbar',
/*
|--------------------------------------------------------------------------
| DebugBar route domain
|--------------------------------------------------------------------------
|
| By default DebugBar route served from the same domain that request served.
| To override default domain, specify it as a non-empty value.
*/
'route_domain' => null,
];

68
config/filesystems.php Normal file
View File

@ -0,0 +1,68 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| Here you may specify the default filesystem disk that should be used
| by the framework. The "local" disk, as well as a variety of cloud
| based disks are available to your application. Just store away!
|
*/
'default' => env('FILESYSTEM_DRIVER', 'local'),
/*
|--------------------------------------------------------------------------
| Default Cloud Filesystem Disk
|--------------------------------------------------------------------------
|
| Many applications store files both locally and in the cloud. For this
| reason, you may specify a default "cloud" driver here. This driver
| will be bound as the Cloud disk implementation in the container.
|
*/
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "s3", "rackspace"
|
*/
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_KEY'),
'secret' => env('AWS_SECRET'),
'region' => env('AWS_REGION'),
'bucket' => env('AWS_BUCKET'),
],
],
];

27
config/librenms.php Normal file
View File

@ -0,0 +1,27 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| User
|--------------------------------------------------------------------------
|
| This value is the user LibreNMS runs as. It is used to secure permissions
| and grant access to things needed. Defaults to librenms.
*/
'user' => env('LIBRENMS_USER', 'librenms'),
/*
|--------------------------------------------------------------------------
| User
|--------------------------------------------------------------------------
|
| This value is the group LibreNMS runs as. It is used to secure permissions
| and grant access to things needed. Defaults to the same as LIBRENMS_USER.
*/
'group' => env('LIBRENMS_GROUP', env('LIBRENMS_USER', 'librenms')),
];

123
config/mail.php Normal file
View File

@ -0,0 +1,123 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "sendmail", "mailgun", "mandrill", "ses",
| "sparkpost", "log", "array"
|
*/
'driver' => env('MAIL_DRIVER', 'smtp'),
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Mailgun mail service which will provide reliable deliveries.
|
*/
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to deliver e-mails to
| users of the application. Like the host we have set this value to
| stay compatible with the Mailgun e-mail application by default.
|
*/
'port' => env('MAIL_PORT', 587),
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Markdown Mail Settings
|--------------------------------------------------------------------------
|
| If you are using Markdown based email rendering, you may configure your
| theme and component paths here, allowing you to customize the design
| of the emails. Or, you may simply stick with the Laravel defaults!
|
*/
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
];

85
config/queue.php Normal file
View File

@ -0,0 +1,85 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Queue Driver
|--------------------------------------------------------------------------
|
| Laravel's queue API supports an assortment of back-ends via a single
| API, giving you convenient access to each back-end using the same
| syntax for each one. Here you may set the default queue driver.
|
| Supported: "sync", "database", "beanstalkd", "sqs", "redis", "null"
|
*/
'default' => env('QUEUE_DRIVER', 'sync'),
/*
|--------------------------------------------------------------------------
| Queue Connections
|--------------------------------------------------------------------------
|
| Here you may configure the connection information for each server that
| is used by your application. A default configuration has been added
| for each back-end shipped with Laravel. You are free to add more.
|
*/
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
],
'beanstalkd' => [
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
],
'sqs' => [
'driver' => 'sqs',
'key' => 'your-public-key',
'secret' => 'your-secret-key',
'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id',
'queue' => 'your-queue-name',
'region' => 'us-east-1',
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => 'default',
'retry_after' => 90,
],
],
/*
|--------------------------------------------------------------------------
| Failed Queue Jobs
|--------------------------------------------------------------------------
|
| These options configure the behavior of failed queue job logging so you
| can control which database and table are used to store the jobs that
| have failed. You may change them to any database / table you wish.
|
*/
'failed' => [
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],
];

38
config/services.php Normal file
View File

@ -0,0 +1,38 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Third Party Services
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Stripe, Mailgun, SparkPost and others. This file provides a sane
| default location for this type of information, allowing packages
| to have a conventional place to find your various credentials.
|
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
],
'ses' => [
'key' => env('SES_KEY'),
'secret' => env('SES_SECRET'),
'region' => 'us-east-1',
],
'sparkpost' => [
'secret' => env('SPARKPOST_SECRET'),
],
'stripe' => [
'model' => App\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
];

179
config/session.php Normal file
View File

@ -0,0 +1,179 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Session Driver
|--------------------------------------------------------------------------
|
| This option controls the default session "driver" that will be used on
| requests. By default, we will use the lightweight native driver but
| you may specify any of the other wonderful drivers provided here.
|
| Supported: "file", "cookie", "database", "apc",
| "memcached", "redis", "array"
|
*/
'driver' => env('SESSION_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
'lifetime' => 120,
'expire_on_close' => false,
/*
|--------------------------------------------------------------------------
| Session Encryption
|--------------------------------------------------------------------------
|
| This option allows you to easily specify that all of your session data
| should be encrypted before it is stored. All encryption will be run
| automatically by Laravel and you can use the Session like normal.
|
*/
'encrypt' => false,
/*
|--------------------------------------------------------------------------
| Session File Location
|--------------------------------------------------------------------------
|
| When using the native session driver, we need a location where session
| files may be stored. A default has been set for you but a different
| location may be specified. This is only needed for file sessions.
|
*/
'files' => storage_path('framework/sessions'),
/*
|--------------------------------------------------------------------------
| Session Database Connection
|--------------------------------------------------------------------------
|
| When using the "database" or "redis" session drivers, you may specify a
| connection that should be used to manage these sessions. This should
| correspond to a connection in your database configuration options.
|
*/
'connection' => null,
/*
|--------------------------------------------------------------------------
| Session Database Table
|--------------------------------------------------------------------------
|
| When using the "database" session driver, you may specify the table we
| should use to manage the sessions. Of course, a sensible default is
| provided for you; however, you are free to change this as needed.
|
*/
'table' => 'sessions',
/*
|--------------------------------------------------------------------------
| Session Cache Store
|--------------------------------------------------------------------------
|
| When using the "apc" or "memcached" session drivers, you may specify a
| cache store that should be used for these sessions. This value must
| correspond with one of the application's configured cache stores.
|
*/
'store' => null,
/*
|--------------------------------------------------------------------------
| Session Sweeping Lottery
|--------------------------------------------------------------------------
|
| Some session drivers must manually sweep their storage location to get
| rid of old sessions from storage. Here are the chances that it will
| happen on a given request. By default, the odds are 2 out of 100.
|
*/
'lottery' => [2, 100],
/*
|--------------------------------------------------------------------------
| Session Cookie Name
|--------------------------------------------------------------------------
|
| Here you may change the name of the cookie used to identify a session
| instance by ID. The name specified here will get used every time a
| new session cookie is created by the framework for every driver.
|
*/
'cookie' => 'librenms_session',
/*
|--------------------------------------------------------------------------
| Session Cookie Path
|--------------------------------------------------------------------------
|
| The session cookie path determines the path for which the cookie will
| be regarded as available. Typically, this will be the root path of
| your application but you are free to change this when necessary.
|
*/
'path' => '/',
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => env('SESSION_DOMAIN', null),
/*
|--------------------------------------------------------------------------
| HTTPS Only Cookies
|--------------------------------------------------------------------------
|
| By setting this option to true, session cookies will only be sent back
| to the server if the browser has a HTTPS connection. This will keep
| the cookie from being sent to you if it can not be done securely.
|
*/
'secure' => env('SESSION_SECURE_COOKIE', false),
/*
|--------------------------------------------------------------------------
| HTTP Access Only
|--------------------------------------------------------------------------
|
| Setting this value to true will prevent JavaScript from accessing the
| value of the cookie and the cookie will only be accessible through
| the HTTP protocol. You are free to modify this option if needed.
|
*/
'http_only' => true,
];

5
config/toastr.php Normal file
View File

@ -0,0 +1,5 @@
<?php
return [
'options' => []
];

33
config/view.php Normal file
View File

@ -0,0 +1,33 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| View Storage Paths
|--------------------------------------------------------------------------
|
| Most templating systems load templates from disk. Here you may specify
| an array of paths that should be checked for your views. Of course
| the usual Laravel view path has already been registered for you.
|
*/
'paths' => [
resource_path('views'),
],
/*
|--------------------------------------------------------------------------
| Compiled View Path
|--------------------------------------------------------------------------
|
| This option determines where all the compiled Blade templates will be
| stored for your application. Typically, this is within the storage
| directory. However, as usual, you are free to change this value.
|
*/
'compiled' => realpath(storage_path('framework/views')),
];

View File

@ -0,0 +1,24 @@
<?php
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| Here you may define all of your model factories. Model factories give
| you a convenient way to create models for testing and seeding your
| database. Just tell the factory how a default model should look.
|
*/
/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(App\User::class, function (Faker\Generator $faker) {
static $password;
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'password' => $password ?: $password = bcrypt('secret'),
'remember_token' => str_random(10),
];
});

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePasswordResetsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('password_resets');
}
}

View File

@ -0,0 +1,16 @@
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// $this->call(UsersTableSeeder::class);
}
}

View File

@ -9,7 +9,7 @@ source: Installation/Installation-CentOS-7-Apache.md
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
yum install composer cronie fping git httpd ImageMagick jwhois mariadb mariadb-server mtr MySQL-python net-snmp net-snmp-utils nmap php72w php72w-cli php72w-common php72w-curl php72w-gd php72w-mysqlnd php72w-process php72w-snmp php72w-xml php72w-zip python-memcached rrdtool
yum install composer cronie fping git httpd ImageMagick jwhois mariadb mariadb-server mtr MySQL-python net-snmp net-snmp-utils nmap php72w php72w-cli php72w-common php72w-curl php72w-gd php72w-mbstring php72w-mysqlnd php72w-process php72w-snmp php72w-xml php72w-zip python-memcached rrdtool
#### Add librenms user
@ -99,6 +99,12 @@ Install the policy tool for SELinux:
semanage fcontext -a -t httpd_sys_content_t '/opt/librenms/rrd(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/opt/librenms/rrd(/.*)?'
restorecon -RFvv /opt/librenms/rrd/
semanage fcontext -a -t httpd_sys_content_t '/opt/librenms/storage(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/opt/librenms/storage(/.*)?'
restorecon -RFvv /opt/librenms/storage/
semanage fcontext -a -t httpd_sys_content_t '/opt/librenms/bootstrap/cache(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/opt/librenms/bootstrap/cache(/.*)?'
restorecon -RFvv /opt/librenms/bootstrap/cache/
setsebool -P httpd_can_sendmail=1
##### Allow fping
@ -156,8 +162,8 @@ LibreNMS keeps logs in `/opt/librenms/logs`. Over time these can become large an
### Set permissions
chown -R librenms:librenms /opt/librenms
setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs
setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs
setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
## Web installer ##

View File

@ -9,14 +9,14 @@ source: Installation/Installation-CentOS-7-Nginx.md
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
yum install composer cronie fping git ImageMagick jwhois mariadb mariadb-server mtr MySQL-python net-snmp net-snmp-utils nginx nmap php72w php72w-cli php72w-common php72w-curl php72w-fpm php72w-gd php72w-mysqlnd php72w-process php72w-snmp php72w-xml php72w-zip python-memcached rrdtool
yum install composer cronie fping git ImageMagick jwhois mariadb mariadb-server mtr MySQL-python net-snmp net-snmp-utils nginx nmap php72w php72w-cli php72w-common php72w-curl php72w-fpm php72w-gd php72w-mbstring php72w-mysqlnd php72w-process php72w-snmp php72w-xml php72w-zip python-memcached rrdtool
#### Add librenms user
useradd librenms -d /opt/librenms -M -r
usermod -a -G librenms nginx
#### Install LibreNMS
#### Download LibreNMS
cd /opt
composer create-project --no-dev --keep-vcs librenms/librenms librenms dev-master
@ -133,6 +133,12 @@ Install the policy tool for SELinux:
semanage fcontext -a -t httpd_sys_content_t '/opt/librenms/rrd(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/opt/librenms/rrd(/.*)?'
restorecon -RFvv /opt/librenms/rrd/
semanage fcontext -a -t httpd_sys_content_t '/opt/librenms/storage(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/opt/librenms/storage(/.*)?'
restorecon -RFvv /opt/librenms/storage/
semanage fcontext -a -t httpd_sys_content_t '/opt/librenms/bootstrap/cache(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/opt/librenms/bootstrap/cache(/.*)?'
restorecon -RFvv /opt/librenms/bootstrap/cache/
setsebool -P httpd_can_sendmail=1
setsebool -P httpd_execmem 1
@ -191,8 +197,8 @@ LibreNMS keeps logs in `/opt/librenms/logs`. Over time these can become large an
### Set permissions
chown -R librenms:librenms /opt/librenms
setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs
setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs
setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
## Web installer ##

View File

@ -5,7 +5,7 @@ source: Installation/Installation-Ubuntu-1604-Apache.md
## Install Required Packages ##
apt install apache2 composer fping git graphviz imagemagick libapache2-mod-php7.0 mariadb-client mariadb-server mtr-tiny nmap php7.0-cli php7.0-curl php7.0-gd php7.0-json php7.0-mcrypt php7.0-mysql php7.0-snmp php7.0-xml php7.0-zip python-memcache python-mysqldb rrdtool snmp snmpd whois
apt install apache2 composer fping git graphviz imagemagick libapache2-mod-php7.0 mariadb-client mariadb-server mtr-tiny nmap php7.0-cli php7.0-curl php7.0-gd php7.0-json php7.0-mbstring php7.0-mcrypt php7.0-mysql php7.0-snmp php7.0-xml php7.0-zip python-memcache python-mysqldb rrdtool snmp snmpd whois
#### Add librenms user
@ -111,8 +111,8 @@ LibreNMS keeps logs in `/opt/librenms/logs`. Over time these can become large an
### Set permissions
chown -R librenms:librenms /opt/librenms
setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs
setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs
setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
## Web installer ##

View File

@ -5,7 +5,7 @@ source: Installation/Installation-Ubuntu-1604-Nginx.md
## Install Required Packages ##
apt install composer fping git graphviz imagemagick mariadb-client mariadb-server mtr-tiny nginx-full nmap php7.0-cli php7.0-curl php7.0-fpm php7.0-gd php7.0-mcrypt php7.0-mysql php7.0-snmp php7.0-xml php7.0-zip python-memcache python-mysqldb rrdtool snmp snmpd whois
apt install composer fping git graphviz imagemagick mariadb-client mariadb-server mtr-tiny nginx-full nmap php7.0-cli php7.0-curl php7.0-fpm php7.0-gd php7.0-mbstring php7.0-mcrypt php7.0-mysql php7.0-snmp php7.0-xml php7.0-zip python-memcache python-mysqldb rrdtool snmp snmpd whois
#### Add librenms user
@ -116,8 +116,8 @@ LibreNMS keeps logs in `/opt/librenms/logs`. Over time these can become large an
### Set permissions
chown -R librenms:librenms /opt/librenms
setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs
setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs
setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
## Web installer ##

View File

@ -1,15 +0,0 @@
<?php
session_start();
if (isset($_REQUEST['width'], $_REQUEST['height'])) {
if (is_numeric($_REQUEST['height']) && is_numeric($_REQUEST['width'])) {
$_SESSION['screen_width'] = $_REQUEST['width'];
$_SESSION['screen_height'] = $_REQUEST['height'];
}
}
session_write_close();
header('Content-type: text/plain');
echo $_SESSION['screen_width'] . 'x' . $_SESSION['screen_height'];

View File

@ -1,225 +0,0 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
*
* 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. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
$init_modules = array('web', 'alerts');
require realpath(__DIR__ . '/..') . '/includes/init.php';
use LibreNMS\Config;
$app = new \Slim\Slim();
if (Config::get('api.cors.enabled') === true) {
$corsOptions = array(
"origin" => Config::get('api.cors.origin'),
"maxAge" => Config::get('api.cors.maxage'),
"allowMethods" => Config::get('api.cors.allowmethods'),
"allowHeaders" => Config::get('api.cors.allowheaders'),
);
$cors = new \CorsSlim\CorsSlim($corsOptions);
$app->add($cors);
}
require $config['install_dir'] . '/html/includes/api_functions.inc.php';
$app->setName('api');
$app->notFound(function () use ($app) {
api_error(404, "This API route doesn't exist.");
});
$app->group(
'/api',
function () use ($app) {
$app->group(
'/v0',
function () use ($app) {
$app->get('/bgp', 'authToken', 'list_bgp')->name('list_bgp');
$app->get('/bgp/:id', 'authToken', 'get_bgp')->name('get_bgp');
$app->get('/ospf', 'authToken', 'list_ospf')->name('list_ospf');
// api/v0/bgp
$app->get('/oxidized(/:hostname)', 'authToken', 'list_oxidized')->name('list_oxidized');
$app->group(
'/devices',
function () use ($app) {
$app->delete('/:hostname', 'authToken', 'del_device')->name('del_device');
// api/v0/devices/$hostname
$app->get('/:hostname', 'authToken', 'get_device')->name('get_device');
// api/v0/devices/$hostname
$app->patch('/:hostname', 'authToken', 'update_device')->name('update_device_field');
$app->patch('/:hostname/rename/:new_hostname', 'authToken', 'rename_device')->name('rename_device');
$app->get('/:hostname/vlans', 'authToken', 'get_vlans')->name('get_vlans');
// api/v0/devices/$hostname/vlans
$app->get('/:hostname/graphs', 'authToken', 'get_graphs')->name('get_graphs');
// api/v0/devices/$hostname/graphs
$app->get('/:hostname/health(/:type)(/:sensor_id)', 'authToken', 'list_available_health_graphs')->name('list_available_health_graphs');
$app->get('/:hostname/wireless(/:type)(/:sensor_id)', 'authToken', 'list_available_wireless_graphs')->name('list_available_wireless_graphs');
$app->get('/:hostname/ports', 'authToken', 'get_port_graphs')->name('get_port_graphs');
$app->get('/:hostname/ip', 'authToken', 'get_ip_addresses')->name('get_device_ip_addresses');
$app->get('/:hostname/port_stack', 'authToken', 'get_port_stack')->name('get_port_stack');
// api/v0/devices/$hostname/ports
$app->get('/:hostname/components', 'authToken', 'get_components')->name('get_components');
$app->post('/:hostname/components/:type', 'authToken', 'add_components')->name('add_components');
$app->put('/:hostname/components', 'authToken', 'edit_components')->name('edit_components');
$app->delete('/:hostname/components/:component', 'authToken', 'delete_components')->name('delete_components');
$app->get('/:hostname/groups', 'authToken', 'get_device_groups')->name('get_device_groups');
$app->get('/:hostname/graphs/health/:type(/:sensor_id)', 'authToken', 'get_graph_generic_by_hostname')->name('get_health_graph');
$app->get('/:hostname/graphs/wireless/:type(/:sensor_id)', 'authToken', 'get_graph_generic_by_hostname')->name('get_wireless_graph');
$app->get('/:hostname/:type', 'authToken', 'get_graph_generic_by_hostname')->name('get_graph_generic_by_hostname');
// api/v0/devices/$hostname/$type
$app->get('/:hostname/ports/:ifname', 'authToken', 'get_port_stats_by_port_hostname')->name('get_port_stats_by_port_hostname');
// api/v0/devices/$hostname/ports/$ifName
$app->get('/:hostname/ports/:ifname/:type', 'authToken', 'get_graph_by_port_hostname')->name('get_graph_by_port_hostname');
// api/v0/devices/$hostname/ports/$ifName/$type
}
);
$app->get('/devices', 'authToken', 'list_devices')->name('list_devices');
// api/v0/devices
$app->post('/devices', 'authToken', 'add_device')->name('add_device');
// api/v0/devices (json data needs to be passed)
$app->group(
'/devicegroups',
function () use ($app) {
$app->get('/:name', 'authToken', 'get_devices_by_group')->name('get_devices_by_group');
}
);
$app->get('/devicegroups', 'authToken', 'get_device_groups')->name('get_devicegroups');
$app->group(
'/ports',
function () use ($app) {
$app->get('/:portid', 'authToken', 'get_port_info')->name('get_port_info');
$app->get('/:portid/ip', 'authToken', 'get_ip_addresses')->name('get_port_ip_info');
}
);
$app->get('/ports', 'authToken', 'get_all_ports')->name('get_all_ports');
$app->group(
'/portgroups',
function () use ($app) {
$app->get('/multiport/bits/:id', 'authToken', 'get_graph_by_portgroup')->name('get_graph_by_portgroup_multiport_bits');
$app->get('/:group', 'authToken', 'get_graph_by_portgroup')->name('get_graph_by_portgroup');
}
);
$app->group(
'/bills',
function () use ($app) {
$app->get('/:bill_id', 'authToken', 'list_bills')->name('get_bill');
$app->delete('/:id', 'authToken', 'delete_bill')->name('delete_bill');
// api/v0/bills/$bill_id
$app->get('/:bill_id/graphs/:graph_type', 'authToken', 'get_bill_graph')->name('get_bill_graph');
$app->get('/:bill_id/graphdata/:graph_type', 'authToken', 'get_bill_graphdata')->name('get_bill_graphdata');
$app->get('/:bill_id/history', 'authToken', 'get_bill_history')->name('get_bill_history');
$app->get('/:bill_id/history/:bill_hist_id/graphs/:graph_type', 'authToken', 'get_bill_history_graph')->name('get_bill_history_graph');
$app->get('/:bill_id/history/:bill_hist_id/graphdata/:graph_type', 'authToken', 'get_bill_history_graphdata')->name('get_bill_history_graphdata');
}
);
$app->get('/bills', 'authToken', 'list_bills')->name('list_bills');
$app->post('/bills', 'authToken', 'create_edit_bill')->name('create_bill');
// api/v0/bills
// /api/v0/alerts
$app->group(
'/alerts',
function () use ($app) {
$app->get('/:id', 'authToken', 'list_alerts')->name('get_alert');
// api/v0/alerts
$app->put('/:id', 'authToken', 'ack_alert')->name('ack_alert');
// api/v0/alerts/$id (PUT)
$app->put('/unmute/:id', 'authToken', 'unmute_alert')->name('unmute_alert');
// api/v0/alerts/unmute/$id (PUT)
}
);
$app->get('/alerts', 'authToken', 'list_alerts')->name('list_alerts');
// api/v0/alerts
// /api/v0/rules
$app->group(
'/rules',
function () use ($app) {
$app->get('/:id', 'authToken', 'list_alert_rules')->name('get_alert_rule');
// api/v0/rules/$id
$app->delete('/:id', 'authToken', 'delete_rule')->name('delete_rule');
// api/v0/rules/$id (DELETE)
}
);
$app->get('/rules', 'authToken', 'list_alert_rules')->name('list_alert_rules');
// api/v0/rules
$app->post('/rules', 'authToken', 'add_edit_rule')->name('add_rule');
// api/v0/rules (json data needs to be passed)
$app->put('/rules', 'authToken', 'add_edit_rule')->name('edit_rule');
// api/v0/rules (json data needs to be passed)
// Inventory section
$app->group(
'/inventory',
function () use ($app) {
$app->get('/:hostname', 'authToken', 'get_inventory')->name('get_inventory');
}
);
// End Inventory
// Routing section
$app->group(
'/routing',
function () use ($app) {
$app->get('/bgp/cbgp', 'authToken', 'list_cbgp')->name('list_cbgp');
$app->get('/vrf', 'authToken', 'list_vrf')->name('list_vrf');
$app->get('/vrf/:id', 'authToken', 'get_vrf')->name('get_vrf');
$app->group(
'/ipsec',
function () use ($app) {
$app->get('/data/:hostname', 'authToken', 'list_ipsec')->name('list_ipsec');
}
);
}
);
// End Routing
// Resources section
$app->group(
'/resources',
function () use ($app) {
$app->get('/locations', 'authToken', 'list_locations')->name('list_locations');
$app->get('/vlans', 'authToken', 'list_vlans')->name('list_vlans');
$app->group(
'/ip',
function () use ($app) {
$app->get('/addresses/', 'authToken', 'list_ip_addresses')->name('list_ip_addresses');
$app->get('/arp/:ip', 'authToken', 'list_arp')->name('list_arp')->conditions(array('ip' => '[^?]+'));
$app->get('/networks/', 'authToken', 'list_ip_networks')->name('list_ip_networks');
$app->get('/networks/:id/ip', 'authToken', 'get_ip_addresses')->name('get_network_ip_addresses');
}
);
}
);
// End Resources
// Service section
$app->group(
'/services',
function () use ($app) {
$app->get('/:hostname', 'authToken', 'list_services')->name('get_service_for_host');
$app->post('/:hostname', 'authToken', 'add_service_for_host')->name('add_service_for_host');
}
);
$app->get('/services', 'authToken', 'list_services')->name('list_services');
// End Service
$app->group(
'/logs',
function () use ($app) {
$app->get('/eventlog(/:hostname)', 'authToken', 'list_logs')->name('list_eventlog');
$app->get('/syslog(/:hostname)', 'authToken', 'list_logs')->name('list_syslog');
$app->get('/alertlog(/:hostname)', 'authToken', 'list_logs')->name('list_alertlog');
$app->get('/authlog(/:hostname)', 'authToken', 'list_logs')->name('list_authlog');
}
);
}
);
$app->get('/v0', 'authToken', 'show_endpoints');
// api/v0
}
);
$app->run();

1
html/api_v0.php Symbolic link
View File

@ -0,0 +1 @@
index.php

5
html/css/app.css Normal file

File diff suppressed because one or more lines are too long

View File

@ -10,19 +10,6 @@ ini_set('session.cookie_httponly', 1);
ini_set('session.use_strict_mode', 1); // php >= 5.5.2
ini_set('session.use_trans_sid', 0); // insecure feature, be sure it is disabled
// Pre-flight checks
if (!is_dir($config['rrd_dir'])) {
echo "<div class='errorbox'>RRD Log Directory is missing ({$config['rrd_dir']}). Graphing may fail.</div>";
}
if (!is_dir($config['temp_dir'])) {
echo "<div class='errorbox'>Temp Directory is missing ({$config['temp_dir']}). Graphing may fail.</div>";
}
if (!is_writable($config['temp_dir'])) {
echo "<div class='errorbox'>Temp Directory is not writable ({$config['tmp_dir']}). Graphing may fail.</div>";
}
// Clear up any old sessions
dbDelete('session', '`session_expiry` < ?', array(time()));

View File

@ -1,401 +1,58 @@
<?php
/**
* LibreNMS
*
* This file is part of LibreNMS.
*
* @package librenms
* @subpackage webinterface
* @copyright (C) 2006 - 2012 Adam Armstrong
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylor@laravel.com>
*/
use LibreNMS\Authentication\Auth;
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/
if (empty($_SERVER['PATH_INFO'])) {
if (strstr($_SERVER['SERVER_SOFTWARE'], "nginx") && isset($_SERVER['PATH_TRANSLATED']) && isset($_SERVER['ORIG_SCRIPT_FILENAME'])) {
$_SERVER['PATH_INFO'] = str_replace($_SERVER['PATH_TRANSLATED'] . $_SERVER['PHP_SELF'], "", $_SERVER['ORIG_SCRIPT_FILENAME']);
} else {
$_SERVER['PATH_INFO'] = isset($_SERVER['ORIG_PATH_INFO']) ? $_SERVER['ORIG_PATH_INFO'] : '';
}
}
require __DIR__.'/../bootstrap/autoload.php';
if (strpos($_SERVER['REQUEST_URI'], "debug")) {
$debug = true;
ini_set('display_errors', 0);
ini_set('display_startup_errors', 1);
ini_set('log_errors', 1);
ini_set('error_reporting', E_ALL);
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
global $php_debug;
$php_debug[] = array('errno' => $errno, 'errstr' => $errstr, 'errfile' => $errfile, 'errline' => $errline);
});
register_shutdown_function(function () {
$last_error = error_get_last();
if ($last_error['type'] == 1) {
$log_error = array($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']);
print_r($log_error);
}
});
$sql_debug = array();
$php_debug = array();
} else {
$debug = false;
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
ini_set('log_errors', 0);
ini_set('error_reporting', 0);
}
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
// Set variables
$msg_box = array();
// Check for install.inc.php
if (!file_exists('../config.php') && $_SERVER['PATH_INFO'] != '/install.php') {
// no config.php does so let's redirect to the install
header("Location: /install.php");
exit;
}
$app = require_once __DIR__.'/../bootstrap/app.php';
$init_modules = array('web', 'auth');
require realpath(__DIR__ . '/..') . '/includes/init.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
LibreNMS\Plugins::start();
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$runtime_start = microtime(true);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
ob_start();
$response->send();
ini_set('allow_url_fopen', 0);
ini_set('display_errors', 0);
if (strstr($_SERVER['REQUEST_URI'], 'widescreen=yes')) {
$_SESSION['widescreen'] = 1;
}
if (strstr($_SERVER['REQUEST_URI'], 'widescreen=no')) {
unset($_SESSION['widescreen']);
}
# Load the settings for Multi-Tenancy.
if (isset($config['branding']) && is_array($config['branding'])) {
if (isset($config['branding'][$_SERVER['SERVER_NAME']])) {
$config = array_replace_recursive($config, $config['branding'][$_SERVER['SERVER_NAME']]);
} else {
$config = array_replace_recursive($config, $config['branding']['default']);
}
}
# page_title_prefix is displayed, unless page_title is set
if (isset($config['page_title'])) {
$config['page_title_prefix'] = $config['page_title'];
}
?>
<!DOCTYPE HTML>
<html>
<head>
<title><?php echo($config['page_title_suffix']); ?></title>
<base href="<?php echo($config['base_url']); ?>" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<?php
if (empty($config['favicon'])) {
?>
<link rel="apple-touch-icon" sizes="180x180" href="images/apple-touch-icon.png">
<link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16">
<link rel="manifest" href="images/manifest.json">
<link rel="mask-icon" href="images/safari-pinned-tab.svg" color="#5bbad5">
<link rel="shortcut icon" href="images/favicon.ico">
<meta name="msapplication-config" content="images/browserconfig.xml">
<meta name="theme-color" content="#ffffff">
<?php
} else {
echo(' <link rel="shortcut icon" href="'.$config['favicon'].'" />' . "\n");
}
?>
<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="css/bootstrap-datetimepicker.min.css" rel="stylesheet" type="text/css" />
<link href="css/bootstrap-switch.min.css" rel="stylesheet" type="text/css" />
<link href="css/toastr.min.css" rel="stylesheet" type="text/css" />
<link href="css/jquery-ui.min.css" rel="stylesheet" type="text/css" />
<link href="css/jquery.bootgrid.min.css" rel="stylesheet" type="text/css" />
<link href="css/tagmanager.css" rel="stylesheet" type="text/css" />
<link href="css/mktree.css" rel="stylesheet" type="text/css" />
<link href="css/vis.min.css" rel="stylesheet" type="text/css" />
<link href="css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<link href="css/jquery.gridster.min.css" rel="stylesheet" type="text/css" />
<link href="css/leaflet.css" rel="stylesheet" type="text/css" />
<link href="css/MarkerCluster.css" rel="stylesheet" type="text/css" />
<link href="css/MarkerCluster.Default.css" rel="stylesheet" type="text/css" />
<link href="css/leaflet.awesome-markers.css" rel="stylesheet" type="text/css" />
<link href="css/select2.min.css" rel="stylesheet" type="text/css" />
<link href="css/query-builder.default.min.css" rel="stylesheet" type="text/css" />
<link href="<?php echo($config['stylesheet']); ?>?ver=291727421" rel="stylesheet" type="text/css" />
<link href="css/<?php echo $config['site_style']; ?>.css?ver=632417642" rel="stylesheet" type="text/css" />
<?php
foreach ((array)$config['webui']['custom_css'] as $custom_css) {
echo '<link href="' . $custom_css . '" rel="stylesheet" type="text/css" />';
}
?>
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/bootstrap-hover-dropdown.min.js"></script>
<script src="js/bootstrap-switch.min.js"></script>
<script src="js/hogan-2.0.0.js"></script>
<script src="js/jquery.cycle2.min.js"></script>
<script src="js/moment.min.js"></script>
<script src="js/bootstrap-datetimepicker.min.js"></script>
<script src="js/typeahead.bundle.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="js/tagmanager.js"></script>
<script src="js/mktree.js"></script>
<script src="js/jquery.bootgrid.min.js"></script>
<script src="js/handlebars.min.js"></script>
<script src="js/pace.min.js"></script>
<script src="js/qrcode.min.js"></script>
<?php
if ($config['enable_lazy_load'] === true) {
?>
<script src="js/jquery.lazyload.min.js"></script>
<script src="js/lazyload.js"></script>
<?php
}
?>
<script src="js/select2.min.js"></script>
<script src="js/librenms.js"></script>
<script type="text/javascript">
<!-- Begin
function popUp(URL)
{
day = new Date();
id = day.getTime();
eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=550,height=600');");
}
// End -->
</script>
<script type="text/javascript" src="js/overlib_mini.js"></script>
<script type="text/javascript" src="js/toastr.min.js"></script>
</head>
<body>
<?php
if (empty($_SESSION['screen_width']) && empty($_SESSION['screen_height'])) {
echo "<script>updateResolution();</script>";
}
if ((isset($vars['bare']) && $vars['bare'] != "yes") || !isset($vars['bare'])) {
if (Auth::check()) {
require 'includes/print-menubar.php';
}
} else {
echo "<style>body { padding-top: 0px !important;
padding-bottom: 0px !important; }</style>";
}
?>
<br />
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<?php
// To help debug the new URLs :)
if (isset($devel) || isset($vars['devel'])) {
echo("<pre>");
print_r($_GET);
print_r($vars);
echo("</pre>");
}
if (Auth::check()) {
// Authenticated. Print a page.
if (isset($vars['page']) && !strstr("..", $vars['page']) && is_file("pages/" . $vars['page'] . ".inc.php")) {
require "pages/" . $vars['page'] . ".inc.php";
} else {
if (isset($config['front_page']) && is_file($config['front_page'])) {
require $config['front_page'];
} else {
require 'pages/front/default.php';
}
}
} else {
// Not Authenticated. Show status page if enabled
if ($config['public_status'] === true) {
if (isset($vars['page']) && strstr("login", $vars['page'])) {
require 'pages/logon.inc.php';
} else {
echo '<div id="public-status">';
require 'pages/public.inc.php';
echo '</div>';
echo '<div id="public-logon" style="display:none;">';
echo '<div class="well"><h3>Logon<button class="btn btn-default" type="submit" style="float:right;" id="ToggleStatus">Status</button></h3></div>';
require 'pages/logon.inc.php';
echo '</div>';
}
} else {
require 'pages/logon.inc.php';
}
}
?>
</div>
</div>
</div>
<?php
$runtime_end = microtime(true);
$runtime = $runtime_end - $runtime_start;
$gentime = substr($runtime, 0, 5);
# FIXME - move this
if ($config['page_gen']) {
echo '<br />';
printStats();
$fullsize = memory_get_usage();
unset($cache);
$cachesize = $fullsize - memory_get_usage();
if ($cachesize < 0) {
$cachesize = 0;
} // Silly PHP!
echo(' <br />Cached data in memory is '.formatStorage($cachesize).'. Page memory usage is '.formatStorage($fullsize).', peaked at '. formatStorage(memory_get_peak_usage()) .'.');
echo(' <br />Generated in ' . $gentime . ' seconds.');
}
if (isset($pagetitle) && is_array($pagetitle)) {
# if prefix is set, put it in front
if ($config['page_title_prefix']) {
array_unshift($pagetitle, $config['page_title_prefix']);
}
# if suffix is set, put it in the back
if ($config['page_title_suffix']) {
$pagetitle[] = $config['page_title_suffix'];
}
# create and set the title
$title = join(" - ", $pagetitle);
echo("<script type=\"text/javascript\">\ndocument.title = '$title';\n</script>");
}
?>
<?php
if ($config['enable_footer'] == 1 && (isset($vars['bare']) && $vars['bare'] != "yes")) {
?>
<nav class="navbar navbar-default <?php echo $navbar; ?> navbar-fixed-bottom">
<div class="container">
<div class="row">
<div class="col-md-12 text-center">
<?php
echo('<h5>Powered by <a href="' . $config['project_home'] . '" target="_blank" rel="noopener" class="red">' . $config['project_name'].'</a>.</h5>');
?>
</div>
</div>
</div>
</nav>
<?php
}
if (dbFetchCell("SELECT COUNT(*) FROM `devices` WHERE `last_polled` <= DATE_ADD(NOW(), INTERVAL - 15 minute) AND `ignore` = 0 AND `disabled` = 0 AND status = 1", array()) > 0) {
$msg_box[] = array('type' => 'warning', 'message' => "<a href=\"poll-log/filter=unpolled/\">It appears as though you have some devices that haven't completed polling within the last 15 minutes, you may want to check that out :)</a>",'title' => 'Devices unpolled');
}
foreach (dbFetchRows('SELECT `notifications`.* FROM `notifications` WHERE NOT exists( SELECT 1 FROM `notifications_attribs` WHERE `notifications`.`notifications_id` = `notifications_attribs`.`notifications_id` AND `notifications_attribs`.`user_id` = ?) AND `severity` > 1', array(Auth::id())) as $notification) {
$msg_box[] = array(
'type' => 'error',
'message' => "<a href='notifications/'>${notification['body']}</a>",
'title' => $notification['title']
);
}
if (is_array($msg_box)) {
echo("<script>
toastr.options.timeout = 10;
toastr.options.extendedTimeOut = 20;
");
foreach ($msg_box as $message) {
$message['type'] = mres($message['type']);
$message['message'] = mres($message['message']);
$message['title'] = mres($message['title']);
echo "toastr.".$message['type']."('".$message['message']."','".$message['title']."');\n";
}
echo("</script>");
}
if (is_array($sql_debug) && is_array($php_debug) && Auth::check()) {
require_once "includes/print-debug.php";
}
if ($no_refresh !== true && $config['page_refresh'] != 0) {
$refresh = $config['page_refresh'] * 1000;
echo('<script type="text/javascript">
$(document).ready(function() {
$("#countdown_timer_status").html("<i class=\"fa fa-pause fa-fw fa-lg\"></i> Pause");
var Countdown = {
sec: '. $config['page_refresh'] .',
Start: function() {
var cur = this;
this.interval = setInterval(function() {
$("#countdown_timer_status").html("<i class=\"fa fa-pause fa-fw fa-lg\"></i> Pause");
cur.sec -= 1;
display_time = cur.sec;
if (display_time == 0) {
location.reload();
}
if (display_time % 1 === 0 && display_time <= 300) {
$("#countdown_timer").html("<i class=\"fa fa-clock-o fa-fw fa-lg\"></i> Refresh in " + display_time);
}
}, 1000);
},
Pause: function() {
clearInterval(this.interval);
$("#countdown_timer_status").html("<i class=\"fa fa-play fa-fw fa-lg\"></i> Resume");
delete this.interval;
},
Resume: function() {
if (!this.interval) this.Start();
}
};
Countdown.Start();
$("#countdown_timer_status").click("", function(event) {
event.preventDefault();
if (Countdown.interval) {
Countdown.Pause();
} else {
Countdown.Resume();
}
});
$("#countdown_timer").click("", function(event) {
event.preventDefault();
});
});
</script>');
} else {
echo('<script type="text/javascript">
var no_refresh = ' . var_export((bool)$no_refresh, true) . ';
$(document).ready(function() {
$("#countdown_timer").html("Refresh disabled");
$("#countdown_timer_status").html("<i class=\"fa fa-pause fa-fw fa-lg\"></i>");
$("#countdown_timer_status").click("", function(event) {
event.preventDefault();
});
});
</script>');
}
?>
</body>
</html>
$kernel->terminate($request, $response);

34
html/js/app.js Normal file

File diff suppressed because one or more lines are too long

29
html/js/boot.js Normal file
View File

@ -0,0 +1,29 @@
/*
* boot.js
*
* Initialize javascript for LibreNMS v1
*
* 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 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
// set CSRF for jquery ajax request
$.ajaxSetup({
headers:
{ 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }
});

View File

@ -148,7 +148,7 @@ function submitCustomRange(frmdata) {
function updateResolution(refresh)
{
$.post('ajax_setresolution.php',
$.post('ajax/set_resolution',
{
width: $(window).width(),
height:$(window).height()

225
html/legacy_api_v0.php Normal file
View File

@ -0,0 +1,225 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
*
* 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. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
$init_modules = array('web', 'alerts');
require realpath(__DIR__ . '/..') . '/includes/init.php';
use LibreNMS\Config;
$app = new \Slim\Slim();
if (Config::get('api.cors.enabled') === true) {
$corsOptions = array(
"origin" => Config::get('api.cors.origin'),
"maxAge" => Config::get('api.cors.maxage'),
"allowMethods" => Config::get('api.cors.allowmethods'),
"allowHeaders" => Config::get('api.cors.allowheaders'),
);
$cors = new \CorsSlim\CorsSlim($corsOptions);
$app->add($cors);
}
require $config['install_dir'] . '/html/includes/api_functions.inc.php';
$app->setName('api');
$app->notFound(function () use ($app) {
api_error(404, "This API route doesn't exist.");
});
$app->group(
'/api',
function () use ($app) {
$app->group(
'/v0',
function () use ($app) {
$app->get('/bgp', 'authToken', 'list_bgp')->name('list_bgp');
$app->get('/bgp/:id', 'authToken', 'get_bgp')->name('get_bgp');
$app->get('/ospf', 'authToken', 'list_ospf')->name('list_ospf');
// api/v0/bgp
$app->get('/oxidized(/:hostname)', 'authToken', 'list_oxidized')->name('list_oxidized');
$app->group(
'/devices',
function () use ($app) {
$app->delete('/:hostname', 'authToken', 'del_device')->name('del_device');
// api/v0/devices/$hostname
$app->get('/:hostname', 'authToken', 'get_device')->name('get_device');
// api/v0/devices/$hostname
$app->patch('/:hostname', 'authToken', 'update_device')->name('update_device_field');
$app->patch('/:hostname/rename/:new_hostname', 'authToken', 'rename_device')->name('rename_device');
$app->get('/:hostname/vlans', 'authToken', 'get_vlans')->name('get_vlans');
// api/v0/devices/$hostname/vlans
$app->get('/:hostname/graphs', 'authToken', 'get_graphs')->name('get_graphs');
// api/v0/devices/$hostname/graphs
$app->get('/:hostname/health(/:type)(/:sensor_id)', 'authToken', 'list_available_health_graphs')->name('list_available_health_graphs');
$app->get('/:hostname/wireless(/:type)(/:sensor_id)', 'authToken', 'list_available_wireless_graphs')->name('list_available_wireless_graphs');
$app->get('/:hostname/ports', 'authToken', 'get_port_graphs')->name('get_port_graphs');
$app->get('/:hostname/ip', 'authToken', 'get_ip_addresses')->name('get_device_ip_addresses');
$app->get('/:hostname/port_stack', 'authToken', 'get_port_stack')->name('get_port_stack');
// api/v0/devices/$hostname/ports
$app->get('/:hostname/components', 'authToken', 'get_components')->name('get_components');
$app->post('/:hostname/components/:type', 'authToken', 'add_components')->name('add_components');
$app->put('/:hostname/components', 'authToken', 'edit_components')->name('edit_components');
$app->delete('/:hostname/components/:component', 'authToken', 'delete_components')->name('delete_components');
$app->get('/:hostname/groups', 'authToken', 'get_device_groups')->name('get_device_groups');
$app->get('/:hostname/graphs/health/:type(/:sensor_id)', 'authToken', 'get_graph_generic_by_hostname')->name('get_health_graph');
$app->get('/:hostname/graphs/wireless/:type(/:sensor_id)', 'authToken', 'get_graph_generic_by_hostname')->name('get_wireless_graph');
$app->get('/:hostname/:type', 'authToken', 'get_graph_generic_by_hostname')->name('get_graph_generic_by_hostname');
// api/v0/devices/$hostname/$type
$app->get('/:hostname/ports/:ifname', 'authToken', 'get_port_stats_by_port_hostname')->name('get_port_stats_by_port_hostname');
// api/v0/devices/$hostname/ports/$ifName
$app->get('/:hostname/ports/:ifname/:type', 'authToken', 'get_graph_by_port_hostname')->name('get_graph_by_port_hostname');
// api/v0/devices/$hostname/ports/$ifName/$type
}
);
$app->get('/devices', 'authToken', 'list_devices')->name('list_devices');
// api/v0/devices
$app->post('/devices', 'authToken', 'add_device')->name('add_device');
// api/v0/devices (json data needs to be passed)
$app->group(
'/devicegroups',
function () use ($app) {
$app->get('/:name', 'authToken', 'get_devices_by_group')->name('get_devices_by_group');
}
);
$app->get('/devicegroups', 'authToken', 'get_device_groups')->name('get_devicegroups');
$app->group(
'/ports',
function () use ($app) {
$app->get('/:portid', 'authToken', 'get_port_info')->name('get_port_info');
$app->get('/:portid/ip', 'authToken', 'get_ip_addresses')->name('get_port_ip_info');
}
);
$app->get('/ports', 'authToken', 'get_all_ports')->name('get_all_ports');
$app->group(
'/portgroups',
function () use ($app) {
$app->get('/multiport/bits/:id', 'authToken', 'get_graph_by_portgroup')->name('get_graph_by_portgroup_multiport_bits');
$app->get('/:group', 'authToken', 'get_graph_by_portgroup')->name('get_graph_by_portgroup');
}
);
$app->group(
'/bills',
function () use ($app) {
$app->get('/:bill_id', 'authToken', 'list_bills')->name('get_bill');
$app->delete('/:id', 'authToken', 'delete_bill')->name('delete_bill');
// api/v0/bills/$bill_id
$app->get('/:bill_id/graphs/:graph_type', 'authToken', 'get_bill_graph')->name('get_bill_graph');
$app->get('/:bill_id/graphdata/:graph_type', 'authToken', 'get_bill_graphdata')->name('get_bill_graphdata');
$app->get('/:bill_id/history', 'authToken', 'get_bill_history')->name('get_bill_history');
$app->get('/:bill_id/history/:bill_hist_id/graphs/:graph_type', 'authToken', 'get_bill_history_graph')->name('get_bill_history_graph');
$app->get('/:bill_id/history/:bill_hist_id/graphdata/:graph_type', 'authToken', 'get_bill_history_graphdata')->name('get_bill_history_graphdata');
}
);
$app->get('/bills', 'authToken', 'list_bills')->name('list_bills');
$app->post('/bills', 'authToken', 'create_edit_bill')->name('create_bill');
// api/v0/bills
// /api/v0/alerts
$app->group(
'/alerts',
function () use ($app) {
$app->get('/:id', 'authToken', 'list_alerts')->name('get_alert');
// api/v0/alerts
$app->put('/:id', 'authToken', 'ack_alert')->name('ack_alert');
// api/v0/alerts/$id (PUT)
$app->put('/unmute/:id', 'authToken', 'unmute_alert')->name('unmute_alert');
// api/v0/alerts/unmute/$id (PUT)
}
);
$app->get('/alerts', 'authToken', 'list_alerts')->name('list_alerts');
// api/v0/alerts
// /api/v0/rules
$app->group(
'/rules',
function () use ($app) {
$app->get('/:id', 'authToken', 'list_alert_rules')->name('get_alert_rule');
// api/v0/rules/$id
$app->delete('/:id', 'authToken', 'delete_rule')->name('delete_rule');
// api/v0/rules/$id (DELETE)
}
);
$app->get('/rules', 'authToken', 'list_alert_rules')->name('list_alert_rules');
// api/v0/rules
$app->post('/rules', 'authToken', 'add_edit_rule')->name('add_rule');
// api/v0/rules (json data needs to be passed)
$app->put('/rules', 'authToken', 'add_edit_rule')->name('edit_rule');
// api/v0/rules (json data needs to be passed)
// Inventory section
$app->group(
'/inventory',
function () use ($app) {
$app->get('/:hostname', 'authToken', 'get_inventory')->name('get_inventory');
}
);
// End Inventory
// Routing section
$app->group(
'/routing',
function () use ($app) {
$app->get('/bgp/cbgp', 'authToken', 'list_cbgp')->name('list_cbgp');
$app->get('/vrf', 'authToken', 'list_vrf')->name('list_vrf');
$app->get('/vrf/:id', 'authToken', 'get_vrf')->name('get_vrf');
$app->group(
'/ipsec',
function () use ($app) {
$app->get('/data/:hostname', 'authToken', 'list_ipsec')->name('list_ipsec');
}
);
}
);
// End Routing
// Resources section
$app->group(
'/resources',
function () use ($app) {
$app->get('/locations', 'authToken', 'list_locations')->name('list_locations');
$app->get('/vlans', 'authToken', 'list_vlans')->name('list_vlans');
$app->group(
'/ip',
function () use ($app) {
$app->get('/addresses/', 'authToken', 'list_ip_addresses')->name('list_ip_addresses');
$app->get('/arp/:ip', 'authToken', 'list_arp')->name('list_arp')->conditions(array('ip' => '[^?]+'));
$app->get('/networks/', 'authToken', 'list_ip_networks')->name('list_ip_networks');
$app->get('/networks/:id/ip', 'authToken', 'get_ip_addresses')->name('get_network_ip_addresses');
}
);
}
);
// End Resources
// Service section
$app->group(
'/services',
function () use ($app) {
$app->get('/:hostname', 'authToken', 'list_services')->name('get_service_for_host');
$app->post('/:hostname', 'authToken', 'add_service_for_host')->name('add_service_for_host');
}
);
$app->get('/services', 'authToken', 'list_services')->name('list_services');
// End Service
$app->group(
'/logs',
function () use ($app) {
$app->get('/eventlog(/:hostname)', 'authToken', 'list_logs')->name('list_eventlog');
$app->get('/syslog(/:hostname)', 'authToken', 'list_logs')->name('list_syslog');
$app->get('/alertlog(/:hostname)', 'authToken', 'list_logs')->name('list_alertlog');
$app->get('/authlog(/:hostname)', 'authToken', 'list_logs')->name('list_authlog');
}
);
}
);
$app->get('/v0', 'authToken', 'show_endpoints');
// api/v0
}
);
$app->run();

415
html/legacy_index.php Normal file
View File

@ -0,0 +1,415 @@
<?php
/**
* LibreNMS
*
* This file is part of LibreNMS.
*
* @package librenms
* @subpackage webinterface
* @copyright (C) 2006 - 2012 Adam Armstrong
*
*/
use LibreNMS\Authentication\Auth;
use LibreNMS\Config;
if (empty($_SERVER['PATH_INFO'])) {
if (strstr($_SERVER['SERVER_SOFTWARE'], "nginx") && isset($_SERVER['PATH_TRANSLATED']) && isset($_SERVER['ORIG_SCRIPT_FILENAME'])) {
$_SERVER['PATH_INFO'] = str_replace($_SERVER['PATH_TRANSLATED'] . $_SERVER['PHP_SELF'], "", $_SERVER['ORIG_SCRIPT_FILENAME']);
} else {
$_SERVER['PATH_INFO'] = isset($_SERVER['ORIG_PATH_INFO']) ? $_SERVER['ORIG_PATH_INFO'] : '';
}
}
if (strpos($_SERVER['REQUEST_URI'], "debug")) {
$debug = true;
ini_set('display_errors', 0);
ini_set('display_startup_errors', 1);
ini_set('log_errors', 1);
ini_set('error_reporting', E_ALL);
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
global $php_debug;
$php_debug[] = array('errno' => $errno, 'errstr' => $errstr, 'errfile' => $errfile, 'errline' => $errline);
});
register_shutdown_function(function () {
$last_error = error_get_last();
if ($last_error['type'] == 1) {
$log_error = array($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']);
print_r($log_error);
}
});
$sql_debug = array();
$php_debug = array();
} else {
$debug = false;
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
ini_set('log_errors', 0);
ini_set('error_reporting', 0);
}
// Set variables
$msg_box = array();
// Check for install.inc.php
if (!file_exists('../config.php') && $_SERVER['PATH_INFO'] != '/install.php') {
// no config.php does so let's redirect to the install
header("Location: {$config['base_url']}/install.php");
exit;
}
$init_modules = array('web', 'auth');
require realpath(__DIR__ . '/..') . '/includes/init.php';
LibreNMS\Plugins::start();
$runtime_start = microtime(true);
ob_start();
ini_set('allow_url_fopen', 0);
ini_set('display_errors', 0);
if (strstr($_SERVER['REQUEST_URI'], 'widescreen=yes')) {
$_SESSION['widescreen'] = 1;
}
if (strstr($_SERVER['REQUEST_URI'], 'widescreen=no')) {
unset($_SESSION['widescreen']);
}
# Load the settings for Multi-Tenancy.
if (isset($config['branding']) && is_array($config['branding'])) {
if (isset($config['branding'][$_SERVER['SERVER_NAME']])) {
$config = array_replace_recursive($config, $config['branding'][$_SERVER['SERVER_NAME']]);
} else {
$config = array_replace_recursive($config, $config['branding']['default']);
}
}
# page_title_prefix is displayed, unless page_title is set
if (isset($config['page_title'])) {
$config['page_title_prefix'] = $config['page_title'];
}
?>
<!DOCTYPE HTML>
<html>
<head>
<title><?php echo($config['page_title_suffix']); ?></title>
<base href="<?php echo($config['base_url']); ?>" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<?php
if (empty($config['favicon'])) {
?>
<link rel="apple-touch-icon" sizes="180x180" href="images/apple-touch-icon.png">
<link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16">
<link rel="manifest" href="images/manifest.json">
<link rel="mask-icon" href="images/safari-pinned-tab.svg" color="#5bbad5">
<link rel="shortcut icon" href="images/favicon.ico">
<meta name="msapplication-config" content="images/browserconfig.xml">
<meta name="theme-color" content="#ffffff">
<?php
} else {
echo(' <link rel="shortcut icon" href="'.$config['favicon'].'" />' . "\n");
}
?>
<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="css/bootstrap-datetimepicker.min.css" rel="stylesheet" type="text/css" />
<link href="css/bootstrap-switch.min.css" rel="stylesheet" type="text/css" />
<link href="css/toastr.min.css" rel="stylesheet" type="text/css" />
<link href="css/jquery-ui.min.css" rel="stylesheet" type="text/css" />
<link href="css/jquery.bootgrid.min.css" rel="stylesheet" type="text/css" />
<link href="css/tagmanager.css" rel="stylesheet" type="text/css" />
<link href="css/mktree.css" rel="stylesheet" type="text/css" />
<link href="css/vis.min.css" rel="stylesheet" type="text/css" />
<link href="css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<link href="css/jquery.gridster.min.css" rel="stylesheet" type="text/css" />
<link href="css/leaflet.css" rel="stylesheet" type="text/css" />
<link href="css/MarkerCluster.css" rel="stylesheet" type="text/css" />
<link href="css/MarkerCluster.Default.css" rel="stylesheet" type="text/css" />
<link href="css/leaflet.awesome-markers.css" rel="stylesheet" type="text/css" />
<link href="css/select2.min.css" rel="stylesheet" type="text/css" />
<link href="css/query-builder.default.min.css" rel="stylesheet" type="text/css" />
<link href="<?php echo($config['stylesheet']); ?>?ver=291727421" rel="stylesheet" type="text/css" />
<link href="css/<?php echo $config['site_style']; ?>.css?ver=632417642" rel="stylesheet" type="text/css" />
<?php
foreach ((array)$config['webui']['custom_css'] as $custom_css) {
echo '<link href="' . $custom_css . '" rel="stylesheet" type="text/css" />';
}
?>
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/bootstrap-hover-dropdown.min.js"></script>
<script src="js/bootstrap-switch.min.js"></script>
<script src="js/hogan-2.0.0.js"></script>
<script src="js/jquery.cycle2.min.js"></script>
<script src="js/moment.min.js"></script>
<script src="js/bootstrap-datetimepicker.min.js"></script>
<script src="js/typeahead.bundle.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="js/tagmanager.js"></script>
<script src="js/mktree.js"></script>
<script src="js/jquery.bootgrid.min.js"></script>
<script src="js/handlebars.min.js"></script>
<script src="js/pace.min.js"></script>
<script src="js/qrcode.min.js"></script>
<?php
if ($config['enable_lazy_load'] === true) {
?>
<script src="js/jquery.lazyload.min.js"></script>
<script src="js/lazyload.js"></script>
<?php
}
?>
<script src="js/select2.min.js"></script>
<script src="js/librenms.js"></script>
<script type="text/javascript">
<!-- Begin
function popUp(URL)
{
day = new Date();
id = day.getTime();
eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=550,height=600');");
}
// End -->
</script>
<script type="text/javascript" src="js/overlib_mini.js"></script>
<script type="text/javascript" src="js/toastr.min.js"></script>
</head>
<body>
<?php
if (empty($_SESSION['screen_width']) && empty($_SESSION['screen_height'])) {
echo "<script>updateResolution();</script>";
}
if ((isset($vars['bare']) && $vars['bare'] != "yes") || !isset($vars['bare'])) {
if (Auth::check()) {
require 'includes/print-menubar.php';
}
} else {
echo "<style>body { padding-top: 0px !important;
padding-bottom: 0px !important; }</style>";
}
?>
<br />
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<?php
// To help debug the new URLs :)
if (isset($devel) || isset($vars['devel'])) {
echo("<pre>");
print_r($_GET);
print_r($vars);
echo("</pre>");
}
if (Auth::check()) {
// Authenticated. Print a page.
if (isset($vars['page']) && !strstr("..", $vars['page']) && is_file("pages/" . $vars['page'] . ".inc.php")) {
require "pages/" . $vars['page'] . ".inc.php";
} else {
if (isset($config['front_page']) && is_file($config['front_page'])) {
require $config['front_page'];
} else {
require 'pages/front/default.php';
}
}
} else {
// Not Authenticated. Show status page if enabled
if ($config['public_status'] === true) {
if (isset($vars['page']) && strstr("login", $vars['page'])) {
require 'pages/logon.inc.php';
} else {
echo '<div id="public-status">';
require 'pages/public.inc.php';
echo '</div>';
echo '<div id="public-logon" style="display:none;">';
echo '<div class="well"><h3>Logon<button class="btn btn-default" type="submit" style="float:right;" id="ToggleStatus">Status</button></h3></div>';
require 'pages/logon.inc.php';
echo '</div>';
}
} else {
require 'pages/logon.inc.php';
}
}
?>
</div>
</div>
</div>
<?php
$runtime_end = microtime(true);
$runtime = $runtime_end - $runtime_start;
$gentime = substr($runtime, 0, 5);
# FIXME - move this
if ($config['page_gen']) {
echo '<br />';
printStats();
$fullsize = memory_get_usage();
unset($cache);
$cachesize = $fullsize - memory_get_usage();
if ($cachesize < 0) {
$cachesize = 0;
} // Silly PHP!
echo(' <br />Cached data in memory is '.formatStorage($cachesize).'. Page memory usage is '.formatStorage($fullsize).', peaked at '. formatStorage(memory_get_peak_usage()) .'.');
echo(' <br />Generated in ' . $gentime . ' seconds.');
}
if (isset($pagetitle) && is_array($pagetitle)) {
# if prefix is set, put it in front
if ($config['page_title_prefix']) {
array_unshift($pagetitle, $config['page_title_prefix']);
}
# if suffix is set, put it in the back
if ($config['page_title_suffix']) {
$pagetitle[] = $config['page_title_suffix'];
}
# create and set the title
$title = join(" - ", $pagetitle);
echo("<script type=\"text/javascript\">\ndocument.title = '$title';\n</script>");
}
?>
<?php
if ($config['enable_footer'] == 1 && (isset($vars['bare']) && $vars['bare'] != "yes")) {
?>
<nav class="navbar navbar-default <?php echo $navbar; ?> navbar-fixed-bottom">
<div class="container">
<div class="row">
<div class="col-md-12 text-center">
<?php
echo('<h5>Powered by <a href="' . $config['project_home'] . '" target="_blank" rel="noopener" class="red">' . $config['project_name'].'</a>.</h5>');
?>
</div>
</div>
</div>
</nav>
<?php
}
// Pre-flight checks
$rrd_dir = Config::get('rrd_dir');
if (!is_dir($rrd_dir)) {
$msg_box[] = ['type' => 'error', 'message' => "RRD Log Directory is missing ($rrd_dir). Graphing may fail."];
}
$temp_dir = Config::get('temp_dir');
if (!is_dir($temp_dir)) {
$msg_box[] = ['type' => 'error', 'message' => "Temp Directory is missing ($temp_dir). Graphing may fail."];
} elseif (!is_writable($temp_dir)) {
$msg_box[] = ['type' => 'error', 'message' => "Temp Directory is not writable ($temp_dir). Graphing may fail."];
}
if (dbFetchCell("SELECT COUNT(*) FROM `devices` WHERE `last_polled` <= DATE_ADD(NOW(), INTERVAL - 15 minute) AND `ignore` = 0 AND `disabled` = 0 AND status = 1", array()) > 0) {
$msg_box[] = ['type' => 'warning', 'message' => "<a href=\"poll-log/filter=unpolled/\">It appears as though you have some devices that haven't completed polling within the last 15 minutes, you may want to check that out :)</a>",'title' => 'Devices unpolled'];
}
foreach (dbFetchRows('SELECT `notifications`.* FROM `notifications` WHERE NOT exists( SELECT 1 FROM `notifications_attribs` WHERE `notifications`.`notifications_id` = `notifications_attribs`.`notifications_id` AND `notifications_attribs`.`user_id` = ?) AND `severity` > 1', array(Auth::id())) as $notification) {
$msg_box[] = [
'type' => 'error',
'message' => "<a href='notifications/'>${notification['body']}</a>",
'title' => $notification['title']
];
}
if (is_array($msg_box)) {
echo("<script>
toastr.options.timeout = 10;
toastr.options.extendedTimeOut = 20;
");
foreach ($msg_box as $message) {
$message['type'] = mres($message['type']);
$message['message'] = mres($message['message']);
$message['title'] = mres($message['title']);
echo "toastr.".$message['type']."('".$message['message']."','".$message['title']."');\n";
}
echo("</script>");
}
if (is_array($sql_debug) && is_array($php_debug) && Auth::check()) {
require_once "includes/print-debug.php";
}
if ($no_refresh !== true && $config['page_refresh'] != 0) {
$refresh = $config['page_refresh'] * 1000;
echo('<script type="text/javascript">
$(document).ready(function() {
$("#countdown_timer_status").html("<i class=\"fa fa-pause fa-fw fa-lg\"></i> Pause");
var Countdown = {
sec: '. $config['page_refresh'] .',
Start: function() {
var cur = this;
this.interval = setInterval(function() {
$("#countdown_timer_status").html("<i class=\"fa fa-pause fa-fw fa-lg\"></i> Pause");
cur.sec -= 1;
display_time = cur.sec;
if (display_time == 0) {
location.reload();
}
if (display_time % 1 === 0 && display_time <= 300) {
$("#countdown_timer").html("<i class=\"fa fa-clock-o fa-fw fa-lg\"></i> Refresh in " + display_time);
}
}, 1000);
},
Pause: function() {
clearInterval(this.interval);
$("#countdown_timer_status").html("<i class=\"fa fa-play fa-fw fa-lg\"></i> Resume");
delete this.interval;
},
Resume: function() {
if (!this.interval) this.Start();
}
};
Countdown.Start();
$("#countdown_timer_status").click("", function(event) {
event.preventDefault();
if (Countdown.interval) {
Countdown.Pause();
} else {
Countdown.Resume();
}
});
$("#countdown_timer").click("", function(event) {
event.preventDefault();
});
});
</script>');
} else {
echo('<script type="text/javascript">
var no_refresh = ' . var_export((bool)$no_refresh, true) . ';
$(document).ready(function() {
$("#countdown_timer").html("Refresh disabled");
$("#countdown_timer_status").html("<i class=\"fa fa-pause fa-fw fa-lg\"></i>");
$("#countdown_timer_status").click("", function(event) {
event.preventDefault();
});
});
</script>');
}
?>
</body>
</html>

View File

@ -73,7 +73,11 @@ function dbConnect($db_host = null, $db_user = '', $db_pass = '', $db_name = '',
$db_port = null;
}
$database_link = mysqli_connect('p:' . $db_host, $db_user, $db_pass, null, $db_port, $db_socket);
if (!$db_host && !$db_socket) {
throw new DatabaseConnectException("Database configuration not configured");
}
$database_link = @mysqli_connect('p:' . $db_host, $db_user, $db_pass, null, $db_port, $db_socket);
mysqli_options($database_link, MYSQLI_OPT_LOCAL_INFILE, false);
if ($database_link === false) {
$error = mysqli_connect_error();

View File

@ -947,7 +947,7 @@ $config['graphite']['port'] = 2003;
// HTTP and HTTPS, but they will be insecure. Setting this to $_SERVER["HTTPS"]
// will send secure cookies when the site is being accessed over HTTPS, and
// send insecure cookies when the site is being accessed over HTTP.
$config['secure_cookies'] = $_SERVER["HTTPS"];
$config['secure_cookies'] = isset($_SERVER["HTTPS"]) ? $_SERVER["HTTPS"] : false;
// API config
$config['api']['cors']['enabled'] = false;

View File

@ -2417,29 +2417,6 @@ function return_num($entry)
}
}
/**
* Locate the actual path of a binary
*
* @param $binary
* @return mixed
*/
function locate_binary($binary)
{
if (!str_contains($binary, '/')) {
$output = `whereis -b $binary`;
$list = trim(substr($output, strpos($output, ':') + 1));
$targets = explode(' ', $list);
foreach ($targets as $target) {
if (is_executable($target)) {
return $target;
}
}
}
return $binary;
}
/**
* If Distributed, create a lock, then purge the mysql table
*

View File

@ -33,6 +33,8 @@ use LibreNMS\Config;
global $config;
error_reporting(E_ERROR|E_PARSE|E_CORE_ERROR|E_COMPILE_ERROR);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
$install_dir = realpath(__DIR__ . '/..');
chdir($install_dir);
@ -97,6 +99,8 @@ ini_set('display_errors', 1);
if (!module_selected('nodb', $init_modules)) {
// Connect to database
try {
\LibreNMS\DB\Eloquent::boot();
dbConnect();
} catch (\LibreNMS\Exceptions\DatabaseConnectException $e) {
if (isCli()) {
@ -108,8 +112,10 @@ if (!module_selected('nodb', $init_modules)) {
}
}
// try to load from database, otherwise, just process config
Config::load();
// Load config if not already loaded (which is the case if inside Laravel)
if (!Config::has('install_dir')) {
Config::load();
}
// set display_errors back
ini_set('display_errors', $display_bak);

View File

@ -3,9 +3,11 @@
<description>The PSR2 coding standard with LibreNMS exceptions.</description>
<exclude-pattern>/vendor/*</exclude-pattern>
<exclude-pattern>/storage/*</exclude-pattern>
<exclude-pattern>/bootstrap/cache/*</exclude-pattern>
<exclude-pattern>/lib/*</exclude-pattern>
<exclude-pattern>/html/plugins/*</exclude-pattern>
<exclude-pattern>/config.php</exclude-pattern>
<exclude-pattern>/_ide_helper.php</exclude-pattern>
<rule ref="PSR2" >
<exclude name="Generic.Files.LineLength"/>
</rule>

Some files were not shown because too many files have changed in this diff Show More