Skip to content

Commit 1866841

Browse files
Merge branch 'magento-commerce:2.4-develop' into ACQE-4517
2 parents 26eda46 + 647b34e commit 1866841

File tree

250 files changed

+9490
-554
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

250 files changed

+9490
-554
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Authorization\Model;
10+
11+
use Magento\Framework\App\Backpressure\ContextInterface;
12+
use Magento\Framework\App\Backpressure\IdentityProviderInterface;
13+
use Magento\Framework\Exception\RuntimeException;
14+
use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
15+
16+
/**
17+
* Utilizes UserContext for backpressure identity
18+
*/
19+
class IdentityProvider implements IdentityProviderInterface
20+
{
21+
/**
22+
* User context identity type map
23+
*/
24+
private const USER_CONTEXT_IDENTITY_TYPE_MAP = [
25+
UserContextInterface::USER_TYPE_CUSTOMER => ContextInterface::IDENTITY_TYPE_CUSTOMER,
26+
UserContextInterface::USER_TYPE_ADMIN => ContextInterface::IDENTITY_TYPE_ADMIN
27+
];
28+
29+
/**
30+
* @var UserContextInterface
31+
*/
32+
private UserContextInterface $userContext;
33+
34+
/**
35+
* @var RemoteAddress
36+
*/
37+
private RemoteAddress $remoteAddress;
38+
39+
/**
40+
* @param UserContextInterface $userContext
41+
* @param RemoteAddress $remoteAddress
42+
*/
43+
public function __construct(UserContextInterface $userContext, RemoteAddress $remoteAddress)
44+
{
45+
$this->userContext = $userContext;
46+
$this->remoteAddress = $remoteAddress;
47+
}
48+
49+
/**
50+
* @inheritDoc
51+
*
52+
* @throws RuntimeException
53+
*/
54+
public function fetchIdentityType(): int
55+
{
56+
if (!$this->userContext->getUserId()) {
57+
return ContextInterface::IDENTITY_TYPE_IP;
58+
}
59+
60+
$userType = $this->userContext->getUserType();
61+
if (isset(self::USER_CONTEXT_IDENTITY_TYPE_MAP[$userType])) {
62+
return self::USER_CONTEXT_IDENTITY_TYPE_MAP[$userType];
63+
}
64+
65+
throw new RuntimeException(__('User type not defined'));
66+
}
67+
68+
/**
69+
* @inheritDoc
70+
*
71+
* @throws RuntimeException
72+
*/
73+
public function fetchIdentity(): string
74+
{
75+
$userId = $this->userContext->getUserId();
76+
if ($userId) {
77+
return (string)$userId;
78+
}
79+
80+
$address = $this->remoteAddress->getRemoteAddress();
81+
if (!$address) {
82+
throw new RuntimeException(__('Failed to extract remote address'));
83+
}
84+
85+
return $address;
86+
}
87+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Authorization\Test\Unit\Model;
10+
11+
use Magento\Authorization\Model\IdentityProvider;
12+
use Magento\Authorization\Model\UserContextInterface;
13+
use Magento\Framework\App\Backpressure\ContextInterface;
14+
use Magento\Framework\Exception\RuntimeException;
15+
use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
16+
use PHPUnit\Framework\MockObject\MockObject;
17+
use PHPUnit\Framework\TestCase;
18+
19+
/**
20+
* Tests the IdentityProvider class
21+
*/
22+
class IdentityProviderTest extends TestCase
23+
{
24+
/**
25+
* @var UserContextInterface|MockObject
26+
*/
27+
private $userContext;
28+
29+
/**
30+
* @var RemoteAddress|MockObject
31+
*/
32+
private $remoteAddress;
33+
34+
/**
35+
* @var IdentityProvider
36+
*/
37+
private $model;
38+
39+
/**
40+
* @inheritDoc
41+
*/
42+
protected function setUp(): void
43+
{
44+
parent::setUp();
45+
46+
$this->userContext = $this->createMock(UserContextInterface::class);
47+
$this->remoteAddress = $this->createMock(RemoteAddress::class);
48+
$this->model = new IdentityProvider($this->userContext, $this->remoteAddress);
49+
}
50+
51+
/**
52+
* Cases for identity provider.
53+
*
54+
* @return array
55+
*/
56+
public function getIdentityCases(): array
57+
{
58+
return [
59+
'empty-user-context' => [null, null, '127.0.0.1', ContextInterface::IDENTITY_TYPE_IP, '127.0.0.1'],
60+
'guest-user-context' => [
61+
UserContextInterface::USER_TYPE_GUEST,
62+
null,
63+
'127.0.0.1',
64+
ContextInterface::IDENTITY_TYPE_IP,
65+
'127.0.0.1'
66+
],
67+
'admin-user-context' => [
68+
UserContextInterface::USER_TYPE_ADMIN,
69+
42,
70+
'127.0.0.1',
71+
ContextInterface::IDENTITY_TYPE_ADMIN,
72+
'42'
73+
],
74+
'customer-user-context' => [
75+
UserContextInterface::USER_TYPE_CUSTOMER,
76+
42,
77+
'127.0.0.1',
78+
ContextInterface::IDENTITY_TYPE_CUSTOMER,
79+
'42'
80+
],
81+
];
82+
}
83+
84+
/**
85+
* Verify identity provider.
86+
*
87+
* @param int|null $userType
88+
* @param int|null $userId
89+
* @param string $remoteAddr
90+
* @param int $expectedType
91+
* @param string $expectedIdentity
92+
* @return void
93+
* @dataProvider getIdentityCases
94+
*/
95+
public function testFetchIdentity(
96+
?int $userType,
97+
?int $userId,
98+
string $remoteAddr,
99+
int $expectedType,
100+
string $expectedIdentity
101+
): void {
102+
$this->userContext->method('getUserType')->willReturn($userType);
103+
$this->userContext->method('getUserId')->willReturn($userId);
104+
$this->remoteAddress->method('getRemoteAddress')->willReturn($remoteAddr);
105+
106+
$this->assertEquals($expectedType, $this->model->fetchIdentityType());
107+
$this->assertEquals($expectedIdentity, $this->model->fetchIdentity());
108+
}
109+
110+
/**
111+
* Tests fetching an identity type when user type can't be defined
112+
*/
113+
public function testFetchIdentityTypeUserTypeNotDefined()
114+
{
115+
$this->userContext->method('getUserId')->willReturn(2);
116+
$this->userContext->method('getUserType')->willReturn(null);
117+
$this->expectException(RuntimeException::class);
118+
$this->expectExceptionMessage(__('User type not defined')->getText());
119+
$this->model->fetchIdentityType();
120+
}
121+
122+
/**
123+
* Tests fetching an identity when user address can't be extracted
124+
*/
125+
public function testFetchIdentityFailedToExtractRemoteAddress()
126+
{
127+
$this->userContext->method('getUserId')->willReturn(null);
128+
$this->remoteAddress->method('getRemoteAddress')->willReturn(false);
129+
$this->expectException(RuntimeException::class);
130+
$this->expectExceptionMessage(__('Failed to extract remote address')->getText());
131+
$this->model->fetchIdentity();
132+
}
133+
}

app/code/Magento/Authorization/etc/di.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@
2424
</arguments>
2525
</type>
2626
<preference for="Magento\Authorization\Model\UserContextInterface" type="Magento\Authorization\Model\CompositeUserContext"/>
27+
<preference for="Magento\Framework\App\Backpressure\IdentityProviderInterface"
28+
type="Magento\Authorization\Model\IdentityProvider"/>
2729
</config>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
"We can't find the role for the user you wanted.","We can't find the role for the user you wanted."
22
"Something went wrong while compiling a list of allowed resources. You can find out more in the exceptions log.","Something went wrong while compiling a list of allowed resources. You can find out more in the exceptions log."
3+
"User type not defined","User type not defined"
4+
"Failed to extract remote address","Failed to extract remote address"

0 commit comments

Comments
 (0)