21

I am building a marketplace using Magento2. For that reason I need to be able to load the order of the customer using the vendor's customer credentials.

The problem with this is that Magento2 uses a Plugin to verify that only the Customer of this order (or an Admin) can load the order.

In this case I need to either override the Plugin as a whole, or override the protected method isAllowed(). What can I do without modifying the core?

Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization Looks like this:

use Magento\Authorization\Model\UserContextInterface;
use Magento\Framework\Exception\NoSuchEntityException;
class Authorization
{
    /**
     * @var UserContextInterface
     */
    protected $userContext;

    /**
     * @param UserContextInterface $userContext
     */
    public function __construct(
        \Magento\Authorization\Model\UserContextInterface $userContext
    ) {
        $this->userContext = $userContext;
    }

    /**
     * Checks if order is allowed
     *
     * @param \Magento\Sales\Model\ResourceModel\Order $subject
     * @param callable $proceed
     * @param \Magento\Framework\Model\AbstractModel $order
     * @param mixed $value
     * @param null|string $field
     * @return \Magento\Sales\Model\Order
     * @throws NoSuchEntityException
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function aroundLoad(
        \Magento\Sales\Model\ResourceModel\Order $subject,
        \Closure $proceed,
        \Magento\Framework\Model\AbstractModel $order,
        $value,
        $field = null
    ) {
        $result = $proceed($order, $value, $field);
        if (!$this->isAllowed($order)) {
            throw NoSuchEntityException::singleField('orderId', $order->getId());
        }
        return $result;
    }

    /**
     * Checks if order is allowed for current customer
     *
     * @param \Magento\Sales\Model\Order $order
     * @return bool
     */
    protected function isAllowed(\Magento\Sales\Model\Order $order)
    {
        return $this->userContext->getUserType() == UserContextInterface::USER_TYPE_CUSTOMER
            ? $order->getCustomerId() == $this->userContext->getUserId()
            : true;
    }
}

2 Answers 2

34

You can disable plugin by name. In your case it authorization.

<type name="Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization">
    <plugin name="authorization" disabled="true" />
    <plugin name="vendor_name_authorization" type="Vendor\Name\Model\ResourceModel\Plugin\Sales\Order\Authorization" sortOrder="1" />
</type>

Then you should create own class, which will extend the magento plugin class. In own class you can overwrite protected method.

You can do it without delete and recreate plugin:

<type name="Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization">
    <plugin name="authorization" type="Vendor\Name\Model\ResourceModel\Plugin\Sales\Order\Authorization" sortOrder="1" />
</type>

Sample code of your plugin class:

namespace Vendor\Name\Model\ResourceModel\Plugin\Sales\Order;
class Authorization extends \Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization
{
    protected function isAllowed(\Magento\Sales\Model\Order $order)
    {
            ///You code here
    }
}
1
  • i have tried by overriding plugin inside webapi_rest folder but its not working Jan 17, 2019 at 10:32
14

If you use sergei.sss 1st solution, you will get the error of duplicate Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization
The correct way to do that is:

<type name="Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization">
    <plugin name="authorization" disabled="true" />
    <plugin name="vendor_name_authorization" type="Vendor\Name\Model\ResourceModel\Plugin\Sales\Order\Authorization" sortOrder="1" />
</type>
2
  • Do i need to create a class for this Vendor\Name\Model\ResourceModel\Plugin\Sales\Order\Authorization?
    – senthil
    Oct 7, 2020 at 17:19
  • @senthil If you want to override then yes, you need to create that file, otherwise, if you only need to disable the plugin then no, remove the second line is ok.
    – fudu
    Oct 8, 2020 at 2:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.