ACL, czyli Access Control List to mechanizm, który pozwala ograniczać uprawnienia dla użytkowników panelu administracyjnego w Magento 2. Dzięki ACL masz możliwość definiowania uprawnień dla:

  • elementów w Menu panelu administracyjnego
  • poszczególnych stron (kontrolerów)
  • enpointów API
  • wybranych bloków w layout
  • extension attributes

W tym artykule pokażę Ci na realnym przykładzie jak definiować ACL w Magento 2.

Definiowanie uprawnień

Uprawnienia definiuje się w pliku etc/acl.xml w przestrzeni modułu.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
    <acl>
        <resources>
            <resource id="Magento_Backend::admin">
                <resource id="Magento_Catalog::catalog">
                    <resource id="Mkwiatkowski_CatalogBanners::banners" title="Catalog Banners" sortOrder="100">
                        <resource id="Mkwiatkowski_CatalogBanners::banners_index" title="Banners list" sortOrder="10" />
                        <resource id="Mkwiatkowski_CatalogBanners::banners_add" title="Add and Edit" sortOrder="20" />
                    </resource>
                </resource>
            </resource>
        </resources>
    </acl>
</config>

Każdy zasób musi mieć jako rodzica zasób z ID Magento_Backend::admin, jeśli tego zabraknie to zdefiniowane przez nas zasoby nie pojawią się w panelu administracyjnym na widoku dodawania uprawnień dla roli użytkownika. W linii szóstej odnoszę się do Magento_Catalog::catalog, dzięki czemu zasoby będą widoczne w grupie Catalog. Dalej definiuję już customowe zasoby – rodzic Mkwiatkowski_CatalogBanners::banners, oraz Mkwiatkowski_CatalogBanners::banners_index, które są odpowednikami linków w menu.

Po dodaniu pliku acl.xml należy wyczyścić cache, aby zdefinowane w tym pliku nowe uprawnienia pokazały się w panelu administracyjnym.

Dodanie nowej roli

Czas na dodanie nowej roli użytkownika, której damy dostęp tylko do naszych uprawnień, aby sprawdzić, czy te uprawnienia działają poprawnie. Oczywiście standardowy użytkownik z rolą Administrators ma automatycznie dostęp do wszystkich zasobów. Nowe role tworzymy gdy chcemy ograniczyć dostęp do pewnych funkcjonalności.

Aby dodać nową rolę należy przejść do System > Permissions > User Roles.

ACL w Magento 2

Kliknąć w Add New Role

ACL w Magento 2

W pierwszej zakładce jest możliwość wpisania nazwy dla nowej roli. Niezbędne też jest podanie hasła atywnego użytkownika. Druga zakładka Role Resources pozwala defiionować zasoby do których będzie miał dostęp użytytkownik.

ACL resources

Ważne tutaj jest, aby użytownik miał dostęp do zasobu Dashboard, ponieważ jeśli nie będzie miał to po zalogowaniu się zobaczy stronę 404.

Dodanie uprawnień dla menu

Każdy wężeł w menu ma atrybut resource np.

<add id="Mkwiatkowski_CatalogBanners::banners_add" title="Add new banner" translate="title"
             module="Mkwiatkowski_CatalogBanners" parent="Mkwiatkowski_CatalogBanners::banners" sortOrder="10"
             action="catalogbanners/banner/form"
             resource="Mkwiatkowski_CatalogBanners::banners_add"/>

W tym przypadku dostęp do tego elementu będzie miał użytkownik z zaznaczonym zasobem Mkwiatkowski_CatalogBanners::banners_add

Uprawnienia dla kontrolerów

Każdy kontroler w przestrzeni adminhtml, dziedziczy po klasie Magento/Backend/App/AbstractAction, która ma pole ADMIN_RESOURCE. W tym polu można określić zasób jaki odpowiada za uprawnienia do kontrolera.

const ADMIN_RESOURCE = 'Mkwiatkowski_CatalogBanners::banners';

Jeśli potrzebujesz zaimplementować jakąś głębszą logikę sprawdzania uprawnień to masz możliwość przeciążenia metody isAllowed()

/**
 * @return bool
 */
protected function _isAllowed()
{
    return $this->_authorization->isAllowed(static::ADMIN_RESOURCE);
}

Uprawnienia dla UI componentu listing

UI Component listing przy pobieraniu danych wysyła request AJAX do kontrolera mui/index/render. W pliku xml gdzie jest zdefioniwany ui component jest możliwość zdefiniowania zasobu. Jeśli użytkownik nie ma uprawnień to w odpowiedzi z serwera wróci błąd 403 i listing nie będzie działał, nawet jeśli użytkownik ma dostęp do strony na której jest wyrenderowany UI Component. Ustawienia dot. ACL definiuje się w węźle <dataSource>

<aclResource>Mkwiatkowski_CatalogBanners::banners_index</aclResource>

Utworzenie użytkownika

Aby sprawdzić, czy uprawnienia działają zgodnie z naszymi oczekiwaniami utworzymy nowgo użytkownika.

Przejdź do System -> permissions -> all users

Kliknij Add New User i dodaj użytkownika z rolą Catalog banners editors

Po zalogowaniu się na konto tego usera można zobaczyć, że ma on dostęp tylko do funkcjonalności edycji bannerów:

ACL w Magento 2: dodatkowe informacje

Poniżej opiszę jeszcze możliwości ACL, które nie są wykorzystywane w module Catalog_Banners, ale są dostępne w Magento.

Uprawnienia bloków

Każdy blok zdefiniowany w layout może mieć ustawiony resource:

<block class="Magento\Framework\View\Element\Text" aclResource="Vendor_Module::view_additional">
    <arguments>
        <argument name="text" xsi:type="string">Additional block</argument>
    </arguments>
</block>

W tym przypadku tylko użytkownik, który ma nadane uprawnienia Vendor_Module::view_additional zobaczy ten blok.

Uprawnienia Web API

Każda zadeklarowana metoda Web API musi mieć zdefiniowany resource. Tutaj musisz wiedzieć, że możesz użyć zasobu o nazwie anonymous (metoda dostępna dla każdego) oraz self (metoda dostępna dla zalogowanych). Zobacz na przykłady metod Web APi z zadeklarowanymi zasobami:

<!-- Managing shipping guest information -->
<route url="/V1/guest-carts/:cartId/shipping-information" method="POST">
    <service class="Magento\Checkout\Api\GuestShippingInformationManagementInterface" method="saveAddressInformation"/>
    <resources>
        <resource ref="anonymous" />
    </resources>
</route>
<!-- Managing My shipping information -->
<route url="/V1/carts/mine/shipping-information" method="POST">
    <service class="Magento\Checkout\Api\ShippingInformationManagementInterface" method="saveAddressInformation"/>
    <resources>
        <resource ref="self" />
    </resources>
    <data>
        <parameter name="cartId" force="true">%cart_id%</parameter>
    </data>
</route>
<!-- Managing shipping information-->
<route url="/V1/carts/:cartId/shipping-information" method="POST">
    <service class="Magento\Checkout\Api\ShippingInformationManagementInterface" method="saveAddressInformation"/>
    <resources>
        <resource ref="Magento_Cart::manage" />
    </resources>
</route>

Uprawnienia Extension attributes

Istnieje też możliwość definiowania uprawnień dla Extension Atrtributes. Przykład użycia:

<extension_attributes for="Magento\AsynchronousOperations\Api\Data\OperationInterface">
    <attribute code="start_time" type="string">
        <resources>
            <resource ref="Magento_Logging::system_magento_logging_bulk_operations"/>
        </resources>
        <join reference_table="magento_bulk" join_on_field="bulk_uuid" reference_field="uuid">
            <field column="start_time">start_time</field>
        </join>
    </attribute>
</extension_attributes>

ACL w Magento 2: podsumowanie

ACL to mechanizm, który w łatwy sposób pozwala na ograniczenie dostępu do poszczególnych obszarów panelu administracyjnego w Magento 2. Zmiany związane z ACL dotyczące modułu nad którym pracuję w serii artykułów „Modyfikacja listy produktów” znajdziesz w tym commicie na moim Githubie.