Fixing merge
This commit is contained in:
commit
83604c466b
@ -3,7 +3,7 @@
|
||||
"description": "Access HPCloud and OpenStack services in PHP.",
|
||||
"type": "library",
|
||||
"keywords": ["openstack","hpcloud","cloud","swift","nova"],
|
||||
"license": "MIT-like",
|
||||
"license": "MIT",
|
||||
"homepage": "http://hpcloud.com",
|
||||
"authors": [
|
||||
{
|
||||
|
@ -171,12 +171,16 @@
|
||||
*
|
||||
* @code
|
||||
* <?php
|
||||
* // The explicit way:
|
||||
* // Find out where our ObjectStorage instance lives:
|
||||
* $storageList = $identity->serviceCatalog('object-storage');
|
||||
* $objectStorageUrl = storageList[0]['endpoints'][0]['publicURL'];
|
||||
* // $storageList = $identity->serviceCatalog('object-storage');
|
||||
* // $objectStorageUrl = storageList[0]['endpoints'][0]['publicURL'];
|
||||
*
|
||||
* // Create a new ObjectStorage instance:
|
||||
* $objectStore = new \HPCloud\Storage\ObjectStorage($token, $objectStorageUrl);
|
||||
* // $objectStore = new \HPCloud\Storage\ObjectStorage($token, $objectStorageUrl);
|
||||
*
|
||||
* // Or let ObjectStorage figure out which instance to use:
|
||||
* $objectStore = \HPCloud\Storage\ObjectStorage::newFromIdentity($identity);
|
||||
*
|
||||
* // List containers:
|
||||
* print_r($objectStore->containers());
|
||||
|
@ -269,6 +269,9 @@ Now we can get a new HPCloud::Storage::ObjectStorage instance:
|
||||
$catalog = $idService->serviceCatalog();
|
||||
|
||||
$store = ObjectStorage::newFromServiceCatalog($catalog, $token);
|
||||
|
||||
// UPDATE: As of Beta 6, you can use newFromIdentity():
|
||||
// $store = ObjectStorage::newFromIdentity($idService);
|
||||
?>
|
||||
~~~
|
||||
|
||||
|
@ -29,6 +29,9 @@ SOFTWARE.
|
||||
|
||||
namespace HPCloud;
|
||||
|
||||
use HPCloud\Services\IdentityServices;
|
||||
use HPCloud\Exception;
|
||||
|
||||
/**
|
||||
* Bootstrapping services.
|
||||
*
|
||||
@ -128,6 +131,12 @@ class Bootstrap {
|
||||
'transport' => '\HPCloud\Transport\CURLTransport',
|
||||
);
|
||||
|
||||
/**
|
||||
* An identity services object created from the global settings.
|
||||
* @var object HPCloud::Services::IdentityServices
|
||||
*/
|
||||
public static $identity = NULL;
|
||||
|
||||
/**
|
||||
* Add the autoloader to PHP's autoloader list.
|
||||
*
|
||||
@ -313,4 +322,56 @@ class Bootstrap {
|
||||
public static function hasConfig($name) {
|
||||
return isset(self::$config[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a HPCloud::Services::IdentityService object from the bootstrap config.
|
||||
*
|
||||
* A factory helper function that uses the bootstrap configuration to create
|
||||
* a ready to use HPCloud::Services::IdentityService object.
|
||||
*
|
||||
* @param bool $force
|
||||
* Whether to force the generation of a new object even if one is already
|
||||
* cached.
|
||||
* @retval HPCloud::Services::IdentityService
|
||||
* An authenticated ready to use HPCloud::Services::IdentityService object.
|
||||
* @throws HPCloud::Exception
|
||||
* When the needed configuration to authenticate is not available.
|
||||
*/
|
||||
public static function identity($force = FALSE) {
|
||||
|
||||
// If we already have an identity make sure the token is not expired.
|
||||
if ($force || is_null(self::$identity) || self::$identity->isExpired()) {
|
||||
|
||||
// Make sure we have an endpoint to use
|
||||
if (!self::hasConfig('endpoint')) {
|
||||
throw new Exception('Unable to authenticate. No endpoint supplied.');
|
||||
}
|
||||
|
||||
// Neither user nor account can be an empty string, so we need
|
||||
// to do more checking than self::hasConfig(), which returns TRUE
|
||||
// if an item exists and is an empty string.
|
||||
$user = self::config('username', NULL);
|
||||
$account = self::config('account', NULL);
|
||||
|
||||
// Check if we have a username/password
|
||||
if (!empty($user) && self::hasConfig('password')) {
|
||||
$is = new IdentityServices(self::config('endpoint'));
|
||||
$is->authenticateAsUser($user, self::config('password'), self::config('tenantid', NULL), self::config('tenantname', NULL));
|
||||
self::$identity = $is;
|
||||
}
|
||||
|
||||
// Otherwise we go with access/secret keys
|
||||
elseif (!empty($account) && self::hasConfig('secret')) {
|
||||
$is = new IdentityServices(self::config('endpoint'));
|
||||
$is->authenticateAsAccount($account, self::config('secret'), self::config('tenantid', NULL), self::config('tenantname', NULL));
|
||||
self::$identity = $is;
|
||||
}
|
||||
|
||||
else {
|
||||
throw new Exception('Unable to authenticate. No account credentials supplied.');
|
||||
}
|
||||
}
|
||||
|
||||
return self::$identity;
|
||||
}
|
||||
}
|
||||
|
@ -122,9 +122,14 @@ namespace HPCloud\Services;
|
||||
* - tenants()
|
||||
* - rescope()
|
||||
*
|
||||
* <b>Serializing</b>
|
||||
*
|
||||
* IdentityServices has been intentionally built to serialize well.
|
||||
* This allows implementors to cache IdentityServices objects rather
|
||||
* than make repeated requests for identity information.
|
||||
*
|
||||
*/
|
||||
class IdentityServices {
|
||||
class IdentityServices /*implements Serializable*/ {
|
||||
/**
|
||||
* The version of the API currently supported.
|
||||
*/
|
||||
@ -171,6 +176,8 @@ class IdentityServices {
|
||||
*/
|
||||
protected $catalog = array();
|
||||
|
||||
protected $userDetails;
|
||||
|
||||
/**
|
||||
* Build a new IdentityServices object.
|
||||
*
|
||||
@ -266,7 +273,6 @@ class IdentityServices {
|
||||
'auth' => $ops,
|
||||
);
|
||||
|
||||
|
||||
$body = json_encode($envelope);
|
||||
|
||||
$headers = array(
|
||||
@ -288,17 +294,20 @@ class IdentityServices {
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate to Identity Services with username, password, and tenant ID.
|
||||
* Authenticate to Identity Services with username, password, and either
|
||||
* tenant ID or tenant Name.
|
||||
*
|
||||
* Given an HPCloud username and password, authenticate to Identity Services.
|
||||
* Identity Services will then issue a token that can be used to access other
|
||||
* HPCloud services.
|
||||
*
|
||||
* If a tenant ID is provided, this will also associate the user with the
|
||||
* given tenant ID.
|
||||
* given tenant ID. If a tenant Name is provided, this will associate the user
|
||||
* with the given tenant Name. Only the tenant ID or tenant Name needs to be
|
||||
* given, not both.
|
||||
*
|
||||
* If no tenant ID is given, it will likely be necessary to rescope() the
|
||||
* request (See also tenants()).
|
||||
* If no tenant ID or tenant Name is given, it will likely be necessary to
|
||||
* rescope() the request (See also tenants()).
|
||||
*
|
||||
* Other authentication methods:
|
||||
*
|
||||
@ -312,13 +321,16 @@ class IdentityServices {
|
||||
* @param string $tenantId
|
||||
* The tenant ID for this account. This can be obtained through the
|
||||
* HPCloud console.
|
||||
* @param string $tenantName
|
||||
* The tenant Name for this account. This can be obtained through the
|
||||
* HPCloud console.
|
||||
* @throws HPCloud::Transport::AuthorizationException
|
||||
* If authentication failed.
|
||||
* @throws HPCloud::Exception
|
||||
* For abnormal network conditions. The message will give an indication as
|
||||
* to the underlying problem.
|
||||
*/
|
||||
public function authenticateAsUser($username, $password, $tenantId = NULL) {
|
||||
public function authenticateAsUser($username, $password, $tenantId = NULL, $tenantName = NULL) {
|
||||
$ops = array(
|
||||
'passwordCredentials' => array(
|
||||
'username' => $username,
|
||||
@ -330,6 +342,12 @@ class IdentityServices {
|
||||
if (!empty($tenantId)) {
|
||||
$ops['tenantId'] = $tenantId;
|
||||
}
|
||||
|
||||
// If a tenant name is provided, add it to the auth array.
|
||||
if (!empty($tenantName)) {
|
||||
$ops['tenantName'] = $tenantName;
|
||||
}
|
||||
|
||||
return $this->authenticate($ops);
|
||||
}
|
||||
/**
|
||||
@ -342,10 +360,11 @@ class IdentityServices {
|
||||
* The account ID and access key information can be found in the account
|
||||
* section of the console.
|
||||
*
|
||||
* The third paramater allows you to specify a tenant ID. In order to access
|
||||
* services, this object will need a tenant ID. If none is specified, it can
|
||||
* be set later using rescope(). The tenants() method can be used to get a
|
||||
* list of all available tenant IDs for this token.
|
||||
* The third and fourth paramaters allow you to specify a tenant ID or
|
||||
* tenantName. In order to access services, this object will need a tenant ID
|
||||
* or tenant name. If none is specified, it can be set later using rescope().
|
||||
* The tenants() method can be used to get a list of all available tenant IDs
|
||||
* for this token.
|
||||
*
|
||||
* Other authentication methods:
|
||||
*
|
||||
@ -361,6 +380,9 @@ class IdentityServices {
|
||||
* @param string $tenantId
|
||||
* A valid tenant ID. This will be used to associate a tenant's services
|
||||
* with this token.
|
||||
* @param string $tenantName
|
||||
* The tenant Name for this account. This can be obtained through the
|
||||
* HPCloud console.
|
||||
* @retval string
|
||||
* The auth token.
|
||||
* @throws HPCloud::Transport::AuthorizationException
|
||||
@ -369,7 +391,7 @@ class IdentityServices {
|
||||
* For abnormal network conditions. The message will give an indication as
|
||||
* to the underlying problem.
|
||||
*/
|
||||
public function authenticateAsAccount($account, $key, $tenantId = NULL) {
|
||||
public function authenticateAsAccount($account, $key, $tenantId = NULL, $tenantName = NULL) {
|
||||
$ops = array(
|
||||
'apiAccessKeyCredentials' => array(
|
||||
'accessKey' => $account,
|
||||
@ -380,6 +402,10 @@ class IdentityServices {
|
||||
if (!empty($tenantId)) {
|
||||
$ops['tenantId'] = $tenantId;
|
||||
}
|
||||
if (!empty($tenantName)) {
|
||||
$ops['tenantName'] = $tenantName;
|
||||
}
|
||||
|
||||
return $this->authenticate($ops);
|
||||
}
|
||||
|
||||
@ -416,11 +442,16 @@ class IdentityServices {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tenant name.
|
||||
* Get the tenant name associated with this token.
|
||||
*
|
||||
* If this token has a tenant name, the name will be returned. Otherwise, this
|
||||
* will return NULL.
|
||||
*
|
||||
* This will not be populated until after an authentication method has been
|
||||
* run.
|
||||
*
|
||||
* @retval string
|
||||
* The tenant name. Often this is an email
|
||||
* address or other alpha-numeric string.
|
||||
* The tenant name if available, or NULL.
|
||||
*/
|
||||
public function tenantName() {
|
||||
if (!empty($this->tokenDetails['tenant']['name'])) {
|
||||
@ -460,6 +491,31 @@ class IdentityServices {
|
||||
return $this->tokenDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the current identity has an expired token.
|
||||
*
|
||||
* This does not perform a round-trip to the server. Instead, it compares the
|
||||
* machine's local timestamp with the server's expiration time stamp. A
|
||||
* mis-configured machine timestamp could give spurious results.
|
||||
*
|
||||
* @retval boolean
|
||||
* This will return FALSE if there is a current token and it has
|
||||
* not yet expired (according to the date info). In all other cases
|
||||
* it returns TRUE.
|
||||
*/
|
||||
public function isExpired() {
|
||||
$details = $this->tokenDetails();
|
||||
|
||||
if (empty($details['expires'])) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
$currentDateTime = new \DateTime('now');
|
||||
$expireDateTime = new \DateTime($details['expires']);
|
||||
|
||||
return $currentDateTime > $expireDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the service catalog, optionaly filtering by type.
|
||||
*
|
||||
@ -638,6 +694,14 @@ class IdentityServices {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see HPCloud::Services::IdentityServices::rescopeUsingTenantId()
|
||||
* @deprecated
|
||||
*/
|
||||
public function rescope($tenantId) {
|
||||
return $this->rescopeUsingTenantId($tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rescope the authentication token to a different tenant.
|
||||
*
|
||||
* Note that this will rebuild the service catalog and user information for
|
||||
@ -667,7 +731,7 @@ class IdentityServices {
|
||||
* For abnormal network conditions. The message will give an indication as
|
||||
* to the underlying problem.
|
||||
*/
|
||||
public function rescope($tenantId) {
|
||||
public function rescopeUsingTenantId($tenantId) {
|
||||
$url = $this->url() . '/tokens';
|
||||
$token = $this->token();
|
||||
$data = array(
|
||||
@ -694,6 +758,63 @@ class IdentityServices {
|
||||
return $this->token();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rescope the authentication token to a different tenant.
|
||||
*
|
||||
* Note that this will rebuild the service catalog and user information for
|
||||
* the current object, since this information is sensitive to tenant info.
|
||||
*
|
||||
* An authentication token can be in one of two states:
|
||||
*
|
||||
* - unscoped: It has no associated tenant ID.
|
||||
* - scoped: It has a tenant ID, and can thus access that tenant's services.
|
||||
*
|
||||
* This method allows you to do any of the following:
|
||||
*
|
||||
* - Begin with an unscoped token, and assign it a tenant ID.
|
||||
* - Change a token from one tenant ID to another (re-scoping).
|
||||
* - Remove the tenant ID from a scoped token (unscoping).
|
||||
*
|
||||
* @param string $tenantName
|
||||
* The tenant name that this present token should be bound to. If this is the
|
||||
* empty string (`''`), the present token will be "unscoped" and its tenant
|
||||
* name will be removed.
|
||||
*
|
||||
* @retval string
|
||||
* The authentication token.
|
||||
* @throws HPCloud::Transport::AuthorizationException
|
||||
* If authentication failed.
|
||||
* @throws HPCloud::Exception
|
||||
* For abnormal network conditions. The message will give an indication as
|
||||
* to the underlying problem.
|
||||
*/
|
||||
public function rescopeUsingTenantName($tenantName) {
|
||||
$url = $this->url() . '/tokens';
|
||||
$token = $this->token();
|
||||
$data = array(
|
||||
'auth' => array(
|
||||
'tenantName' => $tenantName,
|
||||
'token' => array(
|
||||
'id' => $token,
|
||||
),
|
||||
),
|
||||
);
|
||||
$body = json_encode($data);
|
||||
|
||||
$headers = array(
|
||||
'Accept' => self::ACCEPT_TYPE,
|
||||
'Content-Type' => 'application/json',
|
||||
'Content-Length' => strlen($body),
|
||||
//'X-Auth-Token' => $token,
|
||||
);
|
||||
|
||||
$client = \HPCloud\Transport::instance();
|
||||
$response = $client->doRequest($url, 'POST', $headers, $body);
|
||||
$this->handleResponse($response);
|
||||
|
||||
return $this->token();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a response object, populate this object.
|
||||
*
|
||||
@ -712,4 +833,24 @@ class IdentityServices {
|
||||
$this->serviceCatalog = $json['access']['serviceCatalog'];
|
||||
}
|
||||
|
||||
/* Not necessary.
|
||||
public function serialize() {
|
||||
$data = array(
|
||||
'tokenDetails' => $this->tokenDetails,
|
||||
'userDetails' => $this->userDetails,
|
||||
'serviceCatalog' => $this->serviceCatalog,
|
||||
'endpoint' => $this->endpoint,
|
||||
);
|
||||
return serialize($data);
|
||||
}
|
||||
|
||||
public function unserialize($data) {
|
||||
$vals = unserialize($data);
|
||||
$this->tokenDetails = $vals['tokenDetails'];
|
||||
$this->userDetails = $vals['userDetails'];
|
||||
$this->serviceCatalog = $vals['serviceCatalog'];
|
||||
$this->endpoint = $vals['endpoint'];
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
@ -138,6 +138,28 @@ class CDN {
|
||||
*/
|
||||
protected $token;
|
||||
|
||||
/**
|
||||
* Create a new instance from an IdentityServices object.
|
||||
*
|
||||
* This builds a new CDN instance form an authenticated
|
||||
* IdentityServices object.
|
||||
*
|
||||
* In the service catalog, this selects the first service entry
|
||||
* for CDN. At this time, that is sufficient.
|
||||
*
|
||||
* @param HPCloud::Services::IdentityServices $identity
|
||||
* The identity to use.
|
||||
* @retval object
|
||||
* A CDN object or FALSE if no CDN services could be found
|
||||
* in the catalog.
|
||||
*/
|
||||
public static function newFromIdentity($identity) {
|
||||
$tok = $identity->token();
|
||||
$cat = $identity->serviceCatalog();
|
||||
|
||||
return self::newFromServiceCatalog($cat, $tok);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CDN object based on a service catalog.
|
||||
*
|
||||
|
@ -163,6 +163,24 @@ class ObjectStorage {
|
||||
return $store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an IdentityServices instance, create an ObjectStorage instance.
|
||||
*
|
||||
* This constructs a new ObjectStorage from an authenticated instance
|
||||
* of an HPCloud::Services::IdentityServices object.
|
||||
*
|
||||
* @param HPCloud::Services::IdentityServices $identity
|
||||
* An identity services object that already has a valid token and a
|
||||
* service catalog.
|
||||
* @retval object ObjectStorage
|
||||
* A new ObjectStorage instance.
|
||||
*/
|
||||
public static function newFromIdentity($identity) {
|
||||
$cat = $identity->serviceCatalog();
|
||||
$tok = $identity->token();
|
||||
return self::newFromServiceCatalog($cat, $tok);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a service catalog and an token, create an ObjectStorage instance.
|
||||
*
|
||||
|
@ -148,7 +148,7 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
*/
|
||||
public static function objectUrl($base, $oname) {
|
||||
if (strpos($oname, '/') === FALSE) {
|
||||
return $base . '/' . $oname;
|
||||
return $base . '/' . rawurlencode($oname);
|
||||
}
|
||||
|
||||
$oParts = explode('/', $oname);
|
||||
@ -513,7 +513,7 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
|
||||
if (empty($file)) {
|
||||
// Now build up the rest of the headers:
|
||||
$headers['ETag'] = $obj->eTag();
|
||||
$headers['Etag'] = $obj->eTag();
|
||||
|
||||
// If chunked, we set transfer encoding; else
|
||||
// we set the content length.
|
||||
@ -541,7 +541,7 @@ class Container implements \Countable, \IteratorAggregate {
|
||||
$hash = hash_init('md5');
|
||||
hash_update_stream($hash, $file);
|
||||
$etag = hash_final($hash);
|
||||
$headers['ETag'] = $etag;
|
||||
$headers['Etag'] = $etag;
|
||||
|
||||
// Not sure if this is necessary:
|
||||
rewind($file);
|
||||
|
@ -451,6 +451,28 @@ class Object {
|
||||
return $this->additionalHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove headers.
|
||||
*
|
||||
* This takes an array of header names, and removes
|
||||
* any matching headers. Typically, only headers set
|
||||
* by setAdditionalHeaders() are removed from an Object.
|
||||
* (RemoteObject works differently).
|
||||
*
|
||||
* @attention
|
||||
* Many headers are generated automatically, such as
|
||||
* Content-Type and Content-Length. Removing these
|
||||
* will simply result in their being regenerated.
|
||||
*
|
||||
* @param array $keys
|
||||
* The header names to be removed.
|
||||
*/
|
||||
public function removeHeaders($keys) {
|
||||
foreach ($keys as $k) {
|
||||
unset($this->additionalHeaders[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This object should be transmitted in chunks.
|
||||
*
|
||||
|
@ -65,7 +65,7 @@ class RemoteObject extends Object {
|
||||
* serve as a good indicator that the object does not have all
|
||||
* attributes set.
|
||||
*/
|
||||
protected $allHeaders;
|
||||
protected $allHeaders = array();
|
||||
|
||||
protected $cdnUrl;
|
||||
protected $cdnSslUrl;
|
||||
@ -125,7 +125,8 @@ class RemoteObject extends Object {
|
||||
public static function newFromHeaders($name, $headers, $token, $url, $cdnUrl = NULL, $cdnSslUrl = NULL) {
|
||||
$object = new RemoteObject($name);
|
||||
|
||||
$object->allHeaders = $headers;
|
||||
//$object->allHeaders = $headers;
|
||||
$object->setHeaders($headers);
|
||||
|
||||
//throw new \Exception(print_r($headers, TRUE));
|
||||
|
||||
@ -259,6 +260,16 @@ class RemoteObject extends Object {
|
||||
return $this->metadata;
|
||||
}
|
||||
|
||||
public function setHeaders($headers) {
|
||||
$this->allHeaders = array();
|
||||
|
||||
foreach ($headers as $name => $value) {
|
||||
if (strpos($name, Container::METADATA_HEADER_PREFIX) !== 0) {
|
||||
$this->allHeaders[$name] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTTP headers sent by the server.
|
||||
*
|
||||
@ -274,6 +285,66 @@ class RemoteObject extends Object {
|
||||
return $this->allHeaders;
|
||||
}
|
||||
|
||||
public function additionalHeaders($mergeAll = FALSE) {
|
||||
// Any additional headers will be set. Note that $this->headers will contain
|
||||
// some headers that are NOT additional. But we do not know which headers are
|
||||
// additional and which are from Swift because Swift does not commit to using
|
||||
// a specific set of headers.
|
||||
if ($mergeAll) {
|
||||
$additionalHeaders = parent::additionalHeaders() + $this->allHeaders;
|
||||
$this->filterHeaders($additionalHeaders);
|
||||
}
|
||||
else {
|
||||
$additionalHeaders = parent::additionalHeaders();
|
||||
}
|
||||
|
||||
return $additionalHeaders;
|
||||
}
|
||||
|
||||
protected $reservedHeaders = array(
|
||||
'etag' => TRUE, 'content-length' => TRUE,
|
||||
'x-auth-token' => TRUE,
|
||||
'transfer-encoding' => TRUE,
|
||||
'x-trans-id' => TRUE,
|
||||
);
|
||||
public function filterHeaders(&$headers) {
|
||||
$unset = array();
|
||||
foreach ($headers as $name => $value) {
|
||||
$lower = strtolower($name);
|
||||
if (isset($this->reservedHeaders[$lower])) {
|
||||
$unset[] = $name;
|
||||
}
|
||||
}
|
||||
foreach ($unset as $u) {
|
||||
unset($headers[$u]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an array of header names.
|
||||
*
|
||||
* This will remove the given headers from the existing headers.
|
||||
* Both additional headers and the original headers from the
|
||||
* server are affected here.
|
||||
*
|
||||
* Note that you cannot remove metadata through this mechanism,
|
||||
* as it is managed using the metadata() methods.
|
||||
*
|
||||
* @attention
|
||||
* Many headers are generated automatically, such as
|
||||
* Content-Type and Content-Length. Removing these
|
||||
* will simply result in their being regenerated.
|
||||
*
|
||||
* @param array $keys
|
||||
* The header names to be removed.
|
||||
*/
|
||||
public function removeHeaders($keys) {
|
||||
foreach ($keys as $key) {
|
||||
unset($this->allHeaders[$key]);
|
||||
unset($this->additionalHeaders[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content of this object.
|
||||
*
|
||||
|
@ -108,7 +108,8 @@ use \HPCloud\Storage\ObjectStorage;
|
||||
* array('swift' => array(
|
||||
* 'account' => ACCOUNT_NUMBER,
|
||||
* 'key' => SECRET_KEY,
|
||||
* 'tenantId' => TENANT_ID
|
||||
* 'tenantid' => TENANT_ID,
|
||||
* 'tenantname' => TENANT_NAME, // Optional instead of tenantid.
|
||||
* 'endpoint' => AUTH_ENDPOINT_URL,
|
||||
* )
|
||||
* )
|
||||
@ -218,9 +219,12 @@ use \HPCloud\Storage\ObjectStorage;
|
||||
* -# User login: username, password, tenantid, endpoint
|
||||
* -# Existing (valid) token: token, swift_endpoint
|
||||
*
|
||||
* @attention
|
||||
* As of 1.0.0-beta6, you may use `tenantname` instead of `tenantid`.
|
||||
*
|
||||
* The third method (token) can be used when the application has already
|
||||
* authenticated. In this case, a token has been generated and assigneet
|
||||
* to an account and tenant ID.
|
||||
* authenticated. In this case, a token has been generated and assigned
|
||||
* to an account and tenant.
|
||||
*
|
||||
* The following parameters may be set either in the stream context
|
||||
* or through HPCloud::Bootstrap::setConfiguration():
|
||||
@ -230,10 +234,10 @@ use \HPCloud\Storage\ObjectStorage;
|
||||
* option.
|
||||
* - swift_endpoint: The URL to the swift instance. This is only necessary if
|
||||
* 'token' is set. Otherwise it is ignored.
|
||||
* - username: A username. MUST be accompanied by 'password' and 'tenantid'.
|
||||
* - password: A password. MUST be accompanied by 'username' and 'tenantid'.
|
||||
* - account: An account ID. MUST be accompanied by a 'key' and 'tenantid'.
|
||||
* - key: A secret key. MUST be accompanied by an 'account' and 'tenantid'.
|
||||
* - username: A username. MUST be accompanied by 'password' and 'tenantid' (or 'tenantname').
|
||||
* - password: A password. MUST be accompanied by 'username' and 'tenantid' (or 'tenantname').
|
||||
* - account: An account ID. MUST be accompanied by a 'key' and 'tenantid' (or 'tenantname').
|
||||
* - key: A secret key. MUST be accompanied by an 'account' and 'tenantid' (or 'tenantname').
|
||||
* - endpoint: The URL to the authentication endpoint. Necessary if you are not
|
||||
* using a 'token' and 'swift_endpoint'.
|
||||
* - use_swift_auth: If this is set to TRUE, it will force the app to use
|
||||
@ -251,6 +255,10 @@ use \HPCloud\Storage\ObjectStorage;
|
||||
* - cdn_require_ssl: If this is set to FALSE, then CDN-based requests
|
||||
* may use plain HTTP instead of HTTPS. This will spead up CDN
|
||||
* fetches at the cost of security.
|
||||
* - tenantid: The tenant ID for the services you will use. (An account may
|
||||
* have multiple tenancies associated.)
|
||||
* - tenantname: The tenant name for the services you will use. You may use
|
||||
* this in lieu of tenant ID.
|
||||
*
|
||||
* @attention
|
||||
* ADVANCED: You can also pass an HPCloud::Storage::CDN object in use_cdn instead of
|
||||
@ -533,7 +541,8 @@ class StreamWrapper {
|
||||
* @code
|
||||
* <?php
|
||||
* Bootstrap::setConfiguration(array(
|
||||
* 'tenantid' => '1234',
|
||||
* 'tenantname' => 'foo@example.com',
|
||||
* // 'tenantid' => '1234', // You can use this instead of tenantname
|
||||
* 'account' => '1234',
|
||||
* 'secret' => '4321',
|
||||
* 'endpoint' => 'https://auth.example.com',
|
||||
@ -947,7 +956,7 @@ class StreamWrapper {
|
||||
* @code
|
||||
* <?php
|
||||
* $cxt = stream_context_create(array(
|
||||
* 'tenantid' => '12345',
|
||||
* 'tenantname' => 'me@example.com',
|
||||
* 'username' => 'me@example.com',
|
||||
* 'password' => 'secret',
|
||||
* 'endpoint' => 'https://auth.example.com',
|
||||
@ -1475,10 +1484,10 @@ class StreamWrapper {
|
||||
* option.
|
||||
* - swift_endpoint: The URL to the swift instance. This is only necessary if
|
||||
* 'token' is set. Otherwise it is ignored.
|
||||
* - username: A username. MUST be accompanied by 'password' and 'tenantid'.
|
||||
* - password: A password. MUST be accompanied by 'username' and 'tenantid'.
|
||||
* - account: An account ID. MUST be accompanied by a 'key' and 'tenantid'.
|
||||
* - key: A secret key. MUST be accompanied by an 'account' and 'tenantid'.
|
||||
* - username: A username. MUST be accompanied by 'password' and 'tenantname'.
|
||||
* - password: A password. MUST be accompanied by 'username' and 'tenantname'.
|
||||
* - account: An account ID. MUST be accompanied by a 'key' and 'tenantname'.
|
||||
* - key: A secret key. MUST be accompanied by an 'account' and 'tenantname'.
|
||||
* - endpoint: The URL to the authentication endpoint. Necessary if you are not
|
||||
* using a 'token' and 'swift_endpoint'.
|
||||
* - use_swift_auth: If this is set to TRUE, it will force the app to use
|
||||
@ -1498,6 +1507,7 @@ class StreamWrapper {
|
||||
$key = $this->cxt('key');
|
||||
|
||||
$tenantId = $this->cxt('tenantid');
|
||||
$tenantName = $this->cxt('tenantname');
|
||||
$authUrl = $this->cxt('endpoint');
|
||||
$endpoint = $this->cxt('swift_endpoint');
|
||||
|
||||
@ -1522,8 +1532,11 @@ class StreamWrapper {
|
||||
|
||||
}
|
||||
// If we get here and tenant ID is not set, we can't get a container.
|
||||
elseif (empty($tenantId) || empty($authUrl)) {
|
||||
throw new \HPCloud\Exception('Tenant ID (tenantid) and endpoint are required.');
|
||||
elseif (empty($tenantId) && empty($tenantName)) {
|
||||
throw new \HPCloud\Exception('Either Tenant ID (tenantid) or Tenant Name (tenantname) is required.');
|
||||
}
|
||||
elseif (empty($authUrl)) {
|
||||
throw new \HPCloud\Exception('An Identity Service Endpoint (endpoint) is required.');
|
||||
}
|
||||
// Try to authenticate and get a new token.
|
||||
else {
|
||||
@ -1612,6 +1625,7 @@ class StreamWrapper {
|
||||
$key = $this->cxt('key');
|
||||
|
||||
$tenantId = $this->cxt('tenantid');
|
||||
$tenantName = $this->cxt('tenantname');
|
||||
$authUrl = $this->cxt('endpoint');
|
||||
|
||||
$ident = new \HPCloud\Services\IdentityServices($authUrl);
|
||||
@ -1619,10 +1633,10 @@ class StreamWrapper {
|
||||
// Frustrated? Go burninate. http://www.homestarrunner.com/trogdor.html
|
||||
|
||||
if (!empty($username) && !empty($password)) {
|
||||
$token = $ident->authenticateAsUser($username, $password, $tenantId);
|
||||
$token = $ident->authenticateAsUser($username, $password, $tenantId, $tenantName);
|
||||
}
|
||||
elseif (!empty($account) && !empty($key)) {
|
||||
$token = $ident->authenticateAsAccount($account, $key, $tenantId);
|
||||
$token = $ident->authenticateAsAccount($account, $key, $tenantId, $tenantName);
|
||||
}
|
||||
else {
|
||||
throw new \HPCloud\Exception('Either username/password or account/key must be provided.');
|
||||
|
@ -179,12 +179,13 @@ class Response {
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (!feof($this->handle)) {
|
||||
$out .= fread($this->handle, 8192);
|
||||
}
|
||||
// XXX: This works fine with CURL, but will not
|
||||
// work with PHP HTTP Stream Wrapper b/c the
|
||||
// wrapper has a bug that will cause this to
|
||||
// hang.
|
||||
$out = stream_get_contents($this->handle);
|
||||
}
|
||||
|
||||
|
||||
// Should we close or rewind?
|
||||
// Cannot rewind PHP HTTP streams.
|
||||
fclose($this->handle);
|
||||
|
@ -26,7 +26,8 @@ SOFTWARE.
|
||||
* You can run the test with `php test/AuthTest.php username key`.
|
||||
*/
|
||||
|
||||
require_once 'src/HPCloud/Bootstrap.php';
|
||||
$base = dirname(__DIR__);
|
||||
require_once $base . '/src/HPCloud/Bootstrap.php';
|
||||
|
||||
use \HPCloud\Storage\ObjectStorage;
|
||||
use \HPCloud\Services\IdentityServices;
|
||||
|
@ -102,8 +102,8 @@ class TestCase extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
$user = self::$settings['hpcloud.swift.account'];
|
||||
$key = self::$settings['hpcloud.swift.key'];
|
||||
// $url = self::$settings['hpcloud.swift.url'];
|
||||
$url = self::$settings['hpcloud.identity.url'];
|
||||
$url = self::$settings['hpcloud.swift.url'];
|
||||
//$url = self::$settings['hpcloud.identity.url'];
|
||||
|
||||
return \HPCloud\Storage\ObjectStorage::newFromSwiftAuth($user, $key, $url);
|
||||
|
||||
@ -145,19 +145,7 @@ class TestCase extends \PHPUnit_Framework_TestCase {
|
||||
if ($reset || empty(self::$ostore)) {
|
||||
$ident = $this->identity($reset);
|
||||
|
||||
$services = $ident->serviceCatalog(\HPCloud\Storage\ObjectStorage::SERVICE_TYPE);
|
||||
|
||||
if (empty($services)) {
|
||||
throw new \Exception('No object-store service found.');
|
||||
}
|
||||
|
||||
/*
|
||||
//$serviceURL = $services[0]['endpoints'][0]['adminURL'];
|
||||
$serviceURL = $services[0]['endpoints'][0]['publicURL'];
|
||||
|
||||
$objStore = new \HPCloud\Storage\ObjectStorage($ident->token(), $serviceURL);
|
||||
*/
|
||||
$objStore = \HPCloud\Storage\ObjectStorage::newFromServiceCatalog($services, $ident->token());
|
||||
$objStore = \HPCloud\Storage\ObjectStorage::newFromIdentity($ident);
|
||||
|
||||
self::$ostore = $objStore;
|
||||
|
||||
|
@ -80,6 +80,18 @@ class CDNTest extends \HPCloud\Tests\TestCase {
|
||||
return $cdn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testConstructor
|
||||
*/
|
||||
public function testNewFromIdentity() {
|
||||
$ident = $this->identity();
|
||||
$cdn = CDN::newFromIdentity($ident);
|
||||
|
||||
$this->assertInstanceOf('\HPCloud\Storage\CDN', $cdn);
|
||||
|
||||
return $cdn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testNewFromServiceCatalog
|
||||
*/
|
||||
|
@ -30,6 +30,7 @@ require_once 'src/HPCloud/Bootstrap.php';
|
||||
require_once 'test/TestCase.php';
|
||||
|
||||
use \HPCloud\Services\IdentityServices;
|
||||
use \HPCloud\Bootstrap;
|
||||
|
||||
|
||||
class IdentityServicesTest extends \HPCloud\Tests\TestCase {
|
||||
@ -169,6 +170,48 @@ class IdentityServicesTest extends \HPCloud\Tests\TestCase {
|
||||
$this->assertNotEmpty($service->token());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testAuthenticateAsAccount
|
||||
*/
|
||||
public function testIsExpired($service) {
|
||||
$this->assertFalse($service->isExpired());
|
||||
|
||||
$service2 = new IdentityServices(self::conf('hpcloud.identity.url'));
|
||||
$this->assertTrue($service2->isExpired());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testAuthenticateAsAccount
|
||||
*/
|
||||
public function testTenantName() {
|
||||
$account = self::conf('hpcloud.identity.account');
|
||||
$secret = self::conf('hpcloud.identity.secret');
|
||||
$user = self::conf('hpcloud.identity.username');
|
||||
$pass = self::conf('hpcloud.identity.password');
|
||||
$tenantName = self::conf('hpcloud.identity.tenantName');
|
||||
|
||||
$service = new IdentityServices(self::conf('hpcloud.identity.url'));
|
||||
$this->assertNull($service->tenantName());
|
||||
|
||||
$service->authenticateAsUser($user, $pass);
|
||||
$this->assertEmpty($service->tenantName());
|
||||
|
||||
$service = new IdentityServices(self::conf('hpcloud.identity.url'));
|
||||
$ret = $service->authenticateAsUser($user, $pass, NULL, $tenantName);
|
||||
$this->assertNotEmpty($service->tenantName());
|
||||
|
||||
$service = new IdentityServices(self::conf('hpcloud.identity.url'));
|
||||
$this->assertNull($service->tenantName());
|
||||
|
||||
$service->authenticateAsAccount($account, $secret);
|
||||
$this->assertEmpty($service->tenantName());
|
||||
|
||||
$service = new IdentityServices(self::conf('hpcloud.identity.url'));
|
||||
$ret = $service->authenticateAsAccount($account, $secret, NULL, $tenantName);
|
||||
$this->assertNotEmpty($service->tenantName());
|
||||
$this->assertEquals($tenantName, $service->tenantName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testAuthenticateAsAccount
|
||||
*/
|
||||
@ -271,6 +314,33 @@ class IdentityServicesTest extends \HPCloud\Tests\TestCase {
|
||||
$this->assertNotEmpty($user['roles']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testAuthenticateAsAccount
|
||||
* @group serialize
|
||||
*/
|
||||
public function testSerialization($service) {
|
||||
|
||||
$ser = serialize($service);
|
||||
|
||||
$this->assertNotEmpty($ser);
|
||||
|
||||
$again = unserialize($ser);
|
||||
|
||||
$this->assertInstanceOf('\HPCloud\Services\IdentityServices', $again);
|
||||
|
||||
$this->assertEquals($service->tenantId(), $again->tenantId());
|
||||
$this->assertEquals($service->serviceCatalog(), $again->serviceCatalog());
|
||||
$this->assertEquals($service->tokenDetails(), $again->tokenDetails());
|
||||
$this->assertEquals($service->user(), $again->user());
|
||||
$this->assertFalse($again->isExpired());
|
||||
|
||||
$tenantId = $again->tenantId();
|
||||
|
||||
$newTok = $again->rescopeUsingTenantId($tenantId);
|
||||
|
||||
$this->assertNotEmpty($newTok);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group tenant
|
||||
*/
|
||||
@ -319,7 +389,7 @@ class IdentityServicesTest extends \HPCloud\Tests\TestCase {
|
||||
$catalog = $service->serviceCatalog();
|
||||
$this->assertEquals(1, count($catalog));
|
||||
|
||||
$service->rescope($tenantId);
|
||||
$service->rescopeUsingTenantId($tenantId);
|
||||
|
||||
$details = $service->tokenDetails();
|
||||
$this->assertEquals($tenantId, $details['tenant']['id']);
|
||||
@ -327,6 +397,46 @@ class IdentityServicesTest extends \HPCloud\Tests\TestCase {
|
||||
$catalog = $service->serviceCatalog();
|
||||
$this->assertGreaterThan(1, count($catalog));
|
||||
|
||||
// Test unscoping
|
||||
$service->rescopeUsingTenantId('');
|
||||
$details = $service->tokenDetails();
|
||||
$this->assertEmpty($details['tenant']);
|
||||
$catalog = $service->serviceCatalog();
|
||||
$this->assertEquals(1, count($catalog));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @group tenant
|
||||
* @depends testTenants
|
||||
*/
|
||||
function testRescopeByTenantName() {
|
||||
$service = new IdentityServices(self::conf('hpcloud.identity.url'));
|
||||
$user = self::conf('hpcloud.identity.username');
|
||||
$pass = self::conf('hpcloud.identity.password');
|
||||
$tenantName = self::conf('hpcloud.identity.tenantName');
|
||||
|
||||
// Authenticate without a tenant ID.
|
||||
$token = $service->authenticateAsUser($user, $pass);
|
||||
|
||||
$this->assertNotEmpty($token);
|
||||
|
||||
$details = $service->tokenDetails();
|
||||
$this->assertEmpty($details['tenant']);
|
||||
|
||||
// With no tenant ID, there should be only
|
||||
// one entry in the catalog.
|
||||
$catalog = $service->serviceCatalog();
|
||||
$this->assertEquals(1, count($catalog));
|
||||
|
||||
$service->rescopeUsingTenantName($tenantName);
|
||||
|
||||
$details = $service->tokenDetails();
|
||||
$this->assertEquals($tenantName, $details['tenant']['name']);
|
||||
|
||||
$catalog = $service->serviceCatalog();
|
||||
$this->assertGreaterThan(1, count($catalog));
|
||||
|
||||
// Test unscoping
|
||||
$service->rescope('');
|
||||
$details = $service->tokenDetails();
|
||||
@ -335,4 +445,77 @@ class IdentityServicesTest extends \HPCloud\Tests\TestCase {
|
||||
$this->assertEquals(1, count($catalog));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the bootstrap identity factory.
|
||||
* @depends testAuthenticateAsAccount
|
||||
* @depends testAuthenticateAsUser
|
||||
*/
|
||||
function testBootstrap() {
|
||||
|
||||
// We need to save the config settings and reset the bootstrap to this.
|
||||
// It does not remove the old settings. The means the identity fall through
|
||||
// for different settings may not happen because of ordering. So, we cache
|
||||
// and reset back to the default for each test.
|
||||
$reset = Bootstrap::$config;
|
||||
|
||||
// Test authenticating as a user.
|
||||
$settings = array(
|
||||
'username' => self::conf('hpcloud.identity.username'),
|
||||
'password' => self::conf('hpcloud.identity.password'),
|
||||
'endpoint' => self::conf('hpcloud.identity.url'),
|
||||
'tenantid' => self::conf('hpcloud.identity.tenantId'),
|
||||
);
|
||||
Bootstrap::setConfiguration($settings);
|
||||
|
||||
$is = Bootstrap::identity(TRUE);
|
||||
$this->assertInstanceOf('\HPCloud\Services\IdentityServices', $is);
|
||||
|
||||
Bootstrap::$config = $reset;
|
||||
|
||||
// Test authenticating as an account.
|
||||
$settings = array(
|
||||
'account' => self::conf('hpcloud.identity.account'),
|
||||
'secret' => self::conf('hpcloud.identity.secret'),
|
||||
'endpoint' => self::conf('hpcloud.identity.url'),
|
||||
'tenantid' => self::conf('hpcloud.identity.tenantId'),
|
||||
);
|
||||
Bootstrap::setConfiguration($settings);
|
||||
|
||||
$is = Bootstrap::identity(TRUE);
|
||||
$this->assertInstanceOf('\HPCloud\Services\IdentityServices', $is);
|
||||
|
||||
// Test getting a second instance from the cache.
|
||||
$is2 = Bootstrap::identity();
|
||||
$this->assertEquals($is, $is2);
|
||||
|
||||
// Test that forcing a refresh does so.
|
||||
$is2 = Bootstrap::identity(TRUE);
|
||||
$this->assertNotEquals($is, $is2);
|
||||
|
||||
Bootstrap::$config = $reset;
|
||||
|
||||
// Test with tenant name
|
||||
$settings = array(
|
||||
'account' => self::conf('hpcloud.identity.account'),
|
||||
'secret' => self::conf('hpcloud.identity.secret'),
|
||||
'endpoint' => self::conf('hpcloud.identity.url'),
|
||||
'tenantname' => self::conf('hpcloud.identity.tenantName'),
|
||||
);
|
||||
Bootstrap::setConfiguration($settings);
|
||||
|
||||
$is = Bootstrap::identity(TRUE);
|
||||
$this->assertInstanceOf('\HPCloud\Services\IdentityServices', $is);
|
||||
|
||||
$settings = array(
|
||||
'username' => self::conf('hpcloud.identity.username'),
|
||||
'password' => self::conf('hpcloud.identity.password'),
|
||||
'endpoint' => self::conf('hpcloud.identity.url'),
|
||||
'tenantname' => self::conf('hpcloud.identity.tenantName'),
|
||||
);
|
||||
Bootstrap::setConfiguration($settings);
|
||||
|
||||
$is = Bootstrap::identity(TRUE);
|
||||
$this->assertInstanceOf('\HPCloud\Services\IdentityServices', $is);
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,17 @@ class ObjectStorageTest extends \HPCloud\Tests\TestCase {
|
||||
}
|
||||
|
||||
public function testNewFromServiceCatalog() {
|
||||
$ostore = $this->objectStore();
|
||||
$ident = $this->identity();
|
||||
$tok = $ident->token();
|
||||
$cat = $ident->serviceCatalog();
|
||||
$ostore = \HPCloud\Storage\ObjectStorage::newFromServiceCatalog($cat, $tok);
|
||||
$this->assertInstanceOf('\HPCloud\Storage\ObjectStorage', $ostore);
|
||||
$this->assertTrue(strlen($ostore->token()) > 0);
|
||||
}
|
||||
|
||||
public function testNewFromIdnetity() {
|
||||
$ident = $this->identity();
|
||||
$ostore = \HPCloud\Storage\ObjectStorage::newFromIdentity($ident);
|
||||
$this->assertInstanceOf('\HPCloud\Storage\ObjectStorage', $ostore);
|
||||
$this->assertTrue(strlen($ostore->token()) > 0);
|
||||
}
|
||||
|
@ -131,4 +131,24 @@ class ObjectTest extends \HPCloud\Tests\TestCase {
|
||||
$this->assertEquals('Leibniz', $got['Gottfried']);
|
||||
|
||||
}
|
||||
|
||||
public function testAdditionalHeaders() {
|
||||
$o = $this->basicObjectFixture();
|
||||
|
||||
$extra = array(
|
||||
'a' => 'b',
|
||||
'aaa' => 'bbb',
|
||||
'ccc' => 'bbb',
|
||||
);
|
||||
$o->setAdditionalHeaders($extra);
|
||||
|
||||
$got = $o->additionalHeaders();
|
||||
$this->assertEquals(3, count($got));
|
||||
|
||||
$o->removeHeaders(array('ccc'));
|
||||
|
||||
|
||||
$got = $o->additionalHeaders();
|
||||
$this->assertEquals(2, count($got));
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,10 @@ class RemoteObjectTest extends \HPCloud\Tests\TestCase {
|
||||
$object->setMetadata(array(self::FMETA_NAME => self::FMETA_VALUE));
|
||||
$object->setDisposition(self::FDISPOSITION);
|
||||
$object->setEncoding(self::FENCODING);
|
||||
$object->setAdditionalHeaders(array(
|
||||
'Access-Control-Allow-Origin' => 'http://example.com',
|
||||
'Access-control-allow-origin' => 'http://example.com',
|
||||
));
|
||||
|
||||
// Need some headers that Swift actually stores and returns. This
|
||||
// one does not seem to be returned ever.
|
||||
@ -146,6 +150,15 @@ class RemoteObjectTest extends \HPCloud\Tests\TestCase {
|
||||
$headers = $obj->headers();
|
||||
$this->assertTrue(count($headers) > 1);
|
||||
|
||||
//fwrite(STDOUT, print_r($headers, TRUE));
|
||||
|
||||
$this->assertNotEmpty($headers['Date']);
|
||||
|
||||
$obj->removeHeaders(array('Date'));
|
||||
|
||||
$headers = $obj->headers();
|
||||
$this->assertFalse(isset($headers['Date']));
|
||||
|
||||
// Swift doesn't return CORS headers even though it is supposed to.
|
||||
//$this->assertEquals(self::FCORS_VALUE, $headers[self::FCORS_NAME]);
|
||||
}
|
||||
|
@ -45,6 +45,46 @@ class StreamWrapperFSTest extends \HPCloud\Tests\TestCase {
|
||||
/*public static function setUpBeforeClass() {
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Cleaning up the test container so we can reuse it for other tests.
|
||||
*/
|
||||
public static function tearDownAfterClass() {
|
||||
|
||||
// First we get an identity
|
||||
$user = self::conf('hpcloud.identity.username');
|
||||
$pass = self::conf('hpcloud.identity.password');
|
||||
$tenantId = self::conf('hpcloud.identity.tenantId');
|
||||
$url = self::conf('hpcloud.identity.url');
|
||||
|
||||
$ident = new \HPCloud\Services\IdentityServices($url);
|
||||
|
||||
$token = $ident->authenticateAsUser($user, $pass, $tenantId);
|
||||
|
||||
// Then we need to get an instance of storage
|
||||
$store = \HPCloud\Storage\ObjectStorage::newFromIdentity($ident);
|
||||
|
||||
|
||||
// Delete the container and all the contents.
|
||||
$cname = self::$settings['hpcloud.swift.container'];
|
||||
|
||||
try {
|
||||
$container = $store->container($cname);
|
||||
}
|
||||
// The container was never created.
|
||||
catch (\HPCloud\Transport\FileNotFoundException $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($container as $object) {
|
||||
try {
|
||||
$container->delete($object->name());
|
||||
}
|
||||
catch (\Exception $e) {}
|
||||
}
|
||||
|
||||
$store->deleteContainer($cname);
|
||||
}
|
||||
|
||||
protected function newUrl($objectName) {
|
||||
$scheme = StreamWrapperFS::DEFAULT_SCHEME;
|
||||
$cname = self::$settings['hpcloud.swift.container'];
|
||||
@ -129,7 +169,7 @@ class StreamWrapperFSTest extends \HPCloud\Tests\TestCase {
|
||||
'account' => self::$settings['hpcloud.identity.account'],
|
||||
'key' => self::$settings['hpcloud.identity.secret'],
|
||||
'endpoint' => self::$settings['hpcloud.identity.url'],
|
||||
'tenantit' => self::$settings['hpcloud.identity.tenantId'],
|
||||
'tenantid' => self::$settings['hpcloud.identity.tenantId'],
|
||||
'token' => $this->objectStore()->token(),
|
||||
'swift_endpoint' => $this->objectStore()->url(),
|
||||
);
|
||||
|
@ -42,6 +42,46 @@ class StreamWrapperTest extends \HPCloud\Tests\TestCase {
|
||||
const FNAME = 'streamTest.txt';
|
||||
const FTYPE = 'application/x-tuna-fish; charset=iso-8859-13';
|
||||
|
||||
/**
|
||||
* Cleaning up the test container so we can reuse it for other tests.
|
||||
*/
|
||||
public static function tearDownAfterClass() {
|
||||
|
||||
// First we get an identity
|
||||
$user = self::conf('hpcloud.identity.username');
|
||||
$pass = self::conf('hpcloud.identity.password');
|
||||
$tenantId = self::conf('hpcloud.identity.tenantId');
|
||||
$url = self::conf('hpcloud.identity.url');
|
||||
|
||||
$ident = new \HPCloud\Services\IdentityServices($url);
|
||||
|
||||
$token = $ident->authenticateAsUser($user, $pass, $tenantId);
|
||||
|
||||
// Then we need to get an instance of storage
|
||||
$store = \HPCloud\Storage\ObjectStorage::newFromIdentity($ident);
|
||||
|
||||
|
||||
// Delete the container and all the contents.
|
||||
$cname = self::$settings['hpcloud.swift.container'];
|
||||
|
||||
try {
|
||||
$container = $store->container($cname);
|
||||
}
|
||||
// The container was never created.
|
||||
catch (\HPCloud\Transport\FileNotFoundException $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($container as $object) {
|
||||
try {
|
||||
$container->delete($object->name());
|
||||
}
|
||||
catch (\Exception $e) {}
|
||||
}
|
||||
|
||||
$store->deleteContainer($cname);
|
||||
}
|
||||
|
||||
protected function newUrl($objectName) {
|
||||
$scheme = StreamWrapper::DEFAULT_SCHEME;
|
||||
$cname = self::$settings['hpcloud.swift.container'];
|
||||
@ -126,7 +166,7 @@ class StreamWrapperTest extends \HPCloud\Tests\TestCase {
|
||||
'account' => self::$settings['hpcloud.identity.account'],
|
||||
'key' => self::$settings['hpcloud.identity.secret'],
|
||||
'endpoint' => self::$settings['hpcloud.identity.url'],
|
||||
'tenantit' => self::$settings['hpcloud.identity.tenantId'],
|
||||
'tenantid' => self::$settings['hpcloud.identity.tenantId'],
|
||||
'token' => $this->objectStore()->token(),
|
||||
'swift_endpoint' => $this->objectStore()->url(),
|
||||
);
|
||||
|
@ -4,9 +4,13 @@
|
||||
;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Settings to work with swift:
|
||||
; Account is the tenandId:console username.
|
||||
hpcloud.swift.account = 12345678:87654321
|
||||
; Key is the console account password.
|
||||
hpcloud.swift.key = abcdef123456
|
||||
hpcloud.swift.url = https://region-a.geo-1.objects.hpcloudsvc.com/auth/v1.0/
|
||||
; URL is the same as used for identity services calls (including port) except
|
||||
; with /auth/v1.0/ appended to the end.
|
||||
hpcloud.swift.url = https://region-a.geo-1.identity.hpcloudsvc.com:35357/auth/v1.0/
|
||||
|
||||
; Container used for testing.
|
||||
hpcloud.swift.container = "I♡HPCloud"
|
||||
|
Loading…
x
Reference in New Issue
Block a user