Completed
Push — master ( 5cd775...78bef9 )
by Jonathan
14:29 queued 04:27
created

User::hasRoleOnDomain()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Uccello\Core\Models;
4
5
use Illuminate\Notifications\Notifiable;
6
use Illuminate\Foundation\Auth\User as Authenticatable;
7
use Illuminate\Database\Eloquent\SoftDeletes;
8
use Illuminate\Support\Collection;
9
use Tymon\JWTAuth\Contracts\JWTSubject;
0 ignored issues
show
Bug introduced by
The type Tymon\JWTAuth\Contracts\JWTSubject was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Nicolaslopezj\Searchable\SearchableTrait;
0 ignored issues
show
Bug introduced by
The type Nicolaslopezj\Searchable\SearchableTrait was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Uccello\Core\Support\Traits\RelatedlistTrait;
12
13
class User extends Authenticatable implements JWTSubject
14
{
15
    use SoftDeletes;
16
    use Notifiable;
17
    use RelatedlistTrait;
18
    use SearchableTrait;
19
20
    /**
21
     * The table associated with the model.
22
     *
23
     * @var string
24
     */
25
    protected $table = 'users';
26
27
    /**
28
     * The attributes that should be mutated to dates.
29
     *
30
     * @var array
31
     */
32
    protected $dates = [ 'deleted_at' ];
33
34
    /**
35
     * The attributes that are mass assignable.
36
     *
37
     * @var array
38
     */
39
    protected $fillable = [
40
        'username',
41
        'first_name',
42
        'last_name',
43
        'email',
44
        'password',
45
        'is_admin',
46
        'domain_id'
47
    ];
48
49
    /**
50
     * The attributes that should be hidden for arrays.
51
     *
52
     * @var array
53
     */
54
    protected $hidden = [
55
        'password', 'remember_token',
56
    ];
57
58
    /**
59
     * The accessors to append to the model's array form.
60
     *
61
     * @var array
62
     */
63
    protected $appends = [
64
        'recordLabel'
65
    ];
66
67
    /**
68
     * Searchable rules.
69
     * See https://github.com/nicolaslopezj/searchable
70
     *
71
     * @var array
72
     */
73
    protected $searchable = [
74
        'columns' => [
75
            'username' => 20,
76
            'first_name' => 10,
77
            'last_name' => 10,
78
            'email' => 5
79
        ]
80
    ];
81
82
    public function domain()
83
    {
84
        return $this->belongsTo(Domain::class);
85
    }
86
87
    public function lastDomain()
88
    {
89
        return $this->belongsTo(Domain::class);
90
    }
91
92
    public function privileges()
93
    {
94
        return $this->hasMany(Privilege::class);
95
    }
96
97
    public function menus()
98
    {
99
        return $this->hasMany(Menu::class);
100
    }
101
102
    /**
103
     * Get the identifier that will be stored in the subject claim of the JWT.
104
     *
105
     * @return mixed
106
     */
107
    public function getJWTIdentifier()
108
    {
109
        return $this->getKey();
110
    }
111
112
    /**
113
     * Return a key value array, containing any custom claims to be added to the JWT.
114
     *
115
     * @return array
116
     */
117
    public function getJWTCustomClaims()
118
    {
119
        return [ ];
120
    }
121
122
    /**
123
     * Returns record label
124
     *
125
     * @return string
126
     */
127
    public function getRecordLabelAttribute() : string
128
    {
129
        return trim($this->first_name.' '.$this->last_name) ?? $this->username;
0 ignored issues
show
Bug Best Practice introduced by
The property last_name does not exist on Uccello\Core\Models\User. Did you maybe forget to declare it?
Loading history...
130
    }
131
132
    /**
133
     * Returns user's roles on a domain
134
     *
135
     * @param \Uccello\Core\Models\Domain $domain
136
     * @return \Illuminate\Support\Collection
137
     */
138
    public function rolesOnDomain($domain) : Collection
139
    {
140
        $roles = new Collection();
141
142
        foreach ($this->privileges->where('domain_id', $domain->id) as $privilege) {
143
            $roles[ ] = $privilege->role;
144
        }
145
146
        return $roles;
147
    }
148
149
    /**
150
     * Check if the user has at least a role on a domain
151
     *
152
     * @param \Uccello\Core\Models\Domain $domain
153
     * @return boolean
154
     */
155
    public function hasRoleOnDomain($domain) : bool {
156
        if ($this->is_admin) {
157
            return true;
158
        }
159
160
        return $this->rolesOnDomain($domain)->count() > 0;
161
    }
162
163
    /**
164
     * Check if the user has at least a role on a domain or its descendants
165
     *
166
     * @param \Uccello\Core\Models\Domain $domain
167
     * @return boolean
168
     */
169
    public function hasRoleOnDescendantDomain(Domain $domain) : bool {
170
        if ($this->is_admin) {
171
            return true;
172
        }
173
174
        $hasRole = false;
175
176
        $descendants = $domain->findDescendants()->get();
177
        foreach ($descendants as $descendant) {
178
            if ($this->hasRoleOnDomain($descendant)) {
179
                $hasRole = true;
180
                break;
181
            }
182
        }
183
184
        return $hasRole;
185
    }
186
187
    /**
188
     * Returns all user capabilities on a module in a domain.
189
     * If the user has a capability in one of the parents of a domain, he also has it in that domain.
190
     *
191
     * @param \Uccello\Core\Models\Domain $domain
192
     * @param \Uccello\Core\Models\Module $module
193
     * @return \Illuminate\Support\Collection
194
     */
195
    public function capabilitiesOnModule(Domain $domain, Module $module) : Collection
196
    {
197
        $capabilities = new Collection();
198
199
        // Get the domain and all its parents
200
        $domainParents = $domain->findAncestors()->get();
201
202
        // Get user privileges on each domain
203
        foreach ($domainParents as $_domain) {
204
            $privileges = $this->privileges->where('domain_id', $_domain->id);
205
206
            foreach ($privileges as $privilege) {
207
208
                foreach ($privilege->role->profiles as $profile) {
209
                    $capabilities = $capabilities->merge($profile->capabilitiesOnModule($module));
210
                }
211
            }
212
        }
213
214
        return $capabilities;
215
    }
216
217
    /**
218
     * Checks if the user has a capability on a module in a domain.
219
     *
220
     * @param string $capabilityName
221
     * @param \Uccello\Core\Models\Domain $domain
222
     * @param \Uccello\Core\Models\Module $module
223
     * @return boolean
224
     */
225
    public function hasCapabilityOnModule(string $capabilityName, Domain $domain, Module $module) : bool
226
    {
227
        $capability = capability($capabilityName);
228
229
        $userCapabilities = $this->capabilitiesOnModule($domain, $module);
230
231
        return $this->is_admin || $userCapabilities->contains($capability);
232
    }
233
234
    /**
235
     * Checks if the user can access to settings panel.
236
     * Checks if the user has at least one admin capability on admin modules in a domain.
237
     *
238
     * @param \Uccello\Core\Models\Domain|null $domain
239
     * @return boolean
240
     */
241
    public function canAccessToSettingsPanel(?Domain $domain) : bool
242
    {
243
        $hasCapability = false;
244
245
        if (empty($domain)) {
246
            $domain = Domain::first();
247
        }
248
249
        foreach (Module::all() as $module) {
250
            if ($module->isAdminModule() === true && $this->canAdmin($domain, $module)) {
251
                $hasCapability = true;
252
                break;
253
            }
254
        }
255
256
        return $hasCapability;
257
    }
258
259
    /**
260
     * Checks if the user can admin a module in a domain.
261
     *
262
     * @param \Uccello\Core\Models\Domain $domain
263
     * @param \Uccello\Core\Models\Module $module
264
     * @return boolean
265
     */
266
    public function canAdmin(Domain $domain, Module $module) : bool
267
    {
268
        return $this->hasCapabilityOnModule('admin', $domain, $module);
269
    }
270
271
    /**
272
     * Checks if the user can create a module in a domain.
273
     *
274
     * @param \Uccello\Core\Models\Domain $domain
275
     * @param \Uccello\Core\Models\Module $module
276
     * @return boolean
277
     */
278
    public function canCreate(Domain $domain, Module $module) : bool
279
    {
280
        return $this->hasCapabilityOnModule('create', $domain, $module) || ($module->isAdminModule() && $this->canAdmin($domain, $module));
281
    }
282
283
    /**
284
     * Checks if the user can retrieve a module in a domain.
285
     *
286
     * @param \Uccello\Core\Models\Domain $domain
287
     * @param \Uccello\Core\Models\Module $module
288
     * @return boolean
289
     */
290
    public function canRetrieve(Domain $domain, Module $module) : bool
291
    {
292
        return $this->hasCapabilityOnModule('retrieve', $domain, $module) || ($module->isAdminModule() && $this->canAdmin($domain, $module));
293
    }
294
295
    /**
296
     * Checks if the user can update a module in a domain.
297
     *
298
     * @param \Uccello\Core\Models\Domain $domain
299
     * @param \Uccello\Core\Models\Module $module
300
     * @return boolean
301
     */
302
    public function canUpdate(Domain $domain, Module $module) : bool
303
    {
304
        return $this->hasCapabilityOnModule('update', $domain, $module) || ($module->isAdminModule() && $this->canAdmin($domain, $module));
305
    }
306
307
    /**
308
     * Checks if the user can delete a module in a domain.
309
     *
310
     * @param \Uccello\Core\Models\Domain $domain
311
     * @param \Uccello\Core\Models\Module $module
312
     * @return boolean
313
     */
314
    public function canDelete(Domain $domain, Module $module) : bool
315
    {
316
        return $this->hasCapabilityOnModule('delete', $domain, $module) || ($module->isAdminModule() && $this->canAdmin($domain, $module));
317
    }
318
319
    /**
320
     * Checks if the user can create by API a module in a domain.
321
     *
322
     * @param \Uccello\Core\Models\Domain $domain
323
     * @param \Uccello\Core\Models\Module $module
324
     * @return boolean
325
     */
326
    public function canCreateByApi(Domain $domain, Module $module) : bool
327
    {
328
        return $this->hasCapabilityOnModule('api-create', $domain, $module) || ($module->isAdminModule() && $this->canAdmin($domain, $module));
329
    }
330
331
    /**
332
     * Checks if the user can retrieve by API a module in a domain.
333
     *
334
     * @param \Uccello\Core\Models\Domain $domain
335
     * @param \Uccello\Core\Models\Module $module
336
     * @return boolean
337
     */
338
    public function canRetrieveByApi(Domain $domain, Module $module) : bool
339
    {
340
        return $this->hasCapabilityOnModule('api-retrieve', $domain, $module) || ($module->isAdminModule() && $this->canAdmin($domain, $module));
341
    }
342
343
    /**
344
     * Checks if the user can update by API a module in a domain.
345
     *
346
     * @param \Uccello\Core\Models\Domain $domain
347
     * @param \Uccello\Core\Models\Module $module
348
     * @return boolean
349
     */
350
    public function canUpdateByApi(Domain $domain, Module $module) : bool
351
    {
352
        return $this->hasCapabilityOnModule('api-update', $domain, $module) || ($module->isAdminModule() && $this->canAdmin($domain, $module));
353
    }
354
355
    /**
356
     * Checks if the user can delete by API a module in a domain.
357
     *
358
     * @param \Uccello\Core\Models\Domain $domain
359
     * @param \Uccello\Core\Models\Module $module
360
     * @return boolean
361
     */
362
    public function canDeleteByApi(Domain $domain, Module $module) : bool
363
    {
364
        return $this->hasCapabilityOnModule('api-delete', $domain, $module) || ($module->isAdminModule() && $this->canAdmin($domain, $module));
365
    }
366
}
367