new: [security] Setting to hide orgs form sharing group view

pull/6749/head
Jakub Onderka 2020-12-11 22:01:47 +01:00
parent b73e978c09
commit a585466dff
6 changed files with 122 additions and 39 deletions

View File

@ -288,6 +288,16 @@ class SharingGroupsController extends AppController
'LOWER(Organisation.name) LIKE' => $term,
];
}
// To allow sort sharing group by number of organisation and also show org count when user don't have permission ot see them
$this->SharingGroup->addCountField('org_count', $this->SharingGroup->SharingGroupOrg, ['SharingGroupOrg.sharing_group_id = SharingGroup.id']);
$this->paginate['fields'][] = 'SharingGroup.org_count';
if (!$this->__showOrgs()) {
unset($this->paginate['contain']['SharingGroupOrg']);
unset($this->paginate['contain']['SharingGroupServer']);
}
$result = $this->paginate();
// check if the current user can modify or delete the SG
@ -331,21 +341,30 @@ class SharingGroupsController extends AppController
if (!$this->SharingGroup->checkIfAuthorised($this->Auth->user(), $id)) {
throw new MethodNotAllowedException('Sharing group doesn\'t exist or you do not have permission to access it.');
}
$sg = $this->SharingGroup->find('first', [
'conditions' => Validation::uuid($id) ? ['SharingGroup.uuid' => $id] : ['SharingGroup.id' => $id],
'contain' => array(
'SharingGroupOrg' => array(
'Organisation' => array(
'fields' => array('id', 'name', 'uuid', 'local')
)
),
'Organisation',
'SharingGroupServer' => array(
'Server' => array(
'fields' => array('id', 'name', 'url')
)
$contain = array(
'Organisation',
'SharingGroupOrg' => array(
'Organisation' => array(
'fields' => array('id', 'name', 'uuid', 'local')
)
),
'SharingGroupServer' => array(
'Server' => array(
'fields' => array('id', 'name', 'url')
)
)
);
if (!$this->__showOrgs()) {
unset($contain['SharingGroupOrg']);
unset($contain['SharingGroupServer']);
$this->SharingGroup->addCountField('org_count', $this->SharingGroup->SharingGroupOrg, ['SharingGroupOrg.sharing_group_id = SharingGroup.id']);
}
$sg = $this->SharingGroup->find('first', [
'conditions' => Validation::uuid($id) ? ['SharingGroup.uuid' => $id] : ['SharingGroup.id' => $id],
'contain' => $contain,
]);
if (isset($sg['SharingGroupServer'])) {
foreach ($sg['SharingGroupServer'] as $key => $sgs) {
@ -577,4 +596,12 @@ class SharingGroupsController extends AppController
return $this->RestResponse->saveFailResponse('SharingGroup', $action, false, $object_type . ' could not be ' . $actionType . ' the sharing group.', $this->response->type());
}
}
/**
* @return bool
*/
private function __showOrgs()
{
return $this->Auth->user()['Role']['perm_sharing_group'] || !Configure::read('Security.hide_organisations_in_sharing_groups');
}
}

View File

@ -3017,6 +3017,21 @@ class AppModel extends Model
}
}
public function addCountField($field, AppModel $model, array $conditions)
{
$db = $this->getDataSource();
$subQuery = $db->buildStatement(
array(
'fields' => ['COUNT(*)'],
'table' => $db->fullTableName($model),
'alias' => $model->alias,
'conditions' => $conditions,
),
$model
);
$this->virtualFields[$field] = $subQuery;
}
/**
* Log exception with backtrace and with nested exceptions.
*

View File

@ -1558,6 +1558,15 @@ class Server extends AppModel
'type' => 'boolean',
'null' => true
),
'hide_organisations_in_sharing_groups' => [
'level' => self::SETTING_RECOMMENDED,
'description' => __('Enabling this setting will block the organisation list from being visible in sharing group besides user with sharing group permission.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean',
'null' => true
],
'disable_local_feed_access' => array(
'level' => 0,
'description' => __('Disabling this setting will allow the creation/modification of local feeds (as opposed to network feeds). Enabling this setting will restrict feed sources to be network based only. When disabled, keep in mind that a malicious site administrator could get access to any arbitrary file on the system that the apache user has access to. Make sure that proper safe-guards are in place. This setting can only be modified via the CLI.'),

View File

@ -204,13 +204,20 @@ class SharingGroup extends AppModel
} elseif ($scope === 'distribution_graph') {
// Specific scope that fetch just necessary information for distribution graph
// @see DistributionGraphTool
$canSeeOrgs = $user['Role']['perm_sharing_group'] || !Configure::read('Security.hide_organisations_in_sharing_groups');
$sgs = $this->find('all', array(
'contain' => ['SharingGroupOrg' => ['org_id']],
'contain' => $canSeeOrgs ? ['SharingGroupOrg' => ['org_id']] : [],
'conditions' => $conditions,
'fields' => ['SharingGroup.id', 'SharingGroup.name', 'SharingGroup.org_id'],
'order' => 'SharingGroup.name ASC'
));
return $this->appendOrgsAndServers($sgs, ['id', 'name'], []);
if ($canSeeOrgs) {
return $this->appendOrgsAndServers($sgs, ['id', 'name'], []);
}
foreach ($sgs as &$sg) {
$sg['SharingGroupOrg'] = [];
}
return $sgs;
} elseif ($scope === 'name') {
$sgs = $this->find('list', array(
'recursive' => -1,
@ -241,8 +248,10 @@ class SharingGroup extends AppModel
{
$orgsToFetch = [];
$serverToFetch = [];
foreach($sharingGroups as $sg) {
$orgsToFetch[$sg['SharingGroup']['org_id']] = true;
foreach ($sharingGroups as $sg) {
if (isset($sg['SharingGroup']['org_id'])) {
$orgsToFetch[$sg['SharingGroup']['org_id']] = true;
}
if (isset($sg['SharingGroupOrg'])) {
foreach ($sg['SharingGroupOrg'] as $sgo) {
$orgsToFetch[$sgo['org_id']] = true;
@ -283,7 +292,7 @@ class SharingGroup extends AppModel
}
foreach ($sharingGroups as &$sg) {
if (isset($orgsById[$sg['SharingGroup']['org_id']])) {
if (isset($sg['SharingGroup']['org_id']) && isset($orgsById[$sg['SharingGroup']['org_id']])) {
$sg['Organisation'] = $orgsById[$sg['SharingGroup']['org_id']];
}

View File

@ -6,6 +6,17 @@ echo $this->element('/genericElements/IndexTable/index_table', array(
'data' => $sharingGroups,
'top_bar' => array(
'children' => array(
array(
'type' => 'simple',
'children' => array(
array(
'text' => __('Add'),
'fa-icon' => 'plus',
'url' => $baseurl . '/sharing_groups/add',
'requirement' => $isAclSharingGroup,
)
)
),
array(
'type' => 'simple',
'children' => array(
@ -68,36 +79,42 @@ echo $this->element('/genericElements/IndexTable/index_table', array(
),
array(
'name' => __('Org count'),
'element' => 'custom',
'class' => 'short',
'function' => function (array $sharingGroup) {
echo count($sharingGroup['SharingGroupOrg']);
}
'sort' => 'SharingGroup.org_count',
'data_path' => 'SharingGroup.org_count',
),
array(
'name' => __('Releasable to'),
'element' => 'custom',
'function' => function (array $sharingGroup) use ($baseurl) {
$combined = __("Organisations:");
if (empty($sharingGroup['SharingGroupOrg'])) $combined .= "<br>N/A";
foreach ($sharingGroup['SharingGroupOrg'] as $sge) {
if (!empty($sge['Organisation'])) {
$combined .= "<br><a href='" . $baseurl . "/organisation/view/" . h($sge['Organisation']['id']) . "'>" . h($sge['Organisation']['name']) . "</a>";
if ($sge['extend']) $combined .= ' (can extend)';
if (empty($sharingGroup['SharingGroupOrg'])) {
$combined .= "<br>N/A";
} else {
foreach ($sharingGroup['SharingGroupOrg'] as $sge) {
if (!empty($sge['Organisation'])) {
$combined .= "<br><a href='" . $baseurl . "/organisation/view/" . h($sge['Organisation']['id']) . "'>" . h($sge['Organisation']['name']) . "</a>";
if ($sge['extend']) {
$combined .= ' (can extend)';
}
}
}
}
$combined .= '<hr style="margin:5px 0;"><br>Instances:';
if (empty($sharingGroup['SharingGroupServer'])) $combined .= "<br>N/A";
foreach ($sharingGroup['SharingGroupServer'] as $sgs) {
if ($sgs['server_id'] != 0) {
$combined .= "<br><a href='" . $baseurl . "/server/view/" . h($sgs['Server']['id']) . "'>" . h($sgs['Server']['name']) . "</a>";
} else {
$combined .= "<br>This instance";
}
if ($sgs['all_orgs']) {
$combined .= ' (all organisations)';
} else {
$combined .= ' (as defined above)';
if (empty($sharingGroup['SharingGroupServer'])) {
$combined .= "<br>N/A";
} else {
foreach ($sharingGroup['SharingGroupServer'] as $sgs) {
if ($sgs['server_id'] != 0) {
$combined .= "<br><a href='" . $baseurl . "/server/view/" . h($sgs['Server']['id']) . "'>" . h($sgs['Server']['name']) . "</a>";
} else {
$combined .= "<br>This instance";
}
if ($sgs['all_orgs']) {
$combined .= ' (all organisations)';
} else {
$combined .= ' (as defined above)';
}
}
} ?>
<span data-toggle="popover" data-trigger="hover" title="<?= __('Distribution List') ?>" data-content="<?= h($combined) ?>">

View File

@ -25,6 +25,12 @@ $tableData[] = [
'key' => __('Events'),
'html' => '<a href="' . $eventsLink . '">' . __n('%s event', '%s events', $sg['SharingGroup']['event_count'], $sg['SharingGroup']['event_count']) . '</a>',
];
if (isset($sg['SharingGroup']['org_count'])) {
$tableData[] = [
'key' => __('Organisations'),
'html' => __n('%s organisation', '%s organisations', $sg['SharingGroup']['org_count'], $sg['SharingGroup']['org_count']),
];
}
echo $this->element('genericElements/viewMetaTable', ['table_data' => $tableData]);
?>
</div></div>
@ -56,7 +62,7 @@ echo $this->element('genericElements/viewMetaTable', ['table_data' => $tableData
</div>
<?php
endif;
if (!$sg['SharingGroup']['roaming']):
if (!$sg['SharingGroup']['roaming'] && isset($sg['SharingGroupServer'])):
?>
<div class="span6">
<b>Instances</b>