## Apache Zeta Components Manual :: File Source for filter.php

## Source for file filter.php

Documentation is available at filter.php

1. <?php
2. /**
3. *
4. * Licensed to the Apache Software Foundation (ASF) under one
5. * or more contributor license agreements. See the NOTICE file
6. * distributed with this work for additional information
7. * regarding copyright ownership. The ASF licenses this file
8. * to you under the Apache License, Version 2.0 (the
9. * "License"); you may not use this file except in compliance
10. * with the License. You may obtain a copy of the License at
11. *
12. * http://www.apache.org/licenses/LICENSE-2.0
13. *
14. * Unless required by applicable law or agreed to in writing,
15. * software distributed under the License is distributed on an
16. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17. * KIND, either express or implied. See the License for the
18. * specific language governing permissions and limitations
19. * under the License.
20. *
21. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
22. * @version //autogentag//
23. * @filesource
24. * @package MvcAuthenticationTiein
25. */
27. /**
28. * This class provides a filter that applications can use for authentication.
29. *
30. * Through the $options argument to the controller you can configure many
31. * aspects of this filter. By default a few settings are made that setup table
32. * names and fields names, as well as names of variables under which certain
33. * bits of the filter will be available in the controller's actions. The filter
34. * needs to be integrated in both the applications configuration (through an
35. * implementation of ezcMvcDispatcherConfiguration) as well as in the
36. * controller handling authentication actions. Please refer to the tutorial on
37. * how to do this.
38. *
39. * Some of the defaults provided in this filter can easily be changed by
40. * inheriting. For example if you want to change the password generation
41. * algorithm you need to override generatePassword(). Another example is when
42. * you want other authentication methods besides session and database. In that
43. * case setupAuth() needs to be overridden in an inherited class.
44. *
45. * @package MvcAuthenticationTiein
46. * @version //autogentag//
47. * @mainclass
48. */
49. class ezcMvcAuthenticationFilter
50. {
51. /**
52. * Contains the filter options object
53. *
54. * @var ezcMvcAuthenticationFilterOptions
55. */
56. private $options;
58. /**
59. * Constructs a new ezcMvcAuthenticationFilter object
60. *
61. * @param ezcMvcAuthenticationFilterOptions $options
62. */
63. function __construct ( ezcMvcAuthenticationFilterOptions $options = null )
64. {
65. $this->options = $options === null ? new ezcMvcAuthenticationFilterOptions () : $options;
66. }
68. /**
69. * Sets a new options object
70. *
71. * @param ezcMvcAuthenticationFilterOptions $options
72. */
73. public function setOptions ( ezcMvcAuthenticationFilterOptions $options )
74. {
75. $this->options = $options;
76. }
78. /**
79. * Returns the currently set options
80. *
81. * @return ezcMvcAuthenticationFilterOptions
82. */
83. public function getOptions ()
84. {
85. return $this->options;
86. }
88. /**
89. * Returns the value of the property $name.
90. *
91. * @throws ezcBasePropertyNotFoundException
92. * if the property $name does not exist
93. * @param string $name
94. * @ignore
95. */
96. public function __get( $name )
97. {
98. switch ( $name )
99. {
100. case 'options':
101. return $this->options;
102. break;
103. }
104. throw new ezcBasePropertyNotFoundException ( $name );
105. }
107. /**
108. * Sets the property $name to $value.
109. *
110. * @throws ezcBasePropertyNotFoundException
111. * if the property $name does not exist
112. * @throws ezcBaseValueException
113. * if $value is not accepted for the property $name
114. * @param string $name
115. * @param mixed $value
116. * @ignore
117. */
118. public function __set( $name, $value )
119. {
120. switch ( $name )
121. {
122. case 'options':
123. if ( !( $value instanceof ezcMvcAuthenticationFilterOptions ) )
124. {
125. throw new ezcBaseValueException ( 'options', $value, 'instanceof ezcMvcAuthenticationFilterOptions' );
126. }
127. $this->options = $value;
128. break;
130. default:
131. throw new ezcBasePropertyNotFoundException ( $name );
132. }
133. }
135. /**
136. * Returns true if the property $name is set, otherwise false.
137. *
138. * @param string $name
139. * @return bool
140. * @ignore
141. */
142. public function __isset( $name )
143. {
144. switch ( $name )
145. {
146. case 'options':
147. return true;
149. default:
150. return false;
151. }
152. }
154. /**
155. * This method sets up the authentication mechanism.
156. *
157. * By default it uses database and session storage only. If you want to do
158. * more complex things, the best way would be to inherit from this class
159. * and override this method. It takes a user name and password, but those
160. * can be empty if your overridden class does not require them. This method
161. * will also be called with $user and $password being NULL in case the
162. * filter needs to check whether a user is already logged in. In this case,
163. * the session should be checked.
164. *
165. * @param string $user
166. * @param string $password
167. *
168. * @return ezcAuthentication
169. */
170. protected function setupAuth ( $user = null, $password = null )
171. {
172. $database = new ezcAuthenticationDatabaseInfo (
173. $this->options->database,
174. $this->options->tableName,
175. array( $this->options->userIdField, $this->options->passwordField )
176. );
177. $databaseFilter = new ezcAuthenticationDatabaseFilter ( $database );
179. // use the options object when creating a new Session object
180. $options = new ezcAuthenticationSessionOptions ();
181. $options->validity = 86400;
182. $options->idKey = $this->options->sessionUserIdKey;
183. $options->timestampKey = $this->options->sessionTimestampKey;
185. $session = new ezcAuthenticationSession ( $options );
186. $session->start();
188. if ( $user === null )
189. {
190. $user = $session->load();
191. $password = null;
192. }
194. $credentials = new ezcAuthenticationPasswordCredentials ( $user, $this-> hashPassword ( $password ) );
195. $authentication = new ezcAuthentication ( $credentials );
196. $authentication->session = $session;
197. $authentication->addFilter( $databaseFilter );
199. return $authentication;
200. }
202. /**
203. * Returns the username associated with the user ID as stored in the session.
204. *
205. * This method could be a likely candidate to override as well, although it
206. * is as configurable as possible. If usernames are not stored in the
207. * database, this method needs to be overridden as well. The method's
208. * return value is used by the setVars() method to add user ID and user
209. * name to the session so that the application can use this data.
210. *
211. * @return string
212. */
213. protected function fetchUserName ()
214. {
215. if ( isset( $_SESSION[$this->options->sessionUserIdKey] ) )
216. {
217. $q = ezcDbInstance :: get ()->createSelectQuery();
218. $q->select( '*' )
219. ->from( $this->options->tableName )
220. ->where( $q->expr->eq( $this->options->userIdField, $q->bindValue( $_SESSION[$this->options->sessionUserIdKey] ) ) );
221. $s = $q->prepare();
222. $s->execute();
223. $r = $s->fetchAll();
225. return $r[0][$this->options->userNameField];
226. }
227. return null;
228. }
230. /**
231. * This method sets the user ID and user name variables as part of the
232. * $request and $result objects.
233. *
234. * This method should be called by the application's runRequestFilters()
235. * and runResultFilters() methods to add authentication information to the
236. * request and/or result. The method also makes the authentication filter
237. * available to the controller actions so it is important that it is called
238. * in both filters, and preferably as the first method call.
239. *
240. * The variable names that contain the user ID and user name can be
241. * configured through the $options object that is passed to the contructor.
242. *
243. * @param ezcMvcRequest|ezcMvcResult
244. */
245. public function setVars ( $requestOrResult )
246. {
247. $requestOrResult->variables[$this->options->varNameFilter] = $this;
248. if ( isset( $_SESSION[$this->options->sessionUserIdKey] ) )
249. {
250. $requestOrResult->variables[$this->options->varNameUserId] = $_SESSION[$this->options->sessionUserIdKey];
251. $requestOrResult->variables[$this->options->varNameUserName] = self::fetchUserName();
252. }
253. }
255. /**
256. * Sets up the authentication mechanism to be used for routes that do not require authentication.
257. *
258. * This method is meant to be run from the runRequestFilters() method for
259. * the routes that do not require authentication or deal with logging in,
260. * logging out and registering users. It sets up the session so that the
261. * controller has access to the authentication data.
262. *
263. * @param ezcMvcRequest $request
264. */
265. public function runAuthCheckLoggedIn ( ezcMvcRequest $request )
266. {
267. $auth = self::setupAuth();
268. $auth->run();
269. }
271. /**
272. * Sets up the authentication mechanism to be used for routes that do require authentication.
273. *
274. * This method is meant to be run from the runRequestFilters() method for
275. * the routes that do require an authenticated user. It sets up the
276. * session so that the controller has access to the authentication data.
277. * The method will return an internal redirect return that redirects to the
278. * configured loginRequiredUri. That Uri's controller and action needs to
279. * present the login form.
280. *
281. * @param ezcMvcRequest $request
282. */
283. public function runAuthRequiredFilter ( $request )
284. {
285. $auth = self::setupAuth();
286. if ( !$auth->run() )
287. {
288. $status = $auth->getStatus();
289. $request->variables['ezcAuth_redirUrl'] = $request->uri;
290. $request->variables['ezcAuth_reasons'] = $status;
292. $request->uri = $this->options->loginRequiredUri;
293. return new ezcMvcInternalRedirect ( $request );
294. }
295. }
297. /**
298. * Method to be called from the controller's login action to log a user in.
299. *
300. * @param ezcMvcRequest $request
301. * @param string $user
302. * @param string $password
303. */
304. public function login ( ezcMvcRequest $request, $user, $password )
305. {
306. return $this-> setupAuth ( $user, $password );
307. }
309. /**
310. * Method to be called from the controller's logout action to log a user out.
311. *
312. * @param ezcMvcRequest $request
313. */
314. public function logout ( ezcMvcRequest $request )
315. {
316. $options = new ezcAuthenticationSessionOptions ();
317. $options->validity = 86400;
319. $session = new ezcAuthenticationSession ( $options );
320. $session->start();
321. unset( $_SESSION[$this->options->sessionUserIdKey] );
322. $session->destroy();
323. }
325. /**
326. * Checks whether a user exists in the database.
327. *
328. * This method should be called from the "register" action to see if the
329. * requested user ID has already been registered or not.
330. *
331. * @param string $username
332. * @return bool
333. */
334. public function checkUserExists ( $username )
335. {
336. $q = ezcDbInstance :: get ()->createSelectQuery();
337. $q->select( $this->options->userIdField )
338. ->from( $this->options->tableName )
339. ->where( $q->expr->eq(
340. $this->options->userIdField,
341. $q->bindValue( $username ) )
342. );
343. $s = $q->prepare();
344. $s->execute();
345. $r = $s->fetchAll();
347. return ( count ( $r ) == 0 );
348. }
350. /**
351. * Returns a generated basic password depending on the $username.
352. *
353. * This method is typically called from the "register" action after a user
354. * ID has been checked for existance.
355. *
356. * @param string $username
357. * @return string
358. */
359. public function generatePassword ( $username )
360. {
361. // generate password
362. mt_srand (
363. base_convert ( substr ( md5 ( $username ), 0, 6 ), 36, 10 ) *
364. microtime ( true )
365. );
366. $a = base_convert ( mt_rand (), 10, 36 );
367. $b = base_convert ( mt_rand (), 10, 36 );
368. $password = substr ( $b . $a, 1, 8 );
370. return $password;
371. }
373. /**
374. * Returns the hashed version of the clear text password
375. *
376. * @param string $password
377. * @return string
378. */
379. protected function hashPassword ( $password )
380. {
381. return md5 ( $password );
382. }
384. /**
385. * Creates an entry in the user database table for $username and $password.
386. *
387. * This method creates a user in the configured user table (through the
388. * options for this class). You can specify extra information as a
389. * key->value pair array as $extraInfo. This method does *not* check
390. * whether a user already exists.
391. *
392. * @param string $username
393. * @param string $password
394. * @param array(string=>mixed) $extraInfo
395. */
396. public function createUser ( $username, $password, array $extraInfo )
397. {
398. $q = ezcDbInstance::get()->createInsertQuery();
399. $q->insertInto( $this->options->tableName )
400. ->set( $this->options->userIdField, $q->bindValue( $username ) )
401. ->set( $this->options->passwordField, $q->bindValue( $this->hashPassword( $password ) ) );
402. foreach ( $extraInfo as $key => $value )
403. {
404. $q->set( $key, $q->bindValue( $value ) );
405. }
406. $s = $q->prepare();
407. $s->execute();
408. }
410. /**
411. * Checks the status from the authentication run and adds the reasons as
412. * variable to the $result.
413. *
414. * This method uses the information that is set by the
415. * runAuthRequiredFilter() filter to generate an user-readable text of the
416. * found $reasons and sets these as the variable ezcAuth_reasons in
417. * the $result. You can supply your own mapping from status codes to
418. * messages, but a default is provided. Please refer to the Authentication
419. * tutorial for information about status codes.
420. *
421. * @param ezcMvcResult $result
422. * @param array(string) $reasons
423. * @param array(string=>array(int=>string) $errorMap
424. */
425. function processLoginRequired ( ezcMvcResult $res, $reasons, $errorMap = null )
426. {
427. $reasonText = array();
429. if ( $errorMap === null )
430. {
431. $errorMap = array(
432. 'ezcAuthenticationDatabaseFilter' => array(
433. ezcAuthenticationHtpasswdFilter ::STATUS_USERNAME_INCORRECT => 'Incorrect or no credentials provided.',
434. ezcAuthenticationHtpasswdFilter ::STATUS_PASSWORD_INCORRECT => 'Incorrect or no credentials provided.'
435. ),
436. 'ezcAuthenticationSession' => array(
437. ezcAuthenticationSession ::STATUS_EMPTY => 'No session',
438. ezcAuthenticationSession ::STATUS_EXPIRED => 'Session expired'
439. ),
440. );
441. }
443. foreach ( $reasons as $line )
444. {
445. list( $key, $value ) = each ( $line );
446. $reasonText[] = $errorMap[$key][$value];
447. }
448. $res->variables['ezcAuth_reasons'] = $reasonText;
449. }
451. /**
452. * Returns either an internal or external redirect depending on whether the
453. * user authenticated succesfully.
454. *
455. * This method is run from the "login" action just after login() has been
456. * called. It takes the $authentication object, the $request and the form
457. * provided $redirUrl. It redirects upon failure to the configured
458. * loginRequiredUri and upon succes to the provided $redirUrl. The
459. * redirection happens by returning an ezcMvcInternalRedirect or
460. * ezcMvcResult with a ezcMvcExternalRedirect status.
461. *
462. * @param ezcAuthentication $authentication
463. * @param ezcMvcRequest $request
464. * @param string $redirUrl
465. * @return ezcMvcInternalRedirect|ezcMvcResult
466. */
467. function returnLoginRedirect ( ezcAuthentication $authentication, ezcMvcRequest $request, $redirUrl )
468. {
469. if ( !$authentication->run() )
470. {
471. $request = clone $request;
472. $status = $authentication->getStatus();
473. $request->variables['ezcAuth_redirUrl'] = $redirUrl;
474. $request->variables['ezcAuth_reasons'] = $status;
476. $request->uri = $this->options->loginRequiredUri;
477. return new ezcMvcInternalRedirect ( $request );
478. }
480. $res = new ezcMvcResult ;
481. $res->status = new ezcMvcExternalRedirect ( $redirUrl );
482. return $res;
483. }
485. /**
486. * Returns an external redirect depending to the configured logoutUri.
487. *
488. * This method is run from the "logout" action just after logout() has been
489. * called. It takes the $request object as parameter although this is not
490. * used by this default implementation. The method returns an
491. * ezcMvcRequest result with a ezcMvcExternalRedirect status to redirect to
492. * the configured logoutUri.
493. *
494. * @param ezcMvcRequest $request
495. * @return ezcMvcResult
496. */
497. function returnLogoutRedirect ( ezcMvcRequest $request )
498. {
499. $res = new ezcMvcResult ;
500. $res->status = new ezcMvcExternalRedirect ( $this->options->logoutUri );
501. return $res;
502. }
503. }
504. ?>

Documentation generated by phpDocumentor 1.4.3