Skip to content

Commit c76716f

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

File tree

5 files changed

+83
-49
lines changed

5 files changed

+83
-49
lines changed

dev/tests/api-functional/framework/Magento/TestFramework/Authentication/Rest/OauthClient.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use Magento\Framework\Oauth\Helper\Utility;
1010
use Magento\TestFramework\Helper\Bootstrap;
11+
use Magento\TestFramework\ObjectManager;
1112
use OAuth\Common\Consumer\Credentials;
1213
use OAuth\Common\Http\Client\ClientInterface;
1314
use OAuth\Common\Http\Exception\TokenResponseException;
@@ -19,7 +20,7 @@
1920
use OAuth\OAuth1\Token\StdOAuth1Token;
2021
use OAuth\OAuth1\Token\TokenInterface;
2122
use Laminas\OAuth\Http\Utility as HTTPUtility;
22-
use Magento\Framework\Oauth\Helper\Signature\Hmac256;
23+
use Magento\Framework\Oauth\Helper\Signature\HmacFactory;
2324

2425
/**
2526
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -58,7 +59,7 @@ public function __construct(
5859
$storage = new \OAuth\Common\Storage\Memory();
5960
}
6061
if (!isset($helper)) {
61-
$helper = new Utility(new HTTPUtility(), new Hmac256());
62+
$helper = new Utility(new HTTPUtility(), new HmacFactory(ObjectManager::getInstance()));
6263
}
6364
if (!isset($signature)) {
6465
$signature = new \Magento\TestFramework\Authentication\Rest\OauthClient\Signature($helper, $credentials);

lib/internal/Magento/Framework/Oauth/Helper/Signature/Hmac256.php renamed to lib/internal/Magento/Framework/Oauth/Helper/Signature/Hmac.php

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,63 @@
99

1010
use Laminas\Crypt\Hmac as HMACEncryption;
1111

12-
class Hmac256
12+
class Hmac
1313
{
14+
/**
15+
* @var string|null
16+
*/
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+
1451
/**
1552
* Sign a request
1653
*
1754
* @param array $params
18-
* @param string $algo
19-
* @param string $consumerSecret
20-
* @param string|null $tokenSecret
2155
* @param mixed $method
2256
* @param mixed $url
2357
* @return string
2458
*/
2559
public function sign(
2660
array $params,
27-
string $algo,
28-
string $consumerSecret,
29-
?string $tokenSecret = null,
3061
?string $method = null,
3162
?string $url = null
3263
): string {
3364
unset($params['oauth_signature']);
3465

3566
$binaryHash = HMACEncryption::compute(
36-
$this->assembleKey($consumerSecret, $tokenSecret),
37-
$algo,
67+
$this->key,
68+
$this->hashAlgorithm,
3869
$this->getBaseSignatureString($params, $method, $url),
3970
HMACEncryption::OUTPUT_BINARY
4071
);
@@ -45,20 +76,17 @@ public function sign(
4576
/**
4677
* Assemble key from consumer and token secrets
4778
*
48-
* @param string $consumerSecret
49-
* @param string|null $tokenSecret
5079
* @return string
5180
*/
52-
private function assembleKey(string $consumerSecret, ?string $tokenSecret): string
81+
private function assembleKey(): string
5382
{
54-
$parts = [$consumerSecret];
55-
if ($tokenSecret !== null) {
56-
$parts[] = $tokenSecret;
83+
$parts = [$this->consumerSecret];
84+
if ($this->tokenSecret !== null) {
85+
$parts[] = $this->tokenSecret;
5786
}
5887
foreach ($parts as $key => $secret) {
5988
$parts[$key] = $this->urlEncode($secret);
6089
}
61-
6290
return implode('&', $parts);
6391
}
6492

lib/internal/Magento/Framework/Oauth/Helper/Utility.php

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@
88
namespace Magento\Framework\Oauth\Helper;
99

1010
use Laminas\OAuth\Http\Utility as LaminasUtility;
11-
use Magento\Framework\Oauth\Helper\Signature\Hmac256;
11+
use Magento\Framework\Oauth\Helper\Signature\Hmac;
12+
use Magento\Framework\Oauth\Helper\Signature\HmacFactory;
1213

1314
class Utility
1415
{
1516
/**
1617
* @param LaminasUtility $httpUtility
17-
* @param Hmac256 $hmac256
18+
* @param HmacFactory $hmacFactory
1819
*/
19-
public function __construct(private readonly LaminasUtility $httpUtility, private readonly Hmac256 $hmac256)
20+
public function __construct(private readonly LaminasUtility $httpUtility, private readonly HmacFactory $hmacFactory)
2021
{
2122
}
2223

@@ -40,7 +41,10 @@ public function sign(
4041
?string $url = null
4142
): string {
4243
if ($this->isHmac256($signatureMethod)) {
43-
return $this->hmac256->sign($params, 'sha256', $consumerSecret, $tokenSecret, $method, $url);
44+
/** @var Hmac $hmac */
45+
$hmac = $this->hmacFactory->create(['consumerSecret' => $consumerSecret, 'tokenSecret' => $tokenSecret, 'hashAlgo' => 'sha256']);
46+
47+
return $hmac->sign($params, $method, $url);
4448
} else {
4549
return $this->httpUtility->sign($params, $signatureMethod, $consumerSecret, $tokenSecret, $method, $url);
4650
}
@@ -65,22 +69,12 @@ private function isHmac256(string $signatureMethod): bool
6569
* Cast to authorization header
6670
*
6771
* @param array $params
72+
* @param string|null $realm
6873
* @param bool $excludeCustomParams
69-
* @return string
7074
*/
71-
public function toAuthorizationHeader(array $params, bool $excludeCustomParams = true): string
75+
public function toAuthorizationHeader(array $params, ?string $realm = null, bool $excludeCustomParams = true)
7276
{
73-
$headerValue = [];
74-
foreach ($params as $key => $value) {
75-
if ($excludeCustomParams) {
76-
if (! preg_match("/^oauth_/", $key)) {
77-
continue;
78-
}
79-
}
80-
$headerValue[] = $this->httpUtility::urlEncode((string)$key)
81-
. '="'
82-
. $this->httpUtility::urlEncode((string)$value) . '"';
83-
}
84-
return 'OAuth ' . implode(",", $headerValue);
77+
$authorizationHeader = $this->httpUtility->toAuthorizationHeader($params, $realm, $excludeCustomParams);
78+
return str_replace('realm="",', '', $authorizationHeader);
8579
}
8680
}

lib/internal/Magento/Framework/Oauth/Oauth.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Oauth implements OauthInterface
3434
/**
3535
* @var Utility
3636
*/
37-
private Utility $hmacSignatureHelper;
37+
private Utility $httpUtility;
3838

3939
/**
4040
* @param Helper\Oauth $oauthHelper
@@ -51,7 +51,7 @@ public function __construct(
5151
$this->_oauthHelper = $oauthHelper;
5252
$this->_nonceGenerator = $nonceGenerator;
5353
$this->_tokenProvider = $tokenProvider;
54-
$this->hmacSignatureHelper = $utility;
54+
$this->httpUtility = $utility;
5555
}
5656

5757
/**
@@ -154,7 +154,7 @@ public function buildAuthorizationHeader(
154154
'oauth_version' => '1.0',
155155
];
156156
$headerParameters = array_merge($headerParameters, $params);
157-
$headerParameters['oauth_signature'] = $this->hmacSignatureHelper->sign(
157+
$headerParameters['oauth_signature'] = $this->httpUtility->sign(
158158
$params,
159159
$signatureMethod,
160160
$headerParameters['oauth_consumer_secret'],
@@ -163,7 +163,7 @@ public function buildAuthorizationHeader(
163163
$requestUrl
164164
);
165165

166-
return $this->hmacSignatureHelper->toAuthorizationHeader($headerParameters);
166+
return $this->httpUtility->toAuthorizationHeader($headerParameters);
167167
}
168168

169169
/**
@@ -188,7 +188,7 @@ protected function _validateSignature($params, $consumerSecret, $httpMethod, $re
188188
);
189189
}
190190

191-
$calculatedSign = $this->hmacSignatureHelper->sign(
191+
$calculatedSign = $this->httpUtility->sign(
192192
$params,
193193
$params['oauth_signature_method'],
194194
$consumerSecret,

lib/internal/Magento/Framework/Oauth/Test/Unit/Helper/UtilityTest.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99

1010
use Magento\Framework\Oauth\Helper\Utility as OauthUtility;
1111
use Laminas\OAuth\Http\Utility as LaminasUtility;
12-
use Magento\Framework\Oauth\Helper\Signature\Hmac256;
12+
use Magento\Framework\Oauth\Helper\Signature\Hmac;
13+
use Magento\Framework\Oauth\Helper\Signature\HmacFactory;
1314
use PHPUnit\Framework\MockObject\MockObject;
1415
use PHPUnit\Framework\TestCase;
1516

@@ -21,14 +22,20 @@ class UtilityTest extends TestCase
2122
private LaminasUtility $httpUtility;
2223

2324
/**
24-
* @var Hmac256|MockObject
25+
* @var Hmac|MockObject
2526
*/
26-
private Hmac256 $hmac256;
27+
private Hmac $hmac;
28+
29+
/**
30+
* @var HmacFactory|MockObject
31+
*/
32+
private HmacFactory $hmacFactory;
2733

2834
protected function setUp(): void
2935
{
3036
$this->httpUtility = $this->createMock(LaminasUtility::class);
31-
$this->hmac256 = $this->createMock(Hmac256::class);
37+
$this->hmac = $this->createMock(Hmac::class);
38+
$this->hmacFactory = $this->createMock(HmacFactory::class);
3239
}
3340

3441
/**
@@ -45,12 +52,16 @@ public function testSignMethodUsesHmac256WhenSignatureMethodIsHmacSha256(): void
4552

4653
$expectedSignature = 'expectedSignature';
4754

48-
$this->hmac256->expects($this->once())
55+
$this->hmac->expects($this->once())
4956
->method('sign')
50-
->with($params, 'sha256', $consumerSecret, $tokenSecret, $method, $url)
57+
->with($params, $method, $url)
5158
->willReturn($expectedSignature);
59+
$this->hmacFactory->expects($this->once())
60+
->method('create')
61+
->with(['consumerSecret' => $consumerSecret, 'tokenSecret' => $tokenSecret, 'hashAlgo' => 'sha256'])
62+
->willReturn($this->hmac);
5263

53-
$utility = new OauthUtility($this->httpUtility, $this->hmac256);
64+
$utility = new OauthUtility($this->httpUtility, $this->hmacFactory);
5465

5566
$signature = $utility->sign($params, $signatureMethod, $consumerSecret, $tokenSecret, $method, $url);
5667

@@ -76,7 +87,7 @@ public function testSignMethodUsesLaminasUtilityWhenSignatureMethodIsRsa(): void
7687
->with($params, $signatureMethod, $consumerSecret, $tokenSecret, $method, $url)
7788
->willReturn($expectedSignature);
7889

79-
$utility = new OauthUtility($this->httpUtility, $this->hmac256);
90+
$utility = new OauthUtility($this->httpUtility, $this->hmacFactory);
8091

8192
$signature = $utility->sign($params, $signatureMethod, $consumerSecret, $tokenSecret, $method, $url);
8293

0 commit comments

Comments
 (0)