Passed
Push — master ( 3be753...7af7b8 )
by Julito
10:23
created

CourseVoter::supports()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 3
nop 2
dl 0
loc 19
rs 9.9666
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
namespace Chamilo\CoreBundle\Security\Authorization\Voter;
5
6
use Chamilo\CoreBundle\Entity\Course;
7
use Chamilo\CoreBundle\Entity\Manager\CourseManager;
8
use Chamilo\UserBundle\Entity\User;
9
use Doctrine\ORM\EntityManager;
10
use Doctrine\ORM\EntityManagerInterface;
11
use Symfony\Component\DependencyInjection\ContainerInterface;
12
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
13
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
14
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
15
use Symfony\Component\Security\Core\User\UserInterface;
16
17
/**
18
 * Class CourseVoter.
19
 *
20
 * @package Chamilo\CoreBundle\Security\Authorization\Voter
21
 */
22
class CourseVoter extends Voter
23
{
24
    public const VIEW = 'VIEW';
25
    public const EDIT = 'EDIT';
26
    public const DELETE = 'DELETE';
27
28
    private $entityManager;
29
    private $courseManager;
30
    private $authorizationChecker;
31
    private $container;
32
33
    /**
34
     * @param EntityManagerInterface        $entityManager
35
     * @param CourseManager                 $courseManager
36
     * @param AuthorizationCheckerInterface $authorizationChecker
37
     * @param ContainerInterface            $container
38
     */
39
    public function __construct(
40
        EntityManagerInterface $entityManager,
41
        CourseManager $courseManager,
42
        AuthorizationCheckerInterface $authorizationChecker,
43
        ContainerInterface $container
44
    ) {
45
        $this->entityManager = $entityManager;
46
        $this->courseManager = $courseManager;
47
        $this->authorizationChecker = $authorizationChecker;
48
        $this->container = $container;
49
    }
50
51
    /**
52
     * @return AuthorizationCheckerInterface
53
     */
54
    public function getAuthorizationChecker()
55
    {
56
        return $this->authorizationChecker;
57
    }
58
59
    /**
60
     * @return EntityManager
61
     */
62
    public function getEntityManager()
63
    {
64
        return $this->entityManager;
65
    }
66
67
    /**
68
     * @return CourseManager
69
     */
70
    public function getCourseManager()
71
    {
72
        return $this->courseManager;
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    protected function supports($attribute, $subject): bool
79
    {
80
        $options = [
81
            self::VIEW,
82
            self::EDIT,
83
            self::DELETE,
84
        ];
85
86
        // if the attribute isn't one we support, return false
87
        if (!in_array($attribute, $options)) {
88
            return false;
89
        }
90
91
        // only vote on Post objects inside this voter
92
        if (!$subject instanceof Course) {
93
            return false;
94
        }
95
96
        return true;
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102
    protected function voteOnAttribute($attribute, $course, TokenInterface $token): bool
103
    {
104
        /** @var User $user */
105
        $user = $token->getUser();
106
        // Anons can enter a course depending of the course visibility
107
        /*if (!$user instanceof UserInterface) {
108
            return false;
109
        }*/
110
111
        $authChecker = $this->getAuthorizationChecker();
112
113
        // Admins have access to everything
114
        if ($authChecker->isGranted('ROLE_ADMIN')) {
115
            return true;
116
        }
117
118
        // Course is active?
119
        /** @var Course $course */
120
        switch ($attribute) {
121
            case self::VIEW:
122
                // Course is hidden then is not visible for nobody expect admins.
123
                if ($course->getVisibility() == Course::HIDDEN) {
124
                    return false;
125
                }
126
127
                // "Open to the world" no need to check if user is registered or if user exists.
128
                // Course::OPEN_WORLD
129
                if ($course->isPublic()) {
130
                    return true;
131
                }
132
133
                // User should be instance of UserInterface.
134
                if (!$user instanceof UserInterface) {
135
                    return false;
136
                }
137
138
                // If user is logged in and is open platform, allow access.
139
                if ($course->getVisibility() == Course::OPEN_PLATFORM) {
140
                    $user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_STUDENT);
141
142
                    if ($course->hasTeacher($user)) {
143
                        $user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER);
144
                    }
145
146
                    $token->setUser($user);
147
148
                    return true;
149
                }
150
151
                // Course::REGISTERED
152
                // User must be subscribed in the course no matter if is teacher/student
153
                if ($course->hasUser($user)) {
154
                    $user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_STUDENT);
155
156
                    if ($course->hasTeacher($user)) {
157
                        $user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER);
158
                    }
159
160
                    $token->setUser($user);
161
162
                    return true;
163
                }
164
                break;
165
            case self::EDIT:
166
            case self::DELETE:
167
                // Only teacher can edit/delete stuff
168
                if ($course->hasTeacher($user)) {
169
                    $user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER);
170
                    $token->setUser($user);
171
172
                    return true;
173
                }
174
                break;
175
        }
176
177
        return false;
178
    }
179
}
180