Skip to content

Commit

Permalink
Added auth guards configuration support(#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
seancheung committed Dec 2, 2020
1 parent 5e3a11b commit 616d27a
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 6 deletions.
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ A sample meta
]
```

### Custom History
### Custom history

Besides the built in `created/updating/deleting/restoring` events, you may store custom history record with `ModelChanged` event.

Expand Down Expand Up @@ -217,6 +217,28 @@ This will translate your model history into

You may set whitelist and blacklist in config file. Please follow the description guide in the published config file.

### Auth guards

If your users are using non-default auth guards, you might see all `$history->hasUser()` become `false` even though the history sources were generated by authenticated users.

To fix this, you'll need to enable custom auth guards scanning in config file:

```php
/*
|--------------------------------------------------------------
| Enable auth guards scan
|--------------------------------------------------------------
|
| You only need to enable this if your users are using non-default auth guards.
| In that case, all tracked user operations will be anonymous.
|
| - Set to `true` to use a full scan mode: all auth guards will be checked. However this does not ensure guard priority.
| - Set to an array to scan only specific auth guards(in the given order). e.g. `['web', 'api', 'admin']`
|
*/
'auth_guards' => null
```

### Known issues

1. When updating a model, if its model label(attributes returned from `getModelLabel`) has been modified, the history message will use its new attributes, which might not be what you expect.
Expand Down
31 changes: 27 additions & 4 deletions src/HistoryObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Panoscape\History;

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

class HistoryObserver
{
Expand Down Expand Up @@ -106,12 +107,12 @@ public static function getModelName($model)

public static function getUserID()
{
return auth()->check() ? auth()->user()->id : null;
return static::getAuth()->check() ? static::getAuth()->user()->id : null;
}

public static function getUserType()
{
return auth()->check() ? get_class(auth()->user()) : null;
return static::getAuth()->check() ? get_class(static::getAuth()->user()) : null;
}

public static function isIgnored($model, $key)
Expand All @@ -124,16 +125,38 @@ public static function isIgnored($model, $key)

public static function filter($action)
{
if(!auth()->check()) {
if(!static::getAuth()->check()) {
if(in_array('nobody', config('history.user_blacklist'))) {
return false;
}
}
elseif(in_array(get_class(auth()->user()), config('history.user_blacklist'))) {
elseif(in_array(get_class(static::getAuth()->user()), config('history.user_blacklist'))) {
return false;
}

return is_null($action) || in_array($action, config('history.events_whitelist'));
}

private static function getAuth()
{
$guards = config('history.auth_guards');
if(is_bool($guards) && $guards == true)
return auth(static::activeGuard());
if(is_array($guards))
{
foreach($guards as $guard)
if(auth($guard)->check()) return auth($guard);
}
return auth();
}

private static function activeGuard()
{
foreach(array_keys(config('auth.guards')) as $guard)
{
if(auth($guard)->check()) return $guard;
}
return null;
}

}
14 changes: 14 additions & 0 deletions src/config/history.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,19 @@
'env_blacklist' => [

],

/*
|--------------------------------------------------------------
| Enable auth guards scan
|--------------------------------------------------------------
|
| You only need to enable this if your users are using non-default auth guards.
| In that case, all tracked user operations will be anonymous.
|
| - Set to `true` to use a full scan mode: all auth guards will be checked. However this does not ensure guard priority.
| - Set to an array to scan only specific auth guards(in the given order). e.g. `['web', 'api', 'admin']`
|
*/
'auth_guards' => null,

];
42 changes: 41 additions & 1 deletion tests/TestCaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Orchestra\Testbench\TestCase;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Panoscape\History\History;
use Panoscape\History\HistoryServiceProvider;
use Panoscape\History\Events\ModelChanged;
Expand Down Expand Up @@ -36,6 +37,12 @@ protected function getEnvironmentSetUp($app)
'password'
]
]);
$app['config']->set('history.auth_guards', ['web','admin']);
// custom auth guard mock
$app['config']->set('auth.guards.admin.driver', 'admin-login');
Auth::viaRequest('admin-login', function(Request $request) {
return null;
});

$app['router']->post('articles', function(Request $request) {
return Article::create(['title' => $request->title]);
Expand All @@ -58,7 +65,7 @@ protected function getEnvironmentSetUp($app)
event(new ModelChanged($model, 'Query Article ' . $model->title, $model->pluck('id')->toArray()));
}
return $model;
});
});
}

public function setUp(): void
Expand Down Expand Up @@ -166,6 +173,32 @@ public function testAnonymous()
$this->assertNull($history->user());
}

public function testCustomGuard()
{
$user = User::first();
$this->assertNotNull($user);

$content = ['title' => 'voluptas ut rem'];
$this->actingAsAdmin($user)->json('POST', '/articles', $content)->assertJson($content);

$article = Article::first();
$this->assertNotNull($article);
$histories = $article->histories;
$this->assertNotNull($histories);
$this->assertEquals(1, count($histories));
$history = $histories[0];
$this->assertTrue($history->hasUser());
$this->assertNotNull($history->user());
$this->assertEquals($user->toJson(), $history->user()->toJson());
$this->assertEquals($article->makeHidden('histories')->toJson(), $history->model()->toJson());

$operations = $user->operations;
$this->assertNotNull($operations);
$this->assertEquals(1, count($operations));
$operation = $operations[0];
$this->assertEquals($history->toJson(), $operation->toJson());
}

public function testCustomEvent()
{
Article::create(['title' => 'maxime fugit saepe']);
Expand All @@ -178,4 +211,11 @@ public function testCustomEvent()
$this->assertEquals('Query Article ' . $article->title, $history->message);
$this->assertEquals([$article->id], $history->meta);
}

private function actingAsAdmin($admin) {
$defaultGuard = config('auth.defaults.guard');
$this->actingAs($admin, 'admin');
Auth::shouldUse($defaultGuard);
return $this;
}
}

0 comments on commit 616d27a

Please sign in to comment.