pelican-panel-mirror/app/Services/Subusers/SubuserUpdateService.php
Boy132 f0f04fd86a
Add backend validation to subuser permissions (#1014)
* add backend validation to subuser permissions

* always allow websocket.connect

* use collection to clean permissions
2025-02-21 11:02:08 +01:00

60 lines
2.1 KiB
PHP

<?php
namespace App\Services\Subusers;
use App\Facades\Activity;
use App\Models\Permission;
use App\Models\Server;
use App\Models\Subuser;
use App\Repositories\Daemon\DaemonServerRepository;
use Illuminate\Http\Client\ConnectionException;
class SubuserUpdateService
{
public function __construct(
private DaemonServerRepository $serverRepository,
) {}
public function handle(Subuser $subuser, Server $server, array $permissions): void
{
$cleanedPermissions = collect($permissions)
->unique()
->filter(fn ($permission) => $permission === Permission::ACTION_WEBSOCKET_CONNECT || auth()->user()->can($permission, $server))
->sort()
->values()
->all();
$current = $subuser->permissions;
sort($current);
$log = Activity::event('server:subuser.update')
->subject($subuser->user)
->property([
'email' => $subuser->user->email,
'old' => $current,
'new' => $cleanedPermissions,
'revoked' => true,
]);
// Only update the database and hit up the daemon instance to invalidate JTI's if the permissions
// have actually changed for the user.
if ($cleanedPermissions !== $current) {
$log->transaction(function ($instance) use ($subuser, $cleanedPermissions, $server) {
$subuser->update(['permissions' => $cleanedPermissions]);
try {
$this->serverRepository->setServer($server)->revokeUserJTI($subuser->user_id);
} catch (ConnectionException $exception) {
// Don't block this request if we can't connect to the daemon instance. Chances are it is
// offline and the token will be invalid once daemon boots back.
logger()->warning($exception, ['user_id' => $subuser->user_id, 'server_id' => $server->id]);
$instance->property('revoked', false);
}
});
}
$log->reset();
}
}