Issues (964)

src/Security/Voter/TeacherAbsenceVoter.php (1 issue)

Severity
1
<?php
2
3
namespace App\Security\Voter;
4
5
use App\Entity\TeacherAbsence;
6
use App\Entity\User;
7
use App\Settings\TeacherAbsenceSettings;
8
use LogicException;
9
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
10
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
11
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
12
13
class TeacherAbsenceVoter extends Voter {
14
15
    public const NewAbsence = 'new-teacher-absence';
16
17
    public const CanViewAny = 'view-any-teacher-absence';
18
    public const Index = 'index';
19
    public const Edit = 'edit';
20
    public const Show = 'show';
21
    public const Remove = 'remove';
22
23
    public const Process = 'process';
24
25
    public function __construct(private readonly AccessDecisionManagerInterface $accessDecisionManager, private readonly TeacherAbsenceSettings $settings) { }
26
27
    protected function supports(string $attribute, mixed $subject): bool {
28
        return $attribute === self::NewAbsence
29
            || $attribute === self::CanViewAny
30
            || $attribute === self::Index
31
            || ($subject instanceof TeacherAbsence && in_array($attribute, [ self::Edit, self::Show, self::Remove, self::Process ]));
32
    }
33
34
    protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool {
35
        if($this->settings->isEnabled() !== true) {
36
            return false;
37
        }
38
39
        switch($attribute) {
40
            case self::Index:
41
                return $this->canCreate($token) || $this->canViewAny($token);
42
43
            case self::NewAbsence:
44
                return $this->canCreate($token);
45
46
            case self::CanViewAny:
47
                return $this->canViewAny($token);
48
49
            case self::Edit:
50
                return $this->canEdit($token, $subject);
51
52
            case self::Show:
53
                return $this->canShow($token, $subject);
54
55
            case self::Remove:
56
                return $this->canRemove($token, $subject);
57
58
            case self::Process:
59
                return $this->canProcess($token, $subject);
60
        }
61
62
        throw new LogicException('This code should not be executed.');
63
    }
64
65
    private function canViewAny(TokenInterface $token): bool {
66
        return $this->accessDecisionManager->decide($token, [ 'ROLE_TEACHER_ABSENCE_MANAGER']);
67
    }
68
69
    private function canCreate(TokenInterface $token): bool {
70
        if($token->getUser() instanceof User && $token->getUser()->isTeacher()) {
71
            return true;
72
        }
73
74
        return $this->accessDecisionManager->decide($token, ['ROLE_TEACHER_ABSENCE_MANAGER']);
75
    }
76
77
    private function canInteractIfTeacherOrManager(TokenInterface $token, TeacherAbsence $absence): bool {
78
        $user = $token->getUser();
79
80
        if(!$user instanceof User) {
81
            return false;
82
        }
83
84
        if($user->getTeacher() !== null && $absence->getTeacher()->getId() === $user->getTeacher()->getId()) {
85
            // Teachers can edit/show/remove their own absences
86
            return true;
87
        }
88
89
        return $this->accessDecisionManager->decide($token, ['ROLE_TEACHER_ABSENCE_MANAGER']);
90
    }
91
92
    private function canEdit(TokenInterface $token, TeacherAbsence $absence): bool {
93
        return $this->canInteractIfTeacherOrManager($token, $absence);
94
    }
95
96
    private function canShow(TokenInterface $token, TeacherAbsence $absence): bool {
97
        return $this->canInteractIfTeacherOrManager($token, $absence);
98
    }
99
100
    private function canRemove(TokenInterface $token, TeacherAbsence $absence): bool {
101
        return $this->canInteractIfTeacherOrManager($token, $absence);
102
    }
103
104
    private function canProcess(TokenInterface $token, TeacherAbsence $absence): bool {
0 ignored issues
show
The parameter $absence is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

104
    private function canProcess(TokenInterface $token, /** @scrutinizer ignore-unused */ TeacherAbsence $absence): bool {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
105
        return $this->accessDecisionManager->decide($token, ['ROLE_TEACHER_ABSENCE_MANAGER']);
106
    }
107
}