| Code Coverage
| Lines | Functions and Methods | Classes and Traits
Total | 84.48% covered (warning) | 84.48% | 49 / 58 | 57.14% covered (warning) | 57.14% | 4 / 7 | CRAP | 0.00% covered (danger) | 0.00% | 0 / 1
AuthorizationService | 84.48% covered (warning) | 84.48% | 49 / 58 | 57.14% covered (warning) | 57.14% | 4 / 7 | 22.65 | 0.00% covered (danger) | 0.00% | 0 / 1
getRolesForUser | 100.00% covered (success) | 100.00% | 9 / 9 | 100.00% covered (success) | 100.00% | 1 / 1 | 1 |
userHasRole | 100.00% covered (success) | 100.00% | 2 / 2 | 100.00% covered (success) | 100.00% | 1 / 1 | 2 |
getPrimaryRole | 100.00% covered (success) | 100.00% | 1 / 1 | 100.00% covered (success) | 100.00% | 1 / 1 | 1 |
getCoachIdForUser | 100.00% covered (success) | 100.00% | 5 / 5 | 100.00% covered (success) | 100.00% | 1 / 1 | 1 |
userCanAccessChild | 81.82% covered (warning) | 81.82% | 9 / 11 | 0.00% covered (danger) | 0.00% | 0 / 1 | 5.15 |
userCanAccessGroup | 78.57% covered (warning) | 78.57% | 11 / 14 | 0.00% covered (danger) | 0.00% | 0 / 1 | 5.25 |
userCanAccessSession | 75.00% covered (warning) | 75.00% | 12 / 16 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6.56 |

1 | <?php
2 |
3 | namespace App\Services;
4 |
5 | use App\Models\ChildModel;
6 | use App\Models\CoachModel;
7 |
8 | class AuthorizationService
9 | {
10 | public function getRolesForUser(int $userId): array
11 | {
12 | $rows = db_connect()
13 | ->table('user_roles')
14 | ->select('roles.slug')
15 | ->join('roles', 'roles.id = user_roles.role_id')
16 | ->where('user_roles.user_id', $userId)
17 | ->orderBy('roles.priority', 'ASC')
18 | ->get()
19 | ->getResultArray();
20 |
21 | return array_values(array_map(static fn (array $row): string => $row['slug'], $rows));
22 | }
23 |
24 | /**
25 | * @param array<int, string>|string $roles
26 | */
27 | public function userHasRole(int $userId, array|string $roles): bool
28 | {
29 | $roles = is_array($roles) ? $roles : [$roles];
30 |
31 | return array_intersect($this->getRolesForUser($userId), $roles) !== [];
32 | }
33 |
34 | public function getPrimaryRole(int $userId): ?string
35 | {
36 | return $this->getRolesForUser($userId)[0] ?? null;
37 | }
38 |
39 | public function getCoachIdForUser(int $userId): ?int
40 | {
41 | $coach = model(CoachModel::class)
42 | ->select('id')
43 | ->where('user_id', $userId)
44 | ->first();
45 |
46 | return $coach['id'] ?? null;
47 | }
48 |
49 | public function userCanAccessChild(int $userId, int $childId): bool
50 | {
51 | if ($this->userHasRole($userId, 'admin')) {
52 | return true;
53 | }
54 |
55 | if (! $this->userHasRole($userId, 'coach')) {
56 | return false;
57 | }
58 |
59 | $coachId = $this->getCoachIdForUser($userId);
60 | if ($coachId === null) {
61 | return false;
62 | }
63 |
64 | $child = model(ChildModel::class)
65 | ->select('primary_coach_id')
66 | ->find($childId);
67 |
68 | return $child !== null && (int) ($child['primary_coach_id'] ?? 0) === $coachId;
69 | }
70 |
71 | public function userCanAccessGroup(int $userId, int $groupId): bool
72 | {
73 | if ($this->userHasRole($userId, 'admin')) {
74 | return true;
75 | }
76 |
77 | if (! $this->userHasRole($userId, 'coach')) {
78 | return false;
79 | }
80 |
81 | $coachId = $this->getCoachIdForUser($userId);
82 | if ($coachId === null) {
83 | return false;
84 | }
85 |
86 | $group = db_connect()
87 | ->table('academy_groups')
88 | ->select('primary_coach_id')
89 | ->where('id', $groupId)
90 | ->get()
91 | ->getRowArray();
92 |
93 | return $group !== null && (int) ($group['primary_coach_id'] ?? 0) === $coachId;
94 | }
95 |
96 | public function userCanAccessSession(int $userId, int $sessionId): bool
97 | {
98 | if ($this->userHasRole($userId, 'admin')) {
99 | return true;
100 | }
101 |
102 | if (! $this->userHasRole($userId, 'coach')) {
103 | return false;
104 | }
105 |
106 | $coachId = $this->getCoachIdForUser($userId);
107 | if ($coachId === null) {
108 | return false;
109 | }
110 |
111 | $session = db_connect()
112 | ->table('attendance_sessions')
113 | ->select('academy_group_id, coach_id')
114 | ->where('id', $sessionId)
115 | ->get()
116 | ->getRowArray();
117 |
118 | if ($session === null) {
119 | return false;
120 | }
121 |
122 | return (int) ($session['coach_id'] ?? 0) === $coachId || $this->userCanAccessGroup($userId, (int) $session['academy_group_id']);
123 | }
124 | }