|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* For licensing terms, see /license.txt */ |
|
4
|
|
|
|
|
5
|
|
|
namespace Chamilo\CoreBundle\Security\Authorization\Voter; |
|
6
|
|
|
|
|
7
|
|
|
use Chamilo\CoreBundle\Repository\CourseRepository; |
|
8
|
|
|
use Chamilo\CourseBundle\Entity\CGroupInfo; |
|
9
|
|
|
use Chamilo\CourseBundle\Repository\CGroupInfoRepository; |
|
10
|
|
|
use Doctrine\ORM\EntityManager; |
|
11
|
|
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; |
|
12
|
|
|
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; |
|
13
|
|
|
use Symfony\Component\Security\Core\Authorization\Voter\Voter; |
|
14
|
|
|
use Symfony\Component\Security\Core\User\UserInterface; |
|
15
|
|
|
|
|
16
|
|
|
/** |
|
17
|
|
|
* Class GroupVoter. |
|
18
|
|
|
*/ |
|
19
|
|
|
class GroupVoter extends Voter |
|
20
|
|
|
{ |
|
21
|
|
|
public const VIEW = 'VIEW'; |
|
22
|
|
|
public const EDIT = 'EDIT'; |
|
23
|
|
|
public const DELETE = 'DELETE'; |
|
24
|
|
|
|
|
25
|
|
|
private $entityManager; |
|
26
|
|
|
private $courseManager; |
|
27
|
|
|
private $groupManager; |
|
28
|
|
|
private $authorizationChecker; |
|
29
|
|
|
|
|
30
|
|
|
public function __construct( |
|
31
|
|
|
EntityManager $entityManager, |
|
32
|
|
|
CourseRepository $courseManager, |
|
33
|
|
|
CGroupInfoRepository $groupManager, |
|
34
|
|
|
AuthorizationCheckerInterface $authorizationChecker |
|
35
|
|
|
) { |
|
36
|
|
|
$this->entityManager = $entityManager; |
|
37
|
|
|
$this->courseManager = $courseManager; |
|
38
|
|
|
$this->groupManager = $groupManager; |
|
39
|
|
|
$this->authorizationChecker = $authorizationChecker; |
|
40
|
|
|
} |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* @return AuthorizationCheckerInterface |
|
44
|
|
|
*/ |
|
45
|
|
|
public function getAuthorizationChecker() |
|
46
|
|
|
{ |
|
47
|
|
|
return $this->authorizationChecker; |
|
48
|
|
|
} |
|
49
|
|
|
|
|
50
|
|
|
/** |
|
51
|
|
|
* @return EntityManager |
|
52
|
|
|
*/ |
|
53
|
|
|
public function getEntityManager() |
|
54
|
|
|
{ |
|
55
|
|
|
return $this->entityManager; |
|
56
|
|
|
} |
|
57
|
|
|
|
|
58
|
|
|
/** |
|
59
|
|
|
* @return CourseRepository |
|
60
|
|
|
*/ |
|
61
|
|
|
public function getCourseManager(): CourseRepository |
|
62
|
|
|
{ |
|
63
|
|
|
return $this->courseManager; |
|
64
|
|
|
} |
|
65
|
|
|
|
|
66
|
|
|
/** |
|
67
|
|
|
* @param CourseRepository $courseManager |
|
68
|
|
|
* |
|
69
|
|
|
* @return GroupVoter |
|
70
|
|
|
*/ |
|
71
|
|
|
public function setCourseManager(CourseRepository $courseManager): self |
|
72
|
|
|
{ |
|
73
|
|
|
$this->courseManager = $courseManager; |
|
74
|
|
|
|
|
75
|
|
|
return $this; |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
/** |
|
79
|
|
|
* @return CGroupInfoRepository |
|
80
|
|
|
*/ |
|
81
|
|
|
public function getGroupManager(): CGroupInfoRepository |
|
82
|
|
|
{ |
|
83
|
|
|
return $this->groupManager; |
|
84
|
|
|
} |
|
85
|
|
|
|
|
86
|
|
|
/** |
|
87
|
|
|
* @param CGroupInfoRepository $groupManager |
|
88
|
|
|
* |
|
89
|
|
|
* @return GroupVoter |
|
90
|
|
|
*/ |
|
91
|
|
|
public function setGroupManager(CGroupInfoRepository $groupManager): self |
|
92
|
|
|
{ |
|
93
|
|
|
$this->groupManager = $groupManager; |
|
94
|
|
|
|
|
95
|
|
|
return $this; |
|
96
|
|
|
} |
|
97
|
|
|
|
|
98
|
|
|
/** |
|
99
|
|
|
* {@inheritdoc} |
|
100
|
|
|
*/ |
|
101
|
|
|
protected function supports($attribute, $subject): bool |
|
102
|
|
|
{ |
|
103
|
|
|
$options = [ |
|
104
|
|
|
self::VIEW, |
|
105
|
|
|
self::EDIT, |
|
106
|
|
|
self::DELETE, |
|
107
|
|
|
]; |
|
108
|
|
|
|
|
109
|
|
|
// if the attribute isn't one we support, return false |
|
110
|
|
|
if (!in_array($attribute, $options)) { |
|
111
|
|
|
return false; |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
// only vote on Post objects inside this voter |
|
115
|
|
|
if (!$subject instanceof CGroupInfo) { |
|
116
|
|
|
return false; |
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
return true; |
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
/** |
|
123
|
|
|
* {@inheritdoc} |
|
124
|
|
|
*/ |
|
125
|
|
|
protected function voteOnAttribute($attribute, $group, TokenInterface $token): bool |
|
126
|
|
|
{ |
|
127
|
|
|
$user = $token->getUser(); |
|
128
|
|
|
|
|
129
|
|
|
// make sure there is a user object (i.e. that the user is logged in) |
|
130
|
|
|
if (!$user instanceof UserInterface) { |
|
131
|
|
|
return false; |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
if (false == $group) { |
|
135
|
|
|
return false; |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
$authChecker = $this->getAuthorizationChecker(); |
|
139
|
|
|
|
|
140
|
|
|
// Admins have access to everything |
|
141
|
|
|
if ($authChecker->isGranted('ROLE_ADMIN')) { |
|
142
|
|
|
return true; |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
$groupInfo = [ |
|
146
|
|
|
'id' => $group->getId(), |
|
147
|
|
|
'session_id' => 0, |
|
148
|
|
|
'status' => $group->getStatus(), |
|
149
|
|
|
]; |
|
150
|
|
|
|
|
151
|
|
|
// Legacy |
|
152
|
|
|
return \GroupManager::userHasAccessToBrowse($user->getId(), $groupInfo); |
|
153
|
|
|
|
|
154
|
|
|
switch ($attribute) { |
|
|
|
|
|
|
155
|
|
|
case self::VIEW: |
|
156
|
|
|
if (!$group->hasUserInCourse($user, $course)) { |
|
157
|
|
|
$user->addRole(ResourceNodeVoter::ROLE_CURRENT_SESSION_COURSE_STUDENT); |
|
158
|
|
|
|
|
159
|
|
|
return true; |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
break; |
|
163
|
|
|
case self::EDIT: |
|
164
|
|
|
case self::DELETE: |
|
165
|
|
|
if (!$session->hasCoachInCourseWithStatus($user, $course)) { |
|
166
|
|
|
$user->addRole(ResourceNodeVoter::ROLE_CURRENT_SESSION_COURSE_TEACHER); |
|
167
|
|
|
|
|
168
|
|
|
return true; |
|
169
|
|
|
} |
|
170
|
|
|
|
|
171
|
|
|
break; |
|
172
|
|
|
} |
|
173
|
|
|
dump("You don't have access to this group!!"); |
|
|
|
|
|
|
174
|
|
|
|
|
175
|
|
|
return false; |
|
176
|
|
|
} |
|
177
|
|
|
} |
|
178
|
|
|
|
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return,dieorexitstatements that have been added for debug purposes.In the above example, the last
return falsewill never be executed, because a return statement has already been met in every possible execution path.