/** * Main method to check authorization * * @param MvcEvent $e * * @return ResponseInterface */ public function checkAccess(MvcEvent $e) { /** @var Response $response */ $response = $e->getResponse(); /** @var UserEntity $identity */ $identity = $this->authService->getIdentity(); $role = $identity ? $identity->getRole() : UserEntity::ROLE_GUEST; list($moduleName, $controllerName, $actionName) = $this->namesResolver->resolve($e); if ($this->acl->isAllowed($role, $moduleName, $controllerName . ':' . $actionName)) { $e->getViewModel()->setVariable('acl', $this->acl); return $response; } $this->getEventManager()->trigger(self::EVENT_IS_NOT_ALLOWED, $e->getTarget()); $router = $e->getRouter(); if ($role !== UserEntity::ROLE_GUEST) { $url = $router->assemble(['controller' => 'no-access'], ['name' => 'auth/default']); } else { $url = $router->assemble(['controller' => 'login'], ['name' => 'access/default']); } $response->setStatusCode(302); $response->getHeaders()->clearHeaders(); $response->getHeaders()->addHeaderLine('Location', $url); $e->stopPropagation(); return $response; }
/** * @param \Zend\Permissions\Acl\Resource\ResourceInterface|string $resource * @param string $action * @return bool */ public function can($resource, $action) { foreach ($this->roles as $role) { if ($this->acl->isAllowed($role, $resource, $action)) { return true; } } return false; }
public function fillResources(array $resourcesConfig) { foreach ($resourcesConfig as $resource => $options) { $inherit = $this->getOption($options, self::INHERIT); if (null !== $inherit && !is_string($inherit) && !$inherit instanceof ResourceInterface) { throw new Exceptions\RuntimeException('Inherit option must be a string or implement ResourceInterface for resources'); } $this->acl->addResource($resource, $inherit); $privileges = $this->getOption($options, self::PRIVILEGES, []); foreach ($privileges as $role => $actions) { $this->acl->allow([$role], [$resource], $actions); } } }
/** * */ public function nav($root) { if (!isset($this->navigation[$root]) || !is_array($this->navigation[$root])) { return []; } $navigation = $this->navigation[$root]; $aclFilter = function ($page) { if (!$this->acl) { return true; } $path = parse_url($page['href'], PHP_URL_PATH); if (isset($page['external'])) { return true; } $resource = 'route' . $path; return $this->acl->isAllowed($this->currentRole, $resource, 'get'); }; $prepare = function ($page) use(&$prepare, &$aclFilter) { if (isset($page['route'])) { $routeData = isset($page['route_data']) ? $page['route_data'] : []; $query = isset($page['query']) ? $page['query'] : []; $page['href'] = $this->router->pathFor($page['route'], $routeData, $query); } $path = parse_url($page['href'], PHP_URL_PATH); $page['active'] = $path !== '/' && 0 === strpos($this->request->getUri()->getPath(), $path); if (isset($page['pages']) && is_array($page['pages'])) { $page['pages'] = array_filter(array_map($prepare, $page['pages']), $aclFilter); } return $page; }; return array_filter(array_map($prepare, $navigation), $aclFilter); }
public function configureAcl(AclInterface $acl) { foreach ($this->getRoles() as $roleId => $parents) { $acl->addRole(new GenericRole($roleId), $parents); foreach ($this->getRules($roleId, 'allow') as $spec) { if (!$acl->hasResource($spec['resource'])) { $acl->addResource(new GenericResource($spec['resource'])); } $acl->allow($roleId, $spec['resource'], $spec['privilege'], $spec['assertion']); } foreach ($this->getRules($roleId, 'deny') as $spec) { if (null !== $spec['resource'] && !$acl->hasResource($spec['resource'])) { $acl->addResource(new GenericResource($spec['resource'])); } $acl->deny($roleId, $spec['resource'], $spec['privilege'], $spec['assertion']); } } return $acl; }
/** * @param string|ResourceInterface $resource */ private function loadResource($resource) { if ($this->acl->hasResource($resource)) { return; } $parent = null; if ($resource instanceof HierarchicalResourceInterface && ($parent = $resource->getParent())) { is_array($parent) ? $this->loadResources($parent) : $this->loadResource($parent); } $this->acl->addResource($resource, $parent); }
/** * Invoke middleware. * * @param RequestInterface $req PSR7 request object * @param ResponseInterface $res PSR7 response object * @param callable $next Next middleware callable * * @return ResponseInterface PSR7 response object */ public function __invoke(Request $req, Response $res, callable $next) { if (!$req->getAttribute('route')) { return $res->withStatus(404); } $isAllowed = false; if ($this->acl->hasResource('route' . $req->getAttribute('route')->getPattern())) { $isAllowed = $isAllowed || $this->acl->isAllowed($this->currentUserRole, 'route' . $req->getAttribute('route')->getPattern(), strtolower($req->getMethod())); } if (is_string($req->getAttribute('route')->getCallable()) && $this->acl->hasResource('callable/' . $req->getAttribute('route')->getCallable())) { $isAllowed = $isAllowed || $this->acl->isAllowed($this->currentUserRole, 'callable/' . $req->getAttribute('route')->getCallable()); } if (!$isAllowed && $this->currentUserRole === $this->defaultRole) { return $res->withRedirect($this->loginUrl); } if (!$isAllowed) { $res = $res->withStatus(403, $this->currentUserRole . ' is not allowed access to this location.'); $res->getBody()->write('Forbidden'); return $res; } return $next($req, $res); }
/** * handler * * Handles MvcEvent::EVENT_ROUTE * * @param MvcEvent $event */ public function handler(MvcEvent $event) { $match = $event->getRouteMatch(); if (!$match) { // we need a route return; } $roles = $this->roleProvider->getRoles(); $resource = $this->resourceProvider->getResource($event); $priviledge = $this->resourceProvider->getPriviledge($event); if (!$this->acl->isAllowed($roles, $resource, $priviledge)) { $controller = $this->config['MultiRoleAclBase']['forbidden']['controller']; $action = $this->config['MultiRoleAclBase']['forbidden']['action']; $response = $event->getResponse(); $match->setParam('oldData', array('controller' => $match->getParam('controller', null), 'action' => $match->getParam('action', null), 'resource' => $resource, 'priviledge' => $priviledge, 'roles' => $roles)); $response->setStatusCode(Response::STATUS_CODE_403); // Forbidden $match->setParam('controller', $controller); $match->setParam('action', $action); } // we make the acl available on views $event->getViewModel()->setVariable('tacl', $this->acl); }
/** * @return AclInterface * @throws \Zend\Permissions\Acl\Exception\InvalidArgumentException */ protected function getAcl() { if ($this->acl === null) { $this->acl = new Acl(); foreach ($this->getRoleProvider()->getRoles() as $role) { $this->acl->addRole($role); } foreach ($this->getResourceProvider()->getResources() as $resource) { if ($resource instanceof Resource) { $this->acl->addResource($resource, $resource->getParentId()); } } foreach ($this->getRuleProvider()->getRules() as $rule) { if ($rule instanceof Rule) { $this->acl->allow($rule->getRoles(), $rule->getResources(), $rule->getPrivileges()); } } } return $this->acl; }
/** * Determines whether or not user has access to requested resource. * * @param ServerRequestInterface $request * @param ResponseInterface $response * @param callable $next * * @return ResponseInterface */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) { $route = $request->getAttribute('route', null); if ($route === null) { // User likely accessing a nonexistent route. Calling next middleware. return $next($request, $response); } $role = $this->getRole($this->auth->getIdentity()); $resource = $route->getPattern(); /* * THIS BUG HAPPENED WHEN ROUTE DID NOT SET ->allow([roles]) * Hope fix problems when an optional / maybe followed by arguments * Route::group('/venues', function (){ Route::get('/', ... Route::get('[/{id:[0-9]+}]', ... dont work for groups that do not have a sub route like '/' */ // $resource = preg_replace("|\[\/[^\[].*\]|", "/", $route->getPattern()); // $resource = $route->getIdentifier(); $privilege = $request->getMethod(); // $isAllowed = false; // if(!$this->acl && $route instanceof AuthorizableRoute){ // $route->getAcl()->isAllowed($role, $resource, $privilege); // } else { // $this->acl->isAllowed($role, $resource, $privilege); // } // var_dump($this->acl); $isAllowed = $this->acl->isAllowed($role, $resource, $privilege); $isAuthenticated = $this->auth->hasIdentity(); if ($isAllowed) { return $next($request, $response); } if ($isAuthenticated) { // Authenticated but unauthorized for this resource return $this->handler->notAuthorized($response); } // Not authenticated and must be authenticated to access this resource return $this->handler->notAuthenticated($response); }
/** * Check permission * * @param string $resource * @param boolean $increaseActions * @return boolean */ public static function checkPermission($resource, $increaseActions = true) { $currentUserIdentity = UserIdentityService::getCurrentUserIdentity(); // admin can do everything if ($currentUserIdentity['role'] == AclBaseModel::DEFAULT_ROLE_ADMIN) { return true; } // process a resource name $resource = str_replace([' ', '-'], [self::ACL_RESOURCE_SPACE_DEVIDER, self::ACL_RESOURCE_SPACE_DEVIDER], $resource); // init an ACL if (null === self::$currentAcl) { self::initAcl($currentUserIdentity); } $aclModel = ServiceLocatorService::getServiceLocator()->get('Application\\Model\\ModelManager')->getInstance('Acl\\Model\\AclBase'); // check the resource existing if (self::$currentAclResources && array_key_exists($resource, self::$currentAclResources)) { // check the resource's dates if (true === ($result = $aclModel->isAclResourceDatesActive(self::$currentAclResources[$resource]))) { // check the permission $permissionResult = self::$currentAcl->isAllowed($currentUserIdentity['role'], $resource); // reset the current resource actions if it needs if (true === ($result = $aclModel->resetAclResource($currentUserIdentity['user_id'], self::$currentAclResources[$resource], $permissionResult, $increaseActions))) { // update ACL resources again self::initAcl($currentUserIdentity); // check the permission again if (true !== ($permissionResult = self::$currentAcl->isAllowed($currentUserIdentity['role'], $resource))) { // check the resource's dates if (true === ($result = $aclModel->isAclResourceDatesActive(self::$currentAclResources[$resource]))) { // a previous action should be finished if ((int) self::$currentAclResources[$resource]['actions_limit'] == (int) self::$currentAclResources[$resource]['actions']) { return true; } } } } return $permissionResult; } } return false; }