Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * TAuthorizationRule, TAuthorizationRuleCollection class file
4
 *
5
 * @author Qiang Xue <qiang.xue@gmail.com>
6
 * @link http://www.pradosoft.com/
7
 * @copyright Copyright &copy; 2005-2008 PradoSoft
8
 * @license http://www.pradosoft.com/license/
9
 * @version $Id: TAuthorizationRule.php 2541 2008-10-21 15:05:13Z qiang.xue $
10
 * @package System.Security
11
 */
12
/**
13
 * TAuthorizationRule class
14
 *
15
 * TAuthorizationRule represents a single authorization rule.
16
 * A rule is specified by an action (required), a list of users (optional),
17
 * a list of roles (optional), a verb (optional), and a list of IP rules (optional).
18
 * Action can be either 'allow' or 'deny'.
19
 * Guest (anonymous, unauthenticated) users are represented by question mark '?'.
20
 * All users (including guest users) are represented by asterisk '*'.
21
 * Authenticated users are represented by '@'.
22
 * Users/roles are case-insensitive.
23
 * Different users/roles are separated by comma ','.
24
 * Verb can be either 'get' or 'post'. If it is absent, it means both.
25
 * IP rules are separated by comma ',' and can contain wild card in the rules (e.g. '192.132.23.33, 192.122.*.*')
26
 *
27
 * @author Qiang Xue <qiang.xue@gmail.com>
28
 * @version $Id: TAuthorizationRule.php 2541 2008-10-21 15:05:13Z qiang.xue $
29
 * @package System.Security
30
 * @since 3.0
31
 */
32
class TAuthorizationRule extends TComponent
33
{
34
	/**
35
	 * @var string action, either 'allow' or 'deny'
36
	 */
37
	private $_action;
38
	/**
39
	 * @var array list of user IDs
40
	 */
41
	private $_users;
42
	/**
43
	 * @var array list of roles
44
	 */
45
	private $_roles;
46
	/**
47
	 * @var string verb, may be empty, 'get', or 'post'.
48
	 */
49
	private $_verb;
50
	/**
51
	 * @var string IP patterns
52
	 */
53
	private $_ipRules;
54
	/**
55
	 * @var boolean if this rule applies to everyone
56
	 */
57
	private $_everyone;
58
	/**
59
	 * @var boolean if this rule applies to guest user
60
	 */
61
	private $_guest;
62
	/**
63
	 * @var boolean if this rule applies to authenticated users
64
	 */
65
	private $_authenticated;
66
 
67
	/**
68
	 * Constructor.
69
	 * @param string action, either 'deny' or 'allow'
70
	 * @param string a comma separated user list
71
	 * @param string a comma separated role list
72
	 * @param string verb, can be empty, 'get', or 'post'
73
	 * @param string IP rules (separated by comma, can contain wild card *)
74
	 */
75
	public function __construct($action,$users,$roles,$verb='',$ipRules='')
76
	{
77
		$action=strtolower(trim($action));
78
		if($action==='allow' || $action==='deny')
79
			$this->_action=$action;
80
		else
81
			throw new TInvalidDataValueException('authorizationrule_action_invalid',$action);
82
		$this->_users=array();
83
		$this->_roles=array();
84
		$this->_ipRules=array();
85
		$this->_everyone=false;
86
		$this->_guest=false;
87
		$this->_authenticated=false;
88
 
89
		if(trim($users)==='')
90
			$users='*';
91
		foreach(explode(',',$users) as $user)
92
		{
93
			if(($user=trim(strtolower($user)))!=='')
94
			{
95
				if($user==='*')
96
				{
97
					$this->_everyone=true;
98
					break;
99
				}
100
				else if($user==='?')
101
					$this->_guest=true;
102
				else if($user==='@')
103
					$this->_authenticated=true;
104
				else
105
					$this->_users[]=$user;
106
			}
107
		}
108
 
109
		if(trim($roles)==='')
110
			$roles='*';
111
		foreach(explode(',',$roles) as $role)
112
		{
113
			if(($role=trim(strtolower($role)))!=='')
114
				$this->_roles[]=$role;
115
		}
116
 
117
		if(($verb=trim(strtolower($verb)))==='')
118
			$verb='*';
119
		if($verb==='*' || $verb==='get' || $verb==='post')
120
			$this->_verb=$verb;
121
		else
122
			throw new TInvalidDataValueException('authorizationrule_verb_invalid',$verb);
123
 
124
		if(trim($ipRules)==='')
125
			$ipRules='*';
126
		foreach(explode(',',$ipRules) as $ipRule)
127
		{
128
			if(($ipRule=trim($ipRule))!=='')
129
				$this->_ipRules[]=$ipRule;
130
		}
131
	}
132
 
133
	/**
134
	 * @return string action, either 'allow' or 'deny'
135
	 */
136
	public function getAction()
137
	{
138
		return $this->_action;
139
	}
140
 
141
	/**
142
	 * @return array list of user IDs
143
	 */
144
	public function getUsers()
145
	{
146
		return $this->_users;
147
	}
148
 
149
	/**
150
	 * @return array list of roles
151
	 */
152
	public function getRoles()
153
	{
154
		return $this->_roles;
155
	}
156
 
157
	/**
158
	 * @return string verb, may be empty, 'get', or 'post'.
159
	 */
160
	public function getVerb()
161
	{
162
		return $this->_verb;
163
	}
164
 
165
	/**
166
	 * @return array list of IP rules.
167
	 * @since 3.1.1
168
	 */
169
	public function getIPRules()
170
	{
171
		return $this->_ipRules;
172
	}
173
 
174
	/**
175
	 * @return boolean if this rule applies to everyone
176
	 */
177
	public function getGuestApplied()
178
	{
179
		return $this->_guest || $this->_everyone;
180
	}
181
 
182
	/**
183
	 * @return boolean if this rule applies to everyone
184
	 */
185
	public function getEveryoneApplied()
186
	{
187
		return $this->_everyone;
188
	}
189
 
190
	/**
191
	 * @return boolean if this rule applies to authenticated users
192
	 */
193
	public function getAuthenticatedApplied()
194
	{
195
		return $this->_authenticated || $this->_everyone;
196
	}
197
 
198
	/**
199
	 * @param IUser the user object
200
	 * @param string the request verb (GET, PUT)
201
	 * @param string the request IP address
202
	 * @return integer 1 if the user is allowed, -1 if the user is denied, 0 if the rule does not apply to the user
203
	 */
204
	public function isUserAllowed(IUser $user,$verb,$ip)
205
	{
206
		if($this->isVerbMatched($verb) && $this->isIpMatched($ip) && $this->isUserMatched($user) && $this->isRoleMatched($user))
207
			return ($this->_action==='allow')?1:-1;
208
		else
209
			return 0;
210
	}
211
 
212
	private function isIpMatched($ip)
213
	{
214
		if(empty($this->_ipRules))
215
			return 1;
216
		foreach($this->_ipRules as $rule)
217
		{
218
			if($rule==='*' || $rule===$ip || (($pos=strpos($rule,'*'))!==false && strncmp($ip,$rule,$pos)===0))
219
				return 1;
220
		}
221
		return 0;
222
	}
223
 
224
	private function isUserMatched($user)
225
	{
226
		return ($this->_everyone || ($this->_guest && $user->getIsGuest()) || ($this->_authenticated && !$user->getIsGuest()) || in_array(strtolower($user->getName()),$this->_users));
227
	}
228
 
229
	private function isRoleMatched($user)
230
	{
231
		foreach($this->_roles as $role)
232
		{
233
			if($role==='*' || $user->isInRole($role))
234
				return true;
235
		}
236
		return false;
237
	}
238
 
239
	private function isVerbMatched($verb)
240
	{
241
		return ($this->_verb==='*' || strcasecmp($verb,$this->_verb)===0);
242
	}
243
}
244
 
245
 
246
/**
247
 * TAuthorizationRuleCollection class.
248
 * TAuthorizationRuleCollection represents a collection of authorization rules {@link TAuthorizationRule}.
249
 * To check if a user is allowed, call {@link isUserAllowed}.
250
 *
251
 * @author Qiang Xue <qiang.xue@gmail.com>
252
 * @version $Id: TAuthorizationRule.php 2541 2008-10-21 15:05:13Z qiang.xue $
253
 * @package System.Security
254
 * @since 3.0
255
 */
256
class TAuthorizationRuleCollection extends TList
257
{
258
	/**
259
	 * @param IUser the user to be authorized
260
	 * @param string verb, can be empty, 'post' or 'get'.
261
	 * @param string the request IP address
262
	 * @return boolean whether the user is allowed
263
	 */
264
	public function isUserAllowed($user,$verb,$ip)
265
	{
266
		if($user instanceof IUser)
267
		{
268
			$verb=strtolower(trim($verb));
269
			foreach($this as $rule)
270
			{
271
				if(($decision=$rule->isUserAllowed($user,$verb,$ip))!==0)
272
					return ($decision>0);
273
			}
274
			return true;
275
		}
276
		else
277
			return false;
278
	}
279
 
280
	/**
281
	 * Inserts an item at the specified position.
282
	 * This overrides the parent implementation by performing additional
283
	 * operations for each newly added TAuthorizationRule object.
284
	 * @param integer the specified position.
285
	 * @param mixed new item
286
	 * @throws TInvalidDataTypeException if the item to be inserted is not a TAuthorizationRule object.
287
	 */
288
	public function insertAt($index,$item)
289
	{
290
		if($item instanceof TAuthorizationRule)
291
			parent::insertAt($index,$item);
292
		else
293
			throw new TInvalidDataTypeException('authorizationrulecollection_authorizationrule_required');
294
	}
295
}
296