-
Notifications
You must be signed in to change notification settings - Fork 3
/
AccessControlFilter.php
127 lines (115 loc) · 3.11 KB
/
AccessControlFilter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php
class AccessControlFilter extends CFilter
{
/**
* @var string the error message to be displayed when authorization fails.
* This property can be overridden by individual access rule via {@link CAccessRule::message}.
* If this property is not set, a default error message will be displayed.
*/
public $message;
private $_rules = array();
/**
* @return array list of access rules.
*/
public function getRules()
{
return $this->_rules;
}
/**
* @param array $rules list of access rules.
*/
public function setRules($rules)
{
foreach ($rules as $rule) {
if (is_array($rule) && isset($rule[0])) {
$r = new AccessRule();
$r->allow = $rule[0] === 'allow';
foreach (array_slice($rule, 1) as $name => $value) {
if ($name === 'message') {
$r->$name = $value;
} else {
if(is_numeric($name)){
$name = $value;
}
$className = 'AccessControl' . ucfirst($name) . 'Term';
if (!class_exists($className)) {
throw new Exception("Class not found");
}
if (is_array($value)) {
foreach ($value as $k => $v){
if(is_string($v)){
strtolower($value[$k]);
}
}
}
$r->addTerm(new $className($value));
}
}
$this->_rules[] = $r;
}
}
}
/**
* Performs the pre-action filtering.
* @param CFilterChain $filterChain the filter chain that the filter is on.
* @return boolean whether the filtering process should continue and the action
* should be executed.
*/
protected function preFilter($filterChain)
{
$app = Yii::app();
$user = $app->getUser();
foreach ($this->getRules() as $rule) {
if (($allow = $rule->isUserAllowed()) > 0) { // allowed
break;
} else if ($allow < 0) { // denied
$this->accessDenied($user, $this->resolveErrorMessage($rule));
return false;
}
}
$event = new CEvent($this);
$this->onAfterAccessFilterSuccess($event);
return true;
}
/**
* Resolves the error message to be displayed.
* This method will check {@link message} and {@link AccessRule::message} to see
* what error message should be displayed.
* @param AccessRule $rule the access rule
* @return string the error message
*/
protected function resolveErrorMessage($rule)
{
if ($rule->message !== null)
return $rule->message;
else if ($this->message !== null)
return $this->message;
else
return Yii::t('yii', 'You are not authorized to perform this action.');
}
/**
* Denies the access of the user.
* This method is invoked when access check fails.
* @param IWebUser $user the current user
* @param string $message the error message to be displayed
*/
protected function accessDenied($user, $message)
{
$event = new CEvent($this);
$this->onAfterAccessFilterFail($event);
if (!$event->handled) {
if ($user->getIsGuest())
$user->loginRequired();
else
throw new CHttpException(403, $message);
}
}
public function onAfterAccessFilterFail($event)
{
return $this->raiseEvent('onAfterAccessFilterFail', $event);
}
public function onAfterAccessFilterSuccess($event)
{
$this->raiseEvent('onAfterAccessFilterSuccess', $event);
}
}