diff --git a/vendor/magento/module-customer/Model/AccountManagement.php b/vendor/magento/module-customer/Model/AccountManagement.php index 08587deee2a7..3719cb61cede 100644 --- a/vendor/magento/module-customer/Model/AccountManagement.php +++ b/vendor/magento/module-customer/Model/AccountManagement.php @@ -877,11 +877,6 @@ public function getConfirmationStatus($customerId) */ public function createAccount(CustomerInterface $customer, $password = null, $redirectUrl = '') { - $groupId = $customer->getGroupId(); - if (isset($groupId) && !$this->authorization->isAllowed(self::ADMIN_RESOURCE)) { - $customer->setGroupId(null); - } - if ($password !== null) { $this->checkPasswordStrength($password); $customerEmail = $customer->getEmail(); diff --git a/vendor/magento/module-customer/Model/AccountManagementApi.php b/vendor/magento/module-customer/Model/AccountManagementApi.php index 02a05705b57e..8b4f78ab26c7 100644 --- a/vendor/magento/module-customer/Model/AccountManagementApi.php +++ b/vendor/magento/module-customer/Model/AccountManagementApi.php @@ -6,16 +6,127 @@ namespace Magento\Customer\Model; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Customer\Api\CustomerMetadataInterface; +use Magento\Customer\Api\CustomerRepositoryInterface; use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Customer\Api\Data\ValidationResultsInterfaceFactory; +use Magento\Customer\Helper\View as CustomerViewHelper; +use Magento\Customer\Model\Config\Share as ConfigShare; +use Magento\Customer\Model\Customer as CustomerModel; +use Magento\Customer\Model\Metadata\Validator; +use Magento\Framework\Api\ExtensibleDataObjectConverter; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\AuthorizationInterface; +use Magento\Framework\DataObjectFactory as ObjectFactory; +use Magento\Framework\Encryption\EncryptorInterface as Encryptor; +use Magento\Framework\Event\ManagerInterface; +use Magento\Framework\Exception\AuthorizationException; +use Magento\Framework\Mail\Template\TransportBuilder; +use Magento\Framework\Math\Random; +use Magento\Framework\Reflection\DataObjectProcessor; +use Magento\Framework\Registry; +use Magento\Framework\Stdlib\DateTime; +use Magento\Framework\Stdlib\StringUtils as StringHelper; +use Magento\Store\Model\StoreManagerInterface; +use Psr\Log\LoggerInterface as PsrLogger; /** * Account Management service implementation for external API access. + * * Handle various customer account actions. * * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class AccountManagementApi extends AccountManagement { + /** + * @var AuthorizationInterface + */ + private $authorization; + + /** + * @param CustomerFactory $customerFactory + * @param ManagerInterface $eventManager + * @param StoreManagerInterface $storeManager + * @param Random $mathRandom + * @param Validator $validator + * @param ValidationResultsInterfaceFactory $validationResultsDataFactory + * @param AddressRepositoryInterface $addressRepository + * @param CustomerMetadataInterface $customerMetadataService + * @param CustomerRegistry $customerRegistry + * @param PsrLogger $logger + * @param Encryptor $encryptor + * @param ConfigShare $configShare + * @param StringHelper $stringHelper + * @param CustomerRepositoryInterface $customerRepository + * @param ScopeConfigInterface $scopeConfig + * @param TransportBuilder $transportBuilder + * @param DataObjectProcessor $dataProcessor + * @param Registry $registry + * @param CustomerViewHelper $customerViewHelper + * @param DateTime $dateTime + * @param CustomerModel $customerModel + * @param ObjectFactory $objectFactory + * @param ExtensibleDataObjectConverter $extensibleDataObjectConverter + * @param AuthorizationInterface $authorization + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + public function __construct( + CustomerFactory $customerFactory, + ManagerInterface $eventManager, + StoreManagerInterface $storeManager, + Random $mathRandom, + Validator $validator, + ValidationResultsInterfaceFactory $validationResultsDataFactory, + AddressRepositoryInterface $addressRepository, + CustomerMetadataInterface $customerMetadataService, + CustomerRegistry $customerRegistry, + PsrLogger $logger, + Encryptor $encryptor, + ConfigShare $configShare, + StringHelper $stringHelper, + CustomerRepositoryInterface $customerRepository, + ScopeConfigInterface $scopeConfig, + TransportBuilder $transportBuilder, + DataObjectProcessor $dataProcessor, + Registry $registry, + CustomerViewHelper $customerViewHelper, + DateTime $dateTime, + CustomerModel $customerModel, + ObjectFactory $objectFactory, + ExtensibleDataObjectConverter $extensibleDataObjectConverter, + AuthorizationInterface $authorization + ) { + $this->authorization = $authorization; + parent::__construct( + $customerFactory, + $eventManager, + $storeManager, + $mathRandom, + $validator, + $validationResultsDataFactory, + $addressRepository, + $customerMetadataService, + $customerRegistry, + $logger, + $encryptor, + $configShare, + $stringHelper, + $customerRepository, + $scopeConfig, + $transportBuilder, + $dataProcessor, + $registry, + $customerViewHelper, + $dateTime, + $customerModel, + $objectFactory, + $extensibleDataObjectConverter + ); + } + /** * @inheritDoc * @@ -23,9 +134,30 @@ class AccountManagementApi extends AccountManagement */ public function createAccount(CustomerInterface $customer, $password = null, $redirectUrl = '') { + $this->validateCustomerRequest($customer); $customer = parent::createAccount($customer, $password, $redirectUrl); $customer->setConfirmation(null); return $customer; } + + /** + * Validate anonymous request + * + * @param CustomerInterface $customer + * @return void + * @throws AuthorizationException + */ + private function validateCustomerRequest(CustomerInterface $customer): void + { + $groupId = $customer->getGroupId(); + if (isset($groupId) && + !$this->authorization->isAllowed(self::ADMIN_RESOURCE) + ) { + $params = ['resources' => self::ADMIN_RESOURCE]; + throw new AuthorizationException( + __("The consumer isn't authorized to access %resources.", $params) + ); + } + } } diff --git a/vendor/magento/module-customer/Plugin/AsyncRequestCustomerGroupAuthorization.php b/vendor/magento/module-customer/Plugin/AsyncRequestCustomerGroupAuthorization.php new file mode 100644 index 000000000000..5b5c8ce1fc0c --- /dev/null +++ b/vendor/magento/module-customer/Plugin/AsyncRequestCustomerGroupAuthorization.php @@ -0,0 +1,78 @@ +authorization = $authorization; + } + + /** + * Validate groupId for anonymous request + * + * @param MassSchedule $massSchedule + * @param string $topic + * @param array $entitiesArray + * @param string|null $groupId + * @param string|null $userId + * @return null + * @throws AuthorizationException + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforePublishMass( + MassSchedule $massSchedule, + string $topic, + array $entitiesArray, + string $groupId = null, + string $userId = null + ) { + foreach ($entitiesArray as $entityParams) { + foreach ($entityParams as $entity) { + if ($entity instanceof CustomerInterface) { + $groupId = $entity->getGroupId(); + if (isset($groupId) && !$this->authorization->isAllowed(self::ADMIN_RESOURCE)) { + $params = ['resources' => self::ADMIN_RESOURCE]; + throw new AuthorizationException( + __("The consumer isn't authorized to access %resources.", $params) + ); + } + } + } + } + return null; + } +} diff --git a/vendor/magento/module-customer/etc/di.xml b/vendor/magento/module-customer/etc/di.xml index b178f51f8919..1792399fb2cb 100644 --- a/vendor/magento/module-customer/etc/di.xml +++ b/vendor/magento/module-customer/etc/di.xml @@ -578,6 +578,7 @@ store_id group_id dob + rp_token country_id @@ -585,4 +586,18 @@ + + + + + email + + + + + + + diff --git a/vendor/magento/module-eav/Model/Attribute/Data/Text.php b/vendor/magento/module-eav/Model/Attribute/Data/Text.php index c41a65a6bfd3..f8bbed29fbc2 100644 --- a/vendor/magento/module-eav/Model/Attribute/Data/Text.php +++ b/vendor/magento/module-eav/Model/Attribute/Data/Text.php @@ -7,11 +7,16 @@ namespace Magento\Eav\Model\Attribute\Data; use Magento\Framework\App\RequestInterface; +use Magento\Framework\Locale\ResolverInterface; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Framework\Stdlib\StringUtils; +use Psr\Log\LoggerInterface; /** * EAV Entity Attribute Text Data Model * * @author Magento Core Team + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ class Text extends \Magento\Eav\Model\Attribute\Data\AbstractData { @@ -21,20 +26,28 @@ class Text extends \Magento\Eav\Model\Attribute\Data\AbstractData protected $_string; /** - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Psr\Log\LoggerInterface $logger - * @param \Magento\Framework\Locale\ResolverInterface $localeResolver - * @param \Magento\Framework\Stdlib\StringUtils $stringHelper + * @var array + */ + private $allowDiacriticsForAttributes; + + /** + * @param TimezoneInterface $localeDate + * @param LoggerInterface $logger + * @param ResolverInterface $localeResolver + * @param StringUtils $stringHelper + * @param array $allowDiacriticsForAttributes * @codeCoverageIgnore */ public function __construct( \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Psr\Log\LoggerInterface $logger, \Magento\Framework\Locale\ResolverInterface $localeResolver, - \Magento\Framework\Stdlib\StringUtils $stringHelper + \Magento\Framework\Stdlib\StringUtils $stringHelper, + array $allowDiacriticsForAttributes = [] ) { parent::__construct($localeDate, $logger, $localeResolver); $this->_string = $stringHelper; + $this->allowDiacriticsForAttributes = $allowDiacriticsForAttributes; } /** @@ -79,8 +92,14 @@ public function validateValue($value) return $errors; } - // if string with diacritics encode it. - $value = $this->encodeDiacritics($value); + if (isset($this->allowDiacriticsForAttributes[$attribute->getEntityType()->getEntityTypeCode()]) + && in_array( + $attribute->getAttributeCode(), + $this->allowDiacriticsForAttributes[$attribute->getEntityType()->getEntityTypeCode()] + )) { + // if string with diacritics encode it. + $value = $this->encodeDiacritics($value); + } $validateLengthResult = $this->validateLength($attribute, $value); $errors = array_merge($errors, $validateLengthResult);