Completed
Push — master ( 3fdf06...e648ff )
by Julito
33:51
created

SessionVoter::getCourseManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
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\CoreBundle\Entity\Session;
9
use Chamilo\UserBundle\Entity\User;
10
use Doctrine\ORM\EntityManager;
11
use Symfony\Component\DependencyInjection\ContainerInterface;
12
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
13
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
14
use Symfony\Component\Security\Core\User\UserInterface;
15
16
/**
17
 * Class SessionVoter
18
 * @package Chamilo\CoreBundle\Security\Authorization\Voter
19
 */
20
class SessionVoter extends Voter
21
{
22
    const VIEW = 'VIEW';
23
    const EDIT = 'EDIT';
24
    const DELETE = 'DELETE';
25
26
    private $entityManager;
27
    private $courseManager;
28
    private $container;
29
30
    /**
31
     * @param EntityManager $entityManager
32
     * @param CourseManager $courseManager
33
     * @param ContainerInterface $container
34
     */
35
    public function __construct(
36
        EntityManager $entityManager,
0 ignored issues
show
Bug introduced by
You have injected the EntityManager via parameter $entityManager. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

Loading history...
37
        CourseManager $courseManager,
38
        ContainerInterface $container
39
    ) {
40
        $this->entityManager = $entityManager;
41
        $this->courseManager = $courseManager;
42
        $this->container = $container;
43
    }
44
45
    /**
46
     * @return EntityManager
47
     */
48
    public function getEntityManager()
49
    {
50
        return $this->entityManager;
51
    }
52
53
    /**
54
     * @return CourseManager
55
     */
56
    public function getCourseManager()
57
    {
58
        return $this->courseManager;
59
    }
60
61
    /**
62
     * @inheritdoc
63
     */
64
    public function supports($attribute, $subject)
65
    {
66
        $options = [
67
            self::VIEW,
68
            self::EDIT,
69
            self::DELETE
70
        ];
71
        return $subject instanceof Session && in_array($attribute, $options);
72
    }
73
74
    /**
75
     * Check if user has access to a session
76
     *
77
     * @inheritdoc
78
     */
79
    protected function voteOnAttribute($attribute, $session, TokenInterface $token)
80
    {
81
        /** @var User $user */
82
        $user = $token->getUser();
83
84
        // Make sure there is a user object (i.e. that the user is logged in)
85
        if (!$user instanceof UserInterface) {
86
            return false;
87
        }
88
89
        // Checks if the current course was set up
90
        // $session->getCurrentCourse() is set in the class CourseListener
91
        /** @var Session $session */
92
        $course = $session->getCurrentCourse();
93
94
        if ($course == false) {
95
            return false;
96
        }
97
98
        $authChecker = $this->container->get('security.authorization_checker');
99
100
        // Admins have access to everything
101
        if ($authChecker->isGranted('ROLE_ADMIN')) {
102
            return true;
103
        }
104
105
        $sessionId = $session->getId();
106
        $userId = $user->getId();
107
108
        switch ($attribute) {
109
            case self::VIEW:
110
                // General coach
111
                $generalCoach = $session->getGeneralCoach();
112 View Code Duplication
                if ($generalCoach) {
113
                    $coachId = $generalCoach->getId();
114
                    $userId = $user->getId();
115
                    if ($coachId == $userId) {
116
                        $user->addRole('ROLE_CURRENT_SESSION_COURSE_TEACHER');
117
118
                        return true;
119
                    }
120
                }
121
122
                // Course-Coach access
123 View Code Duplication
                if ($session->hasCoachInCourseWithStatus($user, $course)) {
124
                    if (!$session->isActiveForCoach()) {
125
                        return false;
126
                    }
127
                    $user->addRole('ROLE_CURRENT_SESSION_COURSE_TEACHER');
128
                    return true;
129
                }
130
131
                // Student access
132
                if ($session->hasUserInCourse($user, $course)) {
133
                    $user->addRole('ROLE_CURRENT_SESSION_COURSE_STUDENT');
134
135
                     // Session duration per student.
136
                    if (!empty($session->getDuration())) {
137
                        $duration = $session->getDuration() * 24 * 60 * 60;
138
139
                        $courseAccess = \CourseManager::getFirstCourseAccessPerSessionAndUser(
140
                            $sessionId,
141
                            $userId
142
                        );
143
144
                        // If there is a session duration but there is no previous
145
                        // access by the user, then the session is still available
146
                        if (count($courseAccess) == 0) {
147
                            return true;
148
                        }
149
150
                        $currentTime = time();
151
                        $firstAccess = 0;
152
                        if (isset($courseAccess['login_course_date'])) {
153
                            $firstAccess = api_strtotime(
154
                                $courseAccess['login_course_date'],
155
                                'UTC'
156
                            );
157
                        }
158
                        $userDurationData = \SessionManager::getUserSession(
159
                            $userId,
160
                            $sessionId
161
                        );
162
                        $userDuration = 0;
163 View Code Duplication
                        if (isset($userDurationData['duration'])) {
164
                            $userDuration = intval($userDurationData['duration']) * 24 * 60 * 60;
165
                        }
166
167
                        $totalDuration = $firstAccess + $duration + $userDuration;
168
                        if ($totalDuration > $currentTime) {
169
                            return true;
170
                        } else {
171
                            return false;
172
                        }
173
                    } else {
174
                        if (!$session->isActiveForStudent()) {
175
                            return false;
176
                        }
177
                    }
178
179
                    return true;
180
                }
181
182
                return false;
183
                break;
184
            case self::EDIT:
185
            case self::DELETE:
186
                // General coach check
187
                $generalCoach = $session->getGeneralCoach();
188 View Code Duplication
                if ($generalCoach) {
189
                    $coachId = $generalCoach->getId();
190
                    $userId = $user->getId();
191
                    if ($coachId == $userId) {
192
                        $user->addRole('ROLE_CURRENT_SESSION_COURSE_TEACHER');
193
194
                        return true;
195
                    }
196
                }
197
198
                // Course session check
199 View Code Duplication
                if ($session->hasCoachInCourseWithStatus($user, $course)) {
200
                    if (!$session->isActiveForCoach()) {
201
                        return false;
202
                    }
203
                    $user->addRole('ROLE_CURRENT_SESSION_COURSE_TEACHER');
204
205
                    return true;
206
                }
207
                return false;
208
                break;
209
        }
210
211
        // User don't have access to the session
212
        return false;
213
214
    }
215
}
216
217