-
Notifications
You must be signed in to change notification settings - Fork 336
/
Copy pathAbilities.php
142 lines (124 loc) · 5.35 KB
/
Abilities.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
namespace Silber\Bouncer\Database\Queries;
use Silber\Bouncer\Database\Models;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent\Model;
class Abilities
{
/**
* Get a query for the authority's abilities.
*
* @param \Illuminate\Database\Eloquent\Model $authority
* @param bool $allowed
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function forAuthority(Model $authority, $allowed = true)
{
return Models::ability()->where(function ($query) use ($authority, $allowed) {
$query->whereExists(static::getRoleConstraint($authority, $allowed));
$query->orWhereExists(static::getAuthorityConstraint($authority, $allowed));
});
}
/**
* Get a query for the authority's forbidden abilities.
*
* @param \Illuminate\Database\Eloquent\Model $authority
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function forbiddenForAuthority(Model $authority)
{
return static::forAuthority($authority, false);
}
/**
* Get a constraint for abilities that have been granted to the given authority through a role.
*
* @param \Illuminate\Database\Eloquent\Model $authority
* @param bool $allowed
* @return \Closure
*/
protected static function getRoleConstraint(Model $authority, $allowed)
{
return function ($query) use ($authority, $allowed) {
$permissions = Models::table('permissions');
$abilities = Models::table('abilities');
$roles = Models::table('roles');
$prefix = Models::prefix();
$query->from($roles)
->join($permissions, $roles.'.id', '=', $permissions.'.entity_id')
->whereRaw("{$prefix}{$permissions}.ability_id = {$prefix}{$abilities}.id")
->where($permissions.".forbidden", ! $allowed)
->where($permissions.".entity_type", Models::role()->getMorphClass());
Models::scope()->applyToModelQuery($query, $roles);
Models::scope()->applyToRelationQuery($query, $permissions);
$query->where(function ($query) use ($roles, $authority, $allowed) {
$query->whereExists(static::getAuthorityRoleConstraint($authority));
if ($allowed) {
static::addRoleInheritCondition($query, $authority, $roles);
}
});
};
}
/**
* Add the role inheritence "where" clause to the given query.
*
* @param \Illuminate\Database\Query\Builder $query
* @param \Illuminate\Database\Eloquent\Model $authority
* @param string $roles
* @return \Closure
*/
protected static function addRoleInheritCondition(Builder $query, Model $authority, $roles)
{
$query->orWhere('level', '<', function ($query) use ($authority, $roles) {
$query->selectRaw('max(level)')
->from($roles)
->whereExists(static::getAuthorityRoleConstraint($authority));
Models::scope()->applyToModelQuery($query, $roles);
});
}
/**
* Get a constraint for roles that are assigned to the given authority.
*
* @param \Illuminate\Database\Eloquent\Model $authority
* @return \Closure
*/
protected static function getAuthorityRoleConstraint(Model $authority)
{
return function ($query) use ($authority) {
$pivot = Models::table('assigned_roles');
$roles = Models::table('roles');
$table = $authority->getTable();
$prefix = Models::prefix();
$query->from($table)
->join($pivot, "{$table}.{$authority->getKeyName()}", '=', $pivot.'.entity_id')
->whereRaw("{$prefix}{$pivot}.role_id = {$prefix}{$roles}.id")
->where($pivot.'.entity_type', $authority->getMorphClass())
->where("{$table}.{$authority->getKeyName()}", $authority->getKey());
Models::scope()->applyToModelQuery($query, $roles);
Models::scope()->applyToRelationQuery($query, $pivot);
};
}
/**
* Get a constraint for abilities that have been granted to the given authority.
*
* @param \Illuminate\Database\Eloquent\Model $authority
* @param bool $allowed
* @return \Closure
*/
protected static function getAuthorityConstraint(Model $authority, $allowed)
{
return function ($query) use ($authority, $allowed) {
$permissions = Models::table('permissions');
$abilities = Models::table('abilities');
$table = $authority->getTable();
$prefix = Models::prefix();
$query->from($table)
->join($permissions, "{$table}.{$authority->getKeyName()}", '=', $permissions.'.entity_id')
->whereRaw("{$prefix}{$permissions}.ability_id = {$prefix}{$abilities}.id")
->where("{$permissions}.entity_type", $authority->getMorphClass())
->where("{$permissions}.forbidden", ! $allowed)
->where("{$table}.{$authority->getKeyName()}", $authority->getKey());
Models::scope()->applyToModelQuery($query, $abilities);
Models::scope()->applyToRelationQuery($query, $permissions);
};
}
}