Company User Roles and Permissions overview

Edit on GitHub

Usually employees within a company have different roles (e.g. purchasing, administration, supervision, etc.). These roles are related to Company Users and are referred to as Company Roles. A role can be default (“is_default” flag), which means that it is used for all new users automatically.

Upon initial creation of the first Company User, the default role is Admin. After the Admin user has been created, he/she creates the structure of the company and can define the default role to be used further on.



Each Company role contains a set of permissions in the form of Permission keys attributed to them.

The Permission keys define what the users are allowed to do.

For example, a user can be allowed to add products to cart.
Permissions that can be used are not limited in any way - you can create and integrate any permissions. Each of the permissions is represented as a plugin in the code.

Here is another example of the connection between company roles and permissions:

  • When a user registers a Company in the system, he/she actually creates a request for Company account registration.
  • After the Company account has been approved, this first Company User becomes the Company administrator.
  • Therefore, one of the roles within the Company will be Administrator who will have all the permissions with regard to creation and management of company profile, user accounts and user rights.

One and the same user can have several Company Roles assigned to them. It means that the same user can be Junior Sales Manager and Team Leader, which in its turn implies that this user has permissions assigned to both roles: Junior Sales Manager and Team Leader. Here it should be noted that the permissions, entitling the user with more rights, win.

For example, suppose Junior Sales Managers are allowed to place an order for up to 1000 Euro, whereas Team Leaders can place orders for up to 2000 Euro. If a user has both roles assigned to him, he/she will be allowed to place orders for up to 2000 Euro, and not 1000 Euro.
Or, for example, if Junior Sales Managers are not allowed to view specific products, but Team Leaders can, the users having both Junior Sales Manager and Team Leader roles will be allowed to view those products.


Company roles and permissions and their relation to the organizational structure can be schematically represented as follows:


Permission Types

Permissions can be simple and complex.

Permission Type Description Example
Simple Simple permissions are those that do not have any logic behind them and answer the question “Does the customer have a permission?”. Simple permissions implement only PermissionPluginInterface (Shared).

A Company User is allowed (or not allowed) to access product details page.


Complex Complex permissions have some logic behind them and answer the question “Does the customer have a permission with some parameters and business logic?”. Complex permissions implement ExecutablePermissionPluginInterface (Shared).

A Company User is allowed (or not allowed) to place an order with grand total over 1000 Euro.


Infrastructural Some permissions should not be managed in the UI, but programatically. Infrastructural permissions implement InfrastructuralPermissionPluginInterface (Shared).

Read shared cart, which is managed by the Shared Carts feature.

Some of the Permissions can be configured for specific roles, for example, “allow adding no more than X items to cart” for junior support engineer.
Or for example, some specific products are not allowed to be viewed by anyone, but Admin and Top Managers.
These values are referred to as **Company Role Permissions**.

Permission can also be Yves-side and Zed-side.

  • Yves permissions do not need to get any data from the database. They refer to key-value storage, or to search to check the right for actions.
For example, the permission to view a product, a page, or permission to place an order, permission to place an order with grand total less X, would be Yves-side permissions.
  • Permissions that require some data from the database or some additional business-logic on top to check the rights for actions, are referred to as Zed permissions.
For example, the permission to add to cart up to X [order value] would be the Zed-side permission. In this case the process of permissions check would be as follows:
  • After the user clicked **Add to cart**, the request comes to Zed and the pre-checks are made following the “add to cart” request.
  • After that, the calculations are run. The calculations apply discounts per item, and then per cart (total).
    The logic behind this is simple: a user might have a discount for a specific item, and a discount for order starting from a specific order value. The order value would be calculated taken the discount per items into account, and therefore the discount per cart would be applied after all discounts per items have been calculated.
  • After the calculations have been made, the cart is saved.

Obviously, the permissions can not be checked at the step when user just clicks Add to cart, because actual order value has not been calculated yet (pre-checks have not been made yet, discounts have not been calculated). Also, the permissions check request can not be started after the cart has been updated - that would be too late, as, the cart has already been persisted. The request for rights check is made somewhere in between - specifically, right after the discounts have been calculated. That is why the so-called “termination hooks” have been implemented deep in logic, where the permissions checks are made.

The termination hooks (plugin stack) do not allow the permissions sneak into the business logic foundation so it will remain clean from the permissions and not overwhelmed with “can” “if not; then…” etc.


The termination hooks are performed one by one, and process termination can happen for any reason, and one of them would be the permissions.