175 lines
5.8 KiB
PHP
175 lines
5.8 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire;
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Laravel\Passport\Client;
|
|
use Laravel\Passport\ClientRepository;
|
|
use Laravel\Passport\Token;
|
|
use Livewire\Component;
|
|
|
|
class OauthClients extends Component
|
|
{
|
|
public string $section = 'all';
|
|
|
|
public $name;
|
|
|
|
public $redirect;
|
|
|
|
public $editClientId;
|
|
|
|
public $editName;
|
|
|
|
public $editRedirect;
|
|
|
|
public $authorizationError;
|
|
|
|
public function mount(?string $section = null): void
|
|
{
|
|
if ($section !== null) {
|
|
$this->section = $section;
|
|
}
|
|
}
|
|
|
|
public function showOauthClients(): bool
|
|
{
|
|
return in_array($this->section, ['all', 'oauth-clients'], true);
|
|
}
|
|
|
|
public function showAuthorizedApplications(): bool
|
|
{
|
|
return in_array($this->section, ['all', 'authorized-applications'], true);
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
$clients = collect();
|
|
if ($this->showOauthClients()) {
|
|
$clients = Client::query()
|
|
->orderByDesc('created_at')
|
|
->get();
|
|
|
|
if ($clients->isNotEmpty()) {
|
|
$tokenCountsByClientId = Token::query()
|
|
->whereIn('client_id', $clients->pluck('id')->all())
|
|
->get(['client_id'])
|
|
->groupBy('client_id')
|
|
->map->count();
|
|
|
|
$clients->each(function ($client) use ($tokenCountsByClientId): void {
|
|
$client->setAttribute('associated_token_count', (int) ($tokenCountsByClientId[$client->id] ?? 0));
|
|
});
|
|
}
|
|
}
|
|
|
|
$authorizedApplications = collect();
|
|
if ($this->showAuthorizedApplications()) {
|
|
$authorizedApplications = Token::query()
|
|
->where('revoked', false)
|
|
->with([
|
|
'client',
|
|
'client.user' => fn ($q) => $q->withTrashed(),
|
|
])
|
|
->orderByDesc('created_at')
|
|
->get()
|
|
->unique('client_id')
|
|
->filter(fn ($token) => $token->client !== null)
|
|
->map(fn ($token) => (object) [
|
|
'client_id' => $token->client_id,
|
|
'client_name' => $token->client->name,
|
|
'client_owner_id' => $token->client->user_id,
|
|
'client_owner_display_name' => $token->client->user?->display_name,
|
|
'client_owner_username' => $token->client->user?->username,
|
|
'client_owner_deleted_at' => $token->client->user?->deleted_at,
|
|
'scopes' => $token->scopes,
|
|
'created_at' => $token->created_at,
|
|
'expires_at' => $token->expires_at,
|
|
])
|
|
->values();
|
|
}
|
|
|
|
return view('livewire.oauth-clients', [
|
|
'clients' => $clients,
|
|
'authorizedApplications' => $authorizedApplications,
|
|
]);
|
|
}
|
|
|
|
public function createClient(): void
|
|
{
|
|
$this->validate([
|
|
'name' => 'required|string|max:255',
|
|
'redirect' => 'required|url|max:255',
|
|
]);
|
|
|
|
app(ClientRepository::class)->create(
|
|
auth()->id(),
|
|
$this->name,
|
|
$this->redirect,
|
|
);
|
|
|
|
session()->flash('success', trans('admin/settings/message.oauth.client_created'));
|
|
$this->dispatch('clientCreated');
|
|
}
|
|
|
|
public function deleteClient(Client $clientId): void
|
|
{
|
|
// test for safety
|
|
// ->delete must be of type Client - thus the model binding
|
|
if ((auth()->user()?->isSuperUser()) || ($clientId->user_id == auth()->id())) {
|
|
app(ClientRepository::class)->delete($clientId);
|
|
session()->flash('success', trans('admin/settings/message.oauth.client_deleted'));
|
|
} else {
|
|
Log::warning('User '.auth()->id().' attempted to delete client '.$clientId->id.' which belongs to user '.$clientId->created_by);
|
|
$this->authorizationError = trans('admin/settings/message.oauth.client_delete_denied');
|
|
}
|
|
}
|
|
|
|
public function deleteAuthorizedApplication(int $clientId): void
|
|
{
|
|
$revokedTokenCount = DB::table('oauth_access_tokens')
|
|
->where('client_id', $clientId)
|
|
->where('revoked', false)
|
|
->update(['revoked' => true]);
|
|
|
|
if ($revokedTokenCount > 0) {
|
|
session()->flash('success', trans('admin/settings/message.oauth.token_deleted'));
|
|
} else {
|
|
Log::warning('User '.auth()->id().' attempted to revoke authorized application client '.$clientId.' without matching active tokens.');
|
|
$this->authorizationError = trans('admin/settings/message.oauth.token_delete_denied');
|
|
}
|
|
}
|
|
|
|
public function editClient(Client $editClientId): void
|
|
{
|
|
$this->editName = $editClientId->name;
|
|
$this->editRedirect = $editClientId->redirect;
|
|
|
|
$this->editClientId = $editClientId->id;
|
|
|
|
$this->dispatch('editClient');
|
|
}
|
|
|
|
public function updateClient(Client $editClientId): void
|
|
{
|
|
$this->validate([
|
|
'editName' => 'required|string|max:255',
|
|
'editRedirect' => 'required|url|max:255',
|
|
]);
|
|
|
|
$client = app(ClientRepository::class)->find($editClientId->id);
|
|
if ($client->user_id == auth()->id()) {
|
|
$client->name = $this->editName;
|
|
$client->redirect = $this->editRedirect;
|
|
$client->save();
|
|
session()->flash('success', trans('admin/settings/message.oauth.client_updated'));
|
|
} else {
|
|
Log::warning('User '.auth()->id().' attempted to edit client '.$editClientId->id.' which belongs to user '.$client->created_by);
|
|
$this->authorizationError = trans('admin/settings/message.oauth.client_edit_denied');
|
|
}
|
|
|
|
$this->dispatch('clientUpdated');
|
|
|
|
}
|
|
}
|