<?php namespace bff\auth; trait UserPermissions { /** * Permissions list * @var array */ protected $permissions; /** * Open modules/scopes list * @var array ['module' => ['scope1', 'scope2', ...], ...] */ protected $openModuleScopes = [ 'users' => ['profile'], ]; /** * Set permissions list * @param array $permissions */ public function setPermissions(array $permissions) { $this->permissions = $permissions; } /** * Get permissions list * @return array */ public function getPermissions() { return $this->permissions; } /** * Has access to module (and scopes(s)). * @param string $module * @param string|array|null $scope * @param array|null $permissions * @return bool */ protected function hasAccessToModuleScope(string $module, $scope = null, ?array $permissions = null) { # validate module if (empty($module)) { return false; } $module = mb_strtolower($module); # validate scope if ($scope) { if (is_array($scope)) { foreach ($scope as $k => $v) { $scope[$k] = mb_strtolower($v); } } else { $scope = mb_strtolower($scope); } } # module scope is open if ($this->isOpenModuleScope($module, $scope)) { return true; } # load permissions if (is_null($permissions)) { $permissions = $this->getPermissions(); } # no permissions if (empty($permissions)) { return false; } # no access to module $allowedScopes = $permissions[$module] ?? []; if (empty($allowedScopes)) { return false; } # full access to module if ($module && in_array($module, $allowedScopes)) { return true; } # has access to any scope of module ? if ($module && is_null($scope)) { # todo: needs explanation return true; } # has access to module scope if ($scope) { if (is_array($scope)) { foreach ($scope as $m) { if ($m && in_array($m, $allowedScopes)) { return true; } } return false; } return in_array($scope, $allowedScopes); } return false; } /** * Check if module scope is in open list. * @param string $module * @param string|array $scope * @return bool */ protected function isOpenModuleScope(string $module, $scope) { if (is_null($scope)) { return false; } if (is_array($scope)) { foreach ($scope as $m) { if ($this->isOpenModuleScope($module, $m)) { return true; } } return false; } return ( isset($this->openModuleScopes[$module]) && is_array($this->openModuleScopes[$module]) && in_array($scope, $this->openModuleScopes[$module]) ); } /** * Set open modules/scopes list. * @param array $list * @param bool $merge * @return void */ public function setOpenModuleScopes(array $list, $merge = false) { if ($merge) { $this->openModuleScopes = array_merge($this->openModuleScopes, $list); } else { $this->openModuleScopes = $list; } } }