18

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;
    }
}
26

1) You can disable plugin by name. In your case it authorization.
Edit: The syntax of this method doesn't work in the modern version of magento, see fudu's answer below or go to the second method.

<type name="Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization">
    <plugin name="authorization" disabled="true" />
</type>
<type name="Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization">
    <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.

2) 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
    }
}
| improve this answer | |
  • i have tried by overriding plugin inside webapi_rest folder but its not working – bhargav shastri Jan 17 '19 at 10:32
11

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>
| improve this answer | |
  • Do i need to create a class for this Vendor\Name\Model\ResourceModel\Plugin\Sales\Order\Authorization? – senthil Oct 7 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 at 2:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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