Feat: make signin / signout uris render related to apptype
- Introduced `needSignInUris` and `needSignOutUris` methods in `OidcConfigResolver` to determine URI requirements based on app type. - Updated `AuthorizationCodeClientFactory` to merge sign-in and sign-out URIs for redirect handling. - Enhanced app creation UI to conditionally display sign-in and sign-out URI fields. - Added authorization check for OIDC app creation using `AppPermissionEnum`.
This commit is contained in:
parent
81e9773f5b
commit
882538130b
@ -23,7 +23,8 @@ public function create(
|
|||||||
): ClientCredentialsData {
|
): ClientCredentialsData {
|
||||||
$client = $this->client->createAuthorizationCodeGrantClient(
|
$client = $this->client->createAuthorizationCodeGrantClient(
|
||||||
name: $data->name,
|
name: $data->name,
|
||||||
redirectUris: $data->signInUris,
|
// laravel-oidc-server expects redirect_uris to consist of sign_in and sign_out uris.
|
||||||
|
redirectUris: array_merge($data->signInUris, $data->signOutUris),
|
||||||
confidential: ApplicationTypeEnum::Web === $data->type,
|
confidential: ApplicationTypeEnum::Web === $data->type,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -21,4 +21,16 @@ public function hasClientSecret(): bool
|
|||||||
{
|
{
|
||||||
return ApplicationTypeEnum::SPA !== $this->applicationType;
|
return ApplicationTypeEnum::SPA !== $this->applicationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function needSignInUris(): bool
|
||||||
|
{
|
||||||
|
|
||||||
|
return ApplicationTypeEnum::Machine !== $this->applicationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function needSignOutUris(): bool
|
||||||
|
{
|
||||||
|
|
||||||
|
return ApplicationTypeEnum::Machine !== $this->applicationType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,8 +10,7 @@
|
|||||||
use App\Models\{ConnectionProtocol, ConnectionStatus};
|
use App\Models\{ConnectionProtocol, ConnectionStatus};
|
||||||
use App\Services\{ApplicationLogoUploader, ConnectedAppService};
|
use App\Services\{ApplicationLogoUploader, ConnectedAppService};
|
||||||
use App\Services\Applications\OIDC\Factory\ClientCreationFactory;
|
use App\Services\Applications\OIDC\Factory\ClientCreationFactory;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\{DB, Log};
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Concerns\HandlesOperations;
|
use App\Concerns\HandlesOperations;
|
||||||
|
use App\Data\Application\CreatedApplicationData;
|
||||||
use App\Data\Application\StoreOIDCAppData;
|
use App\Data\Application\StoreOIDCAppData;
|
||||||
use App\Data\ConnectedApp\ConnectedAppData;
|
use App\Data\ConnectedApp\ConnectedAppData;
|
||||||
use App\Enums\{ApplicationTypeEnum, ConnectionProtocolEnum, UserAccessTypeEnum};
|
use App\Enums\{ApplicationTypeEnum, ConnectionProtocolEnum, Permissions\AppPermissionEnum, UserAccessTypeEnum};
|
||||||
use App\Livewire\Concerns\Choices\{ChoiceField, WithSearchableChoices};
|
use App\Livewire\Concerns\Choices\{ChoiceField, WithSearchableChoices};
|
||||||
use App\Livewire\Concerns\WithRepeaterFields;
|
use App\Livewire\Concerns\WithRepeaterFields;
|
||||||
use App\Livewire\Forms\StoreOIDCAppForm;
|
use App\Livewire\Forms\StoreOIDCAppForm;
|
||||||
@ -57,17 +58,14 @@ public function render()
|
|||||||
|
|
||||||
public function save(bool $goBack = true): void
|
public function save(bool $goBack = true): void
|
||||||
{
|
{
|
||||||
|
$this->authorize(AppPermissionEnum::Create->value);
|
||||||
$this->form->validate();
|
$this->form->validate();
|
||||||
$this->attempt(
|
$this->attempt(
|
||||||
function () {
|
function () {
|
||||||
$data = StoreOIDCAppData::fromArray($this->applicationType, $this->form->pull());
|
$data = StoreOIDCAppData::fromArray($this->applicationType, $this->form->pull());
|
||||||
$appdata = $this->oidcService->createApp($data);
|
$appdata = $this->oidcService->createApp($data);
|
||||||
|
|
||||||
// Show the credentials
|
$this->showCredentials($appdata);
|
||||||
$this->created = true;
|
|
||||||
$this->clientId = $appdata->clientCredentials->clientId;
|
|
||||||
$this->clientSecret = $appdata->clientCredentials->clientSecret;
|
|
||||||
$this->app = $appdata->application;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -105,6 +103,24 @@ public function clearRoles(): void
|
|||||||
$this->clearChoice('roles');
|
$this->clearChoice('roles');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Computed]
|
||||||
|
public function hasClientSecret(): bool
|
||||||
|
{
|
||||||
|
return $this->configResolver->for($this->applicationType)->hasClientSecret();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Computed]
|
||||||
|
public function needSignInUris(): bool
|
||||||
|
{
|
||||||
|
return $this->configResolver->for($this->applicationType)->needSignInUris();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Computed]
|
||||||
|
public function needSignOutUris(): bool
|
||||||
|
{
|
||||||
|
return $this->configResolver->for($this->applicationType)->needSignOutUris();
|
||||||
|
}
|
||||||
|
|
||||||
protected function choiceFields(): array
|
protected function choiceFields(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@ -116,10 +132,12 @@ protected function choiceFields(): array
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Computed]
|
private function showCredentials(CreatedApplicationData $appData): void
|
||||||
public function hasClientSecret(): bool
|
|
||||||
{
|
{
|
||||||
return $this->configResolver->for($this->applicationType)->hasClientSecret();
|
$this->clientId = $appData->clientCredentials->clientId;
|
||||||
|
$this->clientSecret = $appData->clientCredentials->clientSecret;
|
||||||
|
$this->app = $appData->application;
|
||||||
|
$this->created = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
?>
|
?>
|
||||||
@ -132,7 +150,7 @@ public function hasClientSecret(): bool
|
|||||||
>
|
>
|
||||||
<div class="flex w-full justify-center items-center pt-6">
|
<div class="flex w-full justify-center items-center pt-6">
|
||||||
<article class="mx-auto flex items-center gap-4">
|
<article class="mx-auto flex items-center gap-4">
|
||||||
<x-mary-avatar :image="$app->logo ? asset($app->logo) : asset('images/app-icon-placeholder.png')"
|
<x-mary-avatar :image="$app?->logo ? asset($app->logo) : asset('images/app-icon-placeholder.png')"
|
||||||
alt="App logo"
|
alt="App logo"
|
||||||
class="w-14! rounded-lg! p-2"/>
|
class="w-14! rounded-lg! p-2"/>
|
||||||
<h1 class="text-2xl font-medium">{{$app->name}}</h1>
|
<h1 class="text-2xl font-medium">{{$app->name}}</h1>
|
||||||
@ -186,37 +204,40 @@ class="btn-primary"
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- General settings end -->
|
<!-- General settings end -->
|
||||||
|
@if($this->needSignInUris)
|
||||||
<!-- Sign-in uris start -->
|
<!-- Sign-in uris start -->
|
||||||
<hr>
|
<hr>
|
||||||
<div class="flex gap-4 flex-col w-full md:flex-row">
|
<div class="flex gap-4 flex-col w-full md:flex-row">
|
||||||
<article class="w-full md:w-2/5">
|
<article class="w-full md:w-2/5">
|
||||||
<h2 class="font-bold">Sign In Redirect URIs</h2>
|
<h2 class="font-bold">Sign In Redirect URIs</h2>
|
||||||
<p class="text-sm text-gray-500 max-w-70 mt-4">
|
<p class="text-sm text-gray-500 max-w-70 mt-4">
|
||||||
{{config('app.name')}} sends response and ID Token back to these URIs.
|
Allowed URIs which this app can ask to get the response back.
|
||||||
</p>
|
</p>
|
||||||
</article>
|
</article>
|
||||||
<div class="w-full md:w-3/5">
|
<div class="w-full md:w-3/5">
|
||||||
<x-shared.repeater-input model="form.signInUris" :items="$form->signInUris"/>
|
<p class="text-xs text-gray-500 mb-2">You can add this later.</p>
|
||||||
|
<x-shared.repeater-input model="form.signInUris" :items="$form->signInUris"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<!-- Sign-in uris end -->
|
||||||
<!-- Sign-in uris end -->
|
@endif
|
||||||
|
@if($this->needSignOutUris)
|
||||||
<!-- Sign-out uris start -->
|
<!-- Sign-out uris start -->
|
||||||
<hr>
|
<hr>
|
||||||
<div class="flex gap-4 flex-col w-full md:flex-row">
|
<div class="flex gap-4 flex-col w-full md:flex-row">
|
||||||
<article class="w-full md:w-2/5">
|
<article class="w-full md:w-2/5">
|
||||||
<h2 class="font-bold">Sign out Redirect URIs</h2>
|
<h2 class="font-bold">Sign out Redirect URIs</h2>
|
||||||
<p class="text-sm text-gray-500 max-w-70 mt-4">
|
<p class="text-sm text-gray-500 max-w-70 mt-4">
|
||||||
{{config('app.name')}} sends back the user to these URIs after logout.
|
Allowed URIs which this app can redirect the user back to after logout.
|
||||||
</p>
|
</p>
|
||||||
</article>
|
</article>
|
||||||
<div class="w-full md:w-3/5">
|
<div class="w-full md:w-3/5">
|
||||||
<x-shared.repeater-input model="form.signOutUris" :items="$form->signOutUris"/>
|
<p class="text-xs text-gray-500 mb-2">You can add this later.</p>
|
||||||
|
<x-shared.repeater-input model="form.signOutUris" :items="$form->signOutUris"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<!-- Sign-out uris end -->
|
||||||
<!-- Sign-out uris end -->
|
@endif
|
||||||
|
|
||||||
<!-- Access start -->
|
<!-- Access start -->
|
||||||
<hr>
|
<hr>
|
||||||
<div class="flex gap-4 flex-col w-full md:flex-row">
|
<div class="flex gap-4 flex-col w-full md:flex-row">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user