/library/Zend/OpenId/Provider/Storage/File.php

https://bitbucket.org/Ebozavrik/test-application · PHP · 478 lines · 316 code · 40 blank · 122 comment · 49 complexity · d7919275d3c2b36898eb250afc85f970 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_OpenId
  17. * @subpackage Zend_OpenId_Provider
  18. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: File.php 24593 2012-01-05 20:35:02Z matthew $
  21. */
  22. /**
  23. * @see Zend_OpenId_Provider_Storage
  24. */
  25. require_once "Zend/OpenId/Provider/Storage.php";
  26. /**
  27. * External storage implemmentation using serialized files
  28. *
  29. * @category Zend
  30. * @package Zend_OpenId
  31. * @subpackage Zend_OpenId_Provider
  32. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  33. * @license http://framework.zend.com/license/new-bsd New BSD License
  34. */
  35. class Zend_OpenId_Provider_Storage_File extends Zend_OpenId_Provider_Storage
  36. {
  37. /**
  38. * Directory name to store data files in
  39. *
  40. * @var string $_dir
  41. */
  42. private $_dir;
  43. /**
  44. * Constructs storage object and creates storage directory
  45. *
  46. * @param string $dir directory name to store data files in
  47. *
  48. * @throws Zend_OpenId_Exception
  49. */
  50. public function __construct ($dir = null)
  51. {
  52. if ($dir === null) {
  53. $tmp = getenv('TMP');
  54. if (empty( $tmp )) {
  55. $tmp = getenv('TEMP');
  56. if (empty( $tmp )) {
  57. $tmp = "/tmp";
  58. }
  59. }
  60. $user = get_current_user();
  61. if (is_string($user) && !empty( $user )) {
  62. $tmp .= '/' . $user;
  63. }
  64. $dir = $tmp . '/openid/provider';
  65. }
  66. $this->_dir = $dir;
  67. if (!is_dir($this->_dir)) {
  68. if (!@mkdir($this->_dir, 0700, 1)) {
  69. throw new Zend_OpenId_Exception(
  70. "Cannot access storage directory $dir",
  71. Zend_OpenId_Exception::ERROR_STORAGE );
  72. }
  73. }
  74. if (( $f = fopen($this->_dir . '/assoc.lock', 'w+') ) === null) {
  75. throw new Zend_OpenId_Exception(
  76. 'Cannot create a lock file in the directory ' . $dir,
  77. Zend_OpenId_Exception::ERROR_STORAGE );
  78. }
  79. fclose($f);
  80. if (( $f = fopen($this->_dir . '/user.lock', 'w+') ) === null) {
  81. throw new Zend_OpenId_Exception(
  82. 'Cannot create a lock file in the directory ' . $dir,
  83. Zend_OpenId_Exception::ERROR_STORAGE );
  84. }
  85. fclose($f);
  86. }
  87. /**
  88. * Stores information about session identified by $handle
  89. *
  90. * @param string $handle assiciation handle
  91. * @param string $macFunc HMAC function (sha1 or sha256)
  92. * @param string $secret shared secret
  93. * @param string $expires expiration UNIX time
  94. *
  95. * @return bool
  96. */
  97. public function addAssociation ($handle, $macFunc, $secret, $expires)
  98. {
  99. $name = $this->_dir . '/assoc_' . md5($handle);
  100. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  101. if ($lock === false) {
  102. return false;
  103. }
  104. if (!flock($lock, LOCK_EX)) {
  105. fclose($lock);
  106. return false;
  107. }
  108. try {
  109. $f = @fopen($name, 'w+');
  110. if ($f === false) {
  111. fclose($lock);
  112. return false;
  113. }
  114. $data = serialize(array( $handle, $macFunc, $secret, $expires ));
  115. fwrite($f, $data);
  116. fclose($f);
  117. fclose($lock);
  118. return true;
  119. } catch (Exception $e) {
  120. fclose($lock);
  121. throw $e;
  122. }
  123. }
  124. /**
  125. * Gets information about association identified by $handle
  126. * Returns true if given association found and not expired and false
  127. * otherwise
  128. *
  129. * @param string $handle assiciation handle
  130. * @param string &$macFunc HMAC function (sha1 or sha256)
  131. * @param string &$secret shared secret
  132. * @param string &$expires expiration UNIX time
  133. *
  134. * @return bool
  135. */
  136. public function getAssociation ($handle, &$macFunc, &$secret, &$expires)
  137. {
  138. $name = $this->_dir . '/assoc_' . md5($handle);
  139. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  140. if ($lock === false) {
  141. return false;
  142. }
  143. if (!flock($lock, LOCK_EX)) {
  144. fclose($lock);
  145. return false;
  146. }
  147. try {
  148. $f = @fopen($name, 'r');
  149. if ($f === false) {
  150. fclose($lock);
  151. return false;
  152. }
  153. $ret = false;
  154. $data = stream_get_contents($f);
  155. if (!empty( $data )) {
  156. list( $storedHandle, $macFunc, $secret, $expires ) = unserialize($data);
  157. if ($handle === $storedHandle && $expires > time()) {
  158. $ret = true;
  159. } else {
  160. fclose($f);
  161. @unlink($name);
  162. fclose($lock);
  163. return false;
  164. }
  165. }
  166. fclose($f);
  167. fclose($lock);
  168. return $ret;
  169. } catch (Exception $e) {
  170. fclose($lock);
  171. throw $e;
  172. }
  173. }
  174. /**
  175. * Removes information about association identified by $handle
  176. *
  177. * @param string $handle assiciation handle
  178. *
  179. * @return bool
  180. */
  181. public function delAssociation ($handle)
  182. {
  183. $name = $this->_dir . '/assoc_' . md5($handle);
  184. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  185. if ($lock === false) {
  186. return false;
  187. }
  188. if (!flock($lock, LOCK_EX)) {
  189. fclose($lock);
  190. return false;
  191. }
  192. try {
  193. @unlink($name);
  194. fclose($lock);
  195. return true;
  196. } catch (Exception $e) {
  197. fclose($lock);
  198. throw $e;
  199. }
  200. }
  201. /**
  202. * Register new user with given $id and $password
  203. * Returns true in case of success and false if user with given $id already
  204. * exists
  205. *
  206. * @param string $id user identity URL
  207. * @param string $password encoded user password
  208. *
  209. * @return bool
  210. */
  211. public function addUser ($id, $password)
  212. {
  213. $name = $this->_dir . '/user_' . md5($id);
  214. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  215. if ($lock === false) {
  216. return false;
  217. }
  218. if (!flock($lock, LOCK_EX)) {
  219. fclose($lock);
  220. return false;
  221. }
  222. try {
  223. $f = @fopen($name, 'x');
  224. if ($f === false) {
  225. fclose($lock);
  226. return false;
  227. }
  228. $data = serialize(array( $id, $password, array() ));
  229. fwrite($f, $data);
  230. fclose($f);
  231. fclose($lock);
  232. return true;
  233. } catch (Exception $e) {
  234. fclose($lock);
  235. throw $e;
  236. }
  237. }
  238. /**
  239. * Returns true if user with given $id exists and false otherwise
  240. *
  241. * @param string $id user identity URL
  242. *
  243. * @return bool
  244. */
  245. public function hasUser ($id)
  246. {
  247. $name = $this->_dir . '/user_' . md5($id);
  248. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  249. if ($lock === false) {
  250. return false;
  251. }
  252. if (!flock($lock, LOCK_SH)) {
  253. fclose($lock);
  254. return false;
  255. }
  256. try {
  257. $f = @fopen($name, 'r');
  258. if ($f === false) {
  259. fclose($lock);
  260. return false;
  261. }
  262. $ret = false;
  263. $data = stream_get_contents($f);
  264. if (!empty( $data )) {
  265. list( $storedId, $storedPassword, $trusted ) = unserialize($data);
  266. if ($id === $storedId) {
  267. $ret = true;
  268. }
  269. }
  270. fclose($f);
  271. fclose($lock);
  272. return $ret;
  273. } catch (Exception $e) {
  274. fclose($lock);
  275. throw $e;
  276. }
  277. }
  278. /**
  279. * Verify if user with given $id exists and has specified $password
  280. *
  281. * @param string $id user identity URL
  282. * @param string $password user password
  283. *
  284. * @return bool
  285. */
  286. public function checkUser ($id, $password)
  287. {
  288. $name = $this->_dir . '/user_' . md5($id);
  289. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  290. if ($lock === false) {
  291. return false;
  292. }
  293. if (!flock($lock, LOCK_SH)) {
  294. fclose($lock);
  295. return false;
  296. }
  297. try {
  298. $f = @fopen($name, 'r');
  299. if ($f === false) {
  300. fclose($lock);
  301. return false;
  302. }
  303. $ret = false;
  304. $data = stream_get_contents($f);
  305. if (!empty( $data )) {
  306. list( $storedId, $storedPassword, $trusted ) = unserialize($data);
  307. if ($id === $storedId && $password === $storedPassword) {
  308. $ret = true;
  309. }
  310. }
  311. fclose($f);
  312. fclose($lock);
  313. return $ret;
  314. } catch (Exception $e) {
  315. fclose($lock);
  316. throw $e;
  317. }
  318. }
  319. /**
  320. * Removes information abou specified user
  321. *
  322. * @param string $id user identity URL
  323. *
  324. * @return bool
  325. */
  326. public function delUser ($id)
  327. {
  328. $name = $this->_dir . '/user_' . md5($id);
  329. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  330. if ($lock === false) {
  331. return false;
  332. }
  333. if (!flock($lock, LOCK_EX)) {
  334. fclose($lock);
  335. return false;
  336. }
  337. try {
  338. @unlink($name);
  339. fclose($lock);
  340. return true;
  341. } catch (Exception $e) {
  342. fclose($lock);
  343. throw $e;
  344. }
  345. }
  346. /**
  347. * Returns array of all trusted/untrusted sites for given user identified
  348. * by $id
  349. *
  350. * @param string $id user identity URL
  351. *
  352. * @return array
  353. */
  354. public function getTrustedSites ($id)
  355. {
  356. $name = $this->_dir . '/user_' . md5($id);
  357. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  358. if ($lock === false) {
  359. return false;
  360. }
  361. if (!flock($lock, LOCK_SH)) {
  362. fclose($lock);
  363. return false;
  364. }
  365. try {
  366. $f = @fopen($name, 'r');
  367. if ($f === false) {
  368. fclose($lock);
  369. return false;
  370. }
  371. $ret = false;
  372. $data = stream_get_contents($f);
  373. if (!empty( $data )) {
  374. list( $storedId, $storedPassword, $trusted ) = unserialize($data);
  375. if ($id === $storedId) {
  376. $ret = $trusted;
  377. }
  378. }
  379. fclose($f);
  380. fclose($lock);
  381. return $ret;
  382. } catch (Exception $e) {
  383. fclose($lock);
  384. throw $e;
  385. }
  386. }
  387. /**
  388. * Stores information about trusted/untrusted site for given user
  389. *
  390. * @param string $id user identity URL
  391. * @param string $site site URL
  392. * @param mixed $trusted trust data from extension or just a boolean value
  393. *
  394. * @return bool
  395. */
  396. public function addSite ($id, $site, $trusted)
  397. {
  398. $name = $this->_dir . '/user_' . md5($id);
  399. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  400. if ($lock === false) {
  401. return false;
  402. }
  403. if (!flock($lock, LOCK_EX)) {
  404. fclose($lock);
  405. return false;
  406. }
  407. try {
  408. $f = @fopen($name, 'r+');
  409. if ($f === false) {
  410. fclose($lock);
  411. return false;
  412. }
  413. $ret = false;
  414. $data = stream_get_contents($f);
  415. if (!empty( $data )) {
  416. list( $storedId, $storedPassword, $sites ) = unserialize($data);
  417. if ($id === $storedId) {
  418. if ($trusted === null) {
  419. unset( $sites[$site] );
  420. } else {
  421. $sites[$site] = $trusted;
  422. }
  423. rewind($f);
  424. ftruncate($f, 0);
  425. $data = serialize(array( $id, $storedPassword, $sites ));
  426. fwrite($f, $data);
  427. $ret = true;
  428. }
  429. }
  430. fclose($f);
  431. fclose($lock);
  432. return $ret;
  433. } catch (Exception $e) {
  434. fclose($lock);
  435. throw $e;
  436. }
  437. }
  438. }