Passed
Push — master ( 0cdc5b...b949c4 )
by Julito
12:36
created

GroupVoter   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 67
dl 0
loc 135
rs 10
c 0
b 0
f 0
wmc 23

3 Methods

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