|
7 | 7 |
|
8 | 8 | namespace Magento\Framework\Oauth\Helper\Signature;
|
9 | 9 |
|
10 |
| -use Laminas\Crypt\Hmac as HMACEncryption; |
| 10 | +use Laminas\Uri; |
| 11 | +use Laminas\OAuth\Signature\Hmac as HmacSignature; |
| 12 | +use Magento\Framework\Oauth\Helper\Uri\Http; |
11 | 13 |
|
12 |
| -class Hmac |
| 14 | +class Hmac extends HmacSignature |
13 | 15 | {
|
14 | 16 | /**
|
15 |
| - * @var string|null |
| 17 | + * @inheritDoc |
16 | 18 | */
|
17 |
| - private ?string $hashAlgorithm = null; |
18 |
| - |
19 |
| - /** |
20 |
| - * @var string |
21 |
| - */ |
22 |
| - private string $key; |
23 |
| - |
24 |
| - /** |
25 |
| - * @var string |
26 |
| - */ |
27 |
| - private string $consumerSecret; |
28 |
| - |
29 |
| - /** |
30 |
| - * @var string |
31 |
| - */ |
32 |
| - private string $tokenSecret = ''; |
33 |
| - |
34 |
| - /** |
35 |
| - * @param string $consumerSecret |
36 |
| - * @param string|null $tokenSecret |
37 |
| - * @param string|null $hashAlgo |
38 |
| - */ |
39 |
| - public function __construct(string $consumerSecret, ?string $tokenSecret = null, ?string $hashAlgo = null) |
40 |
| - { |
41 |
| - $this->consumerSecret = $consumerSecret; |
42 |
| - if (isset($tokenSecret)) { |
43 |
| - $this->tokenSecret = $tokenSecret; |
44 |
| - } |
45 |
| - $this->key = $this->assembleKey(); |
46 |
| - if (isset($hashAlgo)) { |
47 |
| - $this->hashAlgorithm = $hashAlgo; |
48 |
| - } |
49 |
| - } |
50 |
| - |
51 |
| - /** |
52 |
| - * Sign a request |
53 |
| - * |
54 |
| - * @param array $params |
55 |
| - * @param mixed $method |
56 |
| - * @param mixed $url |
57 |
| - * @return string |
58 |
| - */ |
59 |
| - public function sign( |
60 |
| - array $params, |
61 |
| - ?string $method = null, |
62 |
| - ?string $url = null |
63 |
| - ): string { |
64 |
| - unset($params['oauth_signature']); |
65 |
| - |
66 |
| - $binaryHash = HMACEncryption::compute( |
67 |
| - $this->key, |
68 |
| - $this->hashAlgorithm, |
69 |
| - $this->getBaseSignatureString($params, $method, $url), |
70 |
| - HMACEncryption::OUTPUT_BINARY |
71 |
| - ); |
72 |
| - |
73 |
| - return base64_encode($binaryHash); |
74 |
| - } |
75 |
| - |
76 |
| - /** |
77 |
| - * Assemble key from consumer and token secrets |
78 |
| - * |
79 |
| - * @return string |
80 |
| - */ |
81 |
| - private function assembleKey(): string |
82 |
| - { |
83 |
| - $parts = [$this->consumerSecret]; |
84 |
| - if ($this->tokenSecret !== null) { |
85 |
| - $parts[] = $this->tokenSecret; |
86 |
| - } |
87 |
| - foreach ($parts as $key => $secret) { |
88 |
| - $parts[$key] = $this->urlEncode($secret); |
89 |
| - } |
90 |
| - return implode('&', $parts); |
91 |
| - } |
92 |
| - |
93 |
| - /** |
94 |
| - * Get base signature string |
95 |
| - * |
96 |
| - * @param array $params |
97 |
| - * @param null|string $method |
98 |
| - * @param null|string $url |
99 |
| - * @return string |
100 |
| - */ |
101 |
| - private function getBaseSignatureString(array $params, $method = null, $url = null): string |
102 |
| - { |
103 |
| - $encodedParams = []; |
104 |
| - foreach ($params as $key => $value) { |
105 |
| - $encodedParams[$this->urlEncode($key)] = |
106 |
| - $this->urlEncode($value); |
107 |
| - } |
108 |
| - $baseStrings = []; |
109 |
| - if (isset($method)) { |
110 |
| - $baseStrings[] = strtoupper($method); |
111 |
| - } |
112 |
| - if (isset($url)) { |
113 |
| - $baseStrings[] = $this->urlEncode($url); |
114 |
| - } |
115 |
| - if (isset($encodedParams['oauth_signature'])) { |
116 |
| - unset($encodedParams['oauth_signature']); |
117 |
| - } |
118 |
| - $baseStrings[] = $this->urlEncode( |
119 |
| - $this->toByteValueOrderedQueryString($encodedParams) |
120 |
| - ); |
121 |
| - |
122 |
| - return implode('&', $baseStrings); |
123 |
| - } |
124 |
| - |
125 |
| - /** |
126 |
| - * Transform an array to a byte value ordered query string |
127 |
| - * |
128 |
| - * @param array $params |
129 |
| - * @return string |
130 |
| - */ |
131 |
| - private function toByteValueOrderedQueryString(array $params): string |
132 |
| - { |
133 |
| - $return = []; |
134 |
| - uksort($params, 'strnatcmp'); |
135 |
| - foreach ($params as $key => $value) { |
136 |
| - if (is_array($value)) { |
137 |
| - natsort($value); |
138 |
| - foreach ($value as $keyduplicate) { |
139 |
| - $return[] = $key . '=' . $keyduplicate; |
140 |
| - } |
141 |
| - } else { |
142 |
| - $return[] = $key . '=' . $value; |
143 |
| - } |
144 |
| - } |
145 |
| - return implode('&', $return); |
146 |
| - } |
147 |
| - |
148 |
| - /** |
149 |
| - * URL encode a value |
150 |
| - * |
151 |
| - * @param string $value |
152 |
| - * @return string |
153 |
| - */ |
154 |
| - private function urlEncode(string $value): string |
| 19 | + public function normaliseBaseSignatureUrl($url): string |
155 | 20 | {
|
156 |
| - $encoded = rawurlencode($value); |
157 |
| - return str_replace('%7E', '~', $encoded); |
| 21 | + Uri\UriFactory::registerScheme('http', Http::class); |
| 22 | + Uri\UriFactory::registerScheme('https', Http::class); |
| 23 | + |
| 24 | + $uri = Uri\UriFactory::factory($url); |
| 25 | + $uri->normalize(); |
| 26 | + if ($uri->getScheme() == 'http' && $uri->getPort() == '80') { |
| 27 | + $uri->setPort(''); |
| 28 | + } elseif ($uri->getScheme() == 'https' && $uri->getPort() == '443') { |
| 29 | + $uri->setPort(''); |
| 30 | + } elseif (! in_array($uri->getScheme(), ['http', 'https'])) { |
| 31 | + throw new \InvalidArgumentException('Invalid URL provided; must be an HTTP or HTTPS scheme'); |
| 32 | + } |
| 33 | + $uri->setQuery(''); |
| 34 | + $uri->setFragment(''); |
| 35 | + return $uri->toString(); |
158 | 36 | }
|
159 | 37 | }
|
0 commit comments