Skip to content

Commit 360bc06

Browse files
committed
WIP
1 parent f4ca350 commit 360bc06

11 files changed

+203
-64
lines changed

phpstan-baseline.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ parameters:
1313
-
1414
message: "#^Call to an undefined method object\\:\\:where\\(\\)\\.$#"
1515
count: 1
16-
path: src/Http/Controllers/DeveloperLoginsController.php
16+
path: src/FilamentDevelopersLogin.php
1717

1818
-
1919
message: "#^Access to an undefined property DutchCodingCompany\\\\FilamentDeveloperLogins\\\\Tests\\\\Fixtures\\\\TestUser\\:\\:\\$is_admin\\.$#"

resources/lang/en/auth.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
return [
44
'login-as' => 'Login as',
5+
'switch-to' => 'Switch to',
56

67
'messages' => [
78
'failed' => 'Login failed, check if the user is allowed to access the panel.',

resources/views/components/developer-logins.blade.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@foreach ($users as $label => $email)
1+
@foreach ($users as $label => $credentials)
22
@if ($loop->first)
33
<div class="flex flex-col gap-y-6">
44
<div class="relative flex items-center justify-center text-center">
@@ -22,10 +22,10 @@
2222
@csrf
2323

2424
<input type="hidden" name="panel_id" value="{{ \Filament\Facades\Filament::getId() }}">
25-
<input type="hidden" name="credentials" value="{{ $email }}">
25+
<input type="hidden" name="credentials" value="{{ $credentials }}">
2626

2727
<x-filament::button class="w-full" color="gray" outlined="true" type="submit">
28-
{{ "$label ($email)" }}
28+
{{ "$label ($credentials)" }}
2929
</x-filament::button>
3030
</form>
3131
@if ($loop->first)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@if (filled($users))
2+
<div>
3+
<x-filament::dropdown>
4+
<x-slot name="trigger">
5+
<x-filament::button icon="heroicon-o-user" color="gray" outlined="false">
6+
{{ __('filament-developer-logins::auth.switch-to') }}
7+
</x-filament::button>
8+
</x-slot>
9+
10+
<x-filament::dropdown.list>
11+
@foreach ($users as $label => $credentials)
12+
<x-filament::dropdown.list.item
13+
wire:click="loginAs('{{ $credentials }}')"
14+
color="{{ $credentials === $current ? 'primary' : 'gray' }}"
15+
>
16+
{{ "$label ($credentials)" }}
17+
</x-filament::dropdown.list.item>
18+
@endforeach
19+
</x-filament::dropdown.list>
20+
</x-filament::dropdown>
21+
</div>
22+
@endif
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace DutchCodingCompany\FilamentDeveloperLogins\Facades;
4+
5+
use Illuminate\Support\Facades\Facade;
6+
7+
/**
8+
* @mixin \DutchCodingCompany\FilamentDeveloperLogins\FilamentDevelopersLogin
9+
*/
10+
class FilamentDevelopersLogin extends Facade
11+
{
12+
protected static function getFacadeAccessor(): string
13+
{
14+
return 'filament-developers-login';
15+
}
16+
}

src/FilamentDeveloperLoginsPlugin.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,17 @@
88
use Filament\Contracts\Plugin;
99
use Filament\Facades\Filament;
1010
use Filament\Panel;
11+
use Filament\Support\Concerns\EvaluatesClosures;
1112
use Illuminate\Contracts\Auth\Authenticatable;
1213

1314
class FilamentDeveloperLoginsPlugin implements Plugin
1415
{
16+
use EvaluatesClosures;
17+
1518
public Closure | bool $enabled = false;
1619

20+
public Closure | bool $switchable = true;
21+
1722
/**
1823
* @var array<string, string>
1924
*/
@@ -78,9 +83,21 @@ public function enabled(Closure | bool $value = true): static
7883
return $this;
7984
}
8085

81-
public function getEnabled(): Closure | bool
86+
public function getEnabled(): bool
87+
{
88+
return $this->evaluate($this->enabled);
89+
}
90+
91+
public function switchable(Closure | bool $value): static
92+
{
93+
$this->switchable = $value;
94+
95+
return $this;
96+
}
97+
98+
public function getSwitchable(): bool
8299
{
83-
return $this->enabled;
100+
return $this->evaluate($this->switchable);
84101
}
85102

86103
/**

src/FilamentDeveloperLoginsServiceProvider.php

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
namespace DutchCodingCompany\FilamentDeveloperLogins;
44

5+
use DutchCodingCompany\FilamentDeveloperLogins\Livewire\MenuLogins;
56
use DutchCodingCompany\FilamentDeveloperLogins\View\Components\DeveloperLogins;
67
use Filament\Facades\Filament;
78
use Filament\Support\Concerns\EvaluatesClosures;
89
use Filament\Support\Facades\FilamentView;
910
use Filament\View\PanelsRenderHook;
1011
use Illuminate\Support\Facades\Blade;
12+
use Livewire\Livewire;
1113
use Spatie\LaravelPackageTools\Package;
1214
use Spatie\LaravelPackageTools\PackageServiceProvider;
1315

@@ -25,29 +27,49 @@ public function configurePackage(Package $package): void
2527
->hasTranslations();
2628
}
2729

30+
public function packageRegistered(): void
31+
{
32+
$this->app->singleton(FilamentDevelopersLogin::class);
33+
$this->app->alias(FilamentDevelopersLogin::class, 'filament-developers-login');
34+
}
35+
2836
public function packageBooted(): void
2937
{
3038
Blade::componentNamespace('DutchCodingCompany\FilamentDeveloperLogins\View\Components', 'filament-developer-logins');
3139
Blade::component('developer-logins', DeveloperLogins::class);
40+
Livewire::component('menu-logins', MenuLogins::class);
41+
42+
$this->registerRenderHooks();
43+
}
44+
45+
protected static function registerRenderHooks(): void
46+
{
47+
$panel = Filament::getCurrentPanel();
48+
if (is_null($panel) || ! $panel->hasPlugin('filament-developer-logins')) {
49+
return;
50+
}
51+
52+
/** @var FilamentDeveloperLoginsPlugin $plugin */
53+
$plugin = $panel->getPlugin('filament-developer-logins');
54+
55+
// Check if the plugin is enabled.
56+
if (! $plugin->getEnabled()) {
57+
return;
58+
}
3259

3360
FilamentView::registerRenderHook(
3461
PanelsRenderHook::AUTH_LOGIN_FORM_AFTER,
35-
static function (): ?string {
36-
$panel = Filament::getCurrentPanel();
37-
if (! $panel->hasPlugin('filament-developer-logins')) {
38-
return null;
39-
}
62+
static fn (): string => Blade::render('<x-filament-developer-logins::developer-logins />'),
63+
);
4064

41-
/** @var FilamentDeveloperLoginsPlugin $plugin */
42-
$plugin = $panel->getPlugin('filament-developer-logins');
43-
if (is_bool($plugin->getEnabled())
44-
? ! $plugin->getEnabled()
45-
: ! call_user_func($plugin->getEnabled())
46-
) {
65+
FilamentView::registerRenderHook(
66+
PanelsRenderHook::GLOBAL_SEARCH_AFTER,
67+
static function () use ($plugin) : ?string {
68+
if (! $plugin->getSwitchable()) {
4769
return null;
4870
}
4971

50-
return Blade::render('<x-filament-developer-logins::developer-logins />');
72+
return Blade::render('@livewire(\'menu-logins\')');
5173
},
5274
);
5375
}

src/FilamentDevelopersLogin.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace DutchCodingCompany\FilamentDeveloperLogins;
4+
5+
use DutchCodingCompany\FilamentDeveloperLogins\Exceptions\ImplementationException;
6+
use Filament\Models\Contracts\FilamentUser;
7+
use Filament\Panel;
8+
use Illuminate\Http\RedirectResponse;
9+
use Illuminate\Validation\ValidationException;
10+
use Livewire\Features\SupportRedirects\Redirector;
11+
12+
class FilamentDevelopersLogin
13+
{
14+
public function login(Panel $panel, FilamentDeveloperLoginsPlugin $plugin, string $credentials): RedirectResponse | Redirector
15+
{
16+
if (! in_array($credentials, $plugin->getUsers())) {
17+
throw new ImplementationException('The user is not found in the defined users, please check the configuration of the plugin.');
18+
}
19+
20+
if ($panel->auth()->check()) {
21+
$panel->auth()->logout();
22+
}
23+
24+
$model = (new ($plugin->getModelClass()))
25+
->where($plugin->getColumn(), $credentials)->firstOrFail();
26+
27+
$panel->auth()->login($model);
28+
29+
if (
30+
($model instanceof FilamentUser) &&
31+
(! $model->canAccessPanel($panel))
32+
) {
33+
$panel->auth()->logout();
34+
35+
throw ValidationException::withMessages([
36+
'developer-logins-failed' => __('filament-developer-logins::auth.messages.failed'),
37+
]);
38+
}
39+
40+
session()->regenerate();
41+
42+
return redirect()
43+
->to(
44+
$plugin->getRedirectTo() ?? $panel->getUrl()
45+
);
46+
}
47+
}

src/Http/Controllers/DeveloperLoginsController.php

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,62 +3,39 @@
33
namespace DutchCodingCompany\FilamentDeveloperLogins\Http\Controllers;
44

55
use DutchCodingCompany\FilamentDeveloperLogins\Exceptions\ImplementationException;
6+
use DutchCodingCompany\FilamentDeveloperLogins\Facades\FilamentDevelopersLogin;
67
use DutchCodingCompany\FilamentDeveloperLogins\FilamentDeveloperLoginsPlugin;
78
use DutchCodingCompany\FilamentDeveloperLogins\Http\Requests\LoginAsRequest;
89
use Filament\Facades\Filament;
9-
use Filament\Models\Contracts\FilamentUser;
1010
use Filament\Panel;
1111
use Illuminate\Http\RedirectResponse;
1212
use Illuminate\Routing\Controller;
13-
use Illuminate\Support\Facades\Auth;
14-
use Illuminate\Validation\ValidationException;
13+
use Livewire\Features\SupportRedirects\Redirector;
1514

1615
class DeveloperLoginsController extends Controller
1716
{
18-
protected Panel $panel;
19-
20-
protected FilamentDeveloperLoginsPlugin $plugin;
21-
2217
/**
2318
* @throws ImplementationException
2419
*/
25-
public function loginAs(LoginAsRequest $request): RedirectResponse
20+
public function loginAs(LoginAsRequest $request): RedirectResponse | Redirector
2621
{
27-
$this->initiate($request);
22+
[$panel, $plugin] = $this->initiate($request);
2823

2924
$credentials = $request->validated('credentials');
30-
if (! in_array($credentials, $this->plugin->getUsers())) {
31-
throw new ImplementationException('The user is not found in the defined users, please check the configuration of the plugin.');
32-
}
33-
34-
$model = (new ($this->plugin->getModelClass()))
35-
->where($this->plugin->getColumn(), $credentials)->firstOrFail();
36-
37-
Filament::auth()->login($model);
38-
39-
if (
40-
($model instanceof FilamentUser) &&
41-
(! $model->canAccessPanel($this->panel))
42-
) {
43-
Auth::logout();
44-
45-
throw ValidationException::withMessages([
46-
'developer-logins-failed' => __('filament-developer-logins::auth.messages.failed'),
47-
]);
48-
}
4925

50-
session()->regenerate();
51-
52-
return redirect()
53-
->to(
54-
$this->plugin->getRedirectTo() ?? $this->panel->getUrl()
55-
);
26+
return FilamentDevelopersLogin::login($panel, $plugin, $credentials);
5627
}
5728

58-
protected function initiate(LoginAsRequest $request): void
29+
/**
30+
* @return array{Panel, FilamentDeveloperLoginsPlugin}
31+
*
32+
* @throws ImplementationException
33+
*/
34+
protected function initiate(LoginAsRequest $request): array
5935
{
60-
$this->panel = Filament::getPanel($request->validated('panel_id'));
61-
62-
$this->plugin = FilamentDeveloperLoginsPlugin::getById($request->validated('panel_id'));
36+
return [
37+
Filament::getPanel($request->validated('panel_id')),
38+
FilamentDeveloperLoginsPlugin::getById($request->validated('panel_id')),
39+
];
6340
}
6441
}

src/Http/Requests/LoginAsRequest.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace DutchCodingCompany\FilamentDeveloperLogins\Http\Requests;
44

5+
use DutchCodingCompany\FilamentDeveloperLogins\Facades\FilamentDevelopersLogin;
56
use DutchCodingCompany\FilamentDeveloperLogins\FilamentDeveloperLoginsPlugin;
67
use Filament\Facades\Filament;
78
use Illuminate\Foundation\Http\FormRequest;
@@ -24,13 +25,6 @@ public function rules(): array
2425

2526
public function authorize(): bool
2627
{
27-
return is_bool($this->plugin()->getEnabled())
28-
? $this->plugin()->getEnabled()
29-
: call_user_func($this->plugin()->getEnabled());
30-
}
31-
32-
protected function plugin(): FilamentDeveloperLoginsPlugin
33-
{
34-
return $this->plugin ??= FilamentDeveloperLoginsPlugin::getById($this->get('panel_id'));
28+
return FilamentDeveloperLoginsPlugin::getById($this->get('panel_id'))->getEnabled();
3529
}
3630
}

0 commit comments

Comments
 (0)