Skip to content

Commit

Permalink
MoonShine v2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
Jampire committed Dec 16, 2023
1 parent b67e825 commit 65828bc
Show file tree
Hide file tree
Showing 40 changed files with 592 additions and 280 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
echo "cache-key=${{ env.cache_key }}" >> "$GITHUB_OUTPUT"
echo "extensions=${{ env.extensions }}" >> "$GITHUB_OUTPUT"
echo "tools=${{ env.tools }}" >> "$GITHUB_OUTPUT"
echo "php_versions=['8.1', '8.2']" >> "$GITHUB_OUTPUT"
echo "php_versions=['8.1', '8.2', '8.3']" >> "$GITHUB_OUTPUT"
echo "php_version=['8.1']" >> "$GITHUB_OUTPUT"
code-style:
Expand Down Expand Up @@ -69,6 +69,7 @@ jobs:
cache_key: ${{ needs.env-setup.outputs.cache-key }}
extensions: ${{ needs.env-setup.outputs.extensions }}
min_coverage: 100
type_coverage: 100

rector:
needs: [ env-setup ]
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# Release Notes for 2.x

## [2.0.0 (2023-12-17)](https://github.com/Jampire/moonshine-impersonate/compare/v1.4.1...v2.0.0)

### Adds

- MoonShine v2 support, Belarus Localization ([#25](https://github.com/Jampire/moonshine-impersonate/pull/25))

# Release Notes for 1.x

## [1.4.1 (2023-12-15)](https://github.com/Jampire/moonshine-impersonate/compare/v1.4.0...v1.4.1)
Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ saves lots of time because you can see exactly what they see.

## Compatibility

| MoonShine | MoonShine Impersonate |
|:------------------------:|:-----------------------:|
| \>= v1.52 and <= v1.57.4 | <= v1.2.0 |
| >= v1.58.0 | >= v1.3.0 |
| MoonShine | MoonShine Impersonate |
|:------------------------:|:---------------------:|
| \>= v1.52 and <= v1.57.4 | <= v1.2.0 |
| >= v1.58.0 | >= v1.3.0 |
| >= v2.0 | >= v2.0 |

## Installation

Expand Down Expand Up @@ -67,8 +68,8 @@ Please review and abide by the [Code of Conduct][5].
- [Laravel Orchid impersonation mode][10]
- [Laravel standalone package][11]

[1]: https://moonshine.cutcode.dev/
[2]: https://moonshine.cutcode.dev/section/installation
[1]: https://moonshine-laravel.com/
[2]: https://moonshine-laravel.com/docs/section/installation
[3]: https://dzianiskotau.com/moonshine-impersonate/
[4]: CONTRIBUTING.md
[5]: CODE_OF_CONDUCT.md
Expand Down
1 change: 1 addition & 0 deletions Roadmap.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
- implement `database` provider
- implement `Impersonation` resource
11 changes: 8 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,19 @@
"source": "https://github.com/Jampire/moonshine-impersonate"
},
"require": {
"php": "^8.1|^8.2"
"php": "^8.1|^8.2|^8.3"
},
"require-dev": {
"driftingly/rector-laravel": "^0.20.0",
"laravel/pint": "^1.10",
"moonshine/moonshine": "^1.56",
"moonshine/changelog": "^1.0",
"moonshine/moonshine": "^2.0",
"nunomaduro/collision": "^7.5",
"nunomaduro/larastan": "^2.0",
"orchestra/testbench": "^8.5",
"pestphp/pest": "^2.6",
"pestphp/pest-plugin-laravel": "^2.0",
"pestphp/pest-plugin-type-coverage": "^2.5",
"rector/rector": "^0.16.0"
},
"autoload": {
Expand All @@ -52,7 +54,7 @@
}
},
"conflict": {
"moonshine/moonshine": "<1.58.0 || >= 2"
"moonshine/moonshine": "<2"
},
"scripts": {
"post-autoload-dump": [
Expand All @@ -65,10 +67,13 @@
"analyse": "./vendor/bin/phpstan analyse --ansi --memory-limit=-1",
"tests": "./vendor/bin/pest --no-coverage --parallel",
"tests-coverage": "XDEBUG_MODE=coverage ./vendor/bin/pest --coverage --min=100 --parallel",
"tests-type": "./vendor/bin/pest --type-coverage --min=100 --parallel",
"all": [
"@composer validate --strict --ansi",
"@style",
"@rector",
"@analyse",
"@tests-type",
"@tests-coverage"
]
},
Expand Down
12 changes: 8 additions & 4 deletions config/impersonate.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

'routes' => [
// impersonate routes prefix
'prefix' => env('MS_IMPERSONATE_ROUTE_PREFIX', 'impersonate'),
'prefix' => env('MS_IMPERSONATE_ROUTE_PREFIX', config('moonshine.route.prefix').'/impersonate'),

// what middleware is used for routes to enter/stop impersonation
'middleware' => ['web'],
Expand All @@ -23,10 +23,14 @@
'icon' => env('MS_IMPERSONATE_ENTER_BUTTON_ICON', 'heroicons.outline.eye')
],
'stop' => [
// if true the button will be set to the header of the page
'enabled' => env('MS_IMPERSONATE_STOP_BUTTON_ENABLED', true),
'icon' => env('MS_IMPERSONATE_STOP_BUTTON_ICON', 'heroicons.outline.eye-slash'),
'class' => env('MS_IMPERSONATE_STOP_BUTTON_CLASS', 'btn-pink'),
'class' => env('MS_IMPERSONATE_STOP_BUTTON_CLASS', 'btn-secondary'),
],
],

// query string key name for resource item
'resource_item_key' => env('MS_IMPERSONATE_RESOURCE_ITEM_KEY', 'resourceItem'),

// show 'toast' notifications on different actions
'show_notification' => env('MS_IMPERSONATE_SHOW_NOTIFICATION', true),
];
14 changes: 14 additions & 0 deletions lang/be/ui.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

return [
'buttons' => [
'enter' => [
'label' => 'Падмяніць карыстальніка',
'message' => 'Вы паспяхова пераключыліся на іншага карыстальніка.',
],
'stop' => [
'label' => 'Спыніць падмену карыстальніка',
'message' => 'Падмена карыстальніка была паспяхова спынена!',
],
],
];
13 changes: 13 additions & 0 deletions lang/be/validation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

return [
'enter' => [
'is_impersonating' => 'Вы ўжо ў рэжыме падмены карыстальніка. Спачатку спыніце бягучы рэжым падмены!',
'cannot_impersonate' => 'У вас няма правоў для падмены іншых карыстальнікаў.',
'cannot_be_impersonated' => 'Гэты карыстастальнік не можа быць падменены.',
'id' => 'ID Карыстальніка',
],
'stop' => [
'is_not_impersonating' => 'Ніякі карыстастальнік не падменены. Няма чаго рабіць.',
],
];
5 changes: 5 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
processIsolation="false"
stopOnFailure="false"
>
<source>
<include>
<directory suffix=".php">./src</directory>
</include>
</source>
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
Expand Down
8 changes: 5 additions & 3 deletions resources/views/components/impersonate-stop.blade.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<x-moonshine::link icon="{{ $icon }}" href="{{ $route }}" class="{{ $class }}">
{{ $label }}
</x-moonshine::link>
@if($canStop)
<x-moonshine::link-button icon="{{ $icon }}" href="{{ $route }}" class="{{ $class }}">
{{ $label }}
</x-moonshine::link-button>
@endif
1 change: 0 additions & 1 deletion resources/views/impersonate/buttons/stop.blade.php

This file was deleted.

3 changes: 2 additions & 1 deletion routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
->prefix(config_impersonate('routes.prefix'))
->middleware(config_impersonate('routes.middleware'))
->group(function (): void {
Route::post('/enter', 'enter')->name('enter');
Route::get('/enter', 'enter')->name('enter');
Route::post('/enter', 'enter')->name('enter-confirm');
Route::get('/stop', 'stop')->name('stop');
});
2 changes: 1 addition & 1 deletion src/Actions/EnterAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function __construct(
/**
* @param int $id ID of the impersonated user
*/
public function execute(int $id, bool $shouldValidate = false): bool
public function execute(int $id, bool $shouldValidate = true): bool
{
$user = $this->manager->findUserById($id);

Expand Down
1 change: 1 addition & 0 deletions src/Actions/StopAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public function __construct(
public function execute(): bool
{
$user = $this->manager->getUserFromSession();

if (!$user instanceof Authenticatable) {
return false;
}
Expand Down
32 changes: 28 additions & 4 deletions src/Http/Controllers/ImpersonateController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,51 @@ class ImpersonateController extends Controller
{
public function enter(EnterFormRequest $request, EnterAction $action): Redirector|RedirectResponse
{
if (!$action->execute($request->safe()->id)) {
// TODO: flash message
$result = $action->execute(id: $request->safe()->id, shouldValidate: false);

if (!$result) {
// @codeCoverageIgnoreStart
toast_if(
condition: config_impersonate('show_notification'),
message: trans_impersonate('validation.enter.cannot_be_impersonated'),
type: 'error'
);

return redirect()->back();
// @codeCoverageIgnoreEnd
}

toast_if(
condition: config_impersonate('show_notification'),
message: trans_impersonate('ui.buttons.enter.message'),
type: 'success'
);

return redirect(config_impersonate('redirect_to'));
}

public function stop(StopFormRequest $request, StopAction $action): Redirector|RedirectResponse
{
if (!$action->execute()) {
// TODO: flash message
$result = $action->execute();

if (!$result) {
// @codeCoverageIgnoreStart
toast_if(
condition: config_impersonate('show_notification'),
message: trans_impersonate('validation.stop.is_not_impersonating'),
type: 'error'
);

return redirect()->back();
// @codeCoverageIgnoreEnd
}

toast_if(
condition: config_impersonate('show_notification'),
message: trans_impersonate('ui.buttons.stop.message'),
type: 'success'
);

return redirect(config_impersonate('redirect_to'));
}
}
11 changes: 11 additions & 0 deletions src/Http/Requests/EnterFormRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,15 @@ public function attributes(): array
'id' => trans_impersonate('validation.enter.id'),
];
}

protected function prepareForValidation(): void
{
$key = config_impersonate('resource_item_key');

if ($this->has($key)) {
$this->merge([
'id' => (int)$this->get($key),
]);
}
}
}
36 changes: 1 addition & 35 deletions src/ImpersonateServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use Jampire\MoonshineImpersonate\Providers\EventServiceProvider;
use Jampire\MoonshineImpersonate\Services\ImpersonateManager;
use Jampire\MoonshineImpersonate\Support\Settings;
use Jampire\MoonshineImpersonate\UI\View\Components\StopImpersonation;

/**
* Class ImpersonateServiceProvider
Expand Down Expand Up @@ -76,7 +75,7 @@ private function registerAuthDriver(): void
{
$auth = app('auth');

$auth->extend('session', function (Application $app, $name, array $config) use ($auth): SessionGuard {
$auth->extend('session', function (Application $app, string $name, array $config) use ($auth): SessionGuard {
$provider = $auth->createUserProvider($config['provider']);

$guard = new SessionGuard($name, $provider, $app['session.store']);
Expand All @@ -99,18 +98,8 @@ private function registerAuthDriver(): void

private function registerViews(): void
{
$this->loadViewComponentsAs(Settings::ALIAS, [
'stop' => StopImpersonation::class,
]);

$this->loadViewsFrom(__DIR__.'/../resources/views', Settings::ALIAS);

if (config_impersonate('buttons.stop.enabled') === true) {
config([
'moonshine.header' => Settings::ALIAS . '::impersonate.buttons.stop',
]);
}

if ($this->app->runningUnitTests()) {
$this->loadViewsFrom(__DIR__.'/../tests/Stubs/resources/views', 'moonshine');
}
Expand Down Expand Up @@ -145,28 +134,5 @@ private function publishImpersonateResources(): void
'lang',
]
);

// Views
$this->publishes(
[
__DIR__.'/../resources/views/impersonate' => resource_path('views/vendor/impersonate')
],
[
Settings::ALIAS,
'views',
]
);

// Views Components
$this->publishes(
[
__DIR__.'/../src/UI/View/Components' => app_path('View/Components'),
__DIR__.'/../resources/views/components' => resource_path('views/components'),
],
[
Settings::ALIAS,
'view-components',
]
);
}
}
4 changes: 2 additions & 2 deletions src/Services/ImpersonateManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public function canBeImpersonated(Authenticatable $userToImpersonate): bool
public function saveAuthInSession(Authenticatable $user): void
{
session([
config_impersonate('key') => $user->getAuthIdentifier(),
Settings::key() => $user->getAuthIdentifier(),
Settings::impersonatorSessionKey() => $this->moonshineUser->getAuthIdentifier(),
Settings::impersonatorSessionGuardKey() => Settings::moonShineGuard(),
]);
Expand All @@ -98,7 +98,7 @@ public function saveAuthInSession(Authenticatable $user): void
public function clearAuthFromSession(): void
{
session()->forget([
config_impersonate('key'),
Settings::key(),
Settings::impersonatorSessionKey(),
Settings::impersonatorSessionGuardKey(),
]);
Expand Down
15 changes: 15 additions & 0 deletions src/Support/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\View\View;
use Jampire\MoonshineImpersonate\Support\Settings;
use MoonShine\MoonShineUI;

if (!function_exists('route_impersonate')) {
/**
Expand Down Expand Up @@ -52,3 +53,17 @@ function view_impersonate(string $key, array|Arrayable $data = [], array $mergeD
return view(Settings::ALIAS.'::'.$key, $data, $mergeData);
}
}

if (!function_exists('toast_if')) {
/**
* @author Dzianis Kotau <[email protected]>
*/
function toast_if(bool $condition, string $message, string $type = 'info'): void
{
if (!$condition) {
return;
}

MoonShineUI::toast(message: $message, type: $type);
}
}
Loading

0 comments on commit 65828bc

Please sign in to comment.