Passed
Push — master ( 577984...690f51 )
by Angel Fernando Quiroz
08:47
created

ResourceAclHelper   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 40
c 1
b 0
f 0
dl 0
loc 81
rs 10
wmc 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
B isAllowed() 0 75 7
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Helpers;
8
9
use Chamilo\CoreBundle\Entity\ResourceLink;
10
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
11
use Laminas\Permissions\Acl\Acl;
12
use Laminas\Permissions\Acl\Resource\GenericResource;
13
use Laminas\Permissions\Acl\Role\GenericRole;
14
use Symfony\Bundle\SecurityBundle\Security;
15
use Symfony\Component\Security\Acl\Permission\MaskBuilder;
16
use Symfony\Component\Security\Core\Authentication\Token\NullToken;
17
use Symfony\Component\Security\Core\User\UserInterface;
18
19
readonly class ResourceAclHelper
20
{
21
    public function __construct(
22
        private Security $security,
23
    ) { }
24
25
    public function isAllowed(
26
        string $attribute,
27
        ResourceLink $resourceLink,
28
        iterable $rights,
29
        bool $allowAnonsToView,
30
    ): bool {
31
        // Creating roles
32
        $anon = new GenericRole('IS_AUTHENTICATED_ANONYMOUSLY');
33
        $userRole = new GenericRole('ROLE_USER');
34
        $student = new GenericRole('ROLE_STUDENT');
35
        $teacher = new GenericRole('ROLE_TEACHER');
36
        $studentBoss = new GenericRole('ROLE_STUDENT_BOSS');
37
38
        $currentStudent = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_STUDENT);
39
        $currentTeacher = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER);
40
41
        $currentStudentGroup = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_GROUP_STUDENT);
42
        $currentTeacherGroup = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_GROUP_TEACHER);
43
44
        $currentStudentSession = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_SESSION_STUDENT);
45
        $currentTeacherSession = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_SESSION_TEACHER);
46
47
        // Setting Simple ACL.
48
        $acl = (new Acl())
49
            ->addRole($anon)
50
            ->addRole($userRole)
51
            ->addRole($student)
52
            ->addRole($teacher)
53
            ->addRole($studentBoss)
54
55
            ->addRole($currentStudent)
56
            ->addRole($currentTeacher, ResourceNodeVoter::ROLE_CURRENT_COURSE_STUDENT)
57
58
            ->addRole($currentStudentSession)
59
            ->addRole($currentTeacherSession, ResourceNodeVoter::ROLE_CURRENT_COURSE_SESSION_STUDENT)
60
61
            ->addRole($currentStudentGroup)
62
            ->addRole($currentTeacherGroup, ResourceNodeVoter::ROLE_CURRENT_COURSE_GROUP_STUDENT)
63
        ;
64
65
        // Add a security resource.
66
        $acl->addResource(new GenericResource((string) $resourceLink->getId()));
67
68
        // Check all the right this link has.
69
        // Set rights from the ResourceRight.
70
        foreach ($rights as $right) {
71
            $acl->allow($right->getRole(), null, (string) $right->getMask());
72
        }
73
74
        // Anons can see.
75
        if ($allowAnonsToView) {
76
            $acl->allow($anon, null, (string) ResourceNodeVoter::getReaderMask());
77
        }
78
79
        // Asked mask
80
        $mask = new MaskBuilder();
81
        $mask->add($attribute);
82
83
        $askedMask = (string) $mask->get();
84
85
        if ($this->security->getToken() instanceof NullToken) {
86
            return (bool) $acl->isAllowed('IS_AUTHENTICATED_ANONYMOUSLY', $resourceLink->getId(), $askedMask);
87
        }
88
89
        $user = $this->security->getUser();
90
91
        $roles = $user instanceof UserInterface ? $user->getRoles() : [];
92
93
        foreach ($roles as $role) {
94
            if ($acl->isAllowed($role, $resourceLink->getId(), $askedMask)) {
95
                return true;
96
            }
97
        }
98
99
        return false;
100
    }
101
}