Microsoft_WindowsAzure
[ class tree: Microsoft_WindowsAzure ] [ index: Microsoft_WindowsAzure ] [ all elements ]

Source for file SharedAccessSignature.php

Documentation is available at SharedAccessSignature.php

  1. <?php
  2. /**
  3.  * Copyright (c) 2009 - 2011, RealDolmen
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions are met:
  8.  *     * Redistributions of source code must retain the above copyright
  9.  *       notice, this list of conditions and the following disclaimer.
  10.  *     * Redistributions in binary form must reproduce the above copyright
  11.  *       notice, this list of conditions and the following disclaimer in the
  12.  *       documentation and/or other materials provided with the distribution.
  13.  *     * Neither the name of RealDolmen nor the
  14.  *       names of its contributors may be used to endorse or promote products
  15.  *       derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
  18.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20.  * DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
  21.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  *
  28.  * @category   Microsoft
  29.  * @package    Microsoft_WindowsAzure
  30.  * @copyright  Copyright (c) 2009 - 2011, RealDolmen (http://www.realdolmen.com)
  31.  * @license    http://phpazure.codeplex.com/license
  32.  * @version    $Id: SharedKeyCredentials.php 24305 2009-07-23 06:30:04Z unknown $
  33.  */
  34.  
  35. /**
  36.  * @see Microsoft_AutoLoader
  37.  */
  38. require_once dirname(__FILE__'/../../AutoLoader.php';
  39.  
  40. /**
  41.  * @category   Microsoft
  42.  * @package    Microsoft_WindowsAzure
  43.  * @copyright  Copyright (c) 2009 - 2011, RealDolmen (http://www.realdolmen.com)
  44.  * @license    http://phpazure.codeplex.com/license
  45.  */ 
  46. {
  47.     /**
  48.      * Permission set
  49.      * 
  50.      * @var array 
  51.      */
  52.     protected $_permissionSet = array();
  53.     
  54.     /**
  55.      * Creates a new Microsoft_WindowsAzure_Credentials_SharedAccessSignature instance
  56.      *
  57.      * @param string $accountName Account name for Windows Azure
  58.      * @param string $accountKey Account key for Windows Azure
  59.      * @param boolean $usePathStyleUri Use path-style URI's
  60.      * @param array $permissionSet Permission set
  61.      */
  62.     public function __construct(
  63.         $accountName Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT,
  64.         $accountKey  Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY,
  65.         $usePathStyleUri false$permissionSet array()
  66.     {
  67.         parent::__construct($accountName$accountKey$usePathStyleUri);
  68.         $this->_permissionSet = $permissionSet;
  69.     }
  70.     
  71.     /**
  72.      * Get permission set
  73.      * 
  74.      * @return array 
  75.      */
  76.     public function getPermissionSet()
  77.     {
  78.         return $this->_permissionSet;   
  79.     }
  80.     
  81.     /**
  82.      * Set permisison set
  83.      * 
  84.      * Warning: fine-grained permissions should be added prior to coarse-grained permissions.
  85.      * For example: first add blob permissions, end with container-wide permissions.
  86.      * 
  87.      * Warning: the signed access signature URL must match the account name of the
  88.      * Microsoft_WindowsAzure_Credentials_Microsoft_WindowsAzure_Credentials_SharedAccessSignature instance
  89.      * 
  90.      * @param  array $value Permission set
  91.      * @return void 
  92.      */
  93.     public function setPermissionSet($value array())
  94.     {
  95.         foreach ($value as $url{
  96.             if (strpos($url$this->_accountName=== false{
  97.                 throw new Microsoft_WindowsAzure_Exception('The permission set can only contain URLs for the account name specified in the Microsoft_WindowsAzure_Credentials_SharedAccessSignature instance.');
  98.             }
  99.         }
  100.         $this->_permissionSet = $value;
  101.     }
  102.     
  103.     /**
  104.      * Create signature
  105.      * 
  106.      * @param string $path            Path for the request
  107.      * @param string $resource     Signed resource - container (c) - blob (b)
  108.      * @param string $permissions  Signed permissions - read (r), write (w), delete (d) and list (l)
  109.      * @param string $start        The time at which the Shared Access Signature becomes valid.
  110.      * @param string $expiry       The time at which the Shared Access Signature becomes invalid.
  111.      * @param string $identifier   Signed identifier
  112.      * @return string 
  113.      */
  114.     public function createSignature(
  115.         $path '/',
  116.         $resource 'b',
  117.         $permissions 'r',
  118.         $start '',
  119.         $expiry '',
  120.         $identifier ''
  121.     {
  122.         // Determine path
  123.         if ($this->_usePathStyleUri{
  124.             $path substr($pathstrpos($path'/'));
  125.         }
  126.             
  127.         // Add trailing slash to $path
  128.         if (substr($path01!== '/'{
  129.             $path '/' $path;
  130.         }
  131.  
  132.         // Build canonicalized resource string
  133.         $canonicalizedResource  '/' $this->_accountName;
  134.         /*if ($this->_usePathStyleUri) {
  135.             $canonicalizedResource .= '/' . $this->_accountName;
  136.         }*/
  137.         $canonicalizedResource .= $path;
  138.             
  139.         // Create string to sign   
  140.         $stringToSign   array();
  141.         $stringToSign[$permissions;
  142.         $stringToSign[$start;
  143.         $stringToSign[$expiry;
  144.         $stringToSign[$canonicalizedResource;
  145.         $stringToSign[$identifier;
  146.  
  147.         $stringToSign implode("\n"$stringToSign);
  148.         $signature    base64_encode(hash_hmac('sha256'$stringToSign$this->_accountKeytrue));
  149.     
  150.         return $signature;
  151.     }
  152.  
  153.     /**
  154.      * Create signed query string
  155.      * 
  156.      * @param string $path            Path for the request
  157.      * @param string $queryString  Query string for the request
  158.      * @param string $resource     Signed resource - container (c) - blob (b)
  159.      * @param string $permissions  Signed permissions - read (r), write (w), delete (d) and list (l)
  160.      * @param string $start        The time at which the Shared Access Signature becomes valid.
  161.      * @param string $expiry       The time at which the Shared Access Signature becomes invalid.
  162.      * @param string $identifier   Signed identifier
  163.      * @return string 
  164.      */
  165.     public function createSignedQueryString(
  166.         $path '/',
  167.         $queryString '',
  168.         $resource 'b',
  169.         $permissions 'r',
  170.         $start '',
  171.         $expiry '',
  172.         $identifier ''
  173.     {
  174.         // Parts
  175.         $parts array();
  176.         if ($start !== ''{
  177.             $parts['st=' urlencode($start);
  178.         }
  179.         $parts['se=' urlencode($expiry);
  180.         $parts['sr=' $resource;
  181.         $parts['sp=' $permissions;
  182.         if ($identifier !== ''{
  183.             $parts['si=' urlencode($identifier);
  184.         }
  185.         $parts['sig=' urlencode($this->createSignature($path$resource$permissions$start$expiry$identifier));
  186.  
  187.         // Assemble parts and query string
  188.         if ($queryString != ''{
  189.             $queryString .= '&';
  190.         }
  191.         $queryString .= implode('&'$parts);
  192.  
  193.         return $queryString;
  194.     }
  195.     
  196.     /**
  197.      * Permission matches request?
  198.      *
  199.      * @param string $permissionUrl Permission URL
  200.      * @param string $requestUrl Request URL
  201.      * @param string $resourceType Resource type
  202.      * @param string $requiredPermission Required permission
  203.      * @return string Signed request URL
  204.      */
  205.     public function permissionMatchesRequest(
  206.         $permissionUrl '',
  207.         $requestUrl '',
  208.         $resourceType Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
  209.         $requiredPermission Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
  210.     {
  211.         // Build requirements
  212.         $requiredResourceType $resourceType;
  213.         if ($requiredResourceType == Microsoft_WindowsAzure_Storage::RESOURCE_BLOB{
  214.             $requiredResourceType .= Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER;
  215.         }
  216.  
  217.         // Parse permission url
  218.         $parsedPermissionUrl parse_url($permissionUrl);
  219.         
  220.         // Parse permission properties
  221.         $permissionParts explode('&'$parsedPermissionUrl['query']);
  222.         
  223.         // Parse request url
  224.         $parsedRequestUrl parse_url($requestUrl);
  225.         
  226.         // Check if permission matches request
  227.         $matches true;
  228.         foreach ($permissionParts as $part{
  229.             list($property$valueexplode('='$part2);
  230.             
  231.             if ($property == 'sr'{
  232.                 $matches $matches && (strpbrk($value$requiredResourceType!== false);
  233.             }
  234.             
  235.             if ($property == 'sp'{
  236.                 $matches $matches && (strpbrk($value$requiredPermission!== false);
  237.             }
  238.         }
  239.         
  240.         // Ok, but... does the resource match?
  241.         $matches $matches && (strpos($parsedRequestUrl['path']$parsedPermissionUrl['path']!== false);
  242.         
  243.         // Return
  244.         return $matches;
  245.     }    
  246.     
  247.     /**
  248.      * Sign request URL with credentials
  249.      *
  250.      * @param string $requestUrl Request URL
  251.      * @param string $resourceType Resource type
  252.      * @param string $requiredPermission Required permission
  253.      * @return string Signed request URL
  254.      */
  255.     public function signRequestUrl(
  256.         $requestUrl '',
  257.         $resourceType Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
  258.         $requiredPermission Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
  259.     {
  260.         // Look for a matching permission
  261.         foreach ($this->getPermissionSet(as $permittedUrl{
  262.             if ($this->permissionMatchesRequest($permittedUrl$requestUrl$resourceType$requiredPermission)) {
  263.                 // This matches, append signature data
  264.                 $parsedPermittedUrl parse_url($permittedUrl);
  265.  
  266.                 if (strpos($requestUrl'?'=== false{
  267.                     $requestUrl .= '?';
  268.                 else {
  269.                     $requestUrl .= '&';
  270.                 }
  271.                 
  272.                 $requestUrl .= $parsedPermittedUrl['query'];
  273.  
  274.                 // Return url
  275.                 return $requestUrl;
  276.             }
  277.         }
  278.         
  279.         // Return url, will be unsigned...
  280.         return $requestUrl;
  281.     }
  282.     
  283.     /**
  284.      * Sign request with credentials
  285.      *
  286.      * @param string $httpVerb HTTP verb the request will use
  287.      * @param string $path Path for the request
  288.      * @param string $queryString Query string for the request
  289.      * @param array $headers x-ms headers to add
  290.      * @param boolean $forTableStorage Is the request for table storage?
  291.      * @param string $resourceType Resource type
  292.      * @param string $requiredPermission Required permission
  293.      * @param mixed  $rawData Raw post data
  294.      * @return array Array of headers
  295.      */
  296.     public function signRequestHeaders(
  297.         $httpVerb Microsoft_Http_Client::GET,
  298.         $path '/',
  299.         $queryString '',
  300.         $headers null,
  301.         $forTableStorage false,
  302.         $resourceType Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
  303.         $requiredPermission Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ,
  304.         $rawData null
  305.     {
  306.         return $headers;
  307.     }
  308. }

Documentation generated on Wed, 18 May 2011 12:06:49 +0200 by phpDocumentor 1.4.3