mirror of
https://github.com/librenms/librenms.git
synced 2024-09-21 18:38:25 +00:00
Fix API auth issues (#9185)
* Fix API auth issues Api access page now creates tokens with the correct ID. Correctly creates users for legacy user tokens. Fix Ldap comparison Laravel Util class to make code easier to access/read * More api access page fixes * fix style
This commit is contained in:
parent
c3a24fe88f
commit
e8cf6bb385
@ -194,7 +194,7 @@ class LdapAuthorizer extends AuthorizerBase
|
|||||||
public function getUser($user_id)
|
public function getUser($user_id)
|
||||||
{
|
{
|
||||||
foreach ($this->getUserlist() as $user) {
|
foreach ($this->getUserlist() as $user) {
|
||||||
if ($user['user_id'] === $user_id) {
|
if ((int)$user['user_id'] === (int)$user_id) {
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
116
LibreNMS/Util/Laravel.php
Normal file
116
LibreNMS/Util/Laravel.php
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Laravel.php
|
||||||
|
*
|
||||||
|
* Utility class to gather code to do
|
||||||
|
*
|
||||||
|
* 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\Util;
|
||||||
|
|
||||||
|
use App;
|
||||||
|
use Illuminate\Database\Events\QueryExecuted;
|
||||||
|
use LibreNMS\Config;
|
||||||
|
use LibreNMS\DB\Eloquent;
|
||||||
|
use Log;
|
||||||
|
|
||||||
|
class Laravel
|
||||||
|
{
|
||||||
|
public static function enableQueryDebug()
|
||||||
|
{
|
||||||
|
$db = Eloquent::DB();
|
||||||
|
|
||||||
|
if ($db && !$db->getEventDispatcher()->hasListeners('Illuminate\Database\Events\QueryExecuted')) {
|
||||||
|
$db->listen(function (QueryExecuted $query) {
|
||||||
|
// collect bindings and make them a little more readable
|
||||||
|
$bindings = collect($query->bindings)->map(function ($item) {
|
||||||
|
if ($item instanceof \Carbon\Carbon) {
|
||||||
|
return $item->toDateTimeString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
})->toJson();
|
||||||
|
|
||||||
|
if (class_exists('Log')) {
|
||||||
|
Log::debug("SQL[%Y{$query->sql} %y$bindings%n {$query->time}ms] \n", ['color' => true]);
|
||||||
|
} else {
|
||||||
|
c_echo("SQL[%Y{$query->sql} %y$bindings%n {$query->time}ms] \n");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function disableQueryDebug()
|
||||||
|
{
|
||||||
|
$db = Eloquent::DB();
|
||||||
|
|
||||||
|
if ($db) {
|
||||||
|
// remove all query executed event handlers
|
||||||
|
$db->getEventDispatcher()->flush('Illuminate\Database\Events\QueryExecuted');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function enableCliDebugOutput()
|
||||||
|
{
|
||||||
|
if (class_exists('Log')) {
|
||||||
|
$logger = Log::getMonolog();
|
||||||
|
|
||||||
|
// only install if not existing
|
||||||
|
$install = true;
|
||||||
|
$logfile = Config::get('log_file', base_path('logs/librenms.log'));
|
||||||
|
foreach ($logger->getHandlers() as $handler) {
|
||||||
|
if ($handler instanceof \Monolog\Handler\StreamHandler) {
|
||||||
|
if ($handler->getUrl() == 'php://stdout') {
|
||||||
|
$install = false;
|
||||||
|
} elseif ($handler->getUrl() == $logfile) {
|
||||||
|
// send to librenms log file if not a cli app
|
||||||
|
if (!App::runningInConsole()) {
|
||||||
|
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
|
||||||
|
Log::error("$errno $errfile:$errline $errstr");
|
||||||
|
});
|
||||||
|
$handler->setLevel(\Monolog\Logger::DEBUG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($install) {
|
||||||
|
$handler = new \Monolog\Handler\StreamHandler(
|
||||||
|
'php://stdout',
|
||||||
|
\Monolog\Logger::DEBUG
|
||||||
|
);
|
||||||
|
|
||||||
|
$handler->setFormatter(new CliColorFormatter());
|
||||||
|
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function disableCliDebugOutput()
|
||||||
|
{
|
||||||
|
if (class_exists('Log')) {
|
||||||
|
$handlers = Log::getMonolog()->getHandlers();
|
||||||
|
if (isset($handlers[0]) && $handlers[0]->getUrl() == 'php://stdout') {
|
||||||
|
Log::getMonolog()->popHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,7 @@ use LibreNMS\Authentication\LegacyAuth;
|
|||||||
use LibreNMS\Exceptions\AuthenticationException;
|
use LibreNMS\Exceptions\AuthenticationException;
|
||||||
use Request;
|
use Request;
|
||||||
use Session;
|
use Session;
|
||||||
|
use Toastr;
|
||||||
|
|
||||||
class LegacyUserProvider implements UserProvider
|
class LegacyUserProvider implements UserProvider
|
||||||
{
|
{
|
||||||
@ -50,6 +51,21 @@ class LegacyUserProvider implements UserProvider
|
|||||||
return $this->fetchUserByName($username);
|
return $this->fetchUserByName($username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a user by their legacy auth specific identifier.
|
||||||
|
*
|
||||||
|
* @param int $identifier
|
||||||
|
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||||
|
*/
|
||||||
|
public function retrieveByLegacyId($identifier)
|
||||||
|
{
|
||||||
|
error_reporting(0);
|
||||||
|
$legacy_user = LegacyAuth::get()->getUser($identifier);
|
||||||
|
error_reporting(-1);
|
||||||
|
|
||||||
|
return $this->fetchUserByName($legacy_user['username']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a user by their unique identifier and "remember me" token.
|
* Retrieve a user by their unique identifier and "remember me" token.
|
||||||
*
|
*
|
||||||
@ -181,10 +197,11 @@ class LegacyUserProvider implements UserProvider
|
|||||||
|
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
} catch (AuthenticationException $ae) {
|
} catch (AuthenticationException $ae) {
|
||||||
//
|
Toastr::error($ae->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($new_user)) {
|
if (empty($new_user)) {
|
||||||
|
Toastr::info("No user ($auth_id) [$username]");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,10 +72,17 @@ class TokenUserProvider extends LegacyUserProvider implements UserProvider
|
|||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
// missing user for existing token, create it
|
// missing user for existing token, create it assuming legacy auth_id
|
||||||
$user_id = ApiToken::idFromToken($credentials['api_token']);
|
$api_token = ApiToken::where('token_hash', $credentials['api_token'])->first();
|
||||||
|
$user = $this->retrieveByLegacyId($api_token->user_id);
|
||||||
|
|
||||||
return $this->retrieveById($user_id);
|
// update token user_id
|
||||||
|
if ($user) {
|
||||||
|
$api_token->user_id = $user->user_id;
|
||||||
|
$api_token->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
* the source code distribution for details.
|
* the source code distribution for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use App\Models\ApiToken;
|
||||||
|
use App\Models\User;
|
||||||
use LibreNMS\Authentication\LegacyAuth;
|
use LibreNMS\Authentication\LegacyAuth;
|
||||||
|
|
||||||
if (LegacyAuth::user()->hasGlobalAdmin()) {
|
if (LegacyAuth::user()->hasGlobalAdmin()) {
|
||||||
@ -56,8 +58,8 @@ if (LegacyAuth::user()->hasGlobalAdmin()) {
|
|||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<select class="form-control" id="user_id" name="user_id">
|
<select class="form-control" id="user_id" name="user_id">
|
||||||
<?php
|
<?php
|
||||||
foreach ($userlist = LegacyAuth::get()->getUserlist() as $users) {
|
foreach ($userlist = User::all() as $user) {
|
||||||
echo '<option value="'.$users['user_id'].'">'.$users['username'].'</option>';
|
echo '<option value="' . $user->user_id . '">' . $user->username . ' (' . $user->auth_type . ')</option>';
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@ -130,6 +132,7 @@ echo '
|
|||||||
<table class="table table-bordered table-condensed">
|
<table class="table table-bordered table-condensed">
|
||||||
<tr>
|
<tr>
|
||||||
<th>User</th>
|
<th>User</th>
|
||||||
|
<th>Auth</th>
|
||||||
<th>Token Hash</th>
|
<th>Token Hash</th>
|
||||||
<th>QR Code</th>
|
<th>QR Code</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
@ -138,25 +141,21 @@ echo '
|
|||||||
</tr>
|
</tr>
|
||||||
';
|
';
|
||||||
|
|
||||||
foreach (dbFetchRows('SELECT * FROM `api_tokens` ORDER BY user_id') as $api) {
|
foreach (ApiToken::all() as $api) {
|
||||||
if ($api['disabled'] == '1') {
|
$user_details = $userlist->where('user_id', $api->user_id)->first();
|
||||||
$api_disabled = 'checked';
|
|
||||||
} else {
|
$api_disabled = $api->disabled == 1 ? 'checked' : '';
|
||||||
$api_disabled = '';
|
$color = $user_details->auth_type == LegacyAuth::getType() ? '' : 'bgcolor="lightgrey"';
|
||||||
}
|
|
||||||
foreach ($userlist as $tmp_user) {
|
|
||||||
if ($tmp_user['user_id'] === $api['user_id']) {
|
|
||||||
$user_details = $tmp_user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo '
|
echo '
|
||||||
<tr id="'.$api['id'].'">
|
<tr id="'.$api->id.'" ' . $color . '>
|
||||||
<td>'.$user_details['username'].'</td>
|
<td>'.$user_details->username.'</td>
|
||||||
<td>'.$api['token_hash'].'</td>
|
<td>'.$user_details->auth_type.'</td>
|
||||||
<td><button class="btn btn-info btn-xs" data-toggle="modal" data-target="#display-qr" data-token_hash="'.$api['token_hash'].'"><i class="fa fa-qrcode" ></i></button></td>
|
<td>'.$api->token_hash.'</td>
|
||||||
<td>'.$api['description'].'</td>
|
<td><button class="btn btn-info btn-xs" data-toggle="modal" data-target="#display-qr" data-token_hash="'.$api->token_hash.'"><i class="fa fa-qrcode" ></i></button></td>
|
||||||
<td><input type="checkbox" name="token-status" data-token_id="'.$api['id'].'" data-off-text="No" data-on-text="Yes" data-on-color="danger" '.$api_disabled.' data-size="mini"></td>
|
<td>'.$api->description.'</td>
|
||||||
<td><button type="button" class="btn btn-danger btn-xs" id="'.$api['id'].'" data-token_id="'.$api['id'].'" data-toggle="modal" data-target="#confirm-delete">Delete</button></td>
|
<td><input type="checkbox" name="token-status" data-token_id="'.$api->id.'" data-off-text="No" data-on-text="Yes" data-on-color="danger" '.$api_disabled.' data-size="mini"></td>
|
||||||
|
<td><button type="button" class="btn btn-danger btn-xs" id="'.$api->id.'" data-token_id="'.$api->id.'" data-toggle="modal" data-target="#confirm-delete">Delete</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,6 @@ function set_debug($state = true, $silence = false)
|
|||||||
|
|
||||||
$debug = $state; // set to global
|
$debug = $state; // set to global
|
||||||
|
|
||||||
$db = \LibreNMS\DB\Eloquent::DB();
|
|
||||||
|
|
||||||
restore_error_handler(); // disable Laravel error handler
|
restore_error_handler(); // disable Laravel error handler
|
||||||
|
|
||||||
if (isset($debug) && $debug) {
|
if (isset($debug) && $debug) {
|
||||||
@ -47,75 +45,16 @@ function set_debug($state = true, $silence = false)
|
|||||||
ini_set('log_errors', 0);
|
ini_set('log_errors', 0);
|
||||||
error_reporting(E_ALL & ~E_NOTICE);
|
error_reporting(E_ALL & ~E_NOTICE);
|
||||||
|
|
||||||
if (class_exists('Log')) {
|
\LibreNMS\Util\Laravel::enableCliDebugOutput();
|
||||||
$logger = Log::getMonolog();
|
\LibreNMS\Util\Laravel::enableQueryDebug();
|
||||||
|
|
||||||
// only install if not existing
|
|
||||||
$install = true;
|
|
||||||
$logfile = Config::get('log_file', base_path('logs/librenms.log'));
|
|
||||||
foreach ($logger->getHandlers() as $handler) {
|
|
||||||
if ($handler instanceof \Monolog\Handler\StreamHandler) {
|
|
||||||
if ($handler->getUrl() == 'php://stdout') {
|
|
||||||
$install = false;
|
|
||||||
} elseif ($handler->getUrl() == $logfile) {
|
|
||||||
// send to librenms log file if not a cli app
|
|
||||||
if (!App::runningInConsole()) {
|
|
||||||
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
|
|
||||||
Log::error("$errno $errfile:$errline $errstr");
|
|
||||||
});
|
|
||||||
$handler->setLevel(\Monolog\Logger::DEBUG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($install) {
|
|
||||||
$handler = new \Monolog\Handler\StreamHandler(
|
|
||||||
'php://stdout',
|
|
||||||
\Monolog\Logger::DEBUG
|
|
||||||
);
|
|
||||||
|
|
||||||
$handler->setFormatter(new LibreNMS\Util\CliColorFormatter());
|
|
||||||
|
|
||||||
$logger->pushHandler($handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($db && !$db->getEventDispatcher()->hasListeners('Illuminate\Database\Events\QueryExecuted')) {
|
|
||||||
$db->listen(function (QueryExecuted $query) {
|
|
||||||
// collect bindings and make them a little more readable
|
|
||||||
$bindings = collect($query->bindings)->map(function ($item) {
|
|
||||||
if ($item instanceof \Carbon\Carbon) {
|
|
||||||
return $item->toDateTimeString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $item;
|
|
||||||
})->toJson();
|
|
||||||
|
|
||||||
if (class_exists('Log')) {
|
|
||||||
Log::debug("SQL[%Y{$query->sql} %y$bindings%n {$query->time}ms] \n", ['color' => true]);
|
|
||||||
} else {
|
|
||||||
c_echo("SQL[%Y{$query->sql} %y$bindings%n {$query->time}ms] \n");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('display_startup_errors', 0);
|
ini_set('display_startup_errors', 0);
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
error_reporting($silence ? 0 : E_ERROR);
|
error_reporting($silence ? 0 : E_ERROR);
|
||||||
|
|
||||||
if (class_exists('Log')) {
|
\LibreNMS\Util\Laravel::enableCliDebugOutput();
|
||||||
$handlers = Log::getMonolog()->getHandlers();
|
\LibreNMS\Util\Laravel::disableQueryDebug();
|
||||||
if (isset($handlers[0]) && $handlers[0]->getUrl() == 'php://stdout') {
|
|
||||||
Log::getMonolog()->popHandler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($db) {
|
|
||||||
// remove all query executed event handlers
|
|
||||||
$db->getEventDispatcher()->flush('Illuminate\Database\Events\QueryExecuted');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $debug;
|
return $debug;
|
||||||
|
Loading…
Reference in New Issue
Block a user