Source of file Authentication.php
Size: 12,608 Bytes - Last Modified: 2016-08-28T19:38:31+00:00
/Users/dshafik/src/akamai-open/edgegrid-auth-php/src/Authentication.php
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
Covered by 45 test(s):
83
Covered by 2 test(s):
848586
Covered by 45 test(s):
87
Covered by 1 test(s):
888990
Covered by 44 test(s):
91
Covered by 2 test(s):
9293949596
Covered by 44 test(s):
97
Covered by 44 test(s):
98
Covered by 44 test(s):
99
Covered by 44 test(s):
100101
Covered by 44 test(s):
102103104105106107108109110111112
Covered by 46 test(s):
113
Covered by 46 test(s):
114115116117118119120121122123
Covered by 5 test(s):
124125126127128129130131132133134
Covered by 65 test(s):
135
Covered by 65 test(s):
136
Covered by 15 test(s):
137
Covered by 10 test(s):
138139
Covered by 15 test(s):
140
Covered by 15 test(s):
141142
Covered by 15 test(s):
143
Covered by 10 test(s):
144145146
Covered by 15 test(s):
147
Covered by 1 test(s):
148
Covered by 1 test(s):
149150
Covered by 1 test(s):
151152153154
Covered by 65 test(s):
155156157158159160161162163164165166167168
Covered by 1 test(s):
169
Covered by 1 test(s):
170171172173174175176177178179180181182183
Covered by 45 test(s):
184
Covered by 32 test(s):
185
Covered by 32 test(s):
186
Covered by 32 test(s):
187188
Covered by 45 test(s):
189
Covered by 45 test(s):
190191192193194195196197198199200
Covered by 42 test(s):
201
Covered by 42 test(s):
202203204205206207208209210211212
Covered by 43 test(s):
213
Covered by 43 test(s):
214215216217218219220221222223224
Covered by 57 test(s):
225226
Covered by 57 test(s):
227
Covered by 57 test(s):
228
Covered by 1 test(s):
229230231
Covered by 57 test(s):
232
Covered by 2 test(s):
233234
Covered by 57 test(s):
235236237238239240241242243244245246247248249250
Covered by 90 test(s):
251
Covered by 90 test(s):
252
Covered by 47 test(s):
253254
Covered by 90 test(s):
255256257258259260261262263264265
Covered by 43 test(s):
266
Covered by 43 test(s):
267
Covered by 1 test(s):
268269
Covered by 43 test(s):
270271272273274275276277278279280
Covered by 43 test(s):
281
Covered by 43 test(s):
282283284285286287288289290291292
Covered by 56 test(s):
293
Covered by 56 test(s):
294295296297298299300301302303304305306
Covered by 73 test(s):
307
Covered by 73 test(s):
308309310311312
Covered by 17 test(s):
313
Covered by 7 test(s):
314315316
Covered by 17 test(s):
317318
Covered by 15 test(s):
319
Covered by 1 test(s):
320321322
Covered by 14 test(s):
323
Covered by 14 test(s):
324
Covered by 14 test(s):
325
Covered by 14 test(s):
326
Covered by 14 test(s):
327328329
Covered by 14 test(s):
330
Covered by 14 test(s):
331332333
Covered by 14 test(s):
334
Covered by 14 test(s):
335336337
Covered by 14 test(s):
338339340341342343344345346347
Covered by 45 test(s):
348
Covered by 45 test(s):
349
Covered by 45 test(s):
350
Covered by 43 test(s):
351
Covered by 43 test(s):
352
Covered by 43 test(s):
353354355356
Covered by 45 test(s):
357
Covered by 43 test(s):
358
Covered by 43 test(s):
359
Covered by 16 test(s):
360
Covered by 11 test(s):
361
Covered by 6 test(s):
362
Covered by 1 test(s):
363364
Covered by 5 test(s):
365366367
Covered by 16 test(s):
368
Covered by 43 test(s):
369370371372373
Covered by 45 test(s):
374
Covered by 45 test(s):
375
Covered by 45 test(s):
376
Covered by 16 test(s):
377378379
Covered by 45 test(s):
380381382383384385386387388389390391
Covered by 44 test(s):
392
Covered by 44 test(s):
393394395396397398399400401402403
Covered by 9 test(s):
404
Covered by 9 test(s):
405406407408409410411412413414
Covered by 15 test(s):
415
Covered by 6 test(s):
416417418
Covered by 9 test(s):
419420421422423424425426427428429430
Covered by 44 test(s):
431
Covered by 44 test(s):
432
Covered by 6 test(s):
433
Covered by 6 test(s):
434
Covered by 5 test(s):
435436
Covered by 1 test(s):
437438439440441
Covered by 44 test(s):
442
Covered by 44 test(s):
443
Covered by 44 test(s):
444
Covered by 44 test(s):
445
Covered by 44 test(s):
446
Covered by 44 test(s):
447
Covered by 44 test(s):
448449450
Covered by 44 test(s):
451452453454455456457458459460
Covered by 44 test(s):
461
Covered by 44 test(s):
462463464465466467468469470471472
Covered by 44 test(s):
473
Covered by 44 test(s):
474
Covered by 44 test(s):
475476477478479480481482483484485486487
Covered by 17 test(s):
488
Covered by 7 test(s):
489
Covered by 6 test(s):
490
Covered by 1 test(s):
491
Covered by 1 test(s):
492493494495
Covered by 17 test(s):
496
Covered by 17 test(s):
497
Covered by 1 test(s):
498499500
Covered by 16 test(s):
501
Covered by 1 test(s):
502503504505
Covered by 15 test(s):
506
Covered by 15 test(s):
507508
Covered by 15 test(s):
509510
Covered by 15 test(s):
511512513
| <?php /** * Akamai {OPEN} EdgeGrid Auth for PHP * * Provides Request Signing as per * {@see https://developer.akamai.com/introduction/Client_Auth.html} * * @author Davey Shafik <dshafik@akamai.com> * @copyright Copyright 2015 Akamai Technologies, Inc. All rights reserved. * @license Apache 2.0 * @link https://github.com/akamai-open/edgegrid-auth-php * @link https://developer.akamai.com * @link https://developer.akamai.com/introduction/Client_Auth.html */ namespace Akamai\Open\EdgeGrid; use Akamai\Open\EdgeGrid\Authentication\Nonce; use Akamai\Open\EdgeGrid\Authentication\Timestamp; use Akamai\Open\EdgeGrid\Exception\ConfigException; use Akamai\Open\EdgeGrid\Exception\SignerException\InvalidSignDataException; /** * Akamai {OPEN} EdgeGrid Request Signer * * @package Akamai {OPEN} EdgeGrid Auth */ class Authentication { /** * @var array Authentication tokens */ protected $auth; /** * @var string HTTP method */ protected $httpMethod; /** * @var string HTTP host */ protected $host; /** * @var array Guzzle config */ protected $config = array(); /** * @var string Request path */ protected $path; /** * @var Timestamp Request timestamp */ protected $timestamp; /** * @var Nonce Request nonce */ protected $nonce; /** * @var int Maximum body size for signing */ protected $max_body_size = 131072; /** * @var array A list of headers to be included in the signature */ protected $headers_to_sign = array(); /** * Create the Authentication header * * @return string * @link https://developer.akamai.com/introduction/Client_Auth.html */ public function createAuthHeader() { if ($this->timestamp === null) { $this->setTimestamp(); } if (!$this->timestamp->isValid()) { throw new InvalidSignDataException("Timestamp is invalid. Too old?"); } if ($this->nonce === null) { $this->nonce = new Nonce(); } $auth_header = 'EG1-HMAC-SHA256 ' . 'client_token=' . $this->auth['client_token'] . ';' . 'access_token=' . $this->auth['access_token'] . ';' . 'timestamp=' . $this->timestamp . ';' . 'nonce=' . $this->nonce . ';'; return $auth_header . 'signature=' . $this->signRequest($auth_header); } /** * Set request HTTP method * * @param string $method * @return Authentication */ public function setHttpMethod($method) { $this->httpMethod = $method; return $this; } /** * Get the request host * * @return string */ public function getHost() { return $this->host; } /** * Set request host * * @param mixed $host * @return Authentication */ public function setHost($host) { $this->host = $host; if (strpos($host, '/') !== false || strpos($host, '?') !== false) { if (strpos($host, 'http') === false) { $host = 'https://' . $host; } $url = parse_url($host); $this->host = $url['host']; if (isset($url['path'])) { $this->setPath($url['path']); } if (isset($url['query'])) { if (!isset($url['path'])) { // for example.org?query=string $this->setPath('/'); } $this->setQuery($url['query']); } } return $this; } /** * Set Guzzle config * * This is a convenient way to pass in the * body/query/headers options * * @param mixed $config * @return Authentication */ public function setConfig(array $config) { $this->config = array_merge($this->config, $config); return $this; } /** * Set GET args * * If setting to a string, you MUST encode using RFC3986 * {@see http_build_query()} * * @param array|string $query * @return $this */ public function setQuery($query, $ensure_encoding = true) { if (is_string($query) && $ensure_encoding) { $query_args = array(); parse_str($query, $query_args); $query = http_build_query($query_args, null, '&', PHP_QUERY_RFC3986); } $this->config['query'] = $query; return $this; } /** * Set request body * * @param string $body * return $this; */ public function setBody($body) { $this->config['body'] = $body; return $this; } /** * Set request headers * * @param array $headers * @return $this */ public function setHeaders(array $headers) { $this->config['headers'] = $headers; return $this; } /** * Set request path * * @param mixed $path * @return $this */ public function setPath($path) { $url = parse_url($path); $this->path = $url['path']; if (isset($url['host'])) { $this->setHost($url['host']); } if (isset($url['query'])) { $this->setQuery($url['query']); } return $this; } public function getPath() { return $this->path; } /** * Set signing timestamp * * @param mixed $timestamp * @return $this */ public function setTimestamp($timestamp = null) { $this->timestamp = $timestamp; if ($timestamp === null) { $this->timestamp = new Timestamp(); } return $this; } /** * Set signing nonce * * @param Nonce $nonce * @return $this */ public function setNonce($nonce = null) { $this->nonce = $nonce; if ($nonce === null) { $this->nonce = new Nonce(); } return $this; } /** * Set headers to sign * * @param array $headers_to_sign * @return $this */ public function setHeadersToSign($headers_to_sign) { $this->headers_to_sign = $headers_to_sign; return $this; } /** * Set max body size to sign * * @param int $max_body_size Size (in bytes) * @return $this */ public function setMaxBodySize($max_body_size) { $this->max_body_size = $max_body_size; return $this; } /** * Set Akamai EdgeGrid Authentication Tokens/Secret * * @param string $client_token * @param string $client_secret * @param string $access_token * @return $this */ public function setAuth($client_token, $client_secret, $access_token) { $this->auth = compact('client_token', 'client_secret', 'access_token'); return $this; } public static function createFromEdgeRcFile($section = "default", $path = null) { if ($section === null) { $section = 'default'; } $ini = self::parseEdgeRcFile($path); if (!isset($ini[$section])) { throw new ConfigException("Section \"$section\" does not exist!"); } $auth = new static(); $auth->setAuth( $ini[$section]['client_token'], $ini[$section]['client_secret'], $ini[$section]['access_token'] ); if (isset($ini[$section]['host'])) { $auth->setHost($ini[$section]['host']); } if (isset($ini[$section]['max-size'])) { $auth->setMaxBodySize($ini[$section]['max-size']); } return $auth; } /** * Returns headers in normalized form * * @return string */ protected function canonicalizeHeaders() { $canonical = array(); $headers = array(); if (isset($this->config['headers'])) { $headers = array_combine( array_map('strtolower', array_keys($this->config['headers'])), array_values($this->config['headers']) ); } foreach ($this->headers_to_sign as $key) { $key = strtolower($key); if (isset($headers[$key])) { if (is_array($headers[$key]) && sizeof($headers[$key]) >= 1) { $value = trim($headers[$key][0]); } elseif (is_array($headers[$key]) && sizeof($headers[$key]) == 0) { continue; } else { $value = trim($headers[$key]); } if (!empty($value)) { $canonical[$key] = preg_replace('/\s+/', ' ', $value); } } } ksort($canonical); $serialized_header = ''; foreach ($canonical as $key => $value) { $serialized_header .= $key . ':' . $value . "\t"; } return rtrim($serialized_header); } /** * Returns Base64 encoded HMAC-SHA256 Hash * * @param string $data * @param string $key * @return string */ protected function makeBase64HmacSha256($data, $key) { $hash = base64_encode(hash_hmac('sha256', (string) $data, $key, true)); return $hash; } /** * Returns Base64 encoded SHA256 Hash * * @param string $data * @return string */ protected function makeBase64Sha256($data) { $hash = base64_encode(hash('sha256', (string) $data, true)); return $hash; } /** * Returns a hash of the HTTP POST body * * @return string */ protected function makeContentHash() { if (empty($this->config['body'])) { return ''; } else { // Just substr, it'll return as much as it can return $this->makeBase64Sha256(substr($this->config['body'], 0, $this->max_body_size)); } } /** * Returns a string with all data that will be signed * * @param string $auth_header * @return string */ protected function makeDataToSign($auth_header) { $query = ''; if (isset($this->config['query']) && $this->config['query']) { $query .= '?'; if (is_string($this->config['query'])) { $query .= $this->config['query']; } else { $query .= http_build_query($this->config['query'], null, '&', PHP_QUERY_RFC3986); } } $data = array( strtoupper($this->httpMethod), 'https', $this->host, $this->path . $query, $this->canonicalizeHeaders(), (strtoupper($this->httpMethod) == 'POST') ? $this->makeContentHash() : '', $auth_header ); return implode("\t", $data); } /** * Creates a signing key based on the secret and timestamp * * @return string */ protected function makeSigningKey() { $key = self::makeBase64HmacSha256((string) ($this->timestamp), $this->auth['client_secret']); return $key; } /** * Returns a signature of the given request, timestamp and auth_header * * @param string $auth_header * @return string */ protected function signRequest($auth_header) { return $this->makeBase64HmacSha256( $this->makeDataToSign($auth_header), $this->makeSigningKey() ); } /** * Parse a .edgerc File * * @param $path * @return array * @throws \Exception */ protected static function parseEdgeRcFile($path) { if ($path === null) { if (isset($_SERVER['HOME']) && file_exists($_SERVER['HOME'] . '/.edgerc')) { $path = $_SERVER['HOME'] . "/.edgerc"; } elseif (file_exists('./.edgerc')) { $path = './.edgerc'; } } $file = !$path ? false : realpath($path); if (!$file) { throw new ConfigException("Path to .edgerc file \"$path\" does not exist!"); } if (!is_readable($file)) { throw new ConfigException("Unable to read .edgerc file!"); } // Handle : assignments in .edgerc files $ini = file_get_contents($file); $ini = str_replace(':', '=', $ini); $ini = parse_ini_string($ini, true, INI_SCANNER_RAW); return $ini; } } |