Skip to content

Commit

Permalink
refactoring authentication, rules in MoonShineUserResource, admin use…
Browse files Browse the repository at this point in the history
…r avatar in header, minor fixes
  • Loading branch information
lee-to committed Jul 1, 2022
1 parent 5d71724 commit 67396f9
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 27 deletions.
9 changes: 4 additions & 5 deletions resources/views/auth/login.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@
@endif
</div>

<form class="mt-8" action="#" method="POST">
{{ csrf_field() }}

<input type="hidden" name="remember" value="true">
<form class="mt-8" action="{{ route(config('moonshine.route.prefix') . '.authenticate') }}" method="POST">
@csrf

<div class="rounded-md shadow-sm">
<div>
Expand All @@ -61,7 +59,8 @@ class="text-black appearance-none rounded-none relative block w-full px-3 py-2 b

<div class="mt-6 flex items-center justify-between">
<div class="flex items-center">
<input id="remember_me" type="checkbox" class="form-checkbox h-4 w-4 text-pink transition duration-150 ease-in-out">
<input type="hidden" name="remember" value="0">
<input id="remember_me" name="remember" value="1" type="checkbox" class="form-checkbox h-4 w-4 text-pink transition duration-150 ease-in-out">
<label for="remember_me" class="ml-2 block text-sm leading-5">
{{ trans('moonshine::ui.login.remember_me') }}
</label>
Expand Down
4 changes: 2 additions & 2 deletions resources/views/shared/header.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@
<button @click="dropdownOpen = ! dropdownOpen"
class="relative block h-8 w-8 rounded-full overflow-hidden shadow focus:outline-none">
<img class="h-full w-full object-cover"
src="{{ auth(config('moonshine.auth.guard'))->user()->avatar ? ('/storage/' . auth(config('moonshine.auth.guard'))->user()->avatar) : ("https://ui-avatars.com/api/?name=" . auth(config('moonshine.auth.guard'))->user()->name) }}"
src="{{ auth(config('moonshine.auth.guard'))->user()->avatar ? (Storage::url(auth(config('moonshine.auth.guard'))->user()->avatar)) : ("https://ui-avatars.com/api/?name=" . auth(config('moonshine.auth.guard'))->user()->name) }}"
alt="{{ auth(config('moonshine.auth.guard'))->user()->name }}">
</button>

<div x-show="dropdownOpen" @click="dropdownOpen = false" class="fixed inset-0 h-full w-full z-10"></div>

<div x-show="dropdownOpen"
class="absolute right-0 mt-2 w-48 bg-white dark:bg-dark rounded-md overflow-hidden shadow-xl z-10"
>
>
<a href="{{ route(config('moonshine.route.prefix') . '.logout') }}" class="block px-4 py-2 text-sm text-black dark:text-white hover:bg-purple hover:text-white">{{ trans('moonshine::ui.login.logout') }}</a>
</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions src/Fields/Json.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public function indexViewValue(Model $item, bool $container = false): string
$columns = [];
$values = $item->{$this->field()};

if(!$this->hasFields()) {
return json_encode($values);
}

if($this->isKeyValue()) {
$values = collect($item->{$this->field()})
->map(fn($value, $key) => ['key' => $key, 'value' => $value]);
Expand Down
31 changes: 16 additions & 15 deletions src/Http/Controllers/MoonShineAuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Routing\Redirector;
use Leeto\MoonShine\Http\Requests\LoginFormRequest;

use function auth;
use function back;
Expand All @@ -18,28 +18,29 @@

class MoonShineAuthController extends BaseController
{
public function login(Request $request): Factory|View|Redirector|Application|RedirectResponse
public function login(): Factory|View|Redirector|Application|RedirectResponse
{
if (auth(config('moonshine.auth.guard'))->check()) {
return redirect(route(config('moonshine.route.prefix') . '.index'));
}

if ($request->isMethod('post')) {
$credentials = $request->only(['email', 'password']);
$remember = $request->get('remember', false);
return view('moonshine::auth.login');
}

public function authenticate(LoginFormRequest $request): RedirectResponse
{
$credentials = $request->only(['email', 'password']);
$remember = $request->boolean('remember', false);

if (auth(config('moonshine.auth.guard'))->attempt($credentials, $remember)) {
return redirect(url()->previous());
} else {
$request->session()->flash('alert', trans('moonshine::auth.failed'));
if (auth(config('moonshine.auth.guard'))->attempt($credentials, $remember)) {
return redirect(url()->previous());
} else {
$request->session()->flash('alert', trans('moonshine::auth.failed'));

return back()
->withInput()
->withErrors(['login' => trans('moonshine::auth.failed')]);
}
return back()
->withInput()
->withErrors(['login' => trans('moonshine::auth.failed')]);
}

return view('moonshine::auth.login');
}

public function logout(): Redirector|Application|RedirectResponse
Expand Down
1 change: 1 addition & 0 deletions src/Http/Middleware/Authenticate.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ protected function except(Request $request): bool
{
return $request->is([
config('moonshine.route.prefix') . '/login',
config('moonshine.route.prefix') . '/authenticate',
config('moonshine.route.prefix') . '/logout',
]);
}
Expand Down
40 changes: 40 additions & 0 deletions src/Http/Requests/LoginFormRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Leeto\MoonShine\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class LoginFormRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize(): bool
{
return auth(config('moonshine.auth.guard'))->guest();
}

/**
* Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/
public function rules(): array
{
return [
'email' => ['required', 'email'],
'password' => ['required'],
];
}

protected function prepareForValidation()
{
$this->merge([
'email' => (string)str(request('email'))
->lower()
->trim(),
]);
}
}
3 changes: 2 additions & 1 deletion src/MoonShine.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ protected function addRoutes(): void
Route::get('/', [MoonShineDashboardController::class, 'index'])->name('index');
Route::post('/attachments', [MoonShineDashboardController::class, 'attachments'])->name('attachments');

Route::any('/login', [MoonShineAuthController::class, 'login'])->name('login');
Route::get('/login', [MoonShineAuthController::class, 'login'])->name('login');
Route::post('/authenticate', [MoonShineAuthController::class, 'authenticate'])->name('authenticate');
Route::get('/logout', [MoonShineAuthController::class, 'logout'])->name('logout');

$this->resources->each(function ($resource) {
Expand Down
8 changes: 4 additions & 4 deletions src/Resources/MoonShineUserResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ public function fields(): array
Image::make('Аватар', 'avatar')
->removable()
->showOnExport()
->disk('public')
->dir('images')
->disk(config('filesystems.default'))
->dir('moonshine_users')
->allowedExtensions(['jpg', 'png', 'jpeg', 'gif']),

Date::make('Дата создания', 'created_at')
Expand All @@ -67,7 +67,7 @@ public function fields(): array
public function rules($item): array
{
return [
'name' => 'required|min:5',
'name' => 'required',
'moonshine_user_role_id' => 'required',
'email' => 'sometimes|bail|required|email|unique:moonshine_users,email' . ($item->exists ? ",$item->id" : ''),
'password' => !$item->exists
Expand All @@ -78,7 +78,7 @@ public function rules($item): array

public function search(): array
{
return ["id", "name"];
return ['id', 'name'];
}

public function filters(): array
Expand Down
56 changes: 56 additions & 0 deletions tests/Controllers/MoonShineAuthControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Leeto\MoonShine\Tests\Controllers;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Leeto\MoonShine\Models\MoonshineUser;
use Leeto\MoonShine\Models\MoonshineUserRole;
use Leeto\MoonShine\Resources\MoonShineUserResource;
use Leeto\MoonShine\Tests\TestCase;

class MoonShineAuthControllerTest extends TestCase
{
use RefreshDatabase;

public function test_login_page()
{
$response = $this->get(route(config('moonshine.route.prefix') . '.login'));

$response->assertOk();
$response->assertViewIs('moonshine::auth.login');
}

public function test_login_redirect_to_dashboard()
{
$response = $this->actingAs($this->user, config('moonshine.auth.guard'))
->get(route(config('moonshine.route.prefix') . '.login'));

$response->assertRedirect(route(config('moonshine.route.prefix') . '.index'));
}

public function test_authenticate()
{
$response = $this->post(
route(config('moonshine.route.prefix') . '.authenticate'),
['email' => $this->user->email, 'password' => 'invalid']
);

$response->assertInvalid(['login']);

$response = $this->post(
route(config('moonshine.route.prefix') . '.authenticate'),
['email' => $this->user->email, 'password' => 'test']
);

$response->assertValid();
}

public function test_logout()
{
$response = $this->actingAs($this->user, config('moonshine.auth.guard'))
->get(route(config('moonshine.route.prefix') . '.logout'));

$response->assertRedirect(route(config('moonshine.route.prefix') . '.login'));
}

}

0 comments on commit 67396f9

Please sign in to comment.