fix: [userSettings] Allow admin to edit other user's settings

cli-modification-summary
Sami Mokaddem 2022-01-26 12:11:44 +01:00
parent 44913c5ed7
commit f53b458103
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
7 changed files with 80 additions and 32 deletions

View File

@ -188,12 +188,12 @@ class ACLComponent extends Component
'add' => ['*'],
'edit' => ['*'],
'delete' => ['*'],
'getSettingByName' => ['*'],
'setSetting' => ['*'],
'getMySettingByName' => ['*'],
'setMySetting' => ['*'],
'saveSetting' => ['*'],
'getBookmarks' => ['*'],
'saveBookmark' => ['*'],
'deleteBookmark' => ['*']
'getMyBookmarks' => ['*'],
'saveMyBookmark' => ['*'],
'deleteMyBookmark' => ['*']
],
'Api' => [
'index' => ['*']

View File

@ -124,7 +124,13 @@ class UserSettingsController extends AppController
}
}
public function getSettingByName($settingsName)
/**
* Get a setting by name for the currently logged-in user
*
* @param [type] $settingsName
* @return void
*/
public function getMySettingByName($settingsName)
{
$setting = $this->UserSettings->getSettingByName($this->ACL->getUser(), $settingsName);
if (is_null($setting)) {
@ -140,7 +146,7 @@ class UserSettingsController extends AppController
$this->render('view');
}
public function setSetting($settingsName = false)
public function setMySetting($settingsName = false)
{
if (!$this->request->is('get')) {
$setting = $this->UserSettings->getSettingByName($this->ACL->getUser(), $settingsName);
@ -160,22 +166,23 @@ class UserSettingsController extends AppController
$this->set('settingName', $settingsName);
}
public function saveSetting()
public function saveSetting($user_id = false)
{
$user = $this->getRequestedUserIfAllowed($user_id);
if ($this->request->is('post')) {
$data = $this->ParamHandler->harvestParams([
'name',
'value'
]);
$setting = $this->UserSettings->getSettingByName($this->ACL->getUser(), $data['name']);
$setting = $this->UserSettings->getSettingByName($user, $data['name']);
if (is_null($setting)) { // setting not found, create it
$result = $this->UserSettings->createSetting($this->ACL->getUser(), $data['name'], $data['value']);
$result = $this->UserSettings->createSetting($user, $data['name'], $data['value']);
} else {
$result = $this->UserSettings->editSetting($this->ACL->getUser(), $data['name'], $data['value']);
$result = $this->UserSettings->editSetting($user, $data['name'], $data['value']);
}
$success = !empty($result);
$message = $success ? __('Setting saved') : __('Could not save setting');
$this->CRUD->setResponseForController('setSetting', $success, $message, $result);
$this->CRUD->setResponseForController('saveSetting', $success, $message, $result);
$responsePayload = $this->CRUD->getResponsePayload();
if (!empty($responsePayload)) {
return $responsePayload;
@ -183,7 +190,7 @@ class UserSettingsController extends AppController
}
}
public function getBookmarks($forSidebar = false)
public function getMyBookmarks($forSidebar = false)
{
$bookmarks = $this->UserSettings->getSettingByName($this->ACL->getUser(), $this->UserSettings->BOOKMARK_SETTING_NAME);
$bookmarks = json_decode($bookmarks['value'], true);
@ -193,7 +200,7 @@ class UserSettingsController extends AppController
$this->render('/element/UserSettings/saved-bookmarks');
}
public function saveBookmark()
public function saveMyBookmark()
{
if (!$this->request->is('get')) {
$result = $this->UserSettings->saveBookmark($this->ACL->getUser(), $this->request->getData());
@ -208,7 +215,7 @@ class UserSettingsController extends AppController
$this->set('user_id', $this->ACL->getUser()->id);
}
public function deleteBookmark()
public function deleteMyBookmark()
{
if (!$this->request->is('get')) {
$result = $this->UserSettings->deleteBookmark($this->ACL->getUser(), $this->request->getData());
@ -248,4 +255,26 @@ class UserSettingsController extends AppController
}
return $isAllowed;
}
/**
* Return the requested user if user permissions allow it. Otherwise, return the user currently logged-in
*
* @param bool|int $user_id
* @return void
*/
private function getRequestedUserIfAllowed($user_id = false)
{
$currentUser = $this->ACL->getUser();
if (is_bool($user_id)) {
return $currentUser;
}
if (!empty($currentUser['role']['perm_admin'])) {
$user = $this->Users->get($user_id, [
'contain' => ['Roles', 'Individuals' => 'Organisations']
]);
} else {
$user = $currentUser;
}
return $user;
}
}

View File

@ -220,14 +220,17 @@ class UsersController extends AppController
public function settings($user_id=false)
{
$editingAnotherUser = false;
$currentUser = $this->ACL->getUser();
if (empty($currentUser['role']['perm_admin'])) {
if (empty($currentUser['role']['perm_admin']) || $user_id == $currentUser->id) {
$user = $currentUser;
} else {
$user = $this->Users->get($user_id, [
'contain' => ['Roles', 'Individuals' => 'Organisations']
'contain' => ['Roles', 'Individuals' => 'Organisations', 'Organisations', 'UserSettings']
]);
$editingAnotherUser = true;
}
$this->set('editingAnotherUser', $editingAnotherUser);
$this->set('user', $user);
$all = $this->Users->UserSettings->getSettingsFromProviderForUser($user->id, true);
$this->set('settingsProvider', $all['settingsProvider']);

View File

@ -10,10 +10,12 @@ foreach ($settingsProvider as $settingTitle => $settingContent) {
]);
}
$navLinks[] = __('Bookmarks');
$tabContents[] = $this->element('UserSettings/saved-bookmarks', [
if (empty($editingAnotherUser)) {
$navLinks[] = __('Bookmarks');
$tabContents[] = $this->element('UserSettings/saved-bookmarks', [
'bookmarks' => !empty($user->user_settings_by_name['ui.bookmarks']['value']) ? json_decode($user->user_settings_by_name['ui.bookmarks']['value'], true) : []
]);
]);
}
$tabsOptions = [
'vertical' => true,
@ -29,11 +31,15 @@ $tabsOptions = [
];
$tabs = $this->Bootstrap->tabs($tabsOptions);
echo $this->Html->script('settings');
$saveUrl = '/userSettings/saveSetting';
if(!empty($editingAnotherUser)) {
$saveUrl .= '/' . h($user->id);
}
?>
<script>
window.settingsFlattened = <?= json_encode($settingsFlattened) ?>;
window.saveSettingURL = '/userSettings/saveSetting'
window.saveSettingURL = '<?= $saveUrl ?>'
</script>
<h2 class="fw-light"><?= __('Account settings') ?></h2>
@ -43,7 +49,17 @@ echo $this->Html->script('settings');
<span class="fw-bold font-monospace me-2 fs-5"><?= h($user->username) ?></span>
<span><?= h($user->individual->full_name) ?></span>
</div>
<?php if (!empty($editingAnotherUser)): ?>
<?=
$this->Bootstrap->alert([
'text' => __('Currently editing the account setting of another user.'),
'variant' => 'warning',
'dismissible' => false
])
?>
<?php else: ?>
<div class="fw-light"><?= __('Your personnal account') ?></div>
<?php endif; ?>
</div>
<div class="mt-2">
<?= $tabs ?>

View File

@ -57,6 +57,6 @@ $mainPanelHeight = 'calc(100vh - 42px - 1rem - 56px - 38px - 1rem)';
</div>
<?php else: ?>
<div>
<?= $contentHtml ?>
<?= !empty($contentHtml) ? $contentHtml : sprintf('<p class="text-center mt-3">%s</p>', __('No settings available for this category')) ?>
</div>
<?php endif; ?>

View File

@ -167,7 +167,7 @@ function saveSetting(statusNode, settingName, settingValue) {
}
function openSaveBookmarkModal(bookmark_url = '') {
const url = '/user-settings/saveBookmark';
const url = '/user-settings/saveMyBookmark';
UI.submissionModal(url).then(([modalFactory, ajaxApi]) => {
const $input = modalFactory.$modal.find('input[name="bookmark_url"]')
$input.val(bookmark_url)
@ -175,7 +175,7 @@ function openSaveBookmarkModal(bookmark_url = '') {
}
function deleteBookmark(bookmark, forSidebar=false) {
const url = '/user-settings/deleteBookmark'
const url = '/user-settings/deleteMyBookmark'
AJAXApi.quickFetchAndPostForm(url, {
bookmark_name: bookmark.name,
bookmark_url: bookmark.url,
@ -183,7 +183,7 @@ function deleteBookmark(bookmark, forSidebar=false) {
provideFeedback: true,
statusNode: $('.bookmark-table-container'),
}).then((apiResult) => {
const url = `/userSettings/getBookmarks/${forSidebar ? '1' : '0'}`
const url = `/userSettings/getMyBookmarks/${forSidebar ? '1' : '0'}`
UI.reload(url, $('.bookmark-table-container').parent())
const theToast = UI.toast({
variant: 'success',
@ -191,7 +191,7 @@ function deleteBookmark(bookmark, forSidebar=false) {
bodyHtml: $('<div/>').append(
$('<span/>').text('Cancel deletion operation.'),
$('<button/>').addClass(['btn', 'btn-primary', 'btn-sm', 'ms-3']).text('Restore bookmark').click(function () {
const urlRestore = '/user-settings/saveBookmark'
const urlRestore = '/user-settings/saveMyBookmark'
AJAXApi.quickFetchAndPostForm(urlRestore, {
bookmark_label: bookmark.label,
bookmark_name: bookmark.name,
@ -200,7 +200,7 @@ function deleteBookmark(bookmark, forSidebar=false) {
provideFeedback: true,
statusNode: $('.bookmark-table-container')
}).then(() => {
const url = `/userSettings/getBookmarks/${forSidebar ? '1' : '0'}`
const url = `/userSettings/getMyBookmarks/${forSidebar ? '1' : '0'}`
UI.reload(url, $('.bookmark-table-container').parent())
})
}),
@ -297,7 +297,7 @@ $(document).ready(() => {
$sidebar.addClass('expanded')
}
const settingName = 'ui.sidebar.expanded';
const url = `/user-settings/setSetting/${settingName}`
const url = `/user-settings/setMySetting/${settingName}`
AJAXApi.quickFetchAndPostForm(url, {
value: expanded ? 0 : 1
}, { provideFeedback: false})

View File

@ -1,7 +1,7 @@
// function saveHiddenColumns(table_setting_id, newTableSettings) {
function mergeAndSaveSettings(table_setting_id, newTableSettings) {
const settingName = 'ui.table_setting'
const urlGet = `/user-settings/getSettingByName/${settingName}`
const urlGet = `/user-settings/getMySettingByName/${settingName}`
AJAXApi.quickFetchJSON(urlGet).then(tableSettings => {
tableSettings = JSON.parse(tableSettings.value)
newTableSettings = mergeNewTableSettingsIntoOld(table_setting_id, tableSettings, newTableSettings)
@ -19,7 +19,7 @@ function mergeNewTableSettingsIntoOld(table_setting_id, oldTableSettings, newTab
}
function saveTableSetting(settingName, newTableSettings) {
const urlSet = `/user-settings/setSetting/${settingName}`
const urlSet = `/user-settings/setMySetting/${settingName}`
AJAXApi.quickFetchAndPostForm(urlSet, {
value: JSON.stringify(newTableSettings)
}, {