Passed
Push — master ( 3e8c43...55a4a3 )
by Julito
08:48
created

GroupVoter   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 78
dl 0
loc 161
rs 10
c 0
b 0
f 0
wmc 28

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
A supports() 0 9 2
F voteOnAttribute() 0 127 25
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\Course;
10
use Chamilo\CoreBundle\Entity\User;
11
use Chamilo\CoreBundle\Repository\Node\CourseRepository;
12
use Chamilo\CourseBundle\Entity\CGroup;
13
use Chamilo\CourseBundle\Repository\CGroupRepository;
14
use Doctrine\ORM\EntityManager;
15
use GroupManager;
16
use Symfony\Component\HttpFoundation\RequestStack;
17
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
18
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
19
use Symfony\Component\Security\Core\Security;
20
use Symfony\Component\Security\Core\User\UserInterface;
21
22
class GroupVoter extends Voter
23
{
24
    public const VIEW = 'VIEW';
25
    public const EDIT = 'EDIT';
26
    public const DELETE = 'DELETE';
27
28
    private Security $security;
29
    private RequestStack $requestStack;
30
31
    public function __construct(
32
        //EntityManager $entityManager,
33
        //CourseRepository $courseManager,
34
        //CGroupRepository $groupManager,
35
        RequestStack $requestStack,
36
        Security $security
37
    ) {
38
        //$this->entityManager = $entityManager;
39
        //$this->courseManager = $courseManager;
40
        //$this->groupManager = $groupManager;
41
        $this->security = $security;
42
        $this->requestStack = $requestStack;
43
    }
44
45
    protected function supports(string $attribute, $subject): bool
46
    {
47
        $options = [
48
            self::VIEW,
49
            self::EDIT,
50
            self::DELETE,
51
        ];
52
53
        return $subject instanceof CGroup && \in_array($attribute, $options, true);
54
    }
55
56
    protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
57
    {
58
        /** @var User $user */
59
        $user = $token->getUser();
60
61
        // make sure there is a user object (i.e. that the user is logged in)
62
        if (!$user instanceof UserInterface) {
63
            return false;
64
        }
65
66
        if (false === $subject) {
67
            return false;
68
        }
69
70
        // Admins have access to everything.
71
        if ($this->security->isGranted('ROLE_ADMIN')) {
72
            return true;
73
        }
74
75
        /** @var CGroup $group */
76
        $group = $subject;
77
78
        // The group's parent is the course.
79
        /** @var Course $course */
80
        $course = $group->getParent();
81
82
        if ($course->isHidden()) {
83
            return false;
84
        }
85
86
        if (Course::REGISTERED === $course->getVisibility()) {
87
            if (!$course->hasUser($user)) {
88
                return false;
89
            }
90
        }
91
92
        if ($course->hasTeacher($user)) {
93
            $user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_GROUP_TEACHER);
94
95
            return true;
96
        }
97
98
        // Legacy
99
        //\GroupManager::userHasAccessToBrowse($user->getId(), $group);
100
        $isTutor = $group->hasTutor($user);
101
102
        switch ($attribute) {
103
            case self::VIEW:
104
                if ($isTutor) {
105
                    $user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_GROUP_TEACHER);
106
107
                    return true;
108
                }
109
110
                if (!$group->getStatus()) {
111
                    return false;
112
                }
113
114
                $userIsInGroup = $group->hasMember($user);
115
116
                if ($userIsInGroup) {
117
                    $user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_GROUP_STUDENT);
118
                }
119
120
                $requestUri = '';
121
                // Check if user has access in legacy tool.
122
                $request = $this->requestStack->getCurrentRequest();
123
                if ($request) {
124
                    $requestUri = $request->getRequestUri();
125
                }
126
127
                $tools = [
128
                    '/main/forum/' => $group->getForumState(),
129
                    '/documents/' => $group->getDocState(),
130
                    '/main/calendar/' => $group->getCalendarState(),
131
                    '/main/announcements/' => $group->getAnnouncementsState(),
132
                    '/main/work/' => $group->getWorkState(),
133
                    '/main/wiki/' => $group->getWikiState(),
134
                    /*'/main/group/group_space' => GroupManager::TOOL_PUBLIC,
135
                    '/main/inc/ajax/model.ajax.php' => GroupManager::TOOL_PUBLIC,
136
                    '/main/inc/ajax/announcement.ajax.php' => GroupManager::TOOL_PUBLIC,*/
137
                    //'/main/chat/' => $group->getAnnouncementsState(),  ??
138
                ];
139
140
                $toolStatus = GroupManager::TOOL_PUBLIC;
141
                foreach ($tools as $path => $status) {
142
                    if (str_contains($requestUri, $path)) {
143
                        $toolStatus = $status;
144
145
                        break;
146
                    }
147
                }
148
149
                switch ($toolStatus) {
150
                    case GroupManager::TOOL_NOT_AVAILABLE:
151
                        return false;
152
                    case GroupManager::TOOL_PUBLIC:
153
                        return true;
154
                    case GroupManager::TOOL_PRIVATE:
155
                        if ($userIsInGroup) {
156
                            return true;
157
                        }
158
159
                        break;
160
                    case GroupManager::TOOL_PRIVATE_BETWEEN_USERS:
161
                        // Only works for announcements for now
162
                        if ($userIsInGroup && '/main/announcements/' === $path) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $path seems to be defined by a foreach iteration on line 141. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
163
                            return true;
164
                        }
165
166
                        break;
167
                }
168
169
                break;
170
            case self::EDIT:
171
            case self::DELETE:
172
                if ($isTutor) {
173
                    $user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_GROUP_TEACHER);
174
175
                    return true;
176
                }
177
178
                break;
179
        }
180
        //dump("You don't have access to this group!!");
181
182
        return false;
183
    }
184
}
185