1
|
|
|
<?php /** AccessFilterMicro */ |
2
|
|
|
|
3
|
|
|
namespace Micro\Filter; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Class AccessFilter |
7
|
|
|
* |
8
|
|
|
* @author Oleg Lunegov <[email protected]> |
9
|
|
|
* @link https://github.com/lugnsk/micro |
10
|
|
|
* @copyright Copyright © 2013 Oleg Lunegov |
11
|
|
|
* @license /LICENSE |
12
|
|
|
* @package Micro |
13
|
|
|
* @subpackage Filter |
14
|
|
|
* @version 1.0 |
15
|
|
|
* @since 1.0 |
16
|
|
|
*/ |
17
|
|
|
class AccessFilter extends Filter |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* @inheritdoc |
21
|
|
|
*/ |
22
|
|
|
public function pre(array $params) |
23
|
|
|
{ |
24
|
|
|
foreach ($params['rules'] AS $rule) { |
25
|
|
|
$res = $this->checkRule($rule); |
26
|
|
|
|
27
|
|
|
if ($res === true) { |
28
|
|
|
return true; |
29
|
|
View Code Duplication |
} elseif ($res === false) { |
|
|
|
|
30
|
|
|
$this->result = [ |
31
|
|
|
'redirect' => !empty($rule['redirect']) ? $rule['redirect'] : null, |
32
|
|
|
'message' => !empty($rule['message']) ? $rule['message'] : 'Access denied!' |
33
|
|
|
]; |
34
|
|
|
|
35
|
|
|
return false; |
36
|
|
|
} elseif ($res === null) { |
37
|
|
|
continue; |
38
|
|
|
} |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
return true; |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* Check one rule |
46
|
|
|
* |
47
|
|
|
* @access protected |
48
|
|
|
* |
49
|
|
|
* @param array $rule rule definition |
50
|
|
|
* |
51
|
|
|
* @return bool|null |
52
|
|
|
*/ |
53
|
|
|
protected function checkRule(array $rule) |
54
|
|
|
{ |
55
|
|
|
if ( |
56
|
|
|
$this->matchAction($rule) |
57
|
|
|
&& $this->matchUser($rule) |
58
|
|
|
&& $this->matchRole($rule) |
59
|
|
|
&& $this->matchIP($rule) |
60
|
|
|
&& $this->matchVerb($rule) |
61
|
|
|
) { |
62
|
|
|
return $rule['allow']; |
63
|
|
|
} else { |
64
|
|
|
return null; |
65
|
|
|
} |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Match action |
70
|
|
|
* |
71
|
|
|
* @access protected |
72
|
|
|
* |
73
|
|
|
* @param array $rule rule definition |
74
|
|
|
* |
75
|
|
|
* @return bool |
76
|
|
|
*/ |
77
|
|
|
protected function matchAction($rule) |
78
|
|
|
{ |
79
|
|
|
if (empty($rule['actions'])) { |
80
|
|
|
return true; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
if (is_array($rule['actions'])) { |
84
|
|
|
return in_array($this->action, $rule['actions'], true); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
return $this->action === $rule['actions']; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Match user |
92
|
|
|
* |
93
|
|
|
* @access protected |
94
|
|
|
* @global Container |
95
|
|
|
* |
96
|
|
|
* @param array $rule rule definition |
97
|
|
|
* |
98
|
|
|
* @return bool |
99
|
|
|
*/ |
100
|
|
|
protected function matchUser($rule) |
101
|
|
|
{ |
102
|
|
|
if (empty($rule['users'])) { |
103
|
|
|
return true; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
if (!is_array($rule['users'])) { |
107
|
|
|
$rule['users'][] = $rule['users']; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
foreach ($rule['users'] AS $u) { |
111
|
|
|
switch ($u) { |
112
|
|
|
case '*': |
113
|
|
|
return true; |
114
|
|
|
|
115
|
|
|
case '?': |
116
|
|
|
if ($this->container->user->isGuest()) { |
|
|
|
|
117
|
|
|
return true; |
118
|
|
|
} |
119
|
|
|
break; |
120
|
|
|
|
121
|
|
|
case '@': |
122
|
|
|
if (!$this->container->user->isGuest()) { |
|
|
|
|
123
|
|
|
return true; |
124
|
|
|
} |
125
|
|
|
break; |
126
|
|
|
|
127
|
|
|
default: |
128
|
|
|
if ($this->container->user->getID() === $u) { |
|
|
|
|
129
|
|
|
return true; |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
return false; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Match role |
139
|
|
|
* |
140
|
|
|
* @access protected |
141
|
|
|
* @global Container |
142
|
|
|
* |
143
|
|
|
* @param array $rule rule definition |
144
|
|
|
* |
145
|
|
|
* @return bool |
146
|
|
|
*/ |
147
|
|
View Code Duplication |
protected function matchRole($rule) |
|
|
|
|
148
|
|
|
{ |
149
|
|
|
if (empty($rule['roles'])) { |
150
|
|
|
return true; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
if (!is_array($rule['roles'])) { |
154
|
|
|
$rule['roles'][] = $rule['roles']; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
foreach ($rule['roles'] AS $role) { |
158
|
|
|
if ($this->container->user->check($role)) { |
|
|
|
|
159
|
|
|
return true; |
160
|
|
|
} |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
return false; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Match IP |
168
|
|
|
* |
169
|
|
|
* @access protected |
170
|
|
|
* @global Container |
171
|
|
|
* |
172
|
|
|
* @param array $rule rule definition |
173
|
|
|
* |
174
|
|
|
* @return bool |
175
|
|
|
*/ |
176
|
|
|
protected function matchIP($rule) |
177
|
|
|
{ |
178
|
|
|
if (empty($rule['ips'])) { |
179
|
|
|
return true; |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
if (!is_array($rule['ips'])) { |
183
|
|
|
$rule['ips'][] = $rule['ips']; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
$userIp = $this->container->request->getUserIP(); |
|
|
|
|
187
|
|
|
|
188
|
|
|
foreach ($rule['ips'] AS $r) { |
189
|
|
|
if ($r === '*' || $r === $userIp || (($pos = strpos($r, '*')) !== false && !strncmp($userIp, $r, $pos))) { |
190
|
|
|
return true; |
191
|
|
|
} |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
return false; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* Match verbose |
199
|
|
|
* |
200
|
|
|
* @access protected |
201
|
|
|
* @global Container |
202
|
|
|
* |
203
|
|
|
* @param array $rule rule definition |
204
|
|
|
* |
205
|
|
|
* @return bool |
206
|
|
|
*/ |
207
|
|
View Code Duplication |
protected function matchVerb($rule) |
|
|
|
|
208
|
|
|
{ |
209
|
|
|
if (empty($rule['verb'])) { |
210
|
|
|
return true; |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
if (!is_array($rule['verb'])) { |
214
|
|
|
$rule['verb'][] = $rule['verb']; |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
$verb = $this->container->request->getMethod(); |
|
|
|
|
218
|
|
|
|
219
|
|
|
foreach ($rule['verb'] AS $v) { |
220
|
|
|
if ($v === $verb) { |
221
|
|
|
return true; |
222
|
|
|
} |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
return false; |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
/** |
229
|
|
|
* @inheritdoc |
230
|
|
|
*/ |
231
|
|
|
public function post(array $params) |
232
|
|
|
{ |
233
|
|
|
return $params['data']; |
234
|
|
|
} |
235
|
|
|
} |
236
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.