web/lib/Zend/OpenId/Provider/Storage/File.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     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-2010 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 20096 2010-01-06 02:05:09Z bkarwin $
       
    22  */
       
    23 
       
    24 /**
       
    25  * @see Zend_OpenId_Provider_Storage
       
    26  */
       
    27 require_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-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    36  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    37  */
       
    38 class 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 }