Merge branch '24-admin-section' into 'dev'
Resolve "Admin section" Closes #24 See merge request pnx/httpcb!25
This commit is contained in:
commit
5867103646
42 changed files with 481 additions and 45 deletions
|
|
@ -44,3 +44,4 @@
|
|||
@import "views/about";
|
||||
@import "views/login";
|
||||
@import "views/register";
|
||||
@import "views/backend";
|
||||
|
|
|
|||
33
app/assets/sass/views/_backend.scss
Normal file
33
app/assets/sass/views/_backend.scss
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
.backend {
|
||||
display: flex;
|
||||
@extend .section;
|
||||
padding: 0;
|
||||
|
||||
&-sidemenu {
|
||||
@extend .list-group;
|
||||
width: 15%;
|
||||
background-color: darken($section-bg, 4%);
|
||||
border: 1px solid darken($section-bg, 8%);
|
||||
> li {
|
||||
list-style: none;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
color: $text-secondary-color;
|
||||
padding: .8em 1.6em;
|
||||
|
||||
&:hover {
|
||||
background: darken($section-bg, 8%);
|
||||
color: $text-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
width: 85%;
|
||||
padding: $section-padding;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +1,4 @@
|
|||
|
||||
# ACL in this system is defined as follows:
|
||||
#
|
||||
# - Roles:
|
||||
# Roles define a group of user. like Author, Admin, Guest etc.
|
||||
# Each role can inherit other roles with the "inherit" key.
|
||||
# Each role can gain access to a zone (explained later) by the
|
||||
# "allowed-zones" key. Per default a role is denied access to all zones.
|
||||
#
|
||||
# - Resources:
|
||||
# Resources maps directly to controller names.
|
||||
# There a 2 controllers/resources that are a bit special,
|
||||
# index and error resources are always accessible by everyone (e.g. they
|
||||
# are not part of the ACL).
|
||||
#
|
||||
# - Access levels.
|
||||
# These are not used in this system. a hardcoded "All" level is used.
|
||||
#
|
||||
# Zones
|
||||
#
|
||||
# Zones defines a group of resources. for example an "backend" zone can
|
||||
# have 2 controllers/resources (site-config, user-manager)
|
||||
#
|
||||
# Zones might be implemented using modules later.
|
||||
|
||||
acl:
|
||||
roles:
|
||||
guest:
|
||||
|
|
@ -32,11 +8,12 @@ acl:
|
|||
inherits: guest
|
||||
allowed-zones: user
|
||||
description: Logged in users
|
||||
#admin:
|
||||
# inherits: user
|
||||
# allowed-zones: backend
|
||||
admin:
|
||||
inherits: user
|
||||
description: Administrators
|
||||
allowed-zones: backend
|
||||
|
||||
zones:
|
||||
public: [ auth, api ]
|
||||
user: [ user, callback ]
|
||||
#backend: [ site, user-man ]
|
||||
backend: backend/*
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
|
||||
application:
|
||||
modulesDir : ../app/modules/
|
||||
controllersDir : ../app/controllers/
|
||||
modelsDir : ../app/models/
|
||||
migrationsDir : ../app/migrations/
|
||||
viewsDir : ../app/views/
|
||||
viewsDir : ../app/views/_common/
|
||||
templateDir : ../app/templates/
|
||||
listenersDir : ../app/listeners/
|
||||
libraryDir : ../app/library/
|
||||
|
|
|
|||
|
|
@ -25,3 +25,10 @@ menu:
|
|||
route: about-route
|
||||
controller: index
|
||||
action: about
|
||||
admin:
|
||||
caption: Admin
|
||||
resource: backend/user
|
||||
controller: user
|
||||
action: index
|
||||
route: backend-home
|
||||
|
||||
|
|
|
|||
|
|
@ -56,3 +56,14 @@ router:
|
|||
path:
|
||||
controller: api
|
||||
action: activationlink
|
||||
|
||||
# Backend
|
||||
backend-home:
|
||||
pattern: '/admin'
|
||||
path: backend::user::index
|
||||
backend-user-list:
|
||||
pattern: '/admin/user/list/{page:([0-9]+)}'
|
||||
path: backend::user::index
|
||||
backend-log:
|
||||
pattern: '/admin/log{page:/?([0-9]+)?}'
|
||||
path: backend::log::index
|
||||
|
|
|
|||
21
app/controllers/backend/LogController.php
Normal file
21
app/controllers/backend/LogController.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller\Backend;
|
||||
|
||||
use App\Model\Data\ActivityLog;
|
||||
|
||||
class LogController extends \Phalcon\Mvc\Controller
|
||||
{
|
||||
public function onConstruct()
|
||||
{
|
||||
$this->view->setLayout('side-menu');
|
||||
}
|
||||
|
||||
public function indexAction($page = 1)
|
||||
{
|
||||
$paginator = ActivityLog::getAllPaginationList($page);
|
||||
|
||||
$this->view->page = $paginator->getPaginate();
|
||||
$this->view->pagination_url = '/admin/log/';
|
||||
}
|
||||
}
|
||||
24
app/controllers/backend/UserController.php
Normal file
24
app/controllers/backend/UserController.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller\Backend;
|
||||
|
||||
use App\Model\Data\User;
|
||||
|
||||
class UserController extends \Phalcon\Mvc\Controller
|
||||
{
|
||||
public function onConstruct()
|
||||
{
|
||||
$this->view->setLayout('side-menu');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $page
|
||||
*/
|
||||
public function indexAction($page = 1)
|
||||
{
|
||||
$paginator = User::getPaginationList($page,15);
|
||||
|
||||
$this->view->pagination_url = '/admin/user/list/';
|
||||
$this->view->page = $paginator->getPaginate();
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,19 @@ class Acl
|
|||
*/
|
||||
public function isAllowed($role, $resource)
|
||||
{
|
||||
// Special stuff here :) for resources within modules.
|
||||
|
||||
// Modules and controllers are separated by "/"
|
||||
$pos = strpos($resource, '/');
|
||||
if ($pos !== false) {
|
||||
// Construct the wildcard resource.
|
||||
$wildcard = substr($resource, 0, $pos+1) . '*';
|
||||
|
||||
// If we have this wildcard resource, check against that instead.
|
||||
if ($this->hasResource($wildcard)) {
|
||||
$resource = $wildcard;
|
||||
}
|
||||
}
|
||||
return $this->_adapter->isAllowed($role, $resource, 'All') == \Phalcon\Acl::ALLOW;
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +98,8 @@ class Acl
|
|||
}
|
||||
|
||||
foreach($zones as $zone) {
|
||||
foreach($config->zones->get($zone) as $resource) {
|
||||
$resources = (array) $config->zones->get($zone);
|
||||
foreach($resources as $resource) {
|
||||
$this->_adapter->allow($name, $resource, 'All');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,19 @@ use Phalcon\Mvc\Application;
|
|||
|
||||
class Bootstrap extends Injectable
|
||||
{
|
||||
/**
|
||||
* @var Application
|
||||
*/
|
||||
protected $_app;
|
||||
|
||||
public function __construct(DiInterface $di = null)
|
||||
{
|
||||
if ($di === null) {
|
||||
$di = new DiDefault();
|
||||
}
|
||||
$this->setDI($di);
|
||||
|
||||
$this->_app = new Application();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -34,6 +41,14 @@ class Bootstrap extends Injectable
|
|||
$di->get('debugger')->listen(true, true);
|
||||
}
|
||||
|
||||
// Modules
|
||||
$this->_app->registerModules([
|
||||
'main' => [ 'className' => 'App\Module\Main' ],
|
||||
'backend' => [ 'className' => 'App\Module\Backend' ],
|
||||
]);
|
||||
|
||||
$this->_app->setDefaultModule('main');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +59,7 @@ class Bootstrap extends Injectable
|
|||
*/
|
||||
public function run()
|
||||
{
|
||||
$app = new Application($this->getDI());
|
||||
return $app->handle()->getContent();
|
||||
$this->_app->setDI($this->getDI());
|
||||
return $this->_app->handle()->getContent();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,11 +183,11 @@ class Node extends Container
|
|||
// Assemble route if set.
|
||||
if (strlen($this->getRoute()) > 0) {
|
||||
|
||||
$href = array(
|
||||
$href = [
|
||||
'for' => $this->getRoute(),
|
||||
'controller' => $this->getController(),
|
||||
'action' => $this->getAction()
|
||||
);
|
||||
];
|
||||
}
|
||||
// Otherwise, use default route.
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ class Services extends DiDefault
|
|||
$loader->registerNamespaces(array(
|
||||
'App\Controller' => $config->application->controllersDir,
|
||||
'App\Listener' => $config->application->listenersDir,
|
||||
'App\Module' => $config->application->modulesDir,
|
||||
'App\Model' => $config->application->modelsDir,
|
||||
'App\Form' => $config->application->formsDir,
|
||||
'Httpcb' => $config->application->libraryDir,
|
||||
|
|
@ -222,7 +223,7 @@ class Services extends DiDefault
|
|||
|
||||
$view = new View();
|
||||
|
||||
$view->setViewsDir($config->application->viewsDir);
|
||||
$view->setViewsDir([ $config->application->viewsDir ]);
|
||||
$view->setLayoutsDir('_layouts/');
|
||||
$view->setPartialsDir('_partials/');
|
||||
|
||||
|
|
@ -288,7 +289,8 @@ class Services extends DiDefault
|
|||
$menu = new Menu($navigation);
|
||||
$menu->setMenuClass(null);
|
||||
if ($this->get('auth')->hasIdentity()) {
|
||||
$menu->setAclRole(Acl::ROLE_USER);
|
||||
$type = $this->get('auth')->getIdentity()->getType();
|
||||
$menu->setAclRole($type);
|
||||
} else {
|
||||
$menu->setAclRole(Acl::ROLE_GUEST);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,15 +24,17 @@ class AccessListener extends Plugin
|
|||
*/
|
||||
public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher) : bool
|
||||
{
|
||||
// We only have two roles for now, authenticated users and guests.
|
||||
// If we have an identity, fetch type from authed user.
|
||||
if ($this->auth->hasIdentity()) {
|
||||
$role = Acl::ROLE_USER;
|
||||
} else {
|
||||
$user = $this->auth->getUser();
|
||||
$role = $user->getType();
|
||||
}
|
||||
// Othersize, we default to role.
|
||||
else {
|
||||
$role = Acl::ROLE_GUEST;
|
||||
}
|
||||
|
||||
// Get the resource from controller name.
|
||||
$resource = $dispatcher->getControllerName();
|
||||
$resource = $this->_getCurrentResource($dispatcher);
|
||||
|
||||
// Ignore checks for error resource.
|
||||
if (in_array($resource, $this->_ignored_resources)) {
|
||||
|
|
@ -67,4 +69,15 @@ class AccessListener extends Plugin
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function _getCurrentResource($dispatcher)
|
||||
{
|
||||
// If default module, only fetch controller name.
|
||||
if (strlen($dispatcher->getModuleName()) < 1) {
|
||||
return $dispatcher->getControllerName();
|
||||
}
|
||||
|
||||
// Otherwise, we follow the syntax "<module>/<controller>"
|
||||
return "{$dispatcher->getModuleName()}/{$dispatcher->getControllerName()}";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
19
app/migrations/20181003134001_user_type.php
Normal file
19
app/migrations/20181003134001_user_type.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
class UserType extends AbstractMigration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->table('user')
|
||||
->addColumn('type', 'enum', [
|
||||
'null' => false,
|
||||
'default' => 'user',
|
||||
'values' => [ 'user', 'admin' ],
|
||||
'after' => 'regdate'
|
||||
])
|
||||
->save();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace App\Model\Data;
|
||||
|
||||
use \Phalcon\Paginator\Adapter\QueryBuilder;
|
||||
use Phalcon\Mvc\Model\Query\BuilderInterface,
|
||||
Phalcon\Paginator\Adapter\QueryBuilder;
|
||||
|
||||
class ActivityLog extends Base
|
||||
{
|
||||
|
|
@ -16,6 +17,15 @@ class ActivityLog extends Base
|
|||
|
||||
protected $message;
|
||||
|
||||
/**
|
||||
* Initialize method for model.
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
// Relationships
|
||||
$this->hasOne('user_id', User::class, 'id', ['alias' => 'User']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
|
|
@ -120,6 +130,26 @@ class ActivityLog extends Base
|
|||
->where('user_id = :uid:', array('uid' => $userid))
|
||||
->orderBy('timestamp DESC');
|
||||
|
||||
return self::_paginate($builder, $page, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $page
|
||||
* @param int $limit
|
||||
* @return \Phalcon\Paginator\AdapterInterface
|
||||
*/
|
||||
public static function getAllPaginationList($page = 1, $limit = 30)
|
||||
{
|
||||
$builder = (new self())->getModelsManager()->createBuilder();
|
||||
|
||||
$builder->from(self::class)
|
||||
->orderBy('timestamp DESC');
|
||||
|
||||
return self::_paginate($builder, $page, $limit);
|
||||
}
|
||||
|
||||
protected static function _paginate(BuilderInterface $builder, $page = 1, $limit = 30)
|
||||
{
|
||||
$paginator = new QueryBuilder(array(
|
||||
'builder' => $builder,
|
||||
'page' => $page,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ use Phalcon\Validation,
|
|||
|
||||
class User extends Base
|
||||
{
|
||||
const TYPE_USER = 'user';
|
||||
const TYPE_ADMIN = 'admin';
|
||||
|
||||
const STATUS_ACTIVE = 'Active';
|
||||
const STATUS_DELETED = 'Deleted';
|
||||
const STATUS_SUSPENDED = 'Suspended';
|
||||
|
|
@ -23,6 +26,8 @@ class User extends Base
|
|||
|
||||
protected $email;
|
||||
|
||||
protected $type;
|
||||
|
||||
protected $status;
|
||||
|
||||
protected $password;
|
||||
|
|
@ -203,6 +208,24 @@ class User extends Base
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return User
|
||||
*/
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
|
@ -432,4 +455,24 @@ class User extends Base
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $page
|
||||
* @param int $limit
|
||||
* @return \Phalcon\Paginator\AdapterInterface
|
||||
*/
|
||||
public static function getPaginationList($page = 1, $limit = 30)
|
||||
{
|
||||
$builder = (new self())->getModelsManager()->createBuilder();
|
||||
|
||||
$builder->from(self::class);
|
||||
|
||||
$paginator = new \Phalcon\Paginator\Adapter\QueryBuilder(array(
|
||||
'builder' => $builder,
|
||||
'page' => $page,
|
||||
'limit' => $limit
|
||||
));
|
||||
|
||||
return $paginator;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
app/modules/Backend.php
Normal file
12
app/modules/Backend.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Module;
|
||||
|
||||
class Backend extends Base
|
||||
{
|
||||
protected $_controllerPath = APP_PATH . '/app/controllers/backend';
|
||||
|
||||
protected $_controllerNamespace = 'App\Controller\Backend';
|
||||
|
||||
protected $_viewDir = '../app/views/backend/';
|
||||
}
|
||||
47
app/modules/Base.php
Normal file
47
app/modules/Base.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Module;
|
||||
|
||||
use Phalcon\Loader,
|
||||
Phalcon\DiInterface,
|
||||
Phalcon\Mvc\Dispatcher,
|
||||
Phalcon\Mvc\ModuleDefinitionInterface;
|
||||
|
||||
abstract class Base implements ModuleDefinitionInterface
|
||||
{
|
||||
protected $_controllerPath;
|
||||
|
||||
protected $_controllerNamespace;
|
||||
|
||||
protected $_viewDir;
|
||||
|
||||
/**
|
||||
* Register a specific autoloader for the module
|
||||
*/
|
||||
public function registerAutoloaders(DiInterface $di = null)
|
||||
{
|
||||
$loader = new Loader();
|
||||
|
||||
$loader->registerNamespaces([
|
||||
$this->_controllerNamespace => $this->_controllerPath,
|
||||
]);
|
||||
|
||||
$loader->register();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register specific services for the module
|
||||
*/
|
||||
public function registerServices(DiInterface $di)
|
||||
{
|
||||
$dispatcher = $di->get('dispatcher');
|
||||
|
||||
$dispatcher->setDefaultNamespace($this->_controllerNamespace);
|
||||
|
||||
$di->get('view')->setViewsDir(array_merge(
|
||||
[ $this->_viewDir ],
|
||||
(array) $di->get('view')->getViewsDir()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
12
app/modules/Main.php
Normal file
12
app/modules/Main.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Module;
|
||||
|
||||
class Main extends Base
|
||||
{
|
||||
protected $_controllerPath = APP_PATH . '/app/controllers';
|
||||
|
||||
protected $_controllerNamespace = 'App\Controller';
|
||||
|
||||
protected $_viewDir = '../app/views/main/';
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
<header class="head-section">
|
||||
<div class="top-section">
|
||||
{% include "_templates/navigation.volt" %}
|
||||
{% include "_components/navigation.volt" %}
|
||||
</div>
|
||||
|
||||
{% block masthead %}{% endblock %}
|
||||
|
|
@ -20,14 +20,14 @@
|
|||
|
||||
<main class="content-section">
|
||||
|
||||
{% include "_templates/flash.volt" %}
|
||||
{% include "_components/flash.volt" %}
|
||||
|
||||
{{ content() }}
|
||||
|
||||
</main>
|
||||
|
||||
<div class="footer-section">
|
||||
{% include "_templates/footer.volt" %}
|
||||
{% include "_components/footer.volt" %}
|
||||
</div>
|
||||
|
||||
{{ assets.outputJs() }}
|
||||
19
app/views/backend/_layouts/side-menu.volt
Normal file
19
app/views/backend/_layouts/side-menu.volt
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
<div class="backend">
|
||||
|
||||
<ul class="backend-sidemenu">
|
||||
<li><a href="{{ url('/admin') }}">
|
||||
{{ icon('solid/users') }} Users
|
||||
</a></li>
|
||||
<li><a href="{{ url('/admin/log') }}">
|
||||
{{ icon('solid/bars') }} Log
|
||||
</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="backend-content">
|
||||
{{ content() }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
34
app/views/backend/log/index.volt
Normal file
34
app/views/backend/log/index.volt
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
<h1>Activity Log</h1>
|
||||
|
||||
<table class="table table-condensed table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Ip</th>
|
||||
<th>User</th>
|
||||
<th>Message</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for item in page.items %}
|
||||
<tr>
|
||||
<td>{{ item.getTimestamp() }}</td>
|
||||
<td>{{ item.getIp() }}</td>
|
||||
<td>
|
||||
{% if item.getUser() %}
|
||||
{{ item.getUser().getId() }}:{{ item.getUser().getUsername() }}
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ item.getMessage() }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<nav class="text-center" aria-label="Page navigation">
|
||||
{{ partial('pagination') }}
|
||||
</nav>
|
||||
33
app/views/backend/user/index.volt
Normal file
33
app/views/backend/user/index.volt
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
<h1>Users</h1>
|
||||
|
||||
<table class="table table-striped table-hover">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Username</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Type</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for item in page.items %}
|
||||
<tr>
|
||||
<td>{{ item.id }}</td>
|
||||
<td>{{ item.username }}</td>
|
||||
<td>{{ item.name }}</td>
|
||||
<td>{{ item.email }}</td>
|
||||
<td>{{ item.type }}</td>
|
||||
<td>{{ item.status }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<nav class="text-center" aria-label="Page navigation">
|
||||
{{ partial('pagination') }}
|
||||
</nav>
|
||||
68
docs/ACL.md
Normal file
68
docs/ACL.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
# ACL
|
||||
|
||||
The ACL is defined as follows:
|
||||
|
||||
## Roles
|
||||
|
||||
Roles define a group of user. like Author, Admin, Guest etc.
|
||||
Each role can inherit other roles with the "inherit" key.
|
||||
Each role can gain access to a zone (explained later) by the
|
||||
"allowed-zones" key. Per default a role is denied access to all zones.
|
||||
|
||||
## Resources
|
||||
|
||||
Resources maps directly to `controller` names. If a controller is not
|
||||
under the default module. `<module>/<controller>` format is used instead.
|
||||
|
||||
A special wildcard `*` character can be used to allow access to all
|
||||
controllers (most likely only useful for non-default modules).
|
||||
|
||||
For example the resource `backend/*` Matches all controllers under
|
||||
the backend module.
|
||||
|
||||
### Special controllers.
|
||||
|
||||
There a 2 controllers that are a bit special,
|
||||
`index` and `error` resources are always accessible by everyone (e.g. they
|
||||
are not part of the ACL).
|
||||
|
||||
## Access levels.
|
||||
|
||||
These are not used in this system. a hardcoded "All" level is used.
|
||||
|
||||
## Zones
|
||||
|
||||
Zones defines as 1 or more resources. for example an "backend" zone can
|
||||
have 2 controllers/resources (*site-config*, *user-manager*)
|
||||
|
||||
Zones can also defines entire modules
|
||||
|
||||
|
||||
# Example config.
|
||||
|
||||
acl.yml
|
||||
```yaml
|
||||
acl:
|
||||
roles:
|
||||
guest: # Guests are only allowed to access the public zone.
|
||||
allowed-zones: public
|
||||
description: Non logged in users
|
||||
user: # Users inherits the guest role + has access to user zone.
|
||||
inherits: guest
|
||||
allowed-zones: user
|
||||
description: Logged in users
|
||||
admin: # Admins inherits the user role + has access to backend zone.
|
||||
inherits: user
|
||||
description: Administrators
|
||||
allowed-zones: backend
|
||||
|
||||
zones:
|
||||
# Public zone is the start page in
|
||||
# index controller + login/logout in auth.
|
||||
public: [ auth ]
|
||||
# User zone can access profile and settings controllers
|
||||
user: [ profile, settings ]
|
||||
# Backend zone is the entire backend module.
|
||||
backend: backend/*
|
||||
```
|
||||
Reference in a new issue