Elgg  Version 5.1
UrlSigner.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Security;
4 
7 
13 class UrlSigner {
14 
15  const KEY_MAC = '__elgg_mac';
16  const KEY_EXPIRES = '__elgg_exp';
17 
30  public function sign(string $url, string $expires = null): string {
31  $url = elgg_normalize_url($url);
32 
33  $parts = parse_url($url);
34 
35  if (isset($parts['query'])) {
36  $query = elgg_parse_str($parts['query']);
37  } else {
38  $query = [];
39  }
40 
41  if (isset($query[self::KEY_MAC])) {
42  throw new InvalidArgumentException('URL has already been signed');
43  }
44 
45  if (!empty($expires)) {
46  $query[self::KEY_EXPIRES] = strtotime($expires);
47  }
48 
49  ksort($query);
50 
51  $parts['query'] = http_build_query($query);
52 
53  $url = elgg_http_build_url($parts, false);
54 
55  $token = elgg_build_hmac($url)->getToken();
56 
58  self::KEY_MAC => $token,
59  ]);
60  }
61 
68  public function isValid(string $url): bool {
69 
70  $parts = parse_url($url);
71 
72  if (isset($parts['query'])) {
73  $query = elgg_parse_str($parts['query']);
74  } else {
75  $query = [];
76  }
77 
78  if (!isset($query[self::KEY_MAC])) {
79  // No signature found
80  return false;
81  }
82 
83  $token = $query[self::KEY_MAC];
84  unset($query[self::KEY_MAC]);
85 
86  if (isset($query[self::KEY_EXPIRES]) && $query[self::KEY_EXPIRES] < time()) {
87  // Signature has expired
88  return false;
89  }
90 
91  ksort($query);
92 
93  $parts['query'] = http_build_query($query);
94 
95  $url = elgg_http_build_url($parts, false);
96 
97  return elgg_build_hmac($url)->matchesToken($token);
98  }
99 
108  public function assertValid($url) {
109  if (!$this->isValid($url)) {
110  throw new HttpException(elgg_echo('invalid_request_signature'), ELGG_HTTP_FORBIDDEN);
111  }
112  }
113 }
elgg_parse_str($str)
Elgg UTF-8 string functions.
Definition: mb_wrapper.php:16
const ELGG_HTTP_FORBIDDEN
Definition: constants.php:67
Exception thrown if an argument is not of the expected type.
sign(string $url, string $expires=null)
Normalizes and signs the URL with SHA256 HMAC key.
Definition: UrlSigner.php:30
elgg_echo(string $message_key, array $args=[], string $language= '')
Elgg language module Functions to manage language and translations.
Definition: languages.php:17
elgg parse_url
Parse a URL into its parts.
Definition: elgglib.js:139
assertValid($url)
Assert that an url is signed correctly.
Definition: UrlSigner.php:108
elgg_http_build_url(array $parts, bool $html_encode=true)
Builds a URL from the a parts array like one returned by parse_url().
Definition: elgglib.php:131
elgg_http_add_url_query_elements(string $url, array $elements)
Sets elements in a URL&#39;s query string.
Definition: elgglib.php:181
$expires
$token
Generic HTTP exception.
Component for creating signed URLs.
Definition: UrlSigner.php:13
isValid(string $url)
Validates HMAC signature.
Definition: UrlSigner.php:68
$query
foreach($plugin_guids as $guid) if(empty($deactivated_plugins)) $url
Definition: deactivate.php:39
elgg_normalize_url(string $url)
Definition: output.php:163
elgg_build_hmac($data)
Get an HMAC token builder/validator object.
Definition: actions.php:56