PageRenderTime 124ms CodeModel.GetById 90ms app.highlight 18ms RepoModel.GetById 12ms app.codeStats 0ms

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

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