chg: [users:acl] Improved waterfall model for CRUD operation and updated UI to reflect them

refacto/CRUDComponent
Sami Mokaddem 2023-09-13 09:15:16 +02:00
parent b0ebe774b6
commit 672847b214
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
4 changed files with 57 additions and 48 deletions

View File

@ -352,13 +352,19 @@ class ACLComponent extends Component
if (empty($user) || empty($currentUser)) { if (empty($user) || empty($currentUser)) {
return false; return false;
} }
if ($currentUser['role']['perm_admin']) {
return true;
}
if ($user['id'] === $currentUser['id']) { if ($user['id'] === $currentUser['id']) {
return true; return true;
} }
if (!$currentUser['role']['perm_admin']) {
if ($user['role']['perm_admin']) { if ($user['role']['perm_admin']) {
return false; // org_admins cannot edit admins return false; // org_admins cannot edit admins
} }
if ($currentUser['role']['perm_org_admin'] && $user['role']['perm_group_admin']) {
return false; // org_admins cannot edit group_admin
}
if ($currentUser['role']['perm_group_admin']) { if ($currentUser['role']['perm_group_admin']) {
$this->OrgGroups = TableRegistry::get('OrgGroups'); $this->OrgGroups = TableRegistry::get('OrgGroups');
if ($this->OrgGroups->checkIfUserBelongsToGroupAdminsGroup($currentUser, $user)) { if ($this->OrgGroups->checkIfUserBelongsToGroupAdminsGroup($currentUser, $user)) {
@ -371,13 +377,12 @@ class ACLComponent extends Component
if ($currentUser['id'] == $user['id']) { if ($currentUser['id'] == $user['id']) {
return true; return true;
} }
if ($currentUser['organisation_id'] !== $user['organisation_id']) { if ($currentUser['organisation_id'] === $user['organisation_id']) {
return false;
}
}
}
return true; return true;
} }
}
return false;
}
/* /*
* By default nothing besides the login is public. If configured, override the list with the additional interfaces * By default nothing besides the login is public. If configured, override the list with the additional interfaces

View File

@ -103,5 +103,23 @@ class UsersNavigation extends BaseNavigation
$this->bcf->addSelfLink('Users', 'settings', [ $this->bcf->addSelfLink('Users', 'settings', [
'label' => __('Account settings') 'label' => __('Account settings')
]); ]);
$controller = 'Users';
if (empty($this->viewVars['canEdit'])) {
$this->bcf->removeLink($controller, 'view', $controller, 'edit');
$this->bcf->removeLink($controller, 'edit', $controller, 'edit');
}
}
public function addActions()
{
$controller = 'Users';
if (
empty($this->viewVars['canEdit']) ||
(!empty($this->viewVars['entity']) && $this->viewVars['loggedUser']['id'] == $this->viewVars['entity']['id'])
) {
$this->bcf->removeAction($controller, 'view', $controller, 'delete');
$this->bcf->removeAction($controller, 'edit', $controller, 'delete');
}
} }
} }

View File

@ -19,11 +19,13 @@ class UsersController extends AppController
{ {
$currentUser = $this->ACL->getUser(); $currentUser = $this->ACL->getUser();
$conditions = []; $conditions = [];
$validOrgIDsFOrEdition = [];
if (empty($currentUser['role']['perm_admin'])) { if (empty($currentUser['role']['perm_admin'])) {
$conditions['organisation_id IN'] = [$currentUser['organisation_id']]; $conditions['organisation_id IN'] = [$currentUser['organisation_id']];
if (!empty($currentUser['role']['perm_group_admin'])) { if (!empty($currentUser['role']['perm_group_admin'])) {
$this->loadModel('OrgGroups'); $this->loadModel('OrgGroups');
$conditions['organisation_id IN'] = array_merge($conditions['organisation_id IN'], $this->OrgGroups->getGroupOrgIdsForUser($currentUser)); $validOrgIDsFOrEdition = array_merge($conditions['organisation_id IN'], $this->OrgGroups->getGroupOrgIdsForUser($currentUser));
$conditions['organisation_id IN'] = $validOrgIDsFOrEdition;
} }
} }
$keycloakUsersParsed = null; $keycloakUsersParsed = null;
@ -40,7 +42,8 @@ class UsersController extends AppController
'filters' => $this->filterFields, 'filters' => $this->filterFields,
'quickFilters' => $this->quickFilterFields, 'quickFilters' => $this->quickFilterFields,
'conditions' => $conditions, 'conditions' => $conditions,
'afterFind' => function($data) use ($keycloakUsersParsed) { 'afterFind' => function($data) use ($keycloakUsersParsed, $currentUser) {
$data->_canBeEdited = $this->ACL->canEditUser($currentUser, $data);
// TODO: We might want to uncomment this at some point Still need to evaluate the impact // TODO: We might want to uncomment this at some point Still need to evaluate the impact
// if (!empty(Configure::read('keycloak.enabled'))) { // if (!empty(Configure::read('keycloak.enabled'))) {
// $keycloakUser = $keycloakUsersParsed[$data->username]; // $keycloakUser = $keycloakUsersParsed[$data->username];
@ -57,7 +60,7 @@ class UsersController extends AppController
'validRoles', 'validRoles',
$this->Users->Roles->find('list')->select(['id', 'name'])->order(['name' => 'asc'])->where(['perm_admin' => 0, 'perm_org_admin' => 0])->all()->toArray() $this->Users->Roles->find('list')->select(['id', 'name'])->order(['name' => 'asc'])->where(['perm_admin' => 0, 'perm_org_admin' => 0])->all()->toArray()
); );
$this->set('metaGroup', $this->isAdmin ? 'Administration' : 'Cerebrate'); $this->set('validOrgIDsFOrEdition', $validOrgIDsFOrEdition);
} }
public function add() public function add()
@ -207,8 +210,9 @@ class UsersController extends AppController
if (!empty($responsePayload)) { if (!empty($responsePayload)) {
return $responsePayload; return $responsePayload;
} }
$userToEdit = $this->Users->find()->where(['Users.id' => $id])->contain('Roles')->first();
$this->set('canEdit', $this->ACL->canEditUser($this->ACL->getUser(), $userToEdit));
$this->set('keycloakConfig', Configure::read('keycloak', ['enabled' => false])); $this->set('keycloakConfig', Configure::read('keycloak', ['enabled' => false]));
$this->set('metaGroup', $this->isAdmin ? 'Administration' : 'Cerebrate');
} }
public function edit($id = false) public function edit($id = false)
@ -308,7 +312,8 @@ class UsersController extends AppController
])->toArray() ])->toArray()
]; ];
$this->set(compact('dropdownData')); $this->set(compact('dropdownData'));
$this->set('metaGroup', $this->isAdmin ? 'Administration' : 'Cerebrate'); $userToEdit = $this->Users->find()->where(['Users.id' => $id])->contain('Roles')->first();
$this->set('canEdit', $this->ACL->canEditUser($this->ACL->getUser(), $userToEdit));
$this->render('add'); $this->render('add');
} }

View File

@ -133,19 +133,8 @@ echo $this->element('genericElements/IndexTable/index_table', [
'role_id' => 'role_id' 'role_id' => 'role_id'
] ]
], ],
'function' => function ($row, $options) use ($loggedUser, $validRoles) { 'function' => function ($row, $options) use ($loggedUser, $validRoles, $validOrgIDsFOrEdition) {
if (empty($loggedUser['role']['perm_admin'])) { return $row['_canBeEdited'];
if ($row['id'] == $loggedUser['id']) {
return true;
}
if (empty($loggedUser['role']['perm_org_admin'])) {
return false;
}
if (!isset($validRoles[$options['datapath']['role_id']])) {
return false;
}
}
return true;
} }
] ]
], ],
@ -159,22 +148,14 @@ echo $this->element('genericElements/IndexTable/index_table', [
'role_id' => 'role_id' 'role_id' => 'role_id'
] ]
], ],
'function' => function ($row, $options) use ($loggedUser, $validRoles) { 'function' => function ($row, $options) use ($loggedUser, $validRoles, $validOrgIDsFOrEdition) {
if (empty(Configure::read('user.allow-user-deletion'))) { if (empty(Configure::read('user.allow-user-deletion'))) {
return false; return false;
} }
if ($row['id'] == $loggedUser['id']) { if ($row['id'] == $loggedUser['id']) {
return false; return false;
} }
if (empty($loggedUser['role']['perm_admin'])) { return $row['_canBeEdited'];
if (empty($loggedUser['role']['perm_org_admin'])) {
return false;
}
if (!isset($validRoles[$options['datapath']['role_id']])) {
return false;
}
}
return true;
} }
] ]
], ],