-
Notifications
You must be signed in to change notification settings - Fork 2
Migrating to v2.x.x
- Roles Based Access has been replaced with Conditional transitions (strategy)
One of the things that changed is the roles based schema. In version 2 we can have conditional transitions. This means you can now employ your custom logic to determine if a possible transition is valid for the current context.
A typical example would be employing RBAC permissions over account management. To keep things simple, let's take the following example.
- Assume we have a system with accounts
- Each account can have multiple users.
- One of the possible actions is to terminate the account.
- I want only the account owner to be able to do that and not any related users.
A real-life example most of us are familiar with would be an AWS account. Only he who has owner granted policy can take delete an account (or even modify core information).
How do we achieve that within our state machine with a couple of lines? We will need to create a conditional check for a possible transition (event). Here's the code
namespace ptheofan\statemachine\conditions;
use ptheofan\statemachine\Condition;
use ptheofan\statemachine\interfaces\StateMachineContext;
use Yii;
/**
* Class Permission
*
* @package ptheofan\statemachine\conditions
*/
class Permission extends Condition
{
/**
* @var string
*/
public $permission;
/**
* Execute the command on the $context
*
* @param StateMachineContext $context
* @return bool
*/
public function isValid(StateMachineContext $context)
{
if (empty($this->permission)) {
return true;
}
return Yii::$app->user->can($this->permission, ['context' => $context, 'permission' => $this]);
}
}
And here's how to position it in the configuration file. Notice the <conditions>
part under <event target="cancelled"...
<state value="verified">
<enter>
<command class="ReportStateTransition"/>
</enter>
<event target="cancelled" label="delete.account">
<conditions>
<permission>owner</permission>
</conditions>
</event>
<exit>
<command class="ReportStateTransition" verb="Leaving"/>
</exit>
</state>
In the FSM the rule says that if ALL conditions return true
then this event is valid.