Passed
Push — feature/application-review-ui ( afbf92 )
by Chris
06:55
created

AuthServiceProvider   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 26
eloc 56
dl 0
loc 127
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A register() 0 2 1
D defineGates() 0 79 24
A boot() 0 5 1
1
<?php
2
3
namespace App\Providers;
4
5
use Illuminate\Support\Facades\Auth;
6
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
7
use Illuminate\Support\Facades\Gate;
8
use App\Models\Applicant;
9
use App\Models\Course;
10
use App\Models\Degree;
11
use App\Models\Manager;
12
use App\Models\JobPoster;
13
use App\Models\Reference;
14
use App\Models\WorkSample;
15
use App\Models\JobApplication;
16
use App\Models\WorkExperience;
17
use App\Models\SkillDeclaration;
18
use App\Models\Assessment;
19
use App\Models\RatingGuideQuestion;
20
use App\Models\RatingGuideAnswer;
21
use App\Models\AssessmentPlanNotification;
22
use App\Models\HrAdvisor;
23
use App\Models\User;
24
use App\Policies\UserPolicy;
25
use App\Policies\JobPolicy;
26
use App\Policies\CoursePolicy;
27
use App\Policies\DegreePolicy;
28
use App\Policies\ManagerPolicy;
29
use App\Policies\ApplicantPolicy;
30
use App\Policies\ReferencePolicy;
31
use App\Policies\ApplicationPolicy;
32
use App\Policies\SkillDeclarationPolicy;
33
use App\Policies\WorkExperiencePolicy;
34
use App\Policies\WorkSamplePolicy;
35
use App\Policies\AssessmentPolicy;
36
use App\Policies\RatingGuideQuestionPolicy;
37
use App\Policies\RatingGuideAnswerPolicy;
38
use App\Policies\AssessmentPlanNotificationPolicy;
39
use App\Policies\HrAdvisorPolicy;
40
41
class AuthServiceProvider extends ServiceProvider
42
{
43
    /**
44
     * The policy mappings for the application.
45
     *
46
     * @var array
47
     */
48
    protected $policies = [
49
        User::class => UserPolicy::class,
50
        Applicant::class => ApplicantPolicy::class,
51
        Manager::class => ManagerPolicy::class,
52
        JobPoster::class => JobPolicy::class,
53
        JobApplication::class => ApplicationPolicy::class,
54
        Course::class => CoursePolicy::class,
55
        Degree::class => DegreePolicy::class,
56
        Reference::class => ReferencePolicy::class,
57
        SkillDeclaration::class => SkillDeclarationPolicy::class,
58
        WorkExperience::class => WorkExperiencePolicy::class,
59
        WorkSample::class => WorkSamplePolicy::class,
60
        Assessment::class => AssessmentPolicy::class,
61
        RatingGuideQuestion::class => RatingGuideQuestionPolicy::class,
62
        RatingGuideAnswer::class => RatingGuideAnswerPolicy::class,
63
        AssessmentPlanNotification::class =>  AssessmentPlanNotificationPolicy::class,
64
        HrAdvisor::class => HrAdvisorPolicy::class,
65
    ];
66
67
    /**
68
     * Define any authorization gates
69
     *
70
     * @return void
71
     */
72
    protected function defineGates(): void
73
    {
74
        Gate::define('view-assessment-plan', function ($user, $jobPoster) {
75
            return $user->isAdmin() ||
76
                $user->isManager() && $jobPoster->manager->user_id === $user->id;
77
        });
78
79
        /*
80
         * Returns true if $user owns a job to which $applicant has applied.
81
         */
82
        Gate::define('owns-job-applicant-applied-to', function ($user, $applicant) {
83
            $applicant_id = $applicant->id;
84
            $user_id = $user->id;
85
            return JobPoster::whereHas(
86
                'manager',
87
                function ($q) use ($user_id): void {
88
                    $q->where('user_id', $user_id);
89
                }
90
            )->whereHas(
91
                'submitted_applications',
92
                function ($q) use ($applicant_id): void {
93
                    $q->where('applicant_id', $applicant_id);
94
                }
95
            )->get()->isNotEmpty();
96
        });
97
98
        /*
99
         * Returns true if the $user is an hr_advisor which has claimed a job the applicant has applied to,
100
         * where the job is closed.
101
         */
102
        Gate::define('claims-job-applicant-applied-to', function ($user, $applicant) {
103
            if ($user->isHrAdvisor()) {
104
                return $applicant->submitted_applications->some(function ($application) use ($user) {
105
                    return $user->can('manage', $application->job_poster) && $application->job_poster->isClosed();
106
                });
107
            }
108
            return false;
109
        });
110
111
        /* Logged-in Users can view themselves. Admins can view everyone. Managers can view
112
         * Applicants of their Job Posters. HR Advisors can view Managers
113
         * within their department, and any Applicants of Job Posters created
114
         * by those managers.
115
         */
116
117
        /* TODO: User roles/permissions are getting a little unruly. I needed to add an
118
         * additional check alongside isUpgradedManager() because we have an isAdmin()
119
         * passthrough on that method, which was causing issues on the hr_advisor/manager
120
         * reference.
121
         */
122
        Gate::define('view-user', function ($user, $userProfile) {
123
            return (
124
                // Any user can view themselves.
125
                $user->id === $userProfile->id) ||
126
                (
127
                    // Admins can view anyone.
128
                    $user->isAdmin()) ||
129
                (
130
                    // Managers should be able to view HR Advisors within their department.
131
                    $user->isUpgradedManager() && ($user->manager !== null)
132
                    && !$user->isAdmin()
133
                    && $userProfile->isHrAdvisor() && ($userProfile->hr_advisor !== null)
134
                    && !$userProfile->isAdmin()
135
                    && ($user->manager->department_id === $userProfile->hr_advisor->department_id)) ||
136
                (
137
                    // HR Advisors can view applicants that have applied to Job Posters that have been claimed.
138
                    ($user->isHrAdvisor() && $userProfile->applicant !== null) &&
139
                    Gate::forUser($user)->allows('claims-job-applicant-applied-to', $userProfile->applicant)) ||
140
                (
141
                    // Managers can view Applicants who have applied to their Job Posters.
142
                    (!$user->isAdmin() && $user->isUpgradedManager() && $userProfile->applicant !== null) &&
143
                    Gate::forUser($user)->allows('owns-job-applicant-applied-to', $userProfile->applicant)) ||
144
                (
145
                    // Manager profiles are viewable by any logged in User.
146
                    $user !== null && !$userProfile->isAdmin() && $userProfile->isUpgradedManager());
147
        });
148
149
        Gate::define('view-resources', function ($user) {
150
            return $user->isUpgradedManager() || $user->isHrAdvisor();
151
        });
152
    }
153
154
    public function register(): void
155
    {
156
    }
157
158
    /**
159
     * Register any authentication / authorization services.
160
     *
161
     * @return void
162
     */
163
    public function boot(): void
164
    {
165
        $this->registerPolicies();
166
167
        $this->defineGates();
168
    }
169
}
170