Skip to content

Commit

Permalink
Merge pull request #80 from mostafamaklad/v1.10
Browse files Browse the repository at this point in the history
V1.10.0
  • Loading branch information
mostafamaklad committed Nov 15, 2018
2 parents a07a510 + f75c12b commit d6976db
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 43 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

All Notable changes to `laravel-permission-mongodb` will be documented in this file.

## 1.10.0 - 2018-09-15

### Added
- Add migration files

### Changed
- Update PermissionRegistrar to use Authorizable
- Improve readme description of how defaults work with multiple guards
- Replacing static Permission::class and Role::class with dynamic value
- Improve speed of findByName

## 1.9.0 - 2018-09-14

### Fixed
Expand Down
18 changes: 5 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# laravel-permission-mongodb

[![Latest Version on Packagist][ico-version]][link-packagist]
[![Latest Version on Packagist][ico-version]][link-releases]
[![Software License][ico-license]](LICENSE.md)
[![Build Status][ico-travis]][link-travis]
[![Scrutinizer][ico-scrutinizer]][link-scrutinizer]
Expand Down Expand Up @@ -540,25 +540,16 @@ However when using multiple guards they will act like namespaces for your permis

### Using permissions and roles with multiple guards

By default the default guard (`config('auth.defaults.guard')`) will be used as the guard for new permissions and roles. When creating permissions and roles for specific guards you'll have to specify their `guard_name` on the model:
When creating new permissions and roles, if no guard is specified, then the **first** defined guard in `auth.guards` config array will be used. When creating permissions and roles for specific guards you'll have to specify their `guard_name` on the model:

```php
// Create a superadmin role for the admin users
$role = Role::create(['guard_name' => 'admin', 'name' => 'superadmin']);

// Define a `publish articles` permission for the admin users belonging to the admin guard
$permission = Permission::create(['guard_name' => 'admin', 'name' => 'publish articles']);

// Define a *different* `publish articles` permission for the regular users belonging to the web guard
$permission = Permission::create(['guard_name' => 'web', 'name' => 'publish articles']);
```

To check if a user has permission for a specific guard:

```php
$user->hasPermissionTo('publish articles', 'admin');
```

> **Note**: When determining whether a role/permission is valid on a given model, it chooses the guard in this order: first the `$guard_name` property of the model; then the guard in the config (through a provider); then the first-defined guard in the `auth.guards` config array; then the `auth.defaults.guard` config.
### Assigning permissions and roles to guard users

You can use the same methods to assign permissions and roles to users as described above in [using permissions via roles](#using-permissions-via-roles). Just make sure the `guard_name` on the permission or role matches the guard of the user, otherwise a `GuardDoesNotMatch` exception will be thrown.
Expand Down Expand Up @@ -826,6 +817,7 @@ The MIT License (MIT). Please see [License File](LICENSE.md) for more informatio

[link-author]: https://github.com/mostafamaklad
[link-contributors]: ../../contributors
[link-releases]: ../../releases
[link-laravel-permission]: https://github.com/spatie/laravel-permission
[link-laravel-mongodb]: https://github.com/jenssegers/laravel-mongodb
[link-freekmurze]: https://github.com/freekmurze
4 changes: 2 additions & 2 deletions src/Contracts/PermissionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public function roles(): BelongsToMany;
* Find a permission by its name.
*
* @param string $name
* @param string|null $guardName
* @param string $guardName
*
* @throws PermissionDoesNotExist
*
* @return PermissionInterface
*/
public static function findByName(string $name, $guardName): PermissionInterface;
public static function findByName(string $name, string $guardName): PermissionInterface;
}
29 changes: 15 additions & 14 deletions src/Models/Permission.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ public function __construct(array $attributes = [])
*/
public static function create(array $attributes = [])
{
$helpers = new Helpers();
$helpers = new Helpers();
$attributes['guard_name'] = $attributes['guard_name'] ?? (new Guard())->getDefaultName(static::class);

if (static::getPermissions()->where('name', $attributes['name'])->where(
'guard_name',
$attributes['guard_name']
)->first()) {
$name = (string) $attributes['name'];
$guardName = (string) $attributes['guard_name'];
$name = (string)$attributes['name'];
$guardName = (string)$attributes['guard_name'];
throw new PermissionAlreadyExists($helpers->getPermissionAlreadyExistsMessage($name, $guardName));
}

Expand All @@ -78,22 +78,21 @@ public static function create(array $attributes = [])
* Find or create permission by its name (and optionally guardName).
*
* @param string $name
* @param string|null $guardName
* @param string $guardName
*
* @return PermissionInterface
* @throws \Maklad\Permission\Exceptions\PermissionAlreadyExists
* @throws \ReflectionException
*/
public static function findOrCreate(string $name, $guardName = null): PermissionInterface
public static function findOrCreate(string $name, string $guardName = null): PermissionInterface
{
$guardName = $guardName ?? (new Guard())->getDefaultName(static::class);

$permission = static::getPermissions()
->where('name', $name)
->where('guard_name', $guardName)
->first();
$permission = static::getPermissions()->filter(function ($permission) use ($name, $guardName) {
return $permission->name === $name && $permission->guard_name === $guardName;
})->first();

if (! $permission) {
if (!$permission) {
$permission = static::create(['name' => $name, 'guard_name' => $guardName]);
}

Expand Down Expand Up @@ -122,19 +121,21 @@ public function users()
* Find a permission by its name (and optionally guardName).
*
* @param string $name
* @param string|null $guardName
* @param string $guardName
*
* @return PermissionInterface
* @throws PermissionDoesNotExist
* @throws \ReflectionException
*/
public static function findByName(string $name, $guardName = null): PermissionInterface
public static function findByName(string $name, string $guardName = null): PermissionInterface
{
$guardName = $guardName ?? (new Guard())->getDefaultName(static::class);

$permission = static::getPermissions()->where('name', $name)->where('guard_name', $guardName)->first();
$permission = static::getPermissions()->filter(function ($permission) use ($name, $guardName) {
return $permission->name === $name && $permission->guard_name === $guardName;
})->first();

if (! $permission) {
if (!$permission) {
$helpers = new Helpers();
throw new PermissionDoesNotExist($helpers->getPermissionDoesNotExistMessage($name, $guardName));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Models/Role.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public static function findByName(string $name, $guardName = null): RoleInterfac
public function hasPermissionTo($permission): bool
{
if (\is_string($permission)) {
$permission = app(Permission::class)->findByName($permission, $this->getDefaultGuardName());
$permission = $this->getPermissionClass()->findByName($permission, $this->getDefaultGuardName());
}

if (! $this->getGuardNames()->contains($permission->guard_name)) {
Expand Down
56 changes: 51 additions & 5 deletions src/PermissionRegistrar.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Maklad\Permission;

use Illuminate\Contracts\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Access\Gate;
use Illuminate\Contracts\Cache\Repository;
use Illuminate\Support\Collection;
use Jenssegers\Mongodb\Eloquent\Model;
use Maklad\Permission\Contracts\PermissionInterface as Permission;

/**
Expand All @@ -23,32 +23,78 @@ class PermissionRegistrar
/** @var string */
protected $cacheKey = 'maklad.permission.cache';

/** @var string */
protected $permissionClass;

/** @var string */
protected $roleClass;

/**
* PermissionRegistrar constructor.
* @param Gate $gate
* @param Repository $cache
*/
public function __construct(Gate $gate, Repository $cache)
{
$this->gate = $gate;
$this->gate = $gate;
$this->cache = $cache;
$this->permissionClass = config('permission.models.permission');
$this->roleClass = config('permission.models.role');
}

/**
* Register Permissions
*
* @return bool
*/
public function registerPermissions(): bool
{
$this->getPermissions()->map(function (Permission $permission) {
$this->gate->define($permission->name, function (Model $user) use ($permission) {
$this->gate->define($permission->name, function (Authorizable $user) use ($permission) {
return $user->hasPermissionTo($permission) ?: null;
});
});

return true;
}

/**
* Forget cached permission
*/
public function forgetCachedPermissions()
{
$this->cache->forget($this->cacheKey);
}

/**
* Get Permissions
*
* @return Collection
*/
public function getPermissions(): Collection
{
return $this->cache->remember($this->cacheKey, \config('permission.cache_expiration_time'), function () {
return \app(config('permission.models.permission'))->with('roles')->get();
return $this->cache->remember($this->cacheKey, config('permission.cache_expiration_time'), function () {
return $this->getPermissionClass()->with('roles')->get();
});
}

/**
* Get Permission class
*
* @return \Illuminate\Foundation\Application|mixed
*/
public function getPermissionClass()
{
return app($this->permissionClass);
}

/**
* Get Role class
*
* @return \Illuminate\Foundation\Application|mixed
*/
public function getRoleClass()
{
return app($this->roleClass);
}
}
20 changes: 13 additions & 7 deletions src/Traits/HasPermissions.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*/
trait HasPermissions
{
private $permissionClass;

public static function bootHasPermissions()
{
static::deleting(function (Model $model) {
Expand All @@ -30,6 +32,14 @@ public static function bootHasPermissions()
});
}

public function getPermissionClass()
{
if ($this->permissionClass === null) {
$this->permissionClass = app(PermissionRegistrar::class)->getPermissionClass();
}
return $this->permissionClass;
}

/**
* A role may be given various permissions.
* @return BelongsToMany
Expand Down Expand Up @@ -122,7 +132,7 @@ public function revokePermissionTo(...$permissions): self
protected function getStoredPermission($permission): Permission
{
if (\is_string($permission)) {
return \app(config('permission.models.permission'))->findByName($permission, $this->getDefaultGuardName());
return $this->getPermissionClass()->findByName($permission, $this->getDefaultGuardName());
}

return $permission;
Expand Down Expand Up @@ -214,7 +224,6 @@ public function getPermissionsViaRoles(): Collection
->roles->flatMap(function (Role $role) {
return $role->permissions;
})->sort()->values();
//return \app(\config('permission.models.permission'))->whereIn('role_id', $this->role_ids)->get();
}

/**
Expand All @@ -240,7 +249,7 @@ public function getAllPermissions(): Collection
public function hasPermissionTo($permission, $guardName = null): bool
{
if (\is_string($permission)) {
$permission = \app(\config('permission.models.permission'))->findByName(
$permission = $this->getPermissionClass()->findByName(
$permission,
$guardName ?? $this->getDefaultGuardName()
);
Expand Down Expand Up @@ -295,10 +304,7 @@ protected function hasPermissionViaRole(Permission $permission): bool
public function hasDirectPermission($permission): bool
{
if (\is_string($permission)) {
$permission = \app(
\config('permission.models.permission')
)
->findByName($permission, $this->getDefaultGuardName());
$permission = $this->getPermissionClass()->findByName($permission, $this->getDefaultGuardName());
}

return $this->permissions->contains('id', $permission->id);
Expand Down
13 changes: 12 additions & 1 deletion src/Traits/HasRoles.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Jenssegers\Mongodb\Eloquent\Builder;
use Jenssegers\Mongodb\Eloquent\Model;
use Maklad\Permission\Contracts\RoleInterface as Role;
use Maklad\Permission\PermissionRegistrar;
use ReflectionException;

/**
Expand All @@ -16,6 +17,8 @@ trait HasRoles
{
use HasPermissions;

private $roleClass;

public static function bootHasRoles()
{
static::deleting(function (Model $model) {
Expand All @@ -27,6 +30,14 @@ public static function bootHasRoles()
});
}

public function getRoleClass()
{
if ($this->roleClass === null) {
$this->roleClass = app(PermissionRegistrar::class)->getRoleClass();
}
return $this->roleClass;
}

/**
* A model may have multiple roles.
*/
Expand Down Expand Up @@ -184,7 +195,7 @@ public function hasAllRoles($roles): bool
protected function getStoredRole($role): Role
{
if (\is_string($role)) {
return \app(\config('permission.models.role'))->findByName($role, $this->getDefaultGuardName());
return $this->getRoleClass()->findByName($role, $this->getDefaultGuardName());
}

return $role;
Expand Down

0 comments on commit d6976db

Please sign in to comment.