mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Add new setting to specify if user roles will be set at login or not. Without this setting enabled, roles are only set when the user is first created and never after that. If roles set via Filter-ID attribute or radius.default_roles change, they will never be reflected on existing users. For that reason, the default is set to enabled. Historically, radius did not enforce roles.
76 lines
2.5 KiB
PHP
76 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace LibreNMS\Authentication;
|
|
|
|
use App\Models\User;
|
|
use Dapphp\Radius\Radius;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Str;
|
|
use LibreNMS\Config;
|
|
use LibreNMS\Enum\LegacyAuthLevel;
|
|
use LibreNMS\Exceptions\AuthenticationException;
|
|
use LibreNMS\Util\Debug;
|
|
|
|
class RadiusAuthorizer extends MysqlAuthorizer
|
|
{
|
|
protected static $HAS_AUTH_USERMANAGEMENT = true;
|
|
protected static $CAN_UPDATE_USER = true;
|
|
protected static $CAN_UPDATE_PASSWORDS = false;
|
|
|
|
protected Radius $radius;
|
|
|
|
private array $roles = []; // temp cache of roles
|
|
|
|
public function __construct()
|
|
{
|
|
$this->radius = new Radius(Config::get('radius.hostname'), Config::get('radius.secret'), Config::get('radius.suffix'), Config::get('radius.timeout'), Config::get('radius.port'));
|
|
}
|
|
|
|
public function authenticate($credentials)
|
|
{
|
|
if (empty($credentials['username'])) {
|
|
throw new AuthenticationException('Username is required');
|
|
}
|
|
|
|
if (Debug::isEnabled()) {
|
|
$this->radius->setDebug(true);
|
|
}
|
|
|
|
$password = $credentials['password'] ?? null;
|
|
if ($this->radius->accessRequest($credentials['username'], $password) === true) {
|
|
$user = User::thisAuth()->firstOrNew(['username' => $credentials['username']], [
|
|
'auth_type' => LegacyAuth::getType(),
|
|
'can_modify_passwd' => 0,
|
|
]);
|
|
$new_user = ! $user->exists;
|
|
$user->save();
|
|
|
|
// cache a single role from the Filter-ID attribute now because attributes are cleared every accessRequest
|
|
$filter_id_attribute = $this->radius->getAttribute(11);
|
|
if ($filter_id_attribute && Str::startsWith($filter_id_attribute, 'librenms_role_')) {
|
|
$this->roles[$credentials['username']] = [substr($filter_id_attribute, 14)];
|
|
}
|
|
|
|
if (Config::get('radius.enforce_roles') || $new_user) {
|
|
$user->setRoles($this->roles[$credentials['username']] ?? $this->getDefaultRoles(), true);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
throw new AuthenticationException();
|
|
}
|
|
|
|
public function getRoles(string $username): array|false
|
|
{
|
|
return $this->roles[$username] ?? false;
|
|
}
|
|
|
|
private function getDefaultRoles(): array
|
|
{
|
|
// return roles or translate from the old radius.default_level
|
|
return Config::get('radius.default_roles')
|
|
?: Arr::wrap(LegacyAuthLevel::from(Config::get('radius.default_level') ?? 1)->getName());
|
|
}
|
|
}
|