|
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