Migrate permissions system to use hard-coded action lists, and update the Permissions management page to solely allow role management.

This commit is contained in:
Buster Silver 2016-10-07 15:57:42 -05:00
parent 9a927d97f1
commit cf69f61cf7
12 changed files with 232 additions and 252 deletions

View File

@ -5,9 +5,9 @@
namespace App; namespace App;
use Entity\RolePermission;
use Entity\User; use Entity\User;
use Entity\Role; use Entity\Role;
use Entity\RoleHasAction;
class Acl class Acl
{ {
@ -32,7 +32,7 @@ class Acl
protected function init() protected function init()
{ {
if (null === $this->_actions) if (null === $this->_actions)
$this->_actions = $this->_em->getRepository(RoleHasAction::class)->getActionsForAllRoles(); $this->_actions = $this->_em->getRepository(RolePermission::class)->getActionsForAllRoles();
} }
/** /**

View File

@ -1,40 +0,0 @@
<?php
namespace Entity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Table(name="action")
* @Entity(repositoryClass="ActionRepository")
*/
class Action extends \App\Doctrine\Entity
{
public function __construct()
{
$this->is_global = false;
$this->has_role = new ArrayCollection;
}
/**
* @Column(name="id", type="integer")
* @Id
* @GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/** @Column(name="name", type="string", length=100, nullable=true) */
protected $name;
/** @Column(name="is_global", type="boolean") */
protected $is_global;
/** @OneToMany(targetEntity="Entity\RoleHasAction", mappedBy="action") */
protected $has_role;
}
use App\Doctrine\Repository;
class ActionRepository extends Repository
{
}

View File

@ -12,7 +12,7 @@ class Role extends \App\Doctrine\Entity
public function __construct() public function __construct()
{ {
$this->users = new ArrayCollection; $this->users = new ArrayCollection;
$this->has_action = new ArrayCollection; $this->permissions = new ArrayCollection;
} }
/** /**
@ -28,6 +28,6 @@ class Role extends \App\Doctrine\Entity
/** @ManyToMany(targetEntity="User", mappedBy="roles")*/ /** @ManyToMany(targetEntity="User", mappedBy="roles")*/
protected $users; protected $users;
/** @OneToMany(targetEntity="Entity\RoleHasAction", mappedBy="role") */ /** @OneToMany(targetEntity="Entity\RolePermission", mappedBy="role") */
protected $has_action; protected $permissions;
} }

View File

@ -4,12 +4,12 @@ namespace Entity;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
/** /**
* @Table(name="role_has_actions", uniqueConstraints={ * @Table(name="role_permissions", uniqueConstraints={
* @UniqueConstraint(name="role_action_unique_idx", columns={"role_id","action_id","station_id"}) * @UniqueConstraint(name="role_permission_unique_idx", columns={"role_id","action_name","station_id"})
* }) * })
* @Entity(repositoryClass="RoleHasActionRepository") * @Entity(repositoryClass="RolePermissionRepository")
*/ */
class RoleHasAction extends \App\Doctrine\Entity class RolePermission extends \App\Doctrine\Entity
{ {
/** /**
* @Column(name="id", type="integer") * @Column(name="id", type="integer")
@ -22,23 +22,15 @@ class RoleHasAction extends \App\Doctrine\Entity
protected $role_id; protected $role_id;
/** /**
* @ManyToOne(targetEntity="Role", inversedBy="has_actions") * @ManyToOne(targetEntity="Role", inversedBy="permissions")
* @JoinColumns({ * @JoinColumns({
* @JoinColumn(name="role_id", referencedColumnName="id", onDelete="CASCADE") * @JoinColumn(name="role_id", referencedColumnName="id", onDelete="CASCADE")
* }) * })
*/ */
protected $role; protected $role;
/** @Column(name="action_id", type="integer") */ /** @Column(name="action_name", type="string", length=50, nullable=false) */
protected $action_id; protected $action_name;
/**
* @ManyToOne(targetEntity="Action", inversedBy="has_roles")
* @JoinColumns({
* @JoinColumn(name="action_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
protected $action;
/** @Column(name="station_id", type="integer", nullable=true) */ /** @Column(name="station_id", type="integer", nullable=true) */
protected $station_id; protected $station_id;
@ -54,54 +46,24 @@ class RoleHasAction extends \App\Doctrine\Entity
use App\Doctrine\Repository; use App\Doctrine\Repository;
class RoleHasActionRepository extends Repository class RolePermissionRepository extends Repository
{ {
public function getActionsForAllRoles() public function getActionsForAllRoles()
{ {
$role_has_actions = $this->_em->createQuery('SELECT rha, a FROM '.$this->_entityName.' rha JOIN rha.action a') $all_permissions = $this->fetchArray();
->getArrayResult();
$roles = []; $roles = [];
foreach($all_permissions as $row)
foreach($role_has_actions as $row)
{ {
if ($row['station_id']) if ($row['station_id'])
$roles[$row['role_id']]['stations'][$row['station_id']][] = $row['action']['name']; $roles[$row['role_id']]['stations'][$row['station_id']][] = $row['action_name'];
else else
$roles[$row['role_id']]['global'][] = $row['action']['name']; $roles[$row['role_id']]['global'][] = $row['action_name'];
} }
return $roles; return $roles;
} }
public function getSelectableActions()
{
$actions = [];
$all_actions = $this->_em->getRepository(Action::class)->fetchArray();
$all_stations = $this->_em->getRepository(Station::class)->fetchArray();
foreach($all_actions as $action)
{
if ($action['is_global'])
{
$actions['global'][$action['id']] = $action['name'];
}
else
{
foreach($all_stations as $station)
{
if (!isset($actions['stations'][$station['id']]))
$actions['stations'][$station['id']] = ['name' => $station['name'], 'actions' => []];
$actions['stations'][$station['id']]['actions'][$action['id']] = $action['name'];
}
}
}
return $actions;
}
public function getActionsForRole(Role $role) public function getActionsForRole(Role $role)
{ {
$role_has_action = $this->findBy(['role_id' => $role->id]); $role_has_action = $this->findBy(['role_id' => $role->id]);
@ -110,9 +72,9 @@ class RoleHasActionRepository extends Repository
foreach($role_has_action as $row) foreach($role_has_action as $row)
{ {
if ($row['station_id']) if ($row['station_id'])
$result['actions_'.$row['station_id']][] = $row['action_id']; $result['actions_'.$row['station_id']][] = $row['action_name'];
else else
$result['actions_global'][] = $row['action_id']; $result['actions_global'][] = $row['action_name'];
} }
return $result; return $result;
@ -120,7 +82,7 @@ class RoleHasActionRepository extends Repository
public function setActionsForRole(Role $role, $post_values) public function setActionsForRole(Role $role, $post_values)
{ {
$this->_em->createQuery('DELETE FROM '.$this->_entityName.' rha WHERE rha.role_id = :role_id') $this->_em->createQuery('DELETE FROM '.$this->_entityName.' rp WHERE rp.role_id = :role_id')
->setParameter('role_id', $role->id) ->setParameter('role_id', $role->id)
->execute(); ->execute();
@ -131,17 +93,17 @@ class RoleHasActionRepository extends Repository
if ($post_key_action !== 'actions' || empty($post_value)) if ($post_key_action !== 'actions' || empty($post_value))
continue; continue;
foreach((array)$post_value as $action_id) foreach((array)$post_value as $action_name)
{ {
$record_info = [ $record_info = [
'role_id' => $role->id, 'role_id' => $role->id,
'action_id' => $action_id 'action_name' => $action_name,
]; ];
if ($post_key_id !== 'global') if ($post_key_id !== 'global')
$record_info['station_id'] = $post_key_id; $record_info['station_id'] = $post_key_id;
$record = new RoleHasAction; $record = new RolePermission;
$record->fromArray($this->_em, $record_info); $record->fromArray($this->_em, $record_info);
$this->_em->persist($record); $this->_em->persist($record);

View File

@ -0,0 +1,47 @@
<?php
namespace Migration;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
/**
* Auto-generated Migration: Please modify to your needs!
*/
class Version20161007195027 extends AbstractMigration
{
/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('CREATE TABLE role_permissions (id INT AUTO_INCREMENT NOT NULL, role_id INT NOT NULL, station_id INT DEFAULT NULL, action_name VARCHAR(50) NOT NULL, INDEX IDX_1FBA94E6D60322AC (role_id), INDEX IDX_1FBA94E621BDB235 (station_id), UNIQUE INDEX role_permission_unique_idx (role_id, action_name, station_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
$this->addSql('ALTER TABLE role_permissions ADD CONSTRAINT FK_1FBA94E6D60322AC FOREIGN KEY (role_id) REFERENCES role (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE role_permissions ADD CONSTRAINT FK_1FBA94E621BDB235 FOREIGN KEY (station_id) REFERENCES station (id) ON DELETE CASCADE');
$this->addSql('INSERT INTO role_permissions (role_id, action_name, station_id) SELECT rha.role_id, a.name, rha.station_id FROM role_has_actions AS rha INNER JOIN action AS a ON rha.action_id = a.id');
$this->addSql('ALTER TABLE role_has_actions DROP FOREIGN KEY FK_50EEC1BD9D32F035');
$this->addSql('DROP TABLE action');
$this->addSql('DROP TABLE role_has_actions');
}
/**
* @param Schema $schema
*/
public function down(Schema $schema)
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('CREATE TABLE action (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(100) DEFAULT NULL COLLATE utf8_unicode_ci, is_global TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE role_has_actions (id INT AUTO_INCREMENT NOT NULL, station_id INT DEFAULT NULL, action_id INT NOT NULL, role_id INT NOT NULL, UNIQUE INDEX role_action_unique_idx (role_id, action_id, station_id), INDEX IDX_50EEC1BDD60322AC (role_id), INDEX IDX_50EEC1BD21BDB235 (station_id), INDEX IDX_50EEC1BD9D32F035 (action_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
$this->addSql('ALTER TABLE role_has_actions ADD CONSTRAINT FK_50EEC1BD21BDB235 FOREIGN KEY (station_id) REFERENCES station (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE role_has_actions ADD CONSTRAINT FK_50EEC1BD9D32F035 FOREIGN KEY (action_id) REFERENCES action (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE role_has_actions ADD CONSTRAINT FK_50EEC1BDD60322AC FOREIGN KEY (role_id) REFERENCES role (id) ON DELETE CASCADE');
$this->addSql('DROP TABLE role_permissions');
}
}

View File

@ -0,0 +1,30 @@
<?php
/**
* Module-specific actions (permissions)
*/
return [
'global' => [
'administer all',
'view administration',
'administer settings',
'administer api keys',
'administer user accounts',
'administer permissions',
'administer stations',
],
'station' => [
],
];
/*
['view station management', 0],
['view station reports', 0],
['manage station profile', 0],
['manage station broadcasting', 0],
['manage station streamers', 0],
['manage station media', 0],
['manage station automation', 0],
];
*/

View File

@ -27,7 +27,7 @@ return [
'icon' => 'fa fa-user', 'icon' => 'fa fa-user',
'permission' => 'administer user accounts', 'permission' => 'administer user accounts',
], ],
_('Roles and Permissions') => [ _('Permissions') => [
'url' => 'admin:permissions:index', 'url' => 'admin:permissions:index',
'icon' => 'fa fa-key', 'icon' => 'fa fa-key',
'permission' => 'administer permissions', 'permission' => 'administer permissions',

View File

@ -3,10 +3,28 @@
* Edit Role Form * Edit Role Form
*/ */
/** @var array */
$module_config = $di['module_config'];
$actions = [];
foreach($module_config as $module_name => $config_row)
{
$module_actions = $config_row->actions->toArray();
if (!empty($module_actions))
{
foreach($module_actions['global'] as $action_name)
$actions['global'][$action_name] = $action_name;
foreach($module_actions['station'] as $action_name)
$actions['station'][$action_name] = $action_name;
}
}
/** @var \Doctrine\ORM\EntityManager $em */ /** @var \Doctrine\ORM\EntityManager $em */
$em = $di['em']; $em = $di['em'];
$all_stations = $em->getRepository(\Entity\Station::class)->fetchArray();
$all_actions = $em->getRepository(\Entity\RoleHasAction::class)->getSelectableActions();
$form_config = [ $form_config = [
'method' => 'post', 'method' => 'post',
@ -23,30 +41,31 @@ $form_config = [
], ],
], ],
],
];
$form_config['groups']['grp_global'] = [ 'grp_global' => [
'legend' => _('System-Wide Permissions'), 'legend' => _('System-Wide Permissions'),
'elements' => [ 'elements' => [
'actions_global' => ['multiCheckbox', [ 'actions_global' => ['multiCheckbox', [
'label' => _('Actions'), 'label' => _('Actions'),
'multiOptions' => $all_actions['global'], 'multiOptions' => $actions['global'],
]], ]],
],
],
], ],
]; ];
foreach($all_actions['stations'] as $station_id => $station_info) foreach($all_stations as $station)
{ {
$form_config['groups']['grp_station_'.$station_id] = [ $form_config['groups']['grp_station_'.$station['id']] = [
'legend' => $station_info['name'], 'legend' => $station['name'],
'elements' => [ 'elements' => [
'actions_'.$station_id => ['multiCheckbox', [ 'actions_'.$station['id'] => ['multiCheckbox', [
'label' => _('Actions'), 'label' => _('Actions'),
'multiOptions' => $station_info['actions'], 'multiOptions' => $actions['station'],
]], ]],
], ],

View File

@ -1,9 +1,8 @@
<?php <?php
namespace Modules\Admin\Controllers; namespace Modules\Admin\Controllers;
use \Entity\Action; use Entity\Role;
use \Entity\Role; use Entity\RolePermission;
use Entity\RoleHasAction;
class PermissionsController extends BaseController class PermissionsController extends BaseController
{ {
@ -14,50 +13,31 @@ class PermissionsController extends BaseController
public function indexAction() public function indexAction()
{ {
$this->view->actions = $this->em->getRepository(Action::class)->fetchArray(false, 'name'); $all_roles = $this->em->createQuery('SELECT r, rp, s FROM Entity\Role r LEFT JOIN r.users u LEFT JOIN r.permissions rp LEFT JOIN rp.station s ORDER BY r.id ASC')
$this->view->roles = $this->em->getRepository(Role::class)->fetchArray(false, 'name'); ->getArrayResult();
}
$roles = [];
public function editactionAction()
{ foreach($all_roles as $role)
$form = new \App\Form($this->current_module_config->forms->action->toArray());
if ($this->hasParam('id'))
{ {
$record = $this->em->getRepository(Action::class)->find($this->getParam('id')); $role['permissions_global'] = [];
$form->setDefaults($record->toArray($this->em)); $role['permissions_station'] = [];
foreach($role['permissions'] as $permission)
{
if ($permission['station'])
$role['permissions_station'][$permission['station']['name']][] = $permission['action_name'];
else
$role['permissions_global'][] = $permission['action_name'];
}
$roles[] = $role;
} }
if(!empty($_POST) && $form->isValid($_POST)) $this->view->roles = $roles;
{
$data = $form->getValues();
if (!($record instanceof Action))
$record = new Action;
$record->fromArray($this->em, $data);
$this->em->persist($record);
$this->em->flush();
$this->alert(_('Record updated.'), 'green');
return $this->redirectFromHere(array('action' => 'index', 'id' => NULL, 'csrf' => NULL));
}
return $this->renderForm($form, 'edit', _('Edit Record'));
}
public function deleteactionAction()
{
$action = $this->em->getRepository(Action::class)->find($this->getParam('id'));
if ($action)
$action->delete();
$this->alert(_('Record deleted.'), 'green');
return $this->redirectFromHere(array('action' => 'index', 'id' => NULL, 'csrf' => NULL));
} }
public function rolemembersAction() public function membersAction()
{ {
$roles = $this->em->createQuery('SELECT r, a, u FROM Entity\Role r LEFT JOIN r.actions a LEFT JOIN r.users u') $roles = $this->em->createQuery('SELECT r, a, u FROM Entity\Role r LEFT JOIN r.actions a LEFT JOIN r.users u')
->getArrayResult(); ->getArrayResult();
@ -65,7 +45,7 @@ class PermissionsController extends BaseController
$this->view->roles = $roles; $this->view->roles = $roles;
} }
public function editroleAction() public function editAction()
{ {
$form = new \App\Form($this->current_module_config->forms->role->toArray()); $form = new \App\Form($this->current_module_config->forms->role->toArray());
@ -74,7 +54,7 @@ class PermissionsController extends BaseController
$record = $this->em->getRepository(Role::class)->find($this->getParam('id')); $record = $this->em->getRepository(Role::class)->find($this->getParam('id'));
$record_info = $record->toArray($this->em, true, true); $record_info = $record->toArray($this->em, true, true);
$actions = $this->em->getRepository(RoleHasAction::class)->getActionsForRole($record); $actions = $this->em->getRepository(RolePermission::class)->getActionsForRole($record);
$form->setDefaults(array_merge($record_info, $actions)); $form->setDefaults(array_merge($record_info, $actions));
} }
@ -91,7 +71,7 @@ class PermissionsController extends BaseController
$this->em->persist($record); $this->em->persist($record);
$this->em->flush(); $this->em->flush();
$this->em->getRepository(RoleHasAction::class)->setActionsForRole($record, $data); $this->em->getRepository(RolePermission::class)->setActionsForRole($record, $data);
$this->alert('<b>'._('Record updated.').'</b>', 'green'); $this->alert('<b>'._('Record updated.').'</b>', 'green');
return $this->redirectFromHere(array('action' => 'index', 'id' => NULL, 'csrf' => NULL)); return $this->redirectFromHere(array('action' => 'index', 'id' => NULL, 'csrf' => NULL));
@ -100,7 +80,7 @@ class PermissionsController extends BaseController
return $this->renderForm($form, 'edit', _('Edit Record')); return $this->renderForm($form, 'edit', _('Edit Record'));
} }
public function deleteroleAction() public function deleteAction()
{ {
$record = $this->em->getRepository(Role::class)->find($this->getParam('id')); $record = $this->em->getRepository(Role::class)->find($this->getParam('id'));
if ($record instanceof Role) if ($record instanceof Role)

View File

@ -31,20 +31,14 @@ $app->group('/admin', function() {
$this->get('', 'admin:permissions:index') $this->get('', 'admin:permissions:index')
->setName('admin:permissions:index'); ->setName('admin:permissions:index');
$this->map(['GET', 'POST'], '/role/edit[/{id}]', 'admin:permissions:editrole') $this->map(['GET', 'POST'], '/edit[/{id}]', 'admin:permissions:edit')
->setName('admin:permissions:editrole'); ->setName('admin:permissions:edit');
$this->get('/role/delete/{id}', 'admin:permissions:deleterole') $this->get('/delete/{id}', 'admin:permissions:delete')
->setName('admin:permissions:deleterole'); ->setName('admin:permissions:delete');
$this->get('/role/members/{id}', 'admin:permissions:rolemembers') $this->get('/members/{id}', 'admin:permissions:members')
->setName('admin:permissions:rolemembers'); ->setName('admin:permissions:members');
$this->map(['GET', 'POST'], '/action/edit[/{id}]', 'admin:permissions:editaction')
->setName('admin:permissions:editaction');
$this->get('/action/delete/{id}', 'admin:permissions:deleteaction')
->setName('admin:permissions:deleteaction');
}); });

View File

@ -4,83 +4,53 @@
<h2><?=_('Manage Permissions') ?></h2> <h2><?=_('Manage Permissions') ?></h2>
</div> </div>
<div class="row"> <div class="card">
<div class="col-sm-6"> <div class="card-header ch-alt">
<div class="card"> <h2><?=_('Roles') ?></h2>
<div class="card-header ch-alt"> <a class="btn bgm-blue btn-float" href="<?=$url->routeFromHere(array('action' => 'edit')) ?>"><i class="zmdi zmdi-plus"></i></a>
<h2><?=_('Roles') ?></h2>
<a class="btn bgm-blue btn-float" href="<?=$url->routeFromHere(array('action' => 'editrole')) ?>"><i class="zmdi zmdi-plus"></i></a>
</div>
<div class="table-responsive">
<table class="table table-striped">
<colgroup>
<col width="40%" />
<col width="60%" />
</colgroup>
<thead>
<tr>
<th>&nbsp;</th>
<th><?=_('Role Name') ?></th>
</tr>
</thead>
<tbody>
<?php foreach($roles as $role): ?>
<tr class="input">
<td class="center">
<a class="btn btn-sm btn-primary" href="<?=$url->routeFromHere(array('action' => 'editrole', 'id' => $role['id'])) ?>"><?=_('Edit') ?></a>
<?php if( $role['id'] != 1 ): ?>
<a class="btn btn-sm btn-danger" href="<?=$url->routeFromHere(array('action' => 'deleterole', 'id' => $role['id'])) ?>"><?=_('Delete') ?></a>
<?php else: ?>
<a class="btn btn-sm btn-danger disabled" href="#" onclick="alert('<?=_('This role cannot be deleted.') ?>'); return false;"><?=_('Delete') ?></a>
<?php endif; ?>
</td>
<td align="left"><?=$this->e($role['name']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div> </div>
<div class="col-sm-6"> <div class="table-responsive">
<div class="card"> <table class="table table-striped">
<div class="card-header ch-alt"> <colgroup>
<h2><?=_('Actions') ?></h2> <col width="20%">
<a class="btn bgm-blue btn-float" href="<?=$url->routeFromHere(array('action' => 'editaction')) ?>"><i class="zmdi zmdi-plus"></i></a> <col width="20%">
</div> <col width="30%">
<div class="table-responsive"> <col width="30%">
<table class="table table-striped"> </colgroup>
<colgroup> <thead>
<col width="40%" /> <tr>
<col width="60%" /> <th><?=_('Actions') ?></th>
</colgroup> <th><?=_('Role Name') ?></th>
<thead> <th><?=_('System-Wide Permissions') ?></th>
<tr> <th><?=_('Per-Station Permissions') ?></th>
<th>&nbsp;</th> </tr>
<th><?=_('Action Name') ?></th> </thead>
</tr> <tbody>
</thead> <?php foreach($roles as $role): ?>
<tbody> <tr class="input">
<?php foreach($actions as $action): ?> <td class="center">
<tr class="input"> <a class="btn btn-sm btn-primary" href="<?=$url->routeFromHere(array('action' => 'edit', 'id' => $role['id'])) ?>"><?=_('Edit') ?></a>
<td class="center">
<a class="btn btn-sm btn-primary" href="<?=$url->routeFromHere(array('action' => 'editaction', 'id' => $action['id'])) ?>"><?=_('Edit') ?></a> <?php if( $role['id'] != 1 ): ?>
<a class="btn btn-sm btn-danger" href="<?=$url->routeFromHere(array('action' => 'deleteaction', 'id' => $action['id'])) ?>"><?=_('Delete') ?></a> <a class="btn btn-sm btn-danger" href="<?=$url->routeFromHere(array('action' => 'delete', 'id' => $role['id'])) ?>"><?=_('Delete') ?></a>
</td> <?php else: ?>
<td align="left"> <a class="btn btn-sm btn-danger disabled" href="#" onclick="alert('<?=_('This role cannot be deleted.') ?>'); return false;"><?=_('Delete') ?></a>
<?=$this->e($action['name']) ?><br><small> <?php endif; ?>
<?php if ($action['is_global']): ?> </td>
<?=_('System-Wide') ?> <td>
<?php else: ?> <big><?=$this->e($role['name']) ?></big>
<?=_('Per-Station') ?> </td>
<? endif; ?> <td>
</small> <?=implode($role['permissions_global'], ', ') ?>
</td> </td>
</tr> <td>
<?php foreach($role['permissions_station'] as $station_name => $station_perms): ?>
<div><b><?=$station_name ?></b>: <?=implode($station_perms, ', ') ?></div>
<?php endforeach; ?> <?php endforeach; ?>
</tbody> </td>
</table> </tr>
</div> <?php endforeach; ?>
</div> </tbody>
</table>
</div> </div>
</div> </div>

View File

@ -0,0 +1,18 @@
<?php
/**
* Module-specific actions (permissions)
*/
return [
'global' => [
],
'station' => [
'view station management',
'view station reports',
'manage station profile',
'manage station broadcasting',
'manage station streamers',
'manage station media',
'manage station automation',
],
];