1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @author Rik van der Kemp <[email protected]> |
4
|
|
|
* @copyright Zicht Online <http://www.zicht.nl> |
5
|
|
|
*/ |
6
|
|
|
|
7
|
|
|
namespace Zicht\Bundle\PageBundle\Security\Voter; |
8
|
|
|
|
9
|
|
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; |
10
|
|
|
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; |
11
|
|
|
use Zicht\Bundle\PageBundle\Model\ScheduledContentInterface; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Check content against the scheduled dates |
15
|
|
|
* |
16
|
|
|
* @package Zicht\Bundle\PageBundle\Security\Voter |
17
|
|
|
*/ |
18
|
|
|
class ScheduledContentVoter extends AdminAwareVoterAbstract |
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* Decide based on the current date and time what the vote should be. Static so it's strategy can easily be accessed |
22
|
|
|
* by other components as well, without the actual need for the voter instance. |
23
|
|
|
* |
24
|
|
|
* @param ScheduledContentInterface $object |
25
|
|
|
* @param array $attributes |
26
|
|
|
* @return int |
27
|
|
|
*/ |
28
|
6 |
|
public static function decide(ScheduledContentInterface $object, array $attributes = []) |
29
|
|
|
{ |
30
|
6 |
|
$from = $object->isScheduledFrom(); |
31
|
6 |
|
$till = $object->isScheduledTill(); |
32
|
|
|
$now = new \DateTimeImmutable(); |
33
|
6 |
|
$vote = VoterInterface::ACCESS_ABSTAIN; |
34
|
|
|
|
35
|
6 |
|
if (!$object->isPublic()) { |
36
|
5 |
|
return $vote; |
37
|
5 |
|
} |
38
|
|
|
|
39
|
3 |
|
if (null !== $from || null !== $till) { |
40
|
5 |
|
|
41
|
|
|
if (null !== $from && null !== $till) { |
42
|
1 |
|
switch (true) { |
43
|
2 |
|
case ($from <= $now && $till >= $now): |
44
|
|
|
$vote = VoterInterface::ACCESS_GRANTED; |
45
|
1 |
|
break; |
46
|
1 |
|
case (($from > $now && $till >= $now) && self::hasCmsAttribute($attributes)): |
47
|
5 |
|
$vote = VoterInterface::ACCESS_GRANTED; |
48
|
|
|
break; |
49
|
6 |
|
default: |
50
|
|
|
$vote = VoterInterface::ACCESS_DENIED; |
51
|
|
|
} |
52
|
|
|
} elseif (null !== $from && null === $till) { |
53
|
|
|
// Check only "from "date |
54
|
|
|
switch (true) { |
55
|
|
|
case ($from <= $now): |
56
|
|
|
$vote = VoterInterface::ACCESS_GRANTED; |
57
|
|
|
break; |
58
|
|
|
case ($from > $now && self::hasCmsAttribute($attributes)): |
59
|
|
|
$vote = VoterInterface::ACCESS_GRANTED; |
60
|
|
|
break; |
61
|
6 |
|
default: |
62
|
|
|
$vote = VoterInterface::ACCESS_DENIED; |
63
|
6 |
|
} |
64
|
|
|
} elseif (null == $from && null !== $till) { |
65
|
|
|
// Check only "till" date |
66
|
|
|
$vote = $till >= $now ? VoterInterface::ACCESS_GRANTED : VoterInterface::ACCESS_DENIED; |
67
|
|
|
} |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
return $vote; |
71
|
|
|
} |
72
|
|
|
|
73
|
7 |
|
/** |
74
|
|
|
* Check if the given attributes contain cms roles/attributes |
75
|
7 |
|
* |
76
|
|
|
* @param array $attributes |
77
|
|
|
* @return bool |
78
|
|
|
*/ |
79
|
|
|
protected static function hasCmsAttribute(array $attributes = []) |
80
|
|
|
{ |
81
|
7 |
|
return (in_array('ACTION_POST_UPDATE', $attributes) || in_array('ACTION_POST_PERSIST', $attributes)); |
82
|
|
|
} |
83
|
|
|
|
84
|
7 |
|
/** |
85
|
|
|
* @{inheritDoc} |
86
|
|
|
*/ |
87
|
7 |
|
public function supportsAttribute($attribute) |
88
|
6 |
|
{ |
89
|
6 |
|
return in_array($attribute, array('VIEW', 'ACTION_POST_UPDATE', 'ACTION_POST_PERSIST')); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
6 |
|
* Checks if the voter supports the given class. |
94
|
6 |
|
* |
95
|
6 |
|
* @param string $class A class name |
96
|
|
|
* |
97
|
7 |
|
* @return Boolean true if this Voter can process the class |
98
|
|
|
*/ |
99
|
|
|
public function supportsClass($class) |
100
|
|
|
{ |
101
|
|
|
return in_array('Zicht\Bundle\PageBundle\Model\ScheduledContentInterface', class_implements($class)); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* @{inheritDoc} |
106
|
|
|
*/ |
107
|
|
|
public function vote(TokenInterface $token, $object, array $attributes) |
108
|
|
|
{ |
109
|
|
|
// Abstract class checks if user is admin, if not so it will return VoterInterface::ACCESS_ABSTAIN |
110
|
|
|
$vote = parent::vote($token, $object, $attributes); |
|
|
|
|
111
|
|
|
|
112
|
|
|
/** @var ScheduledContentInterface $object */ |
113
|
|
|
if ($vote === VoterInterface::ACCESS_ABSTAIN && $this->supportsClass(get_class($object))) { |
114
|
|
|
foreach ($attributes as $attribute) { |
115
|
|
|
if (!$this->supportsAttribute($attribute)) { |
116
|
|
|
continue; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
$vote = self::decide($object, $attributes); |
120
|
|
|
} |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
return $vote; |
124
|
|
|
} |
125
|
|
|
} |
126
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.