Skip to content

Commit e0f5892

Browse files
committed
ACP2E-2969: REST API unable to make requests with slash (/) in SKU when using Oauth1
1 parent f8072ac commit e0f5892

File tree

2 files changed

+47
-143
lines changed

2 files changed

+47
-143
lines changed

lib/internal/Magento/Framework/Oauth/Helper/Signature/Hmac.php

Lines changed: 21 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -7,153 +7,31 @@
77

88
namespace Magento\Framework\Oauth\Helper\Signature;
99

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;
1113

12-
class Hmac
14+
class Hmac extends HmacSignature
1315
{
1416
/**
15-
* @var string|null
17+
* @inheritDoc
1618
*/
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
15520
{
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();
15836
}
15937
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
/**
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Framework\Oauth\Helper\Uri;
9+
10+
use Laminas\Uri\Http as LaminasHttp;
11+
12+
class Http extends LaminasHttp
13+
{
14+
/**
15+
* @inheritDoc
16+
*/
17+
protected static function normalizePath($path): string
18+
{
19+
return self::encodePath(
20+
self::decodeUrlEncodedChars(
21+
self::removePathDotSegments($path),
22+
'/[' . self::CHAR_UNRESERVED . ':@&=\+\$,;%]/'
23+
)
24+
);
25+
}
26+
}

0 commit comments

Comments
 (0)