Basic auth now working with control services.
This commit is contained in:
		@@ -8,7 +8,7 @@ namespace HPCloud\Services;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * Control Services (a.k.a. Keystone) provides a central service for managing
 | 
			
		||||
 * Identity Services (a.k.a. Keystone) provides a central service for managing
 | 
			
		||||
 * other services. Through it, you can do the following:
 | 
			
		||||
 *
 | 
			
		||||
 * - Authenticate
 | 
			
		||||
@@ -49,10 +49,32 @@ class ControlServices {
 | 
			
		||||
   */
 | 
			
		||||
  protected $endpoint;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The details sent with the token.
 | 
			
		||||
   *
 | 
			
		||||
   * This is an associative array looking like this:
 | 
			
		||||
   *
 | 
			
		||||
   * @code
 | 
			
		||||
   * <?php
 | 
			
		||||
   * array(
 | 
			
		||||
   *   'id' => 'auth_123abc321defef99',
 | 
			
		||||
   *   'tenant_id' => '123456',
 | 
			
		||||
   *   'tenant_name' => 'matt.butcher@hp.com',
 | 
			
		||||
   *   'expires' => '2012-01-24T12:46:01.682Z'
 | 
			
		||||
   * );
 | 
			
		||||
   * @endcode
 | 
			
		||||
   */
 | 
			
		||||
  protected $tokenDetails;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The service catalog.
 | 
			
		||||
   */
 | 
			
		||||
  protected $catalog = array();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Build a new ControlServices object.
 | 
			
		||||
   *
 | 
			
		||||
   * Each object is bound to a particular control services endpoint.
 | 
			
		||||
   * Each object is bound to a particular identity services endpoint.
 | 
			
		||||
   *
 | 
			
		||||
   * For the URL, you are advised to use the version <i>without</i> a
 | 
			
		||||
   * version number at the end, e.g. http://cs.example.com/ rather
 | 
			
		||||
@@ -67,7 +89,7 @@ class ControlServices {
 | 
			
		||||
   * @endcode
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $url
 | 
			
		||||
   *   An URL pointing to the Control Services endpoint. Note that you do
 | 
			
		||||
   *   An URL pointing to the Identity Services endpoint. Note that you do
 | 
			
		||||
   *   not need the version identifier in the URL, as version information
 | 
			
		||||
   *   is sent in the HTTP headers rather than in the URL. <b>The URL
 | 
			
		||||
   *   should <i>always</i> be to an SSL/TLS encrypted endpoint.</b>.
 | 
			
		||||
@@ -130,14 +152,17 @@ class ControlServices {
 | 
			
		||||
 | 
			
		||||
    $response = $client->doRequest($url, 'POST', $headers, $body);
 | 
			
		||||
 | 
			
		||||
    var_dump($response->content());
 | 
			
		||||
    $this->handleResponse($response);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    return $this->token();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Authenticate to Control Services with username, password, and tenant ID.
 | 
			
		||||
   * Authenticate to Identity Services with username, password, and tenant ID.
 | 
			
		||||
   *
 | 
			
		||||
   * Given an HPCloud username and password, and also the account's tenant ID,
 | 
			
		||||
   * authenticate to Control Services. Control Services will then issue a token
 | 
			
		||||
   * authenticate to Identity Services. Identity Services will then issue a token
 | 
			
		||||
   * that can be used to access other HPCloud services.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $username
 | 
			
		||||
@@ -162,7 +187,7 @@ class ControlServices {
 | 
			
		||||
   * Authenticate to HPCloud using your account ID and access key.
 | 
			
		||||
   *
 | 
			
		||||
   * Given an account ID and and access key (secret key), authenticate
 | 
			
		||||
   * to Control Services. Control Services will then issue a token that can be
 | 
			
		||||
   * to Identity Services. Identity Services will then issue a token that can be
 | 
			
		||||
   * used with other HPCloud services, such as Object Storage (aka Swift).
 | 
			
		||||
   *
 | 
			
		||||
   * The account ID and access key information can be found in the account
 | 
			
		||||
@@ -188,24 +213,150 @@ class ControlServices {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get the token.
 | 
			
		||||
   *
 | 
			
		||||
   * This will not be populated until after one of the authentication
 | 
			
		||||
   * methods has been run.
 | 
			
		||||
   *
 | 
			
		||||
   * @return string
 | 
			
		||||
   *   The token ID to be used in subsequent calls.
 | 
			
		||||
   */
 | 
			
		||||
  public function token() {
 | 
			
		||||
 | 
			
		||||
    return $this->tokenDetails['id'];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get the token details.
 | 
			
		||||
   *
 | 
			
		||||
   * This returns an associative array with several pieces of information
 | 
			
		||||
   * about the token, including:
 | 
			
		||||
   *
 | 
			
		||||
   * - id: The token itself
 | 
			
		||||
   * - expires: When the token expires
 | 
			
		||||
   * - tenant_id: The tenant ID of the authenticated user.
 | 
			
		||||
   * - tenant_name: The username of the authenticated user.
 | 
			
		||||
   *
 | 
			
		||||
   * @code
 | 
			
		||||
   * <?php
 | 
			
		||||
   * array(
 | 
			
		||||
   *   'id' => 'auth_123abc321defef99',
 | 
			
		||||
   *   'tenant_id' => '123456',
 | 
			
		||||
   *   'tenant_name' => 'matt.butcher@hp.com',
 | 
			
		||||
   *   'expires' => '2012-01-24T12:46:01.682Z'
 | 
			
		||||
   * );
 | 
			
		||||
   * @endcode
 | 
			
		||||
   *
 | 
			
		||||
   * @returns array
 | 
			
		||||
   *   An associative array of details.
 | 
			
		||||
   */
 | 
			
		||||
  public function tokenDetails() {
 | 
			
		||||
    return $this->tokenDetails;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get the service catalog.
 | 
			
		||||
   *
 | 
			
		||||
   * This returns the service catalog (largely unprocessed) that
 | 
			
		||||
   * is returned during an authentication request.
 | 
			
		||||
   *
 | 
			
		||||
   * The service catalog contains information about what services (if any) are
 | 
			
		||||
   * available for the present user. Object storage (Swift) Compute instances
 | 
			
		||||
   * (Nova) and other services will each be listed here if they are enabled
 | 
			
		||||
   * on your account. Only services that have been turned on for the account
 | 
			
		||||
   * will be available. (That is, even if you *can* create a compute instance,
 | 
			
		||||
   * until you have actually created one, it will not show up in this list.)
 | 
			
		||||
   *
 | 
			
		||||
   * One of the authentication methods MUST be run before obtaining the service
 | 
			
		||||
   * catalog.
 | 
			
		||||
   *
 | 
			
		||||
   * The return value is an indexed array of associative arrays, where each assoc
 | 
			
		||||
   * array describes an individual service.
 | 
			
		||||
   * @code
 | 
			
		||||
   * <?php
 | 
			
		||||
   * array(
 | 
			
		||||
   *   array(
 | 
			
		||||
   *     'name' : 'Object Storage',
 | 
			
		||||
   *     'type' => 'object-storage',
 | 
			
		||||
   *     'endpoints' => array(
 | 
			
		||||
   *       'tenantId' => '123456',
 | 
			
		||||
   *       'adminURL' => 'https://example.hpcloud.net/1.0',
 | 
			
		||||
   *       'publicUrl' => 'https://example.hpcloud.net/1.0/123456',
 | 
			
		||||
   *       'region' => 'region-a.geo-1',
 | 
			
		||||
   *       'id' => '1.0',
 | 
			
		||||
   *     ),
 | 
			
		||||
   *   ),
 | 
			
		||||
   *   array(
 | 
			
		||||
   *     'name' => 'Identity',
 | 
			
		||||
   *     'type' => 'identity'
 | 
			
		||||
   *     'endpoints' => array(
 | 
			
		||||
   *       'publicUrl' => 'https://example.hpcloud.net/1.0/123456',
 | 
			
		||||
   *       'region' => 'region-a.geo-1',
 | 
			
		||||
   *       'id' => '2.0',
 | 
			
		||||
   *       'list' => 'http://example.hpcloud.net/extension',
 | 
			
		||||
   *     ),
 | 
			
		||||
   *   )
 | 
			
		||||
   *
 | 
			
		||||
   * );
 | 
			
		||||
   * ?>
 | 
			
		||||
   * @endcode
 | 
			
		||||
   *
 | 
			
		||||
   * @todo Paging on the service catalog is not yet implemented.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   An associative array representing
 | 
			
		||||
   *   the service catalog.
 | 
			
		||||
   */
 | 
			
		||||
  public function serviceCatalog() {
 | 
			
		||||
    return $this->serviceCatalog;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function users() {
 | 
			
		||||
  /**
 | 
			
		||||
   * Get information about the currently authenticated user.
 | 
			
		||||
   *
 | 
			
		||||
   * This returns an associative array of information about the authenticated
 | 
			
		||||
   * user, including the user's username and roles.
 | 
			
		||||
   *
 | 
			
		||||
   * The returned data is structured like this:
 | 
			
		||||
   * @code
 | 
			
		||||
   * <?php
 | 
			
		||||
   * array(
 | 
			
		||||
   *   'user' => 'matthew.butcher@hp.com',
 | 
			
		||||
   *   'id' => '1234567890'
 | 
			
		||||
   *   'roles' => array(
 | 
			
		||||
   *     array(
 | 
			
		||||
   *       'name' => 'domainuser',
 | 
			
		||||
   *       'serviceId' => '100',
 | 
			
		||||
   *       'id' => '000100400010011',
 | 
			
		||||
   *     ),
 | 
			
		||||
   *     // One array for each role...
 | 
			
		||||
   *   ),
 | 
			
		||||
   * )
 | 
			
		||||
   * ?>
 | 
			
		||||
   * @endcode
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   An associative array, as described above.
 | 
			
		||||
   */
 | 
			
		||||
  public function user() {
 | 
			
		||||
    return $this->userDetails;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Given a response object, populate this object.
 | 
			
		||||
   *
 | 
			
		||||
   * This parses the JSON data and parcels out the data to the appropriate
 | 
			
		||||
   * fields.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \HPCloud\Transport\Response $response
 | 
			
		||||
   *   A response object.
 | 
			
		||||
   * @return 
 | 
			
		||||
   */
 | 
			
		||||
  protected function handleResponse($response) {
 | 
			
		||||
    $json = json_decode($response->content(), TRUE);
 | 
			
		||||
 | 
			
		||||
    $this->tokenDetails = $json['access']['token'];
 | 
			
		||||
    $this->userDetails = $json['access']['user'];
 | 
			
		||||
    $this->serviceCatalog = $json['access']['serviceCatalog'];
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,28 +9,85 @@
 | 
			
		||||
require_once 'src/HPCloud/Bootstrap.php';
 | 
			
		||||
 | 
			
		||||
use \HPCloud\Storage\ObjectStorage;
 | 
			
		||||
use \HPCloud\Services\ControlServices;
 | 
			
		||||
 | 
			
		||||
$config = array(
 | 
			
		||||
  'transport' => '\HPCloud\Transport\CURLTransport',
 | 
			
		||||
  'transport.timeout' => 240,
 | 
			
		||||
  'transport.debug' => 1,
 | 
			
		||||
  'transport.ssl.verify' => 0,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
\HPCloud\Bootstrap::useAutoloader();
 | 
			
		||||
\HPCloud\Bootstrap::setConfiguration($config);
 | 
			
		||||
 | 
			
		||||
$usage = "php {$argv[0]} ID KEY URL";
 | 
			
		||||
$help = "Authenticate against HPCloud Identity Services.
 | 
			
		||||
 | 
			
		||||
if ($argc < 4) {
 | 
			
		||||
You can authenticate either by account number and access key, or (by using the
 | 
			
		||||
-u flag) by username, password, and tenant ID.
 | 
			
		||||
 | 
			
		||||
In both cases, you must supply a URL to the Identity Services endpoint.
 | 
			
		||||
";
 | 
			
		||||
 | 
			
		||||
$usage = "php {$argv[0]} [-u] ID SECRET URL [TENANT_ID]";
 | 
			
		||||
 | 
			
		||||
if ($argc > 1 && $argv[1] == '--help') {
 | 
			
		||||
  print PHP_EOL . "\t" . $usage . PHP_EOL;
 | 
			
		||||
  print PHP_EOL . $help . PHP_EOL;
 | 
			
		||||
  exit(1);
 | 
			
		||||
}
 | 
			
		||||
elseif ($argc < 4) {
 | 
			
		||||
  print 'ID, Key, and URL are all required.' . PHP_EOL;
 | 
			
		||||
  print $usage . PHP_EOL;
 | 
			
		||||
  exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$user = $argv[1];
 | 
			
		||||
$key = $argv[2];
 | 
			
		||||
$uri = $argv[3];
 | 
			
		||||
$asUser = FALSE;
 | 
			
		||||
$offset = 0;
 | 
			
		||||
if ($argv[1] == '-u') {
 | 
			
		||||
  $asUser = TRUE;
 | 
			
		||||
  ++$offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$user = $argv[1 + $offset];
 | 
			
		||||
$key = $argv[2 + $offset];
 | 
			
		||||
$uri = $argv[3 + $offset];
 | 
			
		||||
 | 
			
		||||
if ($asUser) {
 | 
			
		||||
  if (empty($argv[4 + $offset])) {
 | 
			
		||||
    die("ERROR: Tenant ID is required as a fourth parameter." . PHP_EOL);
 | 
			
		||||
  }
 | 
			
		||||
  $tenantId = $argv[4 + $offset];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
$store = ObjectStorage::newFromSwiftAuth($user, $key, $uri);
 | 
			
		||||
 | 
			
		||||
$token = $store->token();
 | 
			
		||||
 */
 | 
			
		||||
$cs = new ControlServices($uri);
 | 
			
		||||
 | 
			
		||||
if ($asUser) {
 | 
			
		||||
  $token = $cs->authenticateAsUser($user, $key, $tenantId);
 | 
			
		||||
}
 | 
			
		||||
else {
 | 
			
		||||
  $token = $cs->authenticateAsAccount($user, $key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (empty($token)) {
 | 
			
		||||
  print "Authentication seemed to succeed, but no token was return." . PHP_EOL;
 | 
			
		||||
  exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
print "Success! The authentication token is $token." . PHP_EOL;
 | 
			
		||||
$t = "You logged in as %s with token %s (good until %s)." . PHP_EOL;
 | 
			
		||||
$tokenDetails = $cs->tokenDetails();
 | 
			
		||||
$user = $cs->user();
 | 
			
		||||
 | 
			
		||||
printf($t, $user['name'], $cs->token(), $tokenDetails['expires']);
 | 
			
		||||
 | 
			
		||||
print "The following services are available on this account:" . PHP_EOL;
 | 
			
		||||
 | 
			
		||||
$services = $cs->serviceCatalog();
 | 
			
		||||
foreach ($services as $service) {
 | 
			
		||||
  print "\t" . $service['name'] . PHP_EOL;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user