PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/michalmatoga/ebpl
PHP | 442 lines | 316 code | 14 blank | 112 comment | 49 complexity | a8d7a11c82135c7da323823f241b6044 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. * @throws Zend_OpenId_Exception
  48. */
  49. public function __construct($dir = null)
  50. {
  51. if ($dir === null) {
  52. $tmp = getenv('TMP');
  53. if (empty($tmp)) {
  54. $tmp = getenv('TEMP');
  55. if (empty($tmp)) {
  56. $tmp = "/tmp";
  57. }
  58. }
  59. $user = get_current_user();
  60. if (is_string($user) && !empty($user)) {
  61. $tmp .= '/' . $user;
  62. }
  63. $dir = $tmp . '/openid/provider';
  64. }
  65. $this->_dir = $dir;
  66. if (!is_dir($this->_dir)) {
  67. if (!@mkdir($this->_dir, 0700, 1)) {
  68. throw new Zend_OpenId_Exception(
  69. "Cannot access storage directory $dir",
  70. Zend_OpenId_Exception::ERROR_STORAGE);
  71. }
  72. }
  73. if (($f = fopen($this->_dir.'/assoc.lock', 'w+')) === null) {
  74. throw new Zend_OpenId_Exception(
  75. 'Cannot create a lock file in the directory ' . $dir,
  76. Zend_OpenId_Exception::ERROR_STORAGE);
  77. }
  78. fclose($f);
  79. if (($f = fopen($this->_dir.'/user.lock', 'w+')) === null) {
  80. throw new Zend_OpenId_Exception(
  81. 'Cannot create a lock file in the directory ' . $dir,
  82. Zend_OpenId_Exception::ERROR_STORAGE);
  83. }
  84. fclose($f);
  85. }
  86. /**
  87. * Stores information about session identified by $handle
  88. *
  89. * @param string $handle assiciation handle
  90. * @param string $macFunc HMAC function (sha1 or sha256)
  91. * @param string $secret shared secret
  92. * @param string $expires expiration UNIX time
  93. * @return bool
  94. */
  95. public function addAssociation($handle, $macFunc, $secret, $expires)
  96. {
  97. $name = $this->_dir . '/assoc_' . md5($handle);
  98. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  99. if ($lock === false) {
  100. return false;
  101. }
  102. if (!flock($lock, LOCK_EX)) {
  103. fclose($lock);
  104. return false;
  105. }
  106. try {
  107. $f = @fopen($name, 'w+');
  108. if ($f === false) {
  109. fclose($lock);
  110. return false;
  111. }
  112. $data = serialize(array($handle, $macFunc, $secret, $expires));
  113. fwrite($f, $data);
  114. fclose($f);
  115. fclose($lock);
  116. return true;
  117. } catch (Exception $e) {
  118. fclose($lock);
  119. throw $e;
  120. }
  121. }
  122. /**
  123. * Gets information about association identified by $handle
  124. * Returns true if given association found and not expired and false
  125. * otherwise
  126. *
  127. * @param string $handle assiciation handle
  128. * @param string &$macFunc HMAC function (sha1 or sha256)
  129. * @param string &$secret shared secret
  130. * @param string &$expires expiration UNIX time
  131. * @return bool
  132. */
  133. public function getAssociation($handle, &$macFunc, &$secret, &$expires)
  134. {
  135. $name = $this->_dir . '/assoc_' . md5($handle);
  136. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  137. if ($lock === false) {
  138. return false;
  139. }
  140. if (!flock($lock, LOCK_EX)) {
  141. fclose($lock);
  142. return false;
  143. }
  144. try {
  145. $f = @fopen($name, 'r');
  146. if ($f === false) {
  147. fclose($lock);
  148. return false;
  149. }
  150. $ret = false;
  151. $data = stream_get_contents($f);
  152. if (!empty($data)) {
  153. list($storedHandle, $macFunc, $secret, $expires) = unserialize($data);
  154. if ($handle === $storedHandle && $expires > time()) {
  155. $ret = true;
  156. } else {
  157. fclose($f);
  158. @unlink($name);
  159. fclose($lock);
  160. return false;
  161. }
  162. }
  163. fclose($f);
  164. fclose($lock);
  165. return $ret;
  166. } catch (Exception $e) {
  167. fclose($lock);
  168. throw $e;
  169. }
  170. }
  171. /**
  172. * Removes information about association identified by $handle
  173. *
  174. * @param string $handle assiciation handle
  175. * @return bool
  176. */
  177. public function delAssociation($handle)
  178. {
  179. $name = $this->_dir . '/assoc_' . md5($handle);
  180. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  181. if ($lock === false) {
  182. return false;
  183. }
  184. if (!flock($lock, LOCK_EX)) {
  185. fclose($lock);
  186. return false;
  187. }
  188. try {
  189. @unlink($name);
  190. fclose($lock);
  191. return true;
  192. } catch (Exception $e) {
  193. fclose($lock);
  194. throw $e;
  195. }
  196. }
  197. /**
  198. * Register new user with given $id and $password
  199. * Returns true in case of success and false if user with given $id already
  200. * exists
  201. *
  202. * @param string $id user identity URL
  203. * @param string $password encoded user password
  204. * @return bool
  205. */
  206. public function addUser($id, $password)
  207. {
  208. $name = $this->_dir . '/user_' . md5($id);
  209. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  210. if ($lock === false) {
  211. return false;
  212. }
  213. if (!flock($lock, LOCK_EX)) {
  214. fclose($lock);
  215. return false;
  216. }
  217. try {
  218. $f = @fopen($name, 'x');
  219. if ($f === false) {
  220. fclose($lock);
  221. return false;
  222. }
  223. $data = serialize(array($id, $password, array()));
  224. fwrite($f, $data);
  225. fclose($f);
  226. fclose($lock);
  227. return true;
  228. } catch (Exception $e) {
  229. fclose($lock);
  230. throw $e;
  231. }
  232. }
  233. /**
  234. * Returns true if user with given $id exists and false otherwise
  235. *
  236. * @param string $id user identity URL
  237. * @return bool
  238. */
  239. public function hasUser($id)
  240. {
  241. $name = $this->_dir . '/user_' . md5($id);
  242. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  243. if ($lock === false) {
  244. return false;
  245. }
  246. if (!flock($lock, LOCK_SH)) {
  247. fclose($lock);
  248. return false;
  249. }
  250. try {
  251. $f = @fopen($name, 'r');
  252. if ($f === false) {
  253. fclose($lock);
  254. return false;
  255. }
  256. $ret = false;
  257. $data = stream_get_contents($f);
  258. if (!empty($data)) {
  259. list($storedId, $storedPassword, $trusted) = unserialize($data);
  260. if ($id === $storedId) {
  261. $ret = true;
  262. }
  263. }
  264. fclose($f);
  265. fclose($lock);
  266. return $ret;
  267. } catch (Exception $e) {
  268. fclose($lock);
  269. throw $e;
  270. }
  271. }
  272. /**
  273. * Verify if user with given $id exists and has specified $password
  274. *
  275. * @param string $id user identity URL
  276. * @param string $password user password
  277. * @return bool
  278. */
  279. public function checkUser($id, $password)
  280. {
  281. $name = $this->_dir . '/user_' . md5($id);
  282. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  283. if ($lock === false) {
  284. return false;
  285. }
  286. if (!flock($lock, LOCK_SH)) {
  287. fclose($lock);
  288. return false;
  289. }
  290. try {
  291. $f = @fopen($name, 'r');
  292. if ($f === false) {
  293. fclose($lock);
  294. return false;
  295. }
  296. $ret = false;
  297. $data = stream_get_contents($f);
  298. if (!empty($data)) {
  299. list($storedId, $storedPassword, $trusted) = unserialize($data);
  300. if ($id === $storedId && $password === $storedPassword) {
  301. $ret = true;
  302. }
  303. }
  304. fclose($f);
  305. fclose($lock);
  306. return $ret;
  307. } catch (Exception $e) {
  308. fclose($lock);
  309. throw $e;
  310. }
  311. }
  312. /**
  313. * Removes information abou specified user
  314. *
  315. * @param string $id user identity URL
  316. * @return bool
  317. */
  318. public function delUser($id)
  319. {
  320. $name = $this->_dir . '/user_' . md5($id);
  321. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  322. if ($lock === false) {
  323. return false;
  324. }
  325. if (!flock($lock, LOCK_EX)) {
  326. fclose($lock);
  327. return false;
  328. }
  329. try {
  330. @unlink($name);
  331. fclose($lock);
  332. return true;
  333. } catch (Exception $e) {
  334. fclose($lock);
  335. throw $e;
  336. }
  337. }
  338. /**
  339. * Returns array of all trusted/untrusted sites for given user identified
  340. * by $id
  341. *
  342. * @param string $id user identity URL
  343. * @return array
  344. */
  345. public function getTrustedSites($id)
  346. {
  347. $name = $this->_dir . '/user_' . md5($id);
  348. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  349. if ($lock === false) {
  350. return false;
  351. }
  352. if (!flock($lock, LOCK_SH)) {
  353. fclose($lock);
  354. return false;
  355. }
  356. try {
  357. $f = @fopen($name, 'r');
  358. if ($f === false) {
  359. fclose($lock);
  360. return false;
  361. }
  362. $ret = false;
  363. $data = stream_get_contents($f);
  364. if (!empty($data)) {
  365. list($storedId, $storedPassword, $trusted) = unserialize($data);
  366. if ($id === $storedId) {
  367. $ret = $trusted;
  368. }
  369. }
  370. fclose($f);
  371. fclose($lock);
  372. return $ret;
  373. } catch (Exception $e) {
  374. fclose($lock);
  375. throw $e;
  376. }
  377. }
  378. /**
  379. * Stores information about trusted/untrusted site for given user
  380. *
  381. * @param string $id user identity URL
  382. * @param string $site site URL
  383. * @param mixed $trusted trust data from extension or just a boolean value
  384. * @return bool
  385. */
  386. public function addSite($id, $site, $trusted)
  387. {
  388. $name = $this->_dir . '/user_' . md5($id);
  389. $lock = @fopen($this->_dir . '/user.lock', 'w+');
  390. if ($lock === false) {
  391. return false;
  392. }
  393. if (!flock($lock, LOCK_EX)) {
  394. fclose($lock);
  395. return false;
  396. }
  397. try {
  398. $f = @fopen($name, 'r+');
  399. if ($f === false) {
  400. fclose($lock);
  401. return false;
  402. }
  403. $ret = false;
  404. $data = stream_get_contents($f);
  405. if (!empty($data)) {
  406. list($storedId, $storedPassword, $sites) = unserialize($data);
  407. if ($id === $storedId) {
  408. if ($trusted === null) {
  409. unset($sites[$site]);
  410. } else {
  411. $sites[$site] = $trusted;
  412. }
  413. rewind($f);
  414. ftruncate($f, 0);
  415. $data = serialize(array($id, $storedPassword, $sites));
  416. fwrite($f, $data);
  417. $ret = true;
  418. }
  419. }
  420. fclose($f);
  421. fclose($lock);
  422. return $ret;
  423. } catch (Exception $e) {
  424. fclose($lock);
  425. throw $e;
  426. }
  427. }
  428. }