Merge branch 'develop' into main

pull/92/head v1.2
iglocska 2021-12-15 16:31:57 +01:00
commit 33057303b2
No known key found for this signature in database
GPG Key ID: BEA224F1FEF113AC
9 changed files with 167 additions and 58 deletions

View File

@ -116,6 +116,7 @@ class AppController extends Controller
if (!$this->ParamHandler->isRest()) {
$this->set('menu', $this->ACL->getMenu());
$this->set('loggedUser', $this->ACL->getUser());
$this->set('roleAccess', $this->ACL->getRoleAccess(false, false));
}
} else if ($this->ParamHandler->isRest()) {
throw new MethodNotAllowedException(__('Invalid user credentials.'));
@ -131,18 +132,20 @@ class AppController extends Controller
}
$this->ACL->checkAccess();
$this->set('breadcrumb', $this->Navigation->getBreadcrumb());
$this->set('ajax', $this->request->is('ajax'));
$this->request->getParam('prefix');
$this->set('baseurl', Configure::read('App.fullBaseUrl'));
if (!empty($user) && !empty($user->user_settings_by_name['ui.bsTheme']['value'])) {
$this->set('bsTheme', $user->user_settings_by_name['ui.bsTheme']['value']);
} else {
$this->set('bsTheme', Configure::check('ui.bsTheme') ? Configure::read('ui.bsTheme') : 'default');
}
if (!$this->ParamHandler->isRest()) {
$this->set('breadcrumb', $this->Navigation->getBreadcrumb());
$this->set('ajax', $this->request->is('ajax'));
$this->request->getParam('prefix');
$this->set('baseurl', Configure::read('App.fullBaseUrl'));
if (!empty($user) && !empty($user->user_settings_by_name['ui.bsTheme']['value'])) {
$this->set('bsTheme', $user->user_settings_by_name['ui.bsTheme']['value']);
} else {
$this->set('bsTheme', Configure::check('ui.bsTheme') ? Configure::read('ui.bsTheme') : 'default');
}
if ($this->modelClass == 'Tags.Tags') {
$this->set('metaGroup', !empty($this->isAdmin) ? 'Administration' : 'Cerebrate');
if ($this->modelClass == 'Tags.Tags') {
$this->set('metaGroup', !empty($this->isAdmin) ? 'Administration' : 'Cerebrate');
}
}
}
@ -188,4 +191,9 @@ class AppController extends Controller
{
return $this->RestResponse->viewData($this->ACL->findMissingFunctionNames());
}
public function getRoleAccess()
{
return $this->RestResponse->viewData($this->ACL->getRoleAccess(false, false));
}
}

View File

@ -37,6 +37,7 @@ class ACLComponent extends Component
'*' => [
'checkPermission' => ['*'],
'generateUUID' => ['*'],
'getRoleAccess' => ['*'],
'queryACL' => ['perm_admin']
],
'Alignments' => [
@ -45,6 +46,9 @@ class ACLComponent extends Component
'index' => ['*'],
'view' => ['*']
],
'AuditLogs' => [
'index' => ['perm_admin']
],
'AuthKeys' => [
'add' => ['*'],
'delete' => ['*'],
@ -82,19 +86,27 @@ class ACLComponent extends Component
'add' => ['perm_admin'],
'delete' => ['perm_admin'],
'edit' => ['perm_admin'],
'filtering' => ['*'],
'index' => ['*'],
'view' => ['*']
'tag' => ['perm_tagger'],
'untag' => ['perm_tagger'],
'view' => ['*'],
'viewTags' => ['*']
],
'Instance' => [
'home' => ['*'],
'migrate' => ['perm_admin'],
'migrationIndex' => ['perm_admin'],
'rollback' => ['perm_admin'],
'saveSetting' => ['perm_admin'],
'searchAll' => ['*'],
'settings' => ['perm_admin'],
'status' => ['*']
],
'LocalTools' => [
'action' => ['perm_admin'],
'add' => ['perm_admin'],
'batchAction' => ['perm_admin'],
'broodTools' => ['perm_admin'],
'connectionRequest' => ['perm_admin'],
'connectLocal' => ['perm_admin'],
@ -123,7 +135,10 @@ class ACLComponent extends Component
'edit' => ['perm_admin'],
'filtering' => ['*'],
'index' => ['*'],
'view' => ['*']
'tag' => ['perm_tagger'],
'untag' => ['perm_tagger'],
'view' => ['*'],
'viewTags' => ['*']
],
'Outbox' => [
'createEntry' => ['perm_admin'],
@ -162,8 +177,22 @@ class ACLComponent extends Component
'login' => ['*'],
'logout' => ['*'],
'register' => ['*'],
'settings' => ['*'],
'toggle' => ['perm_org_admin'],
'view' => ['*']
],
'UserSettings' => [
'index' => ['*'],
'view' => ['*'],
'add' => ['*'],
'edit' => ['*'],
'delete' => ['*'],
'getSettingByName' => ['*'],
'setSetting' => ['*'],
'saveSetting' => ['*'],
'getBookmarks' => ['*'],
'saveBookmark' => ['*'],
'deleteBookmark' => ['*']
]
);
@ -267,9 +296,19 @@ class ACLComponent extends Component
return true;
}
//$this->__checkLoggedActions($user, $controller, $action);
if (isset($this->aclList['*'][$action])) {
if ($this->evaluateAccessLeaf('*', $action)) {
return true;
}
}
if (!isset($this->aclList[$controller])) {
return $this->__error(404, __('Invalid controller.'), $soft);
}
return $this->evaluateAccessLeaf($controller, $action);
}
private function evaluateAccessLeaf(string $controller, string $action): bool
{
if (isset($this->aclList[$controller][$action]) && !empty($this->aclList[$controller][$action])) {
if (in_array('*', $this->aclList[$controller][$action])) {
return true;
@ -397,13 +436,18 @@ class ACLComponent extends Component
return $missing;
}
public function getRoleAccess($role = false, $url_mode = true)
{
return $this->__checkRoleAccess($role, $url_mode);
}
public function printRoleAccess($content = false)
{
$results = [];
$this->Role = TableRegistry::get('Role');
$this->Role = TableRegistry::get('Roles');
$conditions = [];
if (is_numeric($content)) {
$conditions = array('Role.id' => $content);
$conditions = array('id' => $content);
}
$roles = $this->Role->find('all', array(
'recursive' => -1,
@ -419,44 +463,54 @@ class ACLComponent extends Component
return $results;
}
private function __checkRoleAccess($role)
private function __formatControllerAction(array $results, string $controller, string $action, $url_mode = true): array
{
$result = [];
foreach ($this->__aclList as $controller => $actions) {
$controllerNames = Inflector::variable($controller) == Inflector::underscore($controller) ? array(Inflector::variable($controller)) : array(Inflector::variable($controller), Inflector::underscore($controller));
foreach ($controllerNames as $controllerName) {
foreach ($actions as $action => $permissions) {
if ($role['perm_site_admin']) {
$result[] = DS . $controllerName . DS . $action;
} elseif (in_array('*', $permissions)) {
$result[] = DS . $controllerName . DS . $action . DS . '*';
} elseif (isset($permissions['OR'])) {
$access = false;
foreach ($permissions['OR'] as $permission) {
if ($role[$permission]) {
$access = true;
}
if ($url_mode) {
$results[] = DS . $controller . DS . $action . DS . '*';
} else {
$results[$controller][] = $action;
}
return $results;
}
private function __checkRoleAccess($role = false, $url_mode = true)
{
$results = [];
if ($role === false) {
$role = $this->getUser()['role'];
}
foreach ($this->aclList as $controller => $actions) {
foreach ($actions as $action => $permissions) {
if ($role['perm_admin']) {
$results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
} elseif (in_array('*', $permissions)) {
$results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
} elseif (isset($permissions['OR'])) {
$access = false;
foreach ($permissions['OR'] as $permission) {
if ($role[$permission]) {
$access = true;
}
if ($access) {
$result[] = DS . $controllerName . DS . $action . DS . '*';
}
} elseif (isset($permissions['AND'])) {
$access = true;
foreach ($permissions['AND'] as $permission) {
if ($role[$permission]) {
$access = false;
}
}
if ($access) {
$result[] = DS . $controllerName . DS . $action . DS . '*';
}
} elseif (isset($permissions[0]) && $role[$permissions[0]]) {
$result[] = DS . $controllerName . DS . $action . DS . '*';
}
if ($access) {
$results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
}
} elseif (isset($permissions['AND'])) {
$access = true;
foreach ($permissions['AND'] as $permission) {
if ($role[$permission]) {
$access = false;
}
}
if ($access) {
$results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
}
} elseif (isset($permissions[0]) && $role[$permissions[0]]) {
$results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
}
}
}
return $result;
return $results;
}
public function getMenu()

View File

@ -50,19 +50,30 @@ class EncryptionKeysController extends AppController
public function add()
{
$orgConditions = [];
$individualConditions = [];
$currentUser = $this->ACL->getUser();
$params = ['redirect' => $this->referer()];
if (empty($currentUser['role']['perm_admin'])) {
$params['beforeSave'] = function($entity) {
$orgConditions = [
'id' => $currentUser['organisation_id']
];
if (empty($currentUser['role']['perm_org_admin'])) {
$individualConditions = [
'id' => $currentUser['individual_id']
];
}
$params['beforeSave'] = function($entity) use($currentUser) {
if ($entity['owner_model'] === 'organisation') {
$entity['owner_id'] = $currentUser['organisation_id'];
} else {
if ($currentUser['role']['perm_org_admin']) {
$validIndividuals = $this->Organisations->Alignments->find('list', [
'fields' => ['distinct(individual_id)'],
$this->loadModel('Alignments');
$validIndividuals = $this->Alignments->find('list', [
'keyField' => 'individual_id',
'valueField' => 'id',
'conditions' => ['organisation_id' => $currentUser['organisation_id']]
]);
if (!in_array($entity['owner_id'], $validIndividuals)) {
])->toArray();
if (!isset($validIndividuals[$entity['owner_id']])) {
throw new MethodNotAllowedException(__('Selected individual cannot be linked by the current user.'));
}
} else {
@ -71,6 +82,7 @@ class EncryptionKeysController extends AppController
}
}
}
return $entity;
};
}
$this->CRUD->add($params);
@ -86,7 +98,8 @@ class EncryptionKeysController extends AppController
'conditions' => $orgConditions
]),
'individual' => $this->Individuals->find('list', [
'sort' => ['email' => 'asc']
'sort' => ['email' => 'asc'],
'conditions' => $individualConditions
])
];
$this->set(compact('dropdownData'));

View File

@ -44,5 +44,6 @@ class AppView extends View
$this->loadHelper('FormFieldMassage');
$this->loadHelper('Paginator', ['templates' => 'cerebrate-pagination-templates']);
$this->loadHelper('Tags.Tag');
$this->loadHelper('ACL');
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\View\Helper;
use Cake\View\Helper;
// This helper helps determining the brightness of a colour (initially only used for the tagging) in order to decide
// what text colour to use against the background (black or white)
class ACLHelper extends Helper {
private $roleAccess = [];
public function checkAccess($controller, $action) {
if (empty($this->roleAccess)) {
$this->roleAccess = $this->getView()->get('roleAccess');
}
if (
in_array($action, $this->roleAccess['*']) ||
(isset($this->roleAccess[$controller]) && in_array($action, $this->roleAccess[$controller]))
) {
return true;
} else {
return false;
}
}
}

View File

@ -10,7 +10,8 @@ echo $this->element('genericElements/IndexTable/index_table', [
'data' => [
'type' => 'simple',
'text' => __('Add sharing group'),
'popover_url' => '/SharingGroups/add'
'popover_url' => '/SharingGroups/add',
'requirement' => $this->ACL->checkAccess('SharingGroups', 'add')
]
]
],
@ -48,9 +49,9 @@ echo $this->element('genericElements/IndexTable/index_table', [
],
[
'name' => __('Members'),
'data_path' => 'alignments',
'data_path' => 'sharing_group_orgs',
'element' => 'count_summary',
'url' => '/sharingGroups/view/{{id}}',
'url' => '/sharingGroups/view/{{url_data}}',
'url_data_path' => 'id'
]
],

View File

@ -25,7 +25,8 @@
'label' => __('Password'),
'type' => 'password',
'required' => $this->request->getParam('action') === 'add' ? 'required' : false,
'autocomplete' => 'new-password'
'autocomplete' => 'new-password',
'value' => ''
],
[
'field' => 'confirm_password',

View File

@ -2,7 +2,7 @@
$controlParams = [
'options' => $fieldData['options'],
'empty' => $fieldData['empty'] ?? false,
'value' => $fieldData['value'] ?? [],
'value' => $fieldData['value'] ?? null,
'multiple' => $fieldData['multiple'] ?? false,
'disabled' => $fieldData['disabled'] ?? false,
'class' => ($fieldData['class'] ?? '') . ' formDropdown form-select'

View File

@ -0,0 +1,6 @@
<?php
$params['div'] = false;
$params['class'] .= ' form-control';
$params['value'] = '';
echo $this->FormFieldMassage->prepareFormElement($this->Form, $params, $fieldData);
?>