Skip to content

Commit

Permalink
Revamp custom guards (#4384)
Browse files Browse the repository at this point in the history
* Use custom guard-name throughout Voyager

* Apply fixes from StyleCI (#4382)

* Remove voyager.user.namespace config and use guard instead

* Add docs, fix some small problems

Add docs to use a different user-table.
Other models use other keys for roles - hardcoded them

* Update docs

* Hide profile button if custom guard is set and no datatype exists

* Update docs

Co-Authored-By: Adam Nielsen <[email protected]>

* Apply fixes from StyleCI (#4391)
  • Loading branch information
emptynick authored Sep 9, 2019
1 parent dda0773 commit 4156e38
Show file tree
Hide file tree
Showing 25 changed files with 162 additions and 208 deletions.
81 changes: 77 additions & 4 deletions docs/customization/custom-guard.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,87 @@
# Custom guard

Starting with Voyager 1.2 you can define a \(custom\) guard which is used throughout Voyager.
To do so, just bind your auth-guard to `VoyagerAuth`.
Open your `AuthServiceProvider` and add the following to the register method:
To do so, just bind the name of your auth-guard to `VoyagerGuard`.
First, make sure you have defined a guard as per the [Laravel documentation](https://laravel.com/docs/authentication#adding-custom-guards).
After that open your `AuthServiceProvider` and add the following to the register method:

```php
$this->app->singleton('VoyagerAuth', function () {
return Auth::guard('your-custom-guard');
$this->app->singleton('VoyagerGuard', function () {
return 'your-custom-guard-name';
});
```

Now this guard is used instead of the default guard.


# Example - using a different model and table for Admins

First you have to create a new table. Let's call it `admins`:
```php
<?php
Schema::create('admins', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('role_id')->unsigned()->nullable();
$table->string('name');
$table->string('email')->unique();
$table->string('avatar')->nullable()->default('users/default.png');
$table->string('password')->nullable();
$table->string('remember_token')->nullable();
$table->text('settings')->nullable()->default(null);
$table->timestamps();
$table->foreign('role_id')->references('id')->on('roles');
});
```

and a model which extends Voyagers user-model:

```php
<?php

namespace App;

class Admin extends \TCG\Voyager\Models\User
{

}
```

Next, create a guard named `admin` in your `config/auth.php`:
```
'guards' => [
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
// ...
],
```
And a user provider called `admins`:
```
'providers' => [
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
// ...
],
```

Next you have to tell Voyager to use your new guard.
Open you `AppServiceProvider.php` and add the following to the `register` method:

```php
public function register()
{
$this->app->singleton('VoyagerGuard', function () {
return 'admin';
});
}
```

{% hint style="info" %}
Please note that the user-bread is still responsible to edit users - not admins.
Create a BREAD for the `admins` table if you want to change Admins.
{% endhint %}
17 changes: 16 additions & 1 deletion docs/getting-started/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ To update to the latest version inside of your composer.json file make sure to u

And then run composer update

## Troubleshooting
### Changes to VoyagerAuth
The `VoyagerAuth` singleton was introduced in Voyager 1.2 and returned an instance of the guard.
In Voyager 1.3 this singleton was renamed to `VoyagerGuard` and now returns the name of the guard as a string.
Read more on custom guards [here](../customization/custom-guard.md)

## Update Configuration
The `voyager.php` configuration file had a few changes.

```
'user' => [
'namespace' => null,
],
```
was removed. The user-model which will be used in the `voyager:admin` command is now determined based on the [guard](../customization/custom-guard.md).

### Troubleshooting

Be sure to ask us on our slack channel if you are experiencing any issues and we will try and assist. Thanks.
5 changes: 0 additions & 5 deletions publishable/config/voyager.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@
'user' => [
'add_default_role_on_register' => true,
'default_role' => 'user',
// Set `namespace` to `null` to use `config('auth.providers.users.model')` value
// Set `namespace` to a class to override auth user model.
// However make sure the appointed class must ready to use before installing voyager.
// Otherwise `php artisan voyager:install` will fail with class not found error.
'namespace' => null,
'default_avatar' => 'users/default.png',
'redirect' => '/admin',
],
Expand Down
1 change: 0 additions & 1 deletion publishable/config/voyager_dummy.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
'user' => [
'add_default_role_on_register' => true,
'default_role' => 'user',
'namespace' => null,
'default_avatar' => 'users/default.png',
'redirect' => '/admin',
],
Expand Down
4 changes: 2 additions & 2 deletions resources/views/dashboard/navbar.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ class="caret"></span></a>
<li class="profile-img">
<img src="{{ $user_avatar }}" class="profile-img">
<div class="profile-body">
<h5>{{ app('VoyagerAuth')->user()->name }}</h5>
<h6>{{ app('VoyagerAuth')->user()->email }}</h6>
<h5>{{ Auth::user()->name }}</h5>
<h6>{{ Auth::user()->email }}</h6>
</div>
</li>
<li class="divider"></li>
Expand Down
6 changes: 3 additions & 3 deletions resources/views/master.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@
</div>

<?php
if (\Illuminate\Support\Str::startsWith(app('VoyagerAuth')->user()->avatar, 'http://') || \Illuminate\Support\Str::startsWith(app('VoyagerAuth')->user()->avatar, 'https://')) {
$user_avatar = app('VoyagerAuth')->user()->avatar;
if (\Illuminate\Support\Str::startsWith(Auth::user()->avatar, 'http://') || \Illuminate\Support\Str::startsWith(Auth::user()->avatar, 'https://')) {
$user_avatar = Auth::user()->avatar;
} else {
$user_avatar = Voyager::image(app('VoyagerAuth')->user()->avatar);
$user_avatar = Voyager::image(Auth::user()->avatar);
}
?>

Expand Down
14 changes: 8 additions & 6 deletions resources/views/profile.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
<div style="background-size:cover; background-image: url({{ Voyager::image( Voyager::setting('admin.bg_image'), voyager_asset('/images/bg.jpg')) }}); background-position: center center;position:absolute; top:0; left:0; width:100%; height:300px;"></div>
<div style="height:160px; display:block; width:100%"></div>
<div style="position:relative; z-index:9; text-align:center;">
<img src="@if( !filter_var(app('VoyagerAuth')->user()->avatar, FILTER_VALIDATE_URL)){{ Voyager::image( app('VoyagerAuth')->user()->avatar ) }}@else{{ app('VoyagerAuth')->user()->avatar }}@endif"
<img src="@if( !filter_var(Auth::user()->avatar, FILTER_VALIDATE_URL)){{ Voyager::image( Auth::user()->avatar ) }}@else{{ Auth::user()->avatar }}@endif"
class="avatar"
style="border-radius:50%; width:150px; height:150px; border:5px solid #fff;"
alt="{{ app('VoyagerAuth')->user()->name }} avatar">
<h4>{{ ucwords(app('VoyagerAuth')->user()->name) }}</h4>
<div class="user-email text-muted">{{ ucwords(app('VoyagerAuth')->user()->email) }}</div>
<p>{{ app('VoyagerAuth')->user()->bio }}</p>
<a href="{{ route('voyager.users.edit', app('VoyagerAuth')->user()->getKey()) }}" class="btn btn-primary">{{ __('voyager::profile.edit') }}</a>
alt="{{ Auth::user()->name }} avatar">
<h4>{{ ucwords(Auth::user()->name) }}</h4>
<div class="user-email text-muted">{{ ucwords(Auth::user()->email) }}</div>
<p>{{ Auth::user()->bio }}</p>
@if ($route != '')
<a href="{{ $route }}" class="btn btn-primary">{{ __('voyager::profile.edit') }}</a>
@endif
</div>
@stop
9 changes: 6 additions & 3 deletions src/Commands/AdminCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
namespace TCG\Voyager\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Symfony\Component\Console\Input\InputOption;
use TCG\Voyager\Facades\Voyager;

Expand Down Expand Up @@ -116,7 +118,8 @@ protected function getUser($create = false)
{
$email = $this->argument('email');

$model = config('voyager.user.namespace') ?: config('auth.providers.users.model');
$model = Auth::guard(app('VoyagerGuard'))->getProvider()->getModel();
$model = Str::start($model, '\\');

// If we need to create a new user go ahead and create it
if ($create) {
Expand All @@ -138,13 +141,13 @@ protected function getUser($create = false)

$this->info('Creating admin account');

return $model::create([
return call_user_func($model.'::create', [
'name' => $name,
'email' => $email,
'password' => Hash::make($password),
]);
}

return $model::where('email', $email)->firstOrFail();
return call_user_func($model.'::where', 'email', $email)->firstOrFail();
}
}
3 changes: 2 additions & 1 deletion src/FormFields/MediaPickerHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace TCG\Voyager\FormFields;

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;

class MediaPickerHandler extends AbstractHandler
Expand All @@ -26,7 +27,7 @@ public function createContent($row, $dataType, $dataTypeContent, $options)
}

if (isset($options->base_path)) {
$options->base_path = str_replace('{uid}', app('VoyagerAuth')->user()->getKey(), $options->base_path);
$options->base_path = str_replace('{uid}', Auth::user()->getKey(), $options->base_path);
if (Str::contains($options->base_path, '{date:')) {
$options->base_path = preg_replace_callback('/\{date:([^\/\}]*)\}/', function ($date) {
return \Carbon\Carbon::now()->format($date[1]);
Expand Down
17 changes: 0 additions & 17 deletions src/Http/Controllers/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,21 +276,4 @@ protected function getFieldsWithValidationRules($fieldsConfig)
return !empty($value->details->validation->rule);
});
}

/**
* Authorize a given action for the current user.
*
* @param mixed $ability
* @param mixed|array $arguments
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*
* @return \Illuminate\Auth\Access\Response
*/
public function authorize($ability, $arguments = [])
{
$user = app('VoyagerAuth')->user();

return $this->authorizeForUser($user, $ability, $arguments);
}
}
3 changes: 2 additions & 1 deletion src/Http/Controllers/VoyagerAuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use TCG\Voyager\Facades\Voyager;

class VoyagerAuthController extends Controller
Expand Down Expand Up @@ -61,6 +62,6 @@ public function redirectTo()
*/
protected function guard()
{
return app('VoyagerAuth');
return Auth::guard(app('VoyagerGuard'));
}
}
3 changes: 2 additions & 1 deletion src/Http/Controllers/VoyagerBaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Exception;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use TCG\Voyager\Database\Schema\SchemaManager;
use TCG\Voyager\Events\BreadDataAdded;
Expand Down Expand Up @@ -83,7 +84,7 @@ public function index(Request $request)
}

// Use withTrashed() if model uses SoftDeletes and if toggle is selected
if ($model && in_array(SoftDeletes::class, class_uses($model)) && app('VoyagerAuth')->user()->can('delete', app($dataType->model_name))) {
if ($model && in_array(SoftDeletes::class, class_uses($model)) && Auth::user()->can('delete', app($dataType->model_name))) {
$usesSoftDeletes = true;

if ($request->get('showSoftDeleted')) {
Expand Down
3 changes: 2 additions & 1 deletion src/Http/Controllers/VoyagerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace TCG\Voyager\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
Expand All @@ -19,7 +20,7 @@ public function index()

public function logout()
{
app('VoyagerAuth')->logout();
Auth::logout();

return redirect()->route('voyager.login');
}
Expand Down
3 changes: 2 additions & 1 deletion src/Http/Controllers/VoyagerMediaController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\Facades\Image;
Expand Down Expand Up @@ -231,7 +232,7 @@ public function upload(Request $request)
$name = get_file_name($name);
}
} else {
$name = str_replace('{uid}', app('VoyagerAuth')->user()->getKey(), $request->get('filename'));
$name = str_replace('{uid}', Auth::user()->getKey(), $request->get('filename'));
if (Str::contains($name, '{date:')) {
$name = preg_replace_callback('/\{date:([^\/\}]*)\}/', function ($date) {
return \Carbon\Carbon::now()->format($date[1]);
Expand Down
19 changes: 14 additions & 5 deletions src/Http/Controllers/VoyagerUserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,32 @@
namespace TCG\Voyager\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use TCG\Voyager\Facades\Voyager;

class VoyagerUserController extends VoyagerBaseController
{
public function profile(Request $request)
{
return Voyager::view('voyager::profile');
$route = '';
$dataType = Voyager::model('DataType')->where('model_name', Auth::guard(app('VoyagerGuard'))->getProvider()->getModel())->first();
if (!$dataType && app('VoyagerGuard') == 'web') {
$route = route('voyager.users.edit', Auth::user()->getKey());
} elseif ($dataType) {
$route = route('voyager.'.$dataType->slug.'.edit', Auth::user()->getKey());
}

return Voyager::view('voyager::profile', compact('route'));
}

// POST BR(E)AD
public function update(Request $request, $id)
{
if (app('VoyagerAuth')->user()->getKey() == $id) {
if (Auth::user()->getKey() == $id) {
$request->merge([
'role_id' => app('VoyagerAuth')->user()->role_id,
'user_belongsto_role_relationship' => app('VoyagerAuth')->user()->role_id,
'user_belongstomany_role_relationship' => app('VoyagerAuth')->user()->roles->pluck('id')->toArray(),
'role_id' => Auth::user()->role_id,
'user_belongsto_role_relationship' => Auth::user()->role_id,
'user_belongstomany_role_relationship' => Auth::user()->roles->pluck('id')->toArray(),
]);
}

Expand Down
7 changes: 5 additions & 2 deletions src/Http/Middleware/VoyagerAdminMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace TCG\Voyager\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class VoyagerAdminMiddleware
{
Expand All @@ -16,8 +17,10 @@ class VoyagerAdminMiddleware
*/
public function handle($request, Closure $next)
{
if (!app('VoyagerAuth')->guest()) {
$user = app('VoyagerAuth')->user();
auth()->setDefaultDriver(app('VoyagerGuard'));

if (!Auth::guest()) {
$user = Auth::user();
app()->setLocale($user->locale ?? app()->getLocale());

return $user->hasPermission('browse_admin') ? $next($request) : redirect('/');
Expand Down
Loading

0 comments on commit 4156e38

Please sign in to comment.