Skip to content

Commit

Permalink
Merge pull request #34 from kontenta/linkauth
Browse files Browse the repository at this point in the history
Serialization of AuthorizesWithAbility
  • Loading branch information
erik-epineer authored Oct 30, 2018
2 parents 73ebfc6 + 9bb0436 commit 917c012
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 17 deletions.
34 changes: 22 additions & 12 deletions src/Concerns/AuthorizesWithAbility.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,41 @@

use Illuminate\Contracts\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Auth;
use Kontenta\Kontour\Contracts\AuthorizesWithAbility as AuthorizesWithAbilityContract;

trait AuthorizesWithAbility
{
private $authorizesWithAbilityPolicyOrGate;
use SerializesModels; //If $authorizesWithAbilityArguments is just a single Eloquent model, this will serialize it. (But not if it's an array unfortunately)

private $authorizesWithAbilityName;
private $authorizesWithAbilityArguments;
private $authorizesWithAbilityGuard;

/**
/**
* Register a policy or gate to be used for the authorization
* @param string $policyOrGate
* @param $arguments
* @param string $ability name from a Gate/Policy
* @param array|mixed $arguments for the ability check, typically a model instance
* @return $this
*/
public function registerAbilityForAuthorization(string $policyOrGate, $arguments = []): AuthorizesWithAbilityContract
public function registerAbilityForAuthorization(string $ability, $arguments = []): AuthorizesWithAbilityContract
{
$this->authorizesWithAbilityPolicyOrGate = $policyOrGate;
$this->authorizesWithAbilityName = $ability;
$this->authorizesWithAbilityArguments = $arguments;

return $this;
}

/**
* Register a guard to be used for the authorization
* @param Guard $guard
* @param string $guard
* @return $this
*/
public function registerGuardForAuthorization(Guard $guard): AuthorizesWithAbilityContract
public function registerGuardForAuthorization(string $guard): AuthorizesWithAbilityContract
{
$this->authorizesWithAbilityGuard = $guard;

return $this;
}

Expand All @@ -44,14 +49,19 @@ public function registerGuardForAuthorization(Guard $guard): AuthorizesWithAbili
*/
public function isAuthorized(Authorizable $user = null): bool
{
if ($this->authorizesWithAbilityGuard) {
$user = $this->authorizesWithAbilityGuard->user();
try {
if ($this->authorizesWithAbilityGuard) {
$user = Auth::guard($this->authorizesWithAbilityGuard)->user();
}
} catch (\Exception $e) {
// Something is wrong with the guard... perhaps it no longer exists?
return false;
}

if (!$user) {
if (!$user instanceof Authorizable) {
return false;
}

return $user->can($this->authorizesWithAbilityPolicyOrGate, ...$this->authorizesWithAbilityArguments);
return $user->can($this->authorizesWithAbilityName, $this->authorizesWithAbilityArguments);
}
}
10 changes: 5 additions & 5 deletions src/Contracts/AuthorizesWithAbility.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ interface AuthorizesWithAbility extends Authorizes
{
/**
* Register a policy or gate to be used for the authorization
* @param string $policyOrGate
* @param $arguments
* @param string $ability name from a Gate/Policy
* @param array|mixed $arguments for the ability check, typically a model instance
* @return $this
*/
public function registerAbilityForAuthorization(string $policyOrGate, $arguments = []): AuthorizesWithAbility;
public function registerAbilityForAuthorization(string $ability, $arguments = []): AuthorizesWithAbility;

/**
* Register a guard to be used for the authorization
* @param Guard $guard
* @param string $guard
* @return $this
*/
public function registerGuardForAuthorization(Guard $guard): AuthorizesWithAbility;
public function registerGuardForAuthorization(string $guard): AuthorizesWithAbility;
}
65 changes: 65 additions & 0 deletions tests/Feature/AuthorizesWithAbilityTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace Kontenta\Kontour\Tests\Feature;

use Illuminate\Support\Facades\Gate;
use Kontenta\Kontour\AdminLink;
use Kontenta\Kontour\Tests\Feature\Fakes\User;
use Kontenta\Kontour\Tests\IntegrationTest;

class AuthorizesWithAbilityTest extends IntegrationTest
{
/**
* @var User
*/
private $user;

public function setUp()
{
parent::setUp();
$this->prepareDatabase();
$this->user = factory(User::class)->create();

Gate::define('testGate', function ($user, $argument) {
return $user->id == $argument->id;
});
}

public function test_authorizing_with_gate()
{
$link = AdminLink::create('Reset password', 'http://test.com');
$link->registerAbilityForAuthorization('testGate', $this->user);

$this->assertTrue($link->isAuthorized($this->user));
}

public function test_not_authorized_without_user()
{
$link = AdminLink::create('Reset password', 'http://test.com');
$link->registerAbilityForAuthorization('testGate', $this->user);

$this->assertFalse($link->isAuthorized());
}

public function test_not_authorized_with_non_existing_guard()
{
$link = AdminLink::create('Reset password', 'http://test.com');
$link->registerAbilityForAuthorization('testGate', $this->user);
$link->registerGuardForAuthorization('non.existing.guard');

$this->assertFalse($link->isAuthorized($this->user));
}

public function test_can_be_serialized_and_deserialized()
{
$link = AdminLink::create('Reset password', 'http://test.com');
$link->registerAbilityForAuthorization('testGate', $this->user);

$serializedLink = serialize($link);
$link->__wakeup(); // Restore any serialized models on the original object
$unserializedLink = unserialize($serializedLink);

$this->assertTrue($unserializedLink->isAuthorized($this->user));
$this->assertEquals($link, $unserializedLink, "Unserialization did not produce the orginal object structure");
}
}

0 comments on commit 917c012

Please sign in to comment.