1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
/* For licensing terms, see /license.txt */ |
6
|
|
|
|
7
|
|
|
namespace Chamilo\CoreBundle\Security\Authorization\Voter; |
8
|
|
|
|
9
|
|
|
use Chamilo\CoreBundle\Entity\Session; |
10
|
|
|
use Chamilo\CoreBundle\Entity\User; |
11
|
|
|
use Chamilo\CoreBundle\Settings\SettingsManager; |
12
|
|
|
use Symfony\Bundle\SecurityBundle\Security; |
13
|
|
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; |
14
|
|
|
use Symfony\Component\Security\Core\Authorization\Voter\Voter; |
15
|
|
|
use Symfony\Component\Security\Core\User\UserInterface; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* @todo remove legacy code. |
19
|
|
|
* |
20
|
|
|
* @extends Voter<'VIEW'|'EDIT'|'DELETE', Session> |
21
|
|
|
*/ |
22
|
|
|
class SessionVoter extends Voter |
23
|
|
|
{ |
24
|
|
|
public const VIEW = 'VIEW'; |
25
|
|
|
public const EDIT = 'EDIT'; |
26
|
|
|
public const DELETE = 'DELETE'; |
27
|
|
|
|
28
|
|
|
public function __construct( |
29
|
|
|
private readonly Security $security, |
30
|
|
|
private readonly SettingsManager $settingsManager |
31
|
|
|
) {} |
32
|
|
|
|
33
|
|
|
protected function supports(string $attribute, $subject): bool |
34
|
|
|
{ |
35
|
|
|
$options = [ |
36
|
|
|
self::VIEW, |
37
|
|
|
self::EDIT, |
38
|
|
|
self::DELETE, |
39
|
|
|
]; |
40
|
|
|
|
41
|
|
|
return $subject instanceof Session && \in_array($attribute, $options, true); |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* Check if user has access to a session. |
46
|
|
|
* |
47
|
|
|
* {@inheritdoc} |
48
|
|
|
*/ |
49
|
|
|
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool |
50
|
|
|
{ |
51
|
|
|
/** @var User $user */ |
52
|
|
|
$user = $token->getUser(); |
53
|
|
|
|
54
|
|
|
// Make sure there is a user object (i.e. that the user is logged in) |
55
|
|
|
if (!$user instanceof UserInterface) { |
56
|
|
|
return false; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
// Admins have access to everything. |
60
|
|
|
if ($this->security->isGranted('ROLE_ADMIN')) { |
61
|
|
|
return true; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
// Checks if the current course was set up |
65
|
|
|
// $session->getCurrentCourse() is set in the class CidReqListener. |
66
|
|
|
/** @var Session $session */ |
67
|
|
|
$session = $subject; |
68
|
|
|
$currentCourse = $session->getCurrentCourse(); |
69
|
|
|
|
70
|
|
|
// Course checks. |
71
|
|
|
if ($currentCourse && $currentCourse->isHidden()) { |
72
|
|
|
return false; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
switch ($attribute) { |
76
|
|
|
case self::VIEW: |
77
|
|
|
// @todo improve performance. |
78
|
|
|
$userIsGeneralCoach = $session->hasUserAsGeneralCoach($user); |
79
|
|
|
if (null === $currentCourse) { |
80
|
|
|
$userIsStudent = $session->getSessionRelCourseByUser($user, Session::STUDENT)->count() > 0; |
81
|
|
|
$userIsCourseCoach = $session->hasCoachInCourseList($user); // The current course will be checked in CourseVoter. |
82
|
|
|
} else { |
83
|
|
|
$userIsCourseCoach = $session->hasCourseCoachInCourse($user, $currentCourse); |
84
|
|
|
$userIsStudent = $session->hasUserInCourse($user, $currentCourse, Session::STUDENT); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
if ($userIsGeneralCoach) { |
88
|
|
|
$user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_SESSION_TEACHER); |
89
|
|
|
} elseif ($userIsCourseCoach) { // Course-Coach access. |
90
|
|
|
$user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_SESSION_TEACHER); |
91
|
|
|
} elseif ($userIsStudent) { // Student access. |
92
|
|
|
$user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_SESSION_STUDENT); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
if (Session::INVISIBLE !== $session->checkAccessVisibility($user)) { |
|
|
|
|
96
|
|
|
return true; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
return false; |
100
|
|
|
|
101
|
|
|
case self::EDIT: |
102
|
|
|
case self::DELETE: |
103
|
|
|
$canEdit = $this->canEditSession($user, $session, false); |
104
|
|
|
|
105
|
|
|
if ($canEdit) { |
106
|
|
|
$user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_SESSION_TEACHER); |
107
|
|
|
|
108
|
|
|
return true; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
return false; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
// User don't have access to the session |
115
|
|
|
return false; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
private function canEditSession(User $user, Session $session, bool $checkSession = true): bool |
119
|
|
|
{ |
120
|
|
|
if (!$this->allowToManageSessions()) { |
121
|
|
|
return false; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
if ($this->security->isGranted('ROLE_ADMIN') && $this->allowed($user, $session)) { |
125
|
|
|
return true; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
if ($checkSession) { |
129
|
|
|
return $this->allowed($user, $session); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
return true; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
private function allowToManageSessions(): bool |
136
|
|
|
{ |
137
|
|
|
if ($this->allowManageAllSessions()) { |
138
|
|
|
return true; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
$setting = $this->settingsManager->getSetting('session.allow_teachers_to_create_sessions'); |
142
|
|
|
|
143
|
|
|
return 'true' === $setting && $this->security->isGranted('ROLE_TEACHER'); |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
private function allowManageAllSessions(): bool |
147
|
|
|
{ |
148
|
|
|
return $this->security->isGranted('ROLE_ADMIN') || $this->security->isGranted('ROLE_SESSION_MANAGER'); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
private function allowed(User $user, Session $session): bool |
152
|
|
|
{ |
153
|
|
|
if ($this->security->isGranted('ROLE_ADMIN')) { |
154
|
|
|
return true; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
if ($this->security->isGranted('ROLE_SESSION_MANAGER') |
158
|
|
|
&& 'true' !== $this->settingsManager->getSetting('session.allow_session_admins_to_manage_all_sessions') |
159
|
|
|
&& !$session->hasUserAsSessionAdmin($user) |
160
|
|
|
) { |
161
|
|
|
return false; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
if ($this->security->isGranted('ROLE_TEACHER') |
165
|
|
|
&& 'true' === $this->settingsManager->getSetting('session.allow_teachers_to_create_sessions') |
166
|
|
|
&& !$session->hasUserAsGeneralCoach($user) |
167
|
|
|
) { |
168
|
|
|
return false; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
return true; |
172
|
|
|
} |
173
|
|
|
} |
174
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.