add: sharing groups index view migration

pull/9143/head
Luciano Righetti 2023-06-13 11:29:07 +02:00
parent 9bd808aefd
commit a44e3d8f4e
15 changed files with 1036 additions and 192 deletions

View File

@ -55,11 +55,6 @@
</properties>
</rule>
<!-- Private methods MUST not be prefixed with an underscore -->
<rule ref="PSR2.Methods.MethodDeclaration.Underscore">
<type>error</type>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes">
<severity>0</severity>
</rule>

View File

@ -260,6 +260,6 @@ class AppController extends Controller
// checks if the currently logged user is a site administrator (an admin that can manage any user or event on the instance and create / edit the roles).
protected function isSiteAdmin()
{
return $this->ACLComponent->getUser()->Role->perm_site_admin;
return $this->ACL->getUser()->Role->perm_site_admin;
}
}

View File

@ -15,8 +15,6 @@ class SharingGroupsController extends AppController
{
use LocatorAwareTrait;
public $components = ['Session', 'RequestHandler'];
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
@ -31,18 +29,18 @@ class SharingGroupsController extends AppController
'order' => [
'SharingGroup.name' => 'ASC'
],
'fields' => ['SharingGroup.id', 'SharingGroup.uuid', 'SharingGroup.name', 'SharingGroup.description', 'SharingGroup.releasability', 'SharingGroup.local', 'SharingGroup.active', 'SharingGroup.roaming'],
'fields' => ['id', 'uuid', 'name', 'description', 'releasability', 'local', 'active', 'roaming'],
'contain' => [
'SharingGroupOrg' => [
'Organisation' => ['fields' => ['Organisation.name', 'Organisation.id', 'Organisation.uuid']]
'SharingGroupOrgs' => [
'Organisations' => ['fields' => ['name', 'id', 'uuid']]
],
'Organisation' => [
'fields' => ['Organisation.id', 'Organisation.name', 'Organisation.uuid'],
'Organisations' => [
'fields' => ['id', 'name', 'uuid'],
],
'SharingGroupServer' => [
'fields' => ['SharingGroupServer.all_orgs'],
'Server' => [
'fields' => ['Server.name', 'Server.id']
'SharingGroupServers' => [
'fields' => ['sharing_group_id', 'all_orgs'],
'Servers' => [
'fields' => ['name', 'id']
]
]
],
@ -50,7 +48,7 @@ class SharingGroupsController extends AppController
public function add()
{
$canModifyUuid = $this->Auth->user()['Role']['perm_site_admin'];
$canModifyUuid = $this->ACL->getUser()->Role->perm_site_admin;
if ($this->request->is('post')) {
if ($this->ParamHandler->isRest()) {
@ -58,19 +56,19 @@ class SharingGroupsController extends AppController
$data = $this->request->getData('SharingGroup');
}
$sg = $data;
$id = $this->SharingGroup->captureSG($sg, $this->Auth->user());
$id = $this->SharingGroups->captureSG($sg, $this->ACL->getUser());
if ($id) {
if (empty($sg['roaming']) && empty($sg['SharingGroupServer'])) {
$this->SharingGroup->SharingGroupServer->create();
$this->SharingGroup->SharingGroupServer->save(
$this->SharingGroups->SharingGroupServers->create();
$this->SharingGroups->SharingGroupServers->save(
[
'sharing_group_id' => $this->SharingGroup->id,
'sharing_group_id' => $this->SharingGroups->id,
'server_id' => 0,
'all_orgs' => 0
]
);
}
$sg = $this->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'simplified', false, $id);
$sg = $this->SharingGroups->fetchAllAuthorised($this->ACL->getUser(), 'simplified', false, $id);
if (!empty($sg)) {
$sg = empty($sg) ? [] : $sg[0];
}
@ -88,22 +86,22 @@ class SharingGroupsController extends AppController
$sg['Server'] = $json['servers'];
}
}
$this->SharingGroup->create();
$this->SharingGroups->create();
if (!$canModifyUuid) {
unset($sg['uuid']);
}
$sg['active'] = $sg['active'] ? 1 : 0;
$sg['roaming'] = $sg['roaming'] ? 1 : 0;
$sg['organisation_uuid'] = $this->ACLComponent->getUser()->Organisation->uuid;
$sg['organisation_uuid'] = $this->ACL->getUser()->Organisation->uuid;
$sg['local'] = 1;
$sg['org_id'] = $this->ACLComponent->getUser()->org_id;
if ($this->SharingGroup->save(['SharingGroup' => $sg])) {
$sg['org_id'] = $this->ACL->getUser()->org_id;
if ($this->SharingGroups->save(['SharingGroup' => $sg])) {
if (!empty($sg['Organisation'])) {
foreach ($sg['Organisation'] as $org) {
$this->SharingGroup->SharingGroupOrg->create();
$this->SharingGroup->SharingGroupOrg->save(
$this->SharingGroups->SharingGroupOrgs->create();
$this->SharingGroups->SharingGroupOrgs->save(
[
'sharing_group_id' => $this->SharingGroup->id,
'sharing_group_id' => $this->SharingGroups->id,
'org_id' => $org['id'],
'extend' => $org['extend']
]
@ -112,24 +110,24 @@ class SharingGroupsController extends AppController
}
if (empty($sg['roaming']) && !empty($sg['Server'])) {
foreach ($sg['Server'] as $server) {
$this->SharingGroup->SharingGroupServer->create();
$this->SharingGroup->SharingGroupServer->save(
$this->SharingGroups->SharingGroupServers->create();
$this->SharingGroups->SharingGroupServers->save(
[
'sharing_group_id' => $this->SharingGroup->id,
'sharing_group_id' => $this->SharingGroups->id,
'server_id' => $server['id'],
'all_orgs' => $server['all_orgs']
]
);
}
}
$this->redirect('/SharingGroups/view/' . $this->SharingGroup->id);
$this->redirect('/SharingGroups/view/' . $this->SharingGroups->id);
} else {
$validationReplacements = [
'notempty' => 'This field cannot be left empty.',
];
$validationErrors = $this->SharingGroup->validationErrors;
$validationErrors = $this->SharingGroups->validationErrors;
$failedField = array_keys($validationErrors)[0];
$reason = reset($this->SharingGroup->validationErrors)[0];
$reason = reset($this->SharingGroups->validationErrors)[0];
foreach ($validationReplacements as $k => $vR) {
if ($reason == $k) {
$reason = $vR;
@ -143,7 +141,7 @@ class SharingGroupsController extends AppController
$this->set('localInstance', empty(Configure::read('MISP.external_baseurl')) ? Configure::read('MISP.baseurl') : Configure::read('MISP.external_baseurl'));
// We just pass true and allow the user to edit, since he/she is just about to create the SG. This is needed to reuse the view for the edit
$this->set('user', $this->Auth->user());
$this->set('user', $this->ACL->getUser());
$this->set('canModifyUuid', $canModifyUuid);
}
@ -154,7 +152,7 @@ class SharingGroupsController extends AppController
}
// check if the user is eligible to edit the SG (original creator or extend)
$sharingGroup = $this->SharingGroup->find(
$sharingGroup = $this->SharingGroups->find(
'first',
[
'conditions' => Validation::uuid($id) ? ['SharingGroup.uuid' => $id] : ['SharingGroup.id' => $id],
@ -178,7 +176,7 @@ class SharingGroupsController extends AppController
throw new NotFoundException('Invalid sharing group.');
}
if (!$this->SharingGroup->checkIfAuthorisedExtend($this->Auth->user(), $sharingGroup['SharingGroup']['id'])) {
if (!$this->SharingGroups->checkIfAuthorisedExtend($this->ACL->getUser(), $sharingGroup['SharingGroup']['id'])) {
throw new MethodNotAllowedException('Action not allowed.');
}
if ($this->request->is('post')) {
@ -187,9 +185,9 @@ class SharingGroupsController extends AppController
$data = $this->request->getData('SharingGroup');
}
$data['uuid'] = $sharingGroup['SharingGroup']['uuid'];
$id = $this->SharingGroup->captureSG($data, $this->Auth->user());
$id = $this->SharingGroups->captureSG($data, $this->ACL->getUser());
if ($id) {
$sg = $this->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'simplified', false, $id);
$sg = $this->SharingGroups->fetchAllAuthorised($this->ACL->getUser(), 'simplified', false, $id);
return $this->RestResponse->viewData($sg[0], $this->response->getType());
} else {
return $this->RestResponse->saveFailResponse('SharingGroup', 'add', false, 'Could not save sharing group.', $this->response->getType());
@ -199,22 +197,22 @@ class SharingGroupsController extends AppController
$sg = $json['sharingGroup'];
$sg['id'] = $sharingGroup['SharingGroup']['id'];
$fields = ['name', 'releasability', 'description', 'active', 'roaming'];
$existingSG = $this->SharingGroup->find('first', ['recursive' => -1, 'conditions' => ['SharingGroup.id' => $sharingGroup['SharingGroup']['id']]]);
$existingSG = $this->SharingGroups->find('first', ['recursive' => -1, 'conditions' => ['SharingGroup.id' => $sharingGroup['SharingGroup']['id']]]);
foreach ($fields as $field) {
$existingSG['SharingGroup'][$field] = $sg[$field];
}
unset($existingSG['SharingGroup']['modified']);
if ($this->SharingGroup->save($existingSG)) {
$this->SharingGroup->SharingGroupOrg->updateOrgsForSG($sharingGroup['SharingGroup']['id'], $json['organisations'], $sharingGroup['SharingGroupOrg'], $this->Auth->user());
$this->SharingGroup->SharingGroupServer->updateServersForSG($sharingGroup['SharingGroup']['id'], $json['servers'], $sharingGroup['SharingGroupServer'], $json['sharingGroup']['roaming'], $this->Auth->user());
if ($this->SharingGroups->save($existingSG)) {
$this->SharingGroups->SharingGroupOrgs->updateOrgsForSG($sharingGroup['SharingGroup']['id'], $json['organisations'], $sharingGroup['SharingGroupOrg'], $this->ACL->getUser());
$this->SharingGroups->SharingGroupServers->updateServersForSG($sharingGroup['SharingGroup']['id'], $json['servers'], $sharingGroup['SharingGroupServer'], $json['sharingGroup']['roaming'], $this->ACL->getUser());
$this->redirect('/SharingGroups/view/' . $sharingGroup['SharingGroup']['id']);
} else {
$validationReplacements = [
'notempty' => 'This field cannot be left empty.',
];
$validationErrors = $this->SharingGroup->validationErrors;
$validationErrors = $this->SharingGroups->validationErrors;
$failedField = array_keys($validationErrors)[0];
$reason = reset($this->SharingGroup->validationErrors)[0];
$reason = reset($this->SharingGroups->validationErrors)[0];
foreach ($validationReplacements as $k => $vR) {
if ($reason == $k) {
$reason = $vR;
@ -226,7 +224,7 @@ class SharingGroupsController extends AppController
} elseif ($this->ParamHandler->isRest()) {
return $this->RestResponse->describe('SharingGroup', 'edit', false, $this->response->getType());
}
$orgs = $this->SharingGroup->Organisation->find(
$orgs = $this->SharingGroups->Organisation->find(
'all',
[
'conditions' => ['local' => 1],
@ -239,14 +237,14 @@ class SharingGroupsController extends AppController
$this->set('orgs', $orgs);
$this->set('localInstance', empty(Configure::read('MISP.external_baseurl')) ? Configure::read('MISP.baseurl') : Configure::read('MISP.external_baseurl'));
// We just pass true and allow the user to edit, since he/she is just about to create the SG. This is needed to reuse the view for the edit
$this->set('user', $this->Auth->user());
$this->set('user', $this->ACL->getUser());
}
public function delete($id)
{
$this->request->allowMethod(['post', 'delete']);
$deletedSg = $this->SharingGroup->find(
$deletedSg = $this->SharingGroups->find(
'first',
[
'conditions' => Validation::uuid($id) ? ['uuid' => $id] : ['id' => $id],
@ -254,10 +252,10 @@ class SharingGroupsController extends AppController
'fields' => ['id', 'active'],
]
);
if (empty($deletedSg) || !$this->SharingGroup->checkIfOwner($this->Auth->user(), $deletedSg['SharingGroup']['id'])) {
if (empty($deletedSg) || !$this->SharingGroups->checkIfOwner($this->ACL->getUser(), $deletedSg['SharingGroup']['id'])) {
throw new MethodNotAllowedException('Action not allowed.');
}
if ($this->SharingGroup->delete($deletedSg['SharingGroup']['id'])) {
if ($this->SharingGroups->delete($deletedSg['SharingGroup']['id'])) {
if ($this->ParamHandler->isRest()) {
return $this->RestResponse->saveSuccessResponse('SharingGroups', 'delete', $id, $this->response->getType());
}
@ -279,49 +277,50 @@ class SharingGroupsController extends AppController
public function index($passive = false)
{
$passive = $passive === 'true';
$authorizedSgIds = $this->SharingGroup->authorizedIds($this->Auth->user());
$this->paginate['conditions'][] = ['SharingGroup.id' => $authorizedSgIds];
$this->paginate['conditions'][] = ['SharingGroup.active' => $passive === true ? 0 : 1];
$authorizedSgIds = $this->SharingGroups->authorizedIds($this->ACL->getUser()->toArray());
// TODO: [3.x-MIGRATION] fix this array conversion
// $this->paginate['conditions'][] = ['id' => $authorizedSgIds];
// $this->paginate['conditions'][] = ['active' => $passive === true ? 0 : 1];
if (isset($this->params['named']['value'])) {
$term = '%' . strtolower($this->params['named']['value']) . '%';
if (!empty($this->request->getParam('value'))) {
$term = '%' . strtolower($this->request->getParam('value')) . '%';
if ($this->__showOrgs()) {
$sgIds = $this->SharingGroup->SharingGroupOrg->find(
$sgIds = $this->SharingGroups->SharingGroupOrgs->find(
'column',
[
'conditions' => [
'OR' => [
'Organisation.uuid LIKE' => $term,
'LOWER(Organisation.name) LIKE' => $term,
'Organisations.uuid LIKE' => $term,
'LOWER(Organisations.name) LIKE' => $term,
],
'SharingGroupOrg.sharing_group_id' => $authorizedSgIds,
],
'contain' => ['Organisation'],
'fields' => ['SharingGroupOrg.sharing_group_id'],
'contain' => ['Organisations'],
'fields' => ['SharingGroupOrgs.sharing_group_id'],
]
);
} else {
$sgIds = [];
}
$this->paginate['conditions'][]['OR'] = [
'SharingGroup.id' => $sgIds,
'SharingGroup.uuid LIKE' => $term,
'LOWER(SharingGroup.name) LIKE' => $term,
'LOWER(SharingGroup.description) LIKE' => $term,
'LOWER(SharingGroup.releasability) LIKE' => $term,
'LOWER(Organisation.name) LIKE' => $term,
'id' => $sgIds,
'uuid LIKE' => $term,
'LOWER(name) LIKE' => $term,
'LOWER(description) LIKE' => $term,
'LOWER(releasability) LIKE' => $term,
'LOWER(Organisations.name) LIKE' => $term,
];
}
if ($this->__showOrgs() && isset($this->params['named']['searchorg'])) {
$orgs = explode('|', $this->params['named']['searchorg']);
if ($this->__showOrgs() && !empty($this->request->getParam('searchorg'))) {
$orgs = explode('|', $this->request->getParam('searchorg'));
$conditions = [];
foreach ($orgs as $org) {
$exclude = $org[0] === '!';
if ($exclude) {
$org = substr($org, 1);
}
$org = $this->SharingGroup->Organisation->fetchOrg($org);
$org = $this->SharingGroups->Organisations->fetchOrg($org);
if ($org) {
if ($exclude) {
$conditions['AND'][] = ['org_id !=' => $org['id']];
@ -330,42 +329,44 @@ class SharingGroupsController extends AppController
}
}
}
$sgIds = $this->SharingGroup->SharingGroupOrg->find(
$sgIds = $this->SharingGroups->SharingGroupOrgs->find(
'column',
[
'conditions' => $conditions,
'fields' => ['SharingGroupOrg.sharing_group_id'],
'fields' => ['SharingGroupOrgs.sharing_group_id'],
]
);
if (empty($sgIds)) {
$sgIds = -1;
}
$this->paginate['conditions'][] = ['SharingGroup.id' => $sgIds];
$this->paginate['conditions'][] = ['id' => $sgIds];
}
// 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';
// TODO: [3.x-MIGRATION] fixme, cannot paginate on virtual fields
// $this->paginate['fields'][] = 'SharingGroup.org_count';
if (!$this->__showOrgs()) {
unset($this->paginate['contain']['SharingGroupOrg']);
unset($this->paginate['contain']['SharingGroupServer']);
unset($this->paginate['contain']['SharingGroupOrgs']);
unset($this->paginate['contain']['SharingGroupServers']);
}
$result = $this->paginate();
$result = $this->paginate()->toArray();
// check if the current user can modify or delete the SG
$userOrganisationUuid = $this->Auth->user()['Organisation']['uuid'];
$userOrganisationUuid = $this->ACL->getUser()->Organisation['uuid'];
$response = [];
foreach ($result as $k => $sg) {
$sg = $sg->toArray();
$editable = false;
$deletable = false;
if ($this->userRole['perm_site_admin'] || ($this->userRole['perm_sharing_group'] && $sg['Organisation']['uuid'] === $userOrganisationUuid)) {
if ($this->ACL->getUser()->Role->perm_site_admin || ($this->ACL->getUser()->Role->perm_sharing_group && $sg['Organisation']['uuid'] === $userOrganisationUuid)) {
$editable = true;
$deletable = true;
} else if ($this->userRole['perm_sharing_group']) {
if (!empty($sg['SharingGroupOrg'])) {
foreach ($sg['SharingGroupOrg'] as $sgo) {
} else if ($this->ACL->getUser()->Role->perm_sharing_group) {
if (!empty($sg['SharingGroupOrgs'])) {
foreach ($sg['SharingGroupOrgs'] as $sgo) {
if ($sgo['extend'] && $sgo['org_id'] == $this->Auth->user('org_id')) {
$editable = true;
break;
@ -374,14 +375,15 @@ class SharingGroupsController extends AppController
}
}
$result[$k]['editable'] = $editable;
$result[$k]['deletable'] = $deletable;
$response[$k] = $sg;
$response[$k]['editable'] = $editable;
$response[$k]['deletable'] = $deletable;
}
if ($this->ParamHandler->isRest()) {
return $this->RestResponse->viewData(['response' => $result], $this->response->getType()); // 'response' to keep BC
return $this->RestResponse->viewData(['response' => $response], $this->response->getType()); // 'response' to keep BC
}
$this->set('passive', $passive);
$this->set('sharingGroups', $result);
$this->set('sharingGroups', $response);
$this->set('passedArgs', $passive ? 'true' : '[]');
$this->set('title_for_layout', __('Sharing Groups'));
}
@ -389,10 +391,10 @@ class SharingGroupsController extends AppController
public function view($id)
{
if ($this->request->is('head')) { // Just check if sharing group exists and user can access it
$exists = $this->SharingGroup->checkIfAuthorised($this->Auth->user(), $id);
$exists = $this->SharingGroups->checkIfAuthorised($this->ACL->getUser(), $id);
return new Response(['status' => $exists ? 200 : 404]);
}
if (!$this->SharingGroup->checkIfAuthorised($this->Auth->user(), $id)) {
if (!$this->SharingGroups->checkIfAuthorised($this->ACL->getUser(), $id)) {
throw new MethodNotAllowedException('Sharing group doesn\'t exist or you do not have permission to access it.');
}
@ -413,10 +415,9 @@ class SharingGroupsController extends AppController
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(
$sg = $this->SharingGroups->find(
'first',
[
'conditions' => Validation::uuid($id) ? ['SharingGroup.uuid' => $id] : ['SharingGroup.id' => $id],
@ -443,7 +444,7 @@ class SharingGroupsController extends AppController
'recursive' => -1,
'fields' => ['User.id'],
'contain' => ['Organisation' => [
'fields' => ['Organisation.id', 'Organisation.name', 'Organisation.uuid'],
'fields' => ['Organisations.id', 'Organisation.name', 'Organisation.uuid'],
]]
]
)->first();
@ -459,7 +460,7 @@ class SharingGroupsController extends AppController
}
$EventsTable = $this->fetchTable('Events');
$conditions = $EventsTable->createEventConditions($this->Auth->user());
$conditions = $EventsTable->createEventConditions($this->ACL->getUser());
$conditions['AND']['sharing_group_id'] = $sg['SharingGroup']['id'];
$sg['SharingGroup']['event_count'] = $EventsTable->find(
'count',
@ -470,7 +471,7 @@ class SharingGroupsController extends AppController
]
);
$this->set('mayModify', $this->SharingGroup->checkIfAuthorisedExtend($this->Auth->user(), $sg['SharingGroup']['id']));
$this->set('mayModify', $this->SharingGroups->checkIfAuthorisedExtend($this->ACL->getUser(), $sg['SharingGroup']['id']));
$this->set('id', $sg['SharingGroup']['id']);
$this->set('sg', $sg);
$this->set('menuData', ['menuList' => 'globalActions', 'menuItem' => 'viewSG']);
@ -494,7 +495,7 @@ class SharingGroupsController extends AppController
throw new MethodNotAllowedException('No valid sharing group ID provided.');
}
}
$sg = $this->SharingGroup->fetchSG($id, $this->Auth->user(), false);
$sg = $this->SharingGroups->fetchSG($id, $this->ACL->getUser(), false);
if (empty($sg)) {
throw new MethodNotAllowedException('Invalid sharing group or no editing rights.');
}
@ -513,9 +514,9 @@ class SharingGroupsController extends AppController
];
if (!empty($id)) {
if ($type == 'org') {
return $this->SharingGroup->SharingGroupOrg->Organisation->fetchOrg($id);
return $this->SharingGroups->SharingGroupOrgs->Organisation->fetchOrg($id);
} else {
return $this->SharingGroup->SharingGroupServer->Server->fetchServer($id);
return $this->SharingGroups->SharingGroupServers->Server->fetchServer($id);
}
}
if ($type !== 'org' && $type !== 'server') {
@ -524,9 +525,9 @@ class SharingGroupsController extends AppController
foreach ($params[$type] as $param) {
if (!empty($request[$param])) {
if ($type == 'org') {
return $this->SharingGroup->SharingGroupOrg->Organisation->fetchOrg($request[$param]);
return $this->SharingGroups->SharingGroupOrgs->Organisation->fetchOrg($request[$param]);
} else {
return $this->SharingGroup->SharingGroupServer->Server->fetchServer($request[$param]);
return $this->SharingGroups->SharingGroupServers->Server->fetchServer($request[$param]);
}
}
}
@ -553,7 +554,7 @@ class SharingGroupsController extends AppController
if (!$addOrg) {
return $this->RestResponse->saveFailResponse('SharingGroup', $this->action, false, 'Organisation is already in the sharing group.', $this->response->getType());
}
$this->SharingGroup->SharingGroupOrg->create();
$this->SharingGroups->SharingGroupOrgs->create();
$sgo = [
'SharingGroupOrg' => [
'org_id' => $org['id'],
@ -561,7 +562,7 @@ class SharingGroupsController extends AppController
'extend' => $extend ? 1 : 0
]
];
$result = $this->SharingGroup->SharingGroupOrg->save($sgo);
$result = $this->SharingGroups->SharingGroupOrgs->save($sgo);
return $this->__sendQuickSaveResponse($this->action, $result, 'Organisation');
}
@ -584,7 +585,7 @@ class SharingGroupsController extends AppController
if (false === $removeOrg) {
return $this->RestResponse->saveFailResponse('SharingGroup', $this->action, false, 'Organisation is not in the sharing group.', $this->response->getType());
}
$result = $this->SharingGroup->SharingGroupOrg->delete($removeOrg);
$result = $this->SharingGroups->SharingGroupOrgs->delete($removeOrg);
return $this->__sendQuickSaveResponse($this->action, $result, 'Organisation');
}
@ -612,7 +613,7 @@ class SharingGroupsController extends AppController
if (!$addServer) {
return $this->RestResponse->saveFailResponse('SharingGroup', $this->action, false, 'Server is already in the sharing group.', $this->response->getType());
}
$this->SharingGroup->SharingGroupServer->create();
$this->SharingGroups->SharingGroupServers->create();
$sgs = [
'SharingGroupServer' => [
'server_id' => $server['Server']['id'],
@ -620,7 +621,7 @@ class SharingGroupsController extends AppController
'all_orgs' => $all ? 1 : 0
]
];
$result = $this->SharingGroup->SharingGroupServer->save($sgs);
$result = $this->SharingGroups->SharingGroupServers->save($sgs);
return $this->__sendQuickSaveResponse($this->action, $result);
}
@ -643,7 +644,7 @@ class SharingGroupsController extends AppController
if (false === $removeServer) {
return $this->RestResponse->saveFailResponse('SharingGroup', $this->action, false, 'Server is not in the sharing group.', $this->response->getType());
}
$result = $this->SharingGroup->SharingGroupServer->delete($removeServer);
$result = $this->SharingGroups->SharingGroupServers->delete($removeServer);
return $this->__sendQuickSaveResponse($this->action, $result);
}
@ -665,6 +666,6 @@ class SharingGroupsController extends AppController
*/
private function __showOrgs()
{
return $this->Auth->user()['Role']['perm_sharing_group'] || !Configure::read('Security.hide_organisations_in_sharing_groups');
return $this->ACL->getUser()->Role->perm_sharing_group || !Configure::read('Security.hide_organisations_in_sharing_groups');
}
}

View File

@ -0,0 +1,9 @@
<?php
namespace App\Model\Entity;
use App\Model\Entity\AppModel;
class Server extends AppModel
{
}

View File

@ -3,7 +3,23 @@
namespace App\Model\Entity;
use App\Model\Entity\AppModel;
use Cake\ORM\Locator\LocatorAwareTrait;
class SharingGroup extends AppModel
{
use LocatorAwareTrait;
protected $_virtual = ['org_count'];
protected function _getOrgCount()
{
$SharingGroupOrgsTable = $this->fetchTable('SharingGroupOrgs');
return $SharingGroupOrgsTable->find(
'all',
[
'conditions' => ['SharingGroupOrgs.sharing_group_id = id']
]
)->count();
}
}

View File

@ -0,0 +1,9 @@
<?php
namespace App\Model\Entity;
use App\Model\Entity\AppModel;
class SharingGroupOrg extends AppModel
{
}

View File

@ -2,15 +2,15 @@
namespace App\Model\Table;
use Cake\Collection\CollectionInterface;
use Cake\Database\Expression\QueryExpression;
use Cake\Http\Exception\MethodNotAllowedException;
use Cake\I18n\FrozenTime;
use Cake\ORM\Query;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\Core\Configure;
use Cake\Core\Configure\Engine\PhpConfig;
use Cake\ORM\TableRegistry;
use Cake\Utility\Hash;
use Cake\Database\Expression\QueryExpression;
use Cake\ORM\Query;
use Cake\I18n\FrozenTime;
use InvalidArgumentException;
class AppTable extends Table
{
@ -18,7 +18,7 @@ class AppTable extends Table
{
}
public function getStatisticsUsageForModel(Object $table, array $scopes, array $options=[]): array
public function getStatisticsUsageForModel(Object $table, array $scopes, array $options = []): array
{
$defaultOptions = [
'limit' => 5,
@ -30,16 +30,20 @@ class AppTable extends Table
foreach ($scopes as $scope) {
$queryTopUsage = $table->find();
$queryTopUsage
->select([
->select(
[
$scope,
'count' => $queryTopUsage->func()->count('id'),
]);
]
);
if ($queryTopUsage->getDefaultTypes()[$scope] != 'boolean') {
$queryTopUsage->where(function (QueryExpression $exp) use ($scope) {
$queryTopUsage->where(
function (QueryExpression $exp) use ($scope) {
return $exp
->isNotNull($scope)
->notEq($scope, '');
});
}
);
}
$queryTopUsage
->group($scope)
@ -55,23 +59,29 @@ class AppTable extends Table
) {
$queryOthersUsage = $table->find();
$queryOthersUsage
->select([
->select(
[
'count' => $queryOthersUsage->func()->count('id'),
])
->where(function (QueryExpression $exp, Query $query) use ($topUsage, $scope, $options) {
]
)
->where(
function (QueryExpression $exp, Query $query) use ($topUsage, $scope, $options) {
if (!empty($options['ignoreNull'])) {
return $exp
->isNotNull($scope)
->notEq($scope, '')
->notIn($scope, Hash::extract($topUsage, "{n}.{$scope}"));
} else {
return $exp->or([
return $exp->or(
[
$query->newExpr()->isNull($scope),
$query->newExpr()->eq($scope, ''),
$query->newExpr()->notIn($scope, Hash::extract($topUsage, "{n}.{$scope}")),
]);
]
);
}
})
}
)
->enableHydration(false);
$othersUsage = $queryOthersUsage->all()->toList();
if (!empty($othersUsage)) {
@ -85,7 +95,7 @@ class AppTable extends Table
return $stats;
}
private function getOptions($defaults=[], $options=[]): array
private function getOptions($defaults = [], $options = []): array
{
return array_merge($defaults, $options);
}
@ -130,10 +140,12 @@ class AppTable extends Table
}
$days = $days - 1;
$query = $table->find();
$query->select([
$query->select(
[
'count' => $query->func()->count('id'),
'date' => "DATE({$field})",
])
]
)
->where(["{$field} >" => FrozenTime::now()->subDays($days)])
->group(['date'])
->order(['date']);
@ -159,10 +171,12 @@ class AppTable extends Table
$this->MetaFields = TableRegistry::getTableLocator()->get('MetaFields');
$this->MetaTemplates = TableRegistry::getTableLocator()->get('MetaTemplates');
foreach ($input['metaFields'] as $templateID => $metaFields) {
$metaTemplates = $this->MetaTemplates->find()->where([
$metaTemplates = $this->MetaTemplates->find()->where(
[
'id' => $templateID,
'enabled' => 1
])->contain(['MetaTemplateFields'])->first();
]
)->contain(['MetaTemplateFields'])->first();
$fieldNameToId = [];
foreach ($metaTemplates->meta_template_fields as $i => $metaTemplateField) {
$fieldNameToId[$metaTemplateField->field] = $metaTemplateField->id;
@ -199,16 +213,58 @@ class AppTable extends Table
*/
public function addCountField(string $field, Table $model, array $conditions)
{
$db = $this->getDataSource();
$subQuery = $db->buildStatement(
array(
$subQuery = $this->buildStatement(
[
'fields' => ['COUNT(*)'],
'table' => $db->fullTableName($model),
'table' => $model->table(),
'alias' => $model->alias,
'conditions' => $conditions,
),
],
$model
);
$subQuery->select(['count' => $subQuery->func()->count('*')]);
$this->virtualFields[$field] = $subQuery;
}
/**
* Find method that allows to fetch just one column from database.
* @param $state
* @param $query
* @param array $results
* @return \Cake\ORM\Query The query builder
* @throws InvalidArgumentException
*/
protected function findColumn(Query $query, array $options): Query
{
$fields = $query->clause('select');
if (!isset($fields)) {
throw new InvalidArgumentException("This method requires `fields` option defined.");
}
if (!is_array($fields) || count($fields) != 1) {
throw new InvalidArgumentException("Not a valid array or invalid number of columns, expected one, " . count($fields) . " given");
}
if (isset($options['unique']) && $options['unique']) {
$query->distinct();
}
$query->enableHydration(false);
$query->formatResults(
function (CollectionInterface $results) use ($fields) {
return $results->map(
function ($row) use ($fields) {
return $row[$fields[0]];
}
);
},
$query::APPEND
);
return $query;
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Model\Table;
use App\Model\Entity\SharingGroup;
use App\Model\Table\AppTable;
use ArrayObject;
use Cake\Core\Configure;
use Cake\Datasource\EntityInterface;
use Cake\Event\EventInterface;
use Cake\Http\Exception\MethodNotAllowedException;
use Cake\ORM\Locator\LocatorAwareTrait;
use Cake\ORM\RulesChecker;
use Cake\Utility\Text;
use Cake\Validation\Validation;
use Cake\Validation\Validator;
use InvalidArgumentException;
use App\Model\Entity\Log;
class ServersTable extends AppTable
{
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\Model\Table;
use App\Model\Entity\SharingGroup;
use App\Model\Table\AppTable;
use ArrayObject;
use Cake\Core\Configure;
use Cake\Datasource\EntityInterface;
use Cake\Event\EventInterface;
use Cake\Http\Exception\MethodNotAllowedException;
use Cake\ORM\Locator\LocatorAwareTrait;
use Cake\ORM\RulesChecker;
use Cake\Utility\Text;
use Cake\Validation\Validation;
use Cake\Validation\Validator;
use InvalidArgumentException;
use App\Model\Entity\Log;
class SharingGroupOrgsTable extends AppTable
{
public function initialize(array $config): void
{
parent::initialize($config);
$this->addBehavior('AuditLog');
$this->belongsTo(
'Organisations',
[
'foreignKey' => 'org_id',
]
);
$this->belongsTo(
'SharingGroups',
[
'foreignKey' => 'sharing_group_id',
]
);
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\Model\Table;
use App\Model\Entity\SharingGroup;
use App\Model\Table\AppTable;
use ArrayObject;
use Cake\Core\Configure;
use Cake\Datasource\EntityInterface;
use Cake\Event\EventInterface;
use Cake\Http\Exception\MethodNotAllowedException;
use Cake\ORM\Locator\LocatorAwareTrait;
use Cake\ORM\RulesChecker;
use Cake\Utility\Text;
use Cake\Validation\Validation;
use Cake\Validation\Validator;
use InvalidArgumentException;
use App\Model\Entity\Log;
class SharingGroupServersTable extends AppTable
{
public function initialize(array $config): void
{
parent::initialize($config);
$this->addBehavior('AuditLog');
$this->belongsTo(
'Servers',
[
'foreignKey' => 'server_id',
]
);
$this->belongsTo(
'SharingGroups',
[
'foreignKey' => 'sharing_group_id',
]
);
}
}

View File

@ -17,7 +17,7 @@ use Cake\Validation\Validator;
use InvalidArgumentException;
use App\Model\Entity\Log;
class SharingGroupTable extends AppTable
class SharingGroupsTable extends AppTable
{
use LocatorAwareTrait;
@ -27,21 +27,27 @@ class SharingGroupTable extends AppTable
$this->addBehavior('AuditLog');
$this->belongsTo(
'Organisation'
'Organisations',
[
'foreignKey' => 'org_id',
'propertyName' => 'Organisation'
]
);
// $this->hasMany(
// 'SharingGroupOrg',
// [
// 'dependent' => true,
// ],
// );
// $this->hasMany(
// 'SharingGroupServer',
// [
// 'dependent' => true,
// ],
// );
$this->hasMany(
'SharingGroupOrgs',
[
'dependent' => true,
'propertyName' => 'SharingGroupOrgs'
],
);
$this->hasMany(
'SharingGroupServers',
[
'dependent' => true,
'propertyName' => 'SharingGroupServers'
],
);
// $this->hasMany('Event');
// $this->hasMany('Attribute');
// $this->hasMany('Thread');
@ -155,7 +161,7 @@ class SharingGroupTable extends AppTable
$sgs = $this->find(
'all',
[
'contain' => ['SharingGroupServer' => ['Server'], 'SharingGroupOrg' => ['Organisation'], 'Organisation'],
'contain' => ['SharingGroupServer' => ['Server'], 'SharingGroupOrgs' => ['Organisation'], 'Organisation'],
'conditions' => $conditions,
'order' => 'SharingGroup.name ASC'
]
@ -183,7 +189,7 @@ class SharingGroupTable extends AppTable
[
'fields' => ['SharingGroup.*'],
'contain' => [
'SharingGroupOrg',
'SharingGroupOrgs',
'SharingGroupServer',
]
]
@ -205,7 +211,7 @@ class SharingGroupTable extends AppTable
$sgs = $this->find(
'all',
[
'contain' => $canSeeOrgs ? ['SharingGroupOrg' => ['org_id']] : [],
'contain' => $canSeeOrgs ? ['SharingGroupOrgs' => ['org_id']] : [],
'conditions' => $conditions,
'fields' => ['SharingGroup.id', 'SharingGroup.name', 'SharingGroup.org_id'],
'order' => 'SharingGroup.name ASC'
@ -215,7 +221,7 @@ class SharingGroupTable extends AppTable
return $this->appendOrgsAndServers($sgs, ['id', 'name'], []);
}
foreach ($sgs as &$sg) {
$sg['SharingGroupOrg'] = [];
$sg['SharingGroupOrgs'] = [];
}
return $sgs;
} elseif ($scope === 'name') {
@ -257,8 +263,8 @@ class SharingGroupTable extends AppTable
if (isset($sg['SharingGroup']['org_id'])) {
$orgsToFetch[$sg['SharingGroup']['org_id']] = true;
}
if (isset($sg['SharingGroupOrg'])) {
foreach ($sg['SharingGroupOrg'] as $sgo) {
if (isset($sg['SharingGroupOrgs'])) {
foreach ($sg['SharingGroupOrgs'] as $sgo) {
$orgsToFetch[$sgo['org_id']] = true;
}
}
@ -303,8 +309,8 @@ class SharingGroupTable extends AppTable
$sg['Organisation'] = $orgsById[$sg['SharingGroup']['org_id']];
}
if (isset($sg['SharingGroupOrg'])) {
foreach ($sg['SharingGroupOrg'] as &$sgo) {
if (isset($sg['SharingGroupOrgs'])) {
foreach ($sg['SharingGroupOrgs'] as &$sgo) {
if (isset($orgsById[$sgo['org_id']])) {
$sgo['Organisation'] = $orgsById[$sgo['org_id']];
}
@ -357,8 +363,8 @@ class SharingGroupTable extends AppTable
if (empty($local)) {
$orgCheck = false;
$serverCheck = false;
if (isset($sg['SharingGroupOrg'])) {
foreach ($sg['SharingGroupOrg'] as $org) {
if (isset($sg['SharingGroupOrgs'])) {
foreach ($sg['SharingGroupOrgs'] as $org) {
if (isset($org['Organisation'][0])) {
$org['Organisation'] = $org['Organisation'][0];
}
@ -433,7 +439,7 @@ class SharingGroupTable extends AppTable
}
}
return $this->SharingGroupOrg->hasAny(
return $this->SharingGroupOrgs->hasAny(
[
'sharing_group_id' => $id,
'org_id' => $user['org_id'],
@ -493,7 +499,7 @@ class SharingGroupTable extends AppTable
$authorized = ($adminCheck && $user['Role']['perm_site_admin']) ||
$user['org_id'] === $sg_org_id['SharingGroup']['org_id'] ||
$this->SharingGroupServer->checkIfAuthorised($id) ||
$this->SharingGroupOrg->checkIfAuthorised($id, $user['org_id']);
$this->SharingGroupOrgs->checkIfAuthorised($id, $user['org_id']);
$this->__sgAuthorisationCache['access'][$adminCheck][$id] = $authorized;
if (isset($uuid)) {
// If uuid was provided, cache also result by UUID to make check faster
@ -519,7 +525,7 @@ class SharingGroupTable extends AppTable
$sgids = $this->find(
'column',
[
'fields' => ['id'],
'fields' => ['id']
]
)->toArray();
$sgids = array_map('intval', $sgids);
@ -527,7 +533,7 @@ class SharingGroupTable extends AppTable
$sgids = array_unique(
array_merge(
$this->SharingGroupServer->fetchAllAuthorised(),
$this->SharingGroupOrg->fetchAllAuthorised($user['org_id'])
$this->SharingGroupOrgs->fetchAllAuthorised($user['org_id'])
),
SORT_REGULAR
);
@ -582,7 +588,7 @@ class SharingGroupTable extends AppTable
'recursive' => -1,
'fields' => ['id', 'org_id'],
'contain' => [
'SharingGroupOrg' => ['fields' => ['id', 'org_id']],
'SharingGroupOrgs' => ['fields' => ['id', 'org_id']],
'SharingGroupServer' => ['fields' => ['id', 'server_id', 'all_orgs']],
]
]
@ -599,7 +605,7 @@ class SharingGroupTable extends AppTable
}
}
// return a list of arrays with all organisations tied to the SG.
return array_column($sg['SharingGroupOrg'], 'org_id');
return array_column($sg['SharingGroupOrgs'], 'org_id');
}
public function checkIfServerInSG($sg, $server)
@ -619,8 +625,8 @@ class SharingGroupTable extends AppTable
return false;
}
}
if (isset($sg['SharingGroupOrg']) && !empty($sg['SharingGroupOrg'])) {
foreach ($sg['SharingGroupOrg'] as $org) {
if (isset($sg['SharingGroupOrgs']) && !empty($sg['SharingGroupOrgs'])) {
foreach ($sg['SharingGroupOrgs'] as $org) {
if (isset($org['Organisation']) && $org['Organisation']['uuid'] === $server['RemoteOrg']['uuid']) {
return true;
}
@ -653,7 +659,7 @@ class SharingGroupTable extends AppTable
'contain' => [
'Organisation',
'SharingGroupServer' => ['Server'],
'SharingGroupOrg' => ['Organisation']
'SharingGroupOrgs' => ['Organisation']
]
]
);
@ -795,15 +801,15 @@ class SharingGroupTable extends AppTable
private function __retrieveOrgIdFromCapturedSG($user, $sg)
{
if (!isset($sg['Organisation'])) {
if (!isset($sg['SharingGroupOrg'])) {
$sg['SharingGroupOrg'] = [[
if (!isset($sg['SharingGroupOrgs'])) {
$sg['SharingGroupOrgs'] = [[
'extend' => 1,
'uuid' => $user['Organisation']['uuid'],
'name' => $user['Organisation']['name'],
]];
return $user['org_id'];
} else {
foreach ($sg['SharingGroupOrg'] as $k => $org) {
foreach ($sg['SharingGroupOrgs'] as $k => $org) {
if (!isset($org['Organisation'])) {
$org['Organisation'] = $org;
}
@ -836,8 +842,8 @@ class SharingGroupTable extends AppTable
*/
public function captureCreatorOrg(array $user, int $sg_id)
{
$this->SharingGroupOrg->create();
$this->SharingGroupOrg->save(
$this->SharingGroupOrgs->create();
$this->SharingGroupOrgs->save(
[
'sharing_group_id' => $sg_id,
'org_id' => $user['org_id'],
@ -859,48 +865,48 @@ class SharingGroupTable extends AppTable
public function captureSGOrgs(array $user, array $sg, int $sg_id, bool $force)
{
$creatorOrgFound = false;
if (!empty($sg['SharingGroupOrg'])) {
if (isset($sg['SharingGroupOrg']['id'])) {
$temp = $sg['SharingGroupOrg'];
unset($sg['SharingGroupOrg']);
$sg['SharingGroupOrg'][0] = $temp;
if (!empty($sg['SharingGroupOrgs'])) {
if (isset($sg['SharingGroupOrgs']['id'])) {
$temp = $sg['SharingGroupOrgs'];
unset($sg['SharingGroupOrgs']);
$sg['SharingGroupOrgs'][0] = $temp;
}
foreach ($sg['SharingGroupOrg'] as $k => $org) {
foreach ($sg['SharingGroupOrgs'] as $k => $org) {
if (empty($org['Organisation'])) {
$org['Organisation'] = $org;
}
if (isset($org['Organisation'][0])) {
$org['Organisation'] = $org['Organisation'][0];
}
$sg['SharingGroupOrg'][$k]['org_id'] = $this->Organisation->captureOrg($org['Organisation'], $user, $force);
if ($sg['SharingGroupOrg'][$k]['org_id'] == $user['org_id']) {
$sg['SharingGroupOrgs'][$k]['org_id'] = $this->Organisation->captureOrg($org['Organisation'], $user, $force);
if ($sg['SharingGroupOrgs'][$k]['org_id'] == $user['org_id']) {
$creatorOrgFound = true;
}
unset($sg['SharingGroupOrg'][$k]['Organisation']);
unset($sg['SharingGroupOrgs'][$k]['Organisation']);
if ($force) {
// we are editing not creating here
$temp = $this->SharingGroupOrg->find(
$temp = $this->SharingGroupOrgs->find(
'first',
[
'recursive' => -1,
'conditions' => [
'sharing_group_id' => $sg_id,
'org_id' => $sg['SharingGroupOrg'][$k]['org_id']
'org_id' => $sg['SharingGroupOrgs'][$k]['org_id']
],
]
);
if (empty($temp)) {
$this->SharingGroupOrg->create();
$this->SharingGroupOrg->save(['sharing_group_id' => $sg_id, 'org_id' => $sg['SharingGroupOrg'][$k]['org_id'], 'extend' => $org['extend']]);
$this->SharingGroupOrgs->create();
$this->SharingGroupOrgs->save(['sharing_group_id' => $sg_id, 'org_id' => $sg['SharingGroupOrgs'][$k]['org_id'], 'extend' => $org['extend']]);
} else {
if ($temp['SharingGroupOrg']['extend'] != $sg['SharingGroupOrg'][$k]['extend']) {
$temp['SharingGroupOrg']['extend'] = $sg['SharingGroupOrg'][$k]['extend'];
$this->SharingGroupOrg->save($temp['SharingGroupOrg']);
if ($temp['SharingGroupOrgs']['extend'] != $sg['SharingGroupOrgs'][$k]['extend']) {
$temp['SharingGroupOrgs']['extend'] = $sg['SharingGroupOrgs'][$k]['extend'];
$this->SharingGroupOrgs->save($temp['SharingGroupOrgs']);
}
}
} else {
$this->SharingGroupOrg->create();
$this->SharingGroupOrg->save(['sharing_group_id' => $sg_id, 'org_id' => $sg['SharingGroupOrg'][$k]['org_id'], 'extend' => $org['extend']]);
$this->SharingGroupOrgs->create();
$this->SharingGroupOrgs->save(['sharing_group_id' => $sg_id, 'org_id' => $sg['SharingGroupOrgs'][$k]['org_id'], 'extend' => $org['extend']]);
}
}
}
@ -1001,7 +1007,7 @@ class SharingGroupTable extends AppTable
}
if (!$this->checkIfAuthorised($syncUsers[$sg['SharingGroup']['sync_user_id']], $sg['SharingGroup']['id'], false)) {
$sharingGroupOrg = ['sharing_group_id' => $sg['SharingGroup']['id'], 'org_id' => $syncUsers[$sg['SharingGroup']['sync_user_id']]['org_id'], 'extend' => 0];
$result = $this->SharingGroupOrg->save($sharingGroupOrg);
$result = $this->SharingGroupOrgs->save($sharingGroupOrg);
if (!$result) {
$entry = new Log([
'org' => 'SYSTEM',
@ -1010,7 +1016,7 @@ class SharingGroupTable extends AppTable
'email' => 'SYSTEM',
'action' => 'error',
'user_id' => 0,
'title' => 'Tried to update a sharing group as part of the 2.4.49 update, but saving the changes has resulted in the following error: ' . json_encode($this->SharingGroupOrg->validationErrors)
'title' => 'Tried to update a sharing group as part of the 2.4.49 update, but saving the changes has resulted in the following error: ' . json_encode($this->SharingGroupOrgs->validationErrors)
]);
$LogsTable->save($entry);
}

View File

@ -0,0 +1,158 @@
<div class="users form">
<fieldset>
<legend><?php echo __('New Sharing Group'); ?></legend>
<?php
$data = array(
'children' => array(
array(
'children' => array(
array(
'text' => __('General'),
'title' => __('General tab'),
'class' => 'progress_tab',
'id' => 'page1_tab',
'active' => true,
'onClick' => 'simpleTabPage',
'onClickParams' => array(1)
),
array(
'text' => __('Organisations'),
'title' => __('Organisations tab'),
'class' => 'progress_tab',
'id' => 'page2_tab',
'onClick' => 'simpleTabPage',
'onClickParams' => array(2)
),
array(
'text' => __('MISP Instances'),
'title' => __('MISP instances tab'),
'class' => 'progress_tab',
'id' => 'page3_tab',
'onClick' => 'simpleTabPage',
'onClickParams' => array(3)
),
array(
'text' => __('Summary and Save'),
'title' => __('Sharing group summary'),
'class' => 'progress_tab',
'id' => 'page4_tab',
'onClick' => 'simpleTabPage',
'onClickParams' => array(4)
)
)
)
)
);
if (!$ajax) {
echo $this->element('/genericElements/ListTopBar/scaffold', array('data' => $data));
}
?>
<div id="page1_content" class="multi-page-form-div tabContent" style="width:544px;">
<?php if ($canModifyUuid): ?>
<label for="SharingGroupUuid"><?php echo __('UUID');?></label>
<input type="text" class="input-xxlarge" placeholder="<?= __('If not provided, random UUID will be generated') ?>" id="SharingGroupUuid">
<?php endif; ?>
<label for="SharingGroupName"><?php echo __('Name');?></label>
<input type="text" class="input-xxlarge" placeholder="<?php echo __('Example: Multinational sharing group');?>" id="SharingGroupName">
<label for="SharingGroupReleasability"><?php echo __('Releasable to');?></label>
<input type="text" class="input-xxlarge" placeholder="<?php echo __('Example: Community1, Organisation1, Organisation2');?>" id="SharingGroupReleasability">
<label for="SharingGroupDescription"><?php echo __('Description');?></label>
<textarea class="input-xxlarge" placeholder="<?php echo __('A description of the sharing group.');?>" cols="30" rows="6" id="SharingGroupDescription"></textarea>
<div style="display:block;">
<input type="checkbox" style="float:left;" title="<?php echo __('Active sharing groups can be selected by users of the local instance when creating events. Generally, sharing groups received through synchronisation will have this disabled until manually enabled.');?>" value="1" id="SharingGroupActive" checked>
<label for="SharingGroupActive" style="padding-left:20px;"><?php echo __('Make the sharing group selectable (active)');?></label>
</div>
<span role="button" tabindex="0" aria-label="<?php echo __('Next page');?>" title="<?php echo __('Next page');?>" class="btn btn-inverse" onClick="simpleTabPage(2);"><?php echo __('Next page');?></span>
</div>
<div id="page2_content" class="multi-page-form-div tabContent" style="display:none;width:544px;">
<div class="tabMenuFixedContainer">
<span role="button" tabindex="0" aria-label="<?php echo __('Add local organisation(s) to the sharing group');?>" title="<?php echo __('Add local organisation(s) to the sharing group');?>" class="tabMenuFixed tabMenuFixedCenter tabMenuSides useCursorPointer" onClick="sharingGroupAdd('organisation', 'local');"><?php echo __('Add local organisation');?></span>
<span role="button" tabindex="0" aria-label="<?php echo __('Add remote organisations to the sharing group');?>" title="<?php echo __('Add remote organisations to the sharing group');?>" class="tabMenuFixed tabMenuFixedCenter tabMenuSides useCursorPointer" onClick="sharingGroupAdd('organisation', 'remote');"><?php echo __('Add remote organisation');?></span>
</div>
<table id="organisations_table" class="table table-striped table-hover table-condensed">
<tr id="organisations_table_header">
<th><?php echo __('Type');?></th>
<th><?php echo __('Name');?></th>
<th><?php echo __('UUID');?></th>
<th><?php echo __('Extend');?></th>
<th><?php echo __('Actions');?></th>
</tr>
</table>
<span role="button" tabindex="0" aria-label="<?php echo __('Previous page');?>" title="<?php echo __('Previous page');?>" class="btn btn-inverse" onClick="simpleTabPage(1);"><?php echo __('Previous page');?></span>
<span role="button" tabindex="0" aria-label="<?php echo __('Next page');?>" title="<?php echo __('Next page');?>" class="btn btn-inverse" onClick="simpleTabPage(3);"><?php echo __('Next page');?></span>
</div>
<div id="page3_content" class="multi-page-form-div tabContent" style="display:none;width:544px;">
<div style="display:block;">
<input type="checkbox" style="float:left;" title="<?php echo __('Enable roaming mode for this sharing group. Roaming mode will allow the sharing group to be passed to any instance where the remote recipient is contained in the organisation list. It is preferred to list the recipient instances instead.');?>" value="1" id="SharingGroupRoaming">
<label for="SharingGroupRoaming" style="padding-left:20px;"><?php echo __('<b>Enable roaming mode</b> for this sharing group (pass the event to any connected instance where the sync connection is tied to an organisation contained in the SG organisation list).');?></label>
</div>
<div id="serverList">
<div class="tabMenuFixedContainer">
<span role="button" tabindex="0" aria-label="<?php echo __('Add instance');?>" title="<?php echo __('Add instance');?>" class="tabMenuFixed tabMenuFixedCenter tabMenuSides useCursorPointer" onClick="sharingGroupAdd('server');"><?php echo __('Add instance');?></span>
</div>
<table id="servers_table" class="table table-striped table-hover table-condensed">
<tr>
<th><?php echo __('Name');?></th>
<th><?php echo __('URL');?></th>
<th><?php echo __('All orgs');?></th>
<th><?php echo __('Actions');?></th>
</tr>
</table>
</div>
<span role="button" tabindex="0" aria-label="<?php echo __('Previous page');?>" title="<?php echo __('Previous page');?>" class="btn btn-inverse" onClick="simpleTabPage(2);"><?php echo __('Previous page');?></span>
<span role="button" tabindex="0" aria-label="<?php echo __('Next page');?>" title="<?php echo __('Next page');?>" class="btn btn-inverse" onClick="simpleTabPage(4);"><?php echo __('Next page');?></span>
</div>
</fieldset>
<div id="page4_content" class="multi-page-form-div tabContent" style="display:none;width:544px;">
<p><?php echo __('<span class="bold">General: </span>You are about to create the <span id="summarytitle" class="red bold"></span> sharing group, which is intended to be releasable to <span id="summaryreleasable" class="red bold"></span>.');?> </p>
<p id="localText"><span class="bold"><?php echo __('Local organisations: </span>It will be visible to <span id="summarylocal" class="red bold"></span>, from which <span id="summarylocalextend" class="red bold"></span> can extend the sharing group.');?> </p>
<p id="externalText"><span class="bold"><?php echo __('External organisations: </span>It will also be visible to <span id="summaryexternal" class="red bold"></span>, out of which <span id="summaryexternalextend" class="red bold"></span> can extend the sharing group.');?></p>
<p id="synchronisationText"><?php echo __('<span class="bold">Synchronisation: </span>Furthermore, events are automatically pushed to: <span id="summaryservers" class="red bold"></span>');?></p>
<p><?php echo __('You can edit this information by going back to one of the previous pages, or if you agree with the above mentioned information, click Submit to create the Sharing group.');?></p>
<?php
echo $this->Form->create('SharingGroup');
echo $this->Form->input('json', array('style' => 'display:none;', 'label' => false, 'div' => false));
//echo $this->Form->button(__('Submit'), array('class' => 'btn btn-primary'));
echo $this->Form->end();
?>
<span role="button" tabindex="0" aria-label="<?php echo __('Previous page');?>" title="<?php echo __('Previous page');?>" class="btn btn-inverse" onClick="simpleTabPage(3);"><?php echo __('Previous page');?></span>
<span role="button" tabindex="0" aria-label="<?php echo __('Submit and create sharing group');?>" title="<?php echo __('Submit and create sharing group');?>" class="btn btn-primary" onClick="sgSubmitForm('Add');"><?php echo __('Submit');?></span>
</div>
</div>
<?php
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'globalActions', 'menuItem' => 'addSG'));
?>
<script type="text/javascript">
var lastPage = 4;
var roaming = false;
var organisations = [{
id: '<?php echo h($user['Organisation']['id'])?>',
type: 'local',
name: '<?php echo h($user['Organisation']['name'])?>',
extend: true,
uuid: '',
removable: 0
}];
var orgids = ['<?php echo h($user['Organisation']['id'])?>'];
var servers = [{
id: '0',
name: '<?php echo __('Local instance');?>',
url: '<?php echo h($localInstance); ?>',
all_orgs: false,
removable: 0
}];
var serverids = [0];
$(function() {
if ($('#SharingGroupJson').val()) sharingGroupPopulateFromJson();
sharingGroupPopulateOrganisations();
sharingGroupPopulateServers();
});
$('#SharingGroupRoaming').change(function() {
if ($(this).is(":checked")) {
$('#serverList').hide();
} else {
$('#serverList').show();
}
});
</script>

View File

@ -0,0 +1,209 @@
<div class="users form">
<fieldset>
<legend><?php echo __('Edit Sharing Group'); ?></legend>
<?php
$data = array(
'children' => array(
array(
'children' => array(
array(
'text' => __('General'),
'title' => __('General tab'),
'class' => 'progress_tab',
'id' => 'page1_tab',
'active' => true,
'onClick' => 'simpleTabPage',
'onClickParams' => array(1)
),
array(
'text' => __('Organisations'),
'title' => __('Organisations tab'),
'class' => 'progress_tab',
'id' => 'page2_tab',
'onClick' => 'simpleTabPage',
'onClickParams' => array(2)
),
array(
'text' => __('MISP Instances'),
'title' => __('MISP instances tab'),
'class' => 'progress_tab',
'id' => 'page3_tab',
'onClick' => 'simpleTabPage',
'onClickParams' => array(3)
),
array(
'text' => __('Summary and Save'),
'title' => __('Sharing group summary'),
'class' => 'progress_tab',
'id' => 'page4_tab',
'onClick' => 'simpleTabPage',
'onClickParams' => array(4)
)
)
)
)
);
if (!$ajax) {
echo $this->element('/genericElements/ListTopBar/scaffold', array('data' => $data));
}
?>
<div id="page1_content" class="multi-page-form-div tabContent" style="width:544px;">
<label for="SharingGroupName"><?php echo __('Name');?></label>
<input type="text" class="input-xxlarge" placeholder="<?php echo __('Example: Multinational sharing group');?>" id="SharingGroupName" value="<?php echo h($sharingGroup['SharingGroup']['name']); ?>">
<label for="SharingGroupReleasability"><?php echo __('Releasable to');?></label>
<input type="text" class="input-xxlarge" placeholder="<?php echo __('Example: Community1, Organisation1, Organisation2');?>" id="SharingGroupReleasability" value="<?php echo h($sharingGroup['SharingGroup']['releasability']); ?>">
<label for="SharingGroupDescription"><?php echo __('Description');?></label>
<textarea class="input-xxlarge" placeholder="<?php echo __('A description of the sharing group.');?>" cols="30" rows="6" id="SharingGroupDescription"><?php echo h($sharingGroup['SharingGroup']['description']); ?></textarea>
<div style="display:block;">
<input type="checkbox" style="float:left;" title="<?php echo __('Active sharing groups can be selected by users of the local instance when creating events. Generally, sharing groups received through synchronisation will have this disabled until manually enabled.');?>" <?php if ($sharingGroup['SharingGroup']['active']) echo "checked"; ?> id="SharingGroupActive">
<label for="SharingGroupActive" style="padding-left:20px;"><?php echo __('Make the sharing group selectable (active)');?></label>
</div>
<span role="button" tabindex="0" aria-label="<?php echo __('Next page');?>" title="<?php echo __('Next page');?>" class="btn btn-inverse" onClick="simpleTabPage(2);"><?php echo __('Next page');?></span>
</div>
<div id="page2_content" class="multi-page-form-div tabContent" style="display:none;width:544px;">
<div class="tabMenuFixedContainer">
<span role="button" tabindex="0" aria-label="<?php echo __('Add local organisation(s) to the sharing group');?>" title="<?php echo __('Add local organisation(s) to the sharing group');?>" class="tabMenuFixed tabMenuFixedCenter tabMenuSides useCursorPointer" onClick="sharingGroupAdd('organisation', 'local');"><?php echo __('Add local organisation');?></span>
<span role="button" tabindex="0" aria-label="<?php echo __('Add remote organisations to the sharing group');?>" title="<?php echo __('Add remote organisations to the sharing group');?>" class="tabMenuFixed tabMenuFixedCenter tabMenuSides useCursorPointer" onClick="sharingGroupAdd('organisation', 'remote');"><?php echo __('Add remote organisation');?></span>
</div>
<table id="organisations_table" class="table table-striped table-hover table-condensed">
<tr id="organisations_table_header">
<th><?php echo __('Type');?></th>
<th><?php echo __('Name');?></th>
<th><?php echo __('UUID');?></th>
<th><?php echo __('Extend');?></th>
<th><?php echo __('Actions');?></th>
</tr>
</table>
<span role="button" tabindex="0" aria-label="<?php echo __('Previous page');?>" title="<?php echo __('Previous page');?>" class="btn btn-inverse" onClick="simpleTabPage(1);"><?php echo __('Previous page');?></span>
<span role="button" tabindex="0" aria-label="<?php echo __('Next page');?>" title="<?php echo __('Next page');?>" class="btn btn-inverse" onClick="simpleTabPage(3);"><?php echo __('Next page');?></span>
</div>
<div id="page3_content" class="multi-page-form-div tabContent" style="display:none;width:544px;">
<?php
$serverDivVisibility = "";
$checked = "";
if ($sharingGroup['SharingGroup']['roaming']) {
$serverDivVisibility = 'style="display:none;"';
$checked = "checked";
}
?>
<div style="display:block;">
<input type="checkbox" style="float:left;" title="<?php echo __('Enable roaming mode for this sharing group. Roaming mode will allow the sharing group to be passed to any instance where the remote recipient is contained in the organisation list. It is preferred to list the recipient instances instead.');?>" <?php echo $checked; ?> id="SharingGroupRoaming">
<label for="SharingGroupRoaming" style="padding-left:20px;"><?php echo __('<b>Enable roaming mode</b> for this sharing group (pass the event to any connected instance where the sync connection is tied to an organisation contained in the SG organisation list).');?></label>
</div>
<div id="serverList" <?php echo $serverDivVisibility; ?>>
<div class="tabMenuFixedContainer">
<span role="button" tabindex="0" aria-label="<?php echo __('Add instance');?>" title="<?php echo __('Add instance');?>" class="tabMenuFixed tabMenuFixedCenter tabMenuSides useCursorPointer" onClick="sharingGroupAdd('server');"><?php echo __('Add instance');?></span>
</div>
<table id="servers_table" class="table table-striped table-hover table-condensed">
<tr>
<th><?php echo __('Name');?></th>
<th><?php echo __('URL');?></th>
<th><?php echo __('All orgs');?></th>
<th><?php echo __('Actions');?></th>
</tr>
</table>
</div>
<span role="button" tabindex="0" aria-label="<?php echo __('Previous page');?>" title="<?php echo __('Previous page');?>" class="btn btn-inverse" onClick="simpleTabPage(2);"><?php echo __('Previous page');?></span>
<span role="button" tabindex="0" aria-label="<?php echo __('Next page');?>" title="<?php echo __('Next page');?>" class="btn btn-inverse" onClick="simpleTabPage(4);"><?php echo __('Next page');?></span>
</div>
</fieldset>
<div id="page4_content" class="multi-page-form-div tabContent" style="display:none;width:544px;">
<p><?php echo __('<span class="bold">General: </span>You are about to create the <span id="summarytitle" class="red bold"></span> sharing group, which is intended to be releasable to <span id="summaryreleasable" class="red bold"></span>. </p>
<p id="localText"><span class="bold">Local organisations: </span>It will be visible to <span id="summarylocal" class="red bold"></span>, from which <span id="summarylocalextend" class="red bold"></span> can extend the sharing group. </p>
<p id="externalText"><span class="bold">External organisations: </span>It will also be visible to <span id="summaryexternal" class="red bold"></span>, out of which <span id="summaryexternalextend" class="red bold"></span> can extend the sharing group.');?></p>
<p id="synchronisationText"><span class="bold"><?php echo __('Synchronisation: </span>Furthermore, events are automatically pushed to: <span id="summaryservers" class="red bold"></span>');?></p>
<p><?php echo __('You can edit this information by going back to one of the previous pages, or if you agree with the above mentioned information, click Submit to create the Sharing group.');?></p>
<?php
echo $this->Form->create('SharingGroup');
echo $this->Form->input('json', array('style' => 'display:none;', 'label' => false, 'div' => false));
//echo $this->Form->button(__('Submit'), array('class' => 'btn btn-primary'));
echo $this->Form->end();
?>
<span role="button" tabindex="0" aria-label="<?php echo __('Previous page');?>" title="<?php echo __('Previous page');?>" class="btn btn-inverse" onClick="simpleTabPage(3);"><?php echo __('Previous page');?></span>
<span role="button" tabindex="0" aria-label="<?php echo __('Submit and create sharing group');?>" title="<?php echo __('Submit and create sharing group');?>" class="btn btn-primary" onClick="sgSubmitForm('Edit');">Submit</span>
</div>
</div>
<?php
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'globalActions', 'menuItem' => 'editSG'));
?>
<script type="text/javascript">
var lastPage = 4;
var organisations = [];
var orgids = ['<?php echo h($user['Organisation']['id'])?>'];
var servers = [];
var serverids = [0];
<?php
if (empty($sharingGroup['SharingGroupServer'])):
?>
var servers = [{
id: '0',
name: 'Local instance',
url: '<?php echo h($localInstance); ?>',
all_orgs: true,
removable: 0
}];
var serverids = [0];
<?php
else:
foreach ($sharingGroup['SharingGroupServer'] as $s):
?>
serverids.push(<?php echo h($s['server_id']);?>);
<?php
if ($s['server_id'] == 0):
?>
servers.push({
id: '<?php echo h($s['server_id']);?>',
name: 'Local instance',
url: '<?php echo empty(Configure::read('MISP.external_baseurl')) ? Configure::read('MISP.baseurl') : Configure::read('MISP.external_baseurl');?>',
all_orgs: '<?php echo h($s['all_orgs']); ?>',
removable:0,
});
<?php
else:
?>
servers.push({
id: '<?php echo h($s['server_id']);?>',
name: '<?php echo h($s['Server']['name']); ?>',
url: '<?php echo h($s['Server']['url']); ?>',
all_orgs: '<?php echo h($s['all_orgs']); ?>',
removable:1,
});
<?php
endif;
endforeach;
endif;
?>
<?php
foreach ($sharingGroup['SharingGroupOrg'] as $s):
?>
orgids.push(<?php echo h($s['org_id']);?>);
var removable = 1;
if (<?php echo h($sharingGroup['Organisation']['id']);?> == <?php echo h($s['org_id'])?>) removable = 0;
organisations.push({
id: '<?php echo h($s['org_id']);?>',
type: '<?php echo ($s['Organisation']['local'] == 1 ? 'local' : 'remote'); ?>',
name: '<?php echo h($s['Organisation']['name'])?>',
extend: '<?php echo h($s['extend']);?>',
uuid: '',
removable:removable
});
<?php
endforeach;
?>
$(function() {
if ($('#SharingGroupJson').val()) sharingGroupPopulateFromJson();
sharingGroupPopulateOrganisations();
sharingGroupPopulateServers();
});
$('#SharingGroupRoaming').change(function() {
if ($(this).is(":checked")) {
$('#serverList').hide();
} else {
$('#serverList').show();
}
});
</script>

View File

@ -0,0 +1,173 @@
<div class="sharing_groups<?php if (!$ajax) echo ' index' ?>">
<?= $this->element('/genericElements/IndexTable/index_table', array(
'data' => array(
'title' => __('Sharing Groups'),
'data' => $sharingGroups,
'top_bar' => $ajax ? [] : array(
'children' => array(
array(
'type' => 'simple',
'children' => array(
array(
'text' => __('Add'),
'fa-icon' => 'plus',
'url' => $baseurl . '/sharing_groups/add',
'requirement' => $this->Acl->checkAccess('sharing_groups', 'add'),
)
)
),
array(
'type' => 'simple',
'children' => array(
array(
'url' => $baseurl . '/sharing_groups/index',
'text' => __('Active Sharing Groups'),
'active' => !$passive,
),
array(
'url' => $baseurl . '/sharing_groups/index/true',
'text' => __('Passive Sharing Groups'),
'active' => $passive,
)
)
),
array(
'type' => 'search',
'button' => __('Filter'),
'placeholder' => __('Enter value to search'),
'searchKey' => 'value',
'cancel' => array(
'fa-icon' => 'times',
'title' => __('Remove filters'),
'onClick' => 'cancelSearch',
)
)
)
),
'fields' => array(
array(
'name' => __('ID'),
'sort' => 'id',
'element' => 'links',
'class' => 'short',
'data_path' => 'id',
'url' => $baseurl . '/sharing_groups/view/%s'
),
array(
'name' => __('UUID'),
'data_path' => 'uuid',
'sort' => 'uuid',
'class' => 'short quickSelect',
),
array(
'name' => __('Name'),
'data_path' => 'name',
'sort' => 'name',
'class' => 'short',
),
array(
'name' => __('Creator'),
'sort' => 'Organisation.name',
'element' => 'org',
'data_path' => 'Organisation',
'class' => 'short',
),
array(
'name' => __('Description'),
'data_path' => 'description',
),
array(
'name' => __('Org count'),
'class' => 'short',
'sort' => 'org_count',
'data_path' => 'org_count',
),
array(
'name' => __('Releasable to'),
'element' => 'custom',
'function' => function (array $sharingGroup) use ($baseurl) {
$combined = __("Organisations:");
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";
} 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) ?>">
<?= empty($sharingGroup['releasability']) ?
'<span style="color: gray">' . __('Not defined') . '</span>' :
h($sharingGroup['releasability'])
?>
</span>
<?php
},
)
),
'actions' => array(
array(
'url' => $baseurl . '/sharing_groups/view',
'url_params_data_paths' => ['id'],
'icon' => 'eye',
'title' => __('View Sharing Group'),
),
array(
'url' => '/sharing_groups/edit',
'url_params_data_paths' => ['id'],
'icon' => 'edit',
'complex_requirement' => [
'function' => function (array $sharingGroup) {
return $sharingGroup['editable'];
}
],
'title' => __('Edit Sharing Group'),
),
array(
'url' => '/sharing_groups/delete',
'url_params_data_paths' => ['id'],
'postLinkConfirm' => __('Are you sure you want to delete the sharing group?'),
'icon' => 'trash',
'complex_requirement' => [
'function' => function (array $sharingGroup) {
return $sharingGroup['deletable'];
}
],
'title' => __('Delete Sharing Group'),
),
)
)
));
?>
</div>
<script type="text/javascript">
$(function(){
popoverStartup();
});
</script>
<?php
// TODO: [3.x-MIGRATION]
// if (!$ajax) {
// echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'globalActions', 'menuItem' => 'indexSG'));
// }

View File

@ -0,0 +1,108 @@
<?php
echo $this->element(
'genericElements/SingleViews/single_view',
[
'title' => __('Sharing Group %s', $sg['SharingGroup']['name']),
'data' => $sg,
'fields' => [
[
'key' => __('ID'),
'path' => 'SharingGroup.id'
],
[
'key' => __('UUID'),
'path' => 'SharingGroup.uuid'
],
[
'key' => __('Name'),
'path' => 'SharingGroup.name'
],
[
'key' => __('Releasability'),
'path' => 'SharingGroup.releasability'
],
[
'key' => __('Description'),
'path' => 'SharingGroup.description'
],
[
'key' => __('Selectable'),
'path' => 'SharingGroup.active',
'type' => 'boolean'
],
[
'key' => __('Created by'),
'path' => 'Organisation',
'type' => 'org'
],
[
'key' => __('Synced by'),
'path' => 'SharingGroup.sync_org',
'type' => 'org',
'requirement' => isset($sg['SharingGroup']['sync_org'])
],
[
'key' => __('Events'),
'raw' => __n('%s event', '%s events', $sg['SharingGroup']['event_count'], $sg['SharingGroup']['event_count']),
'url' => sprintf('/events/index/searchsharinggroup:%s', h($sg['SharingGroup']['id']))
],
[
'key' => __('Organisations'),
'type' => 'custom',
'requirement' => isset($sg['SharingGroupOrg']),
'function' => function (array $sharingGroup) {
echo sprintf(
'<div class="span6">
<table class="table table-striped table-hover table-condensed">
<tr>
<th>%s</th>
<th>%s</th>
<th>%s</th>
</tr>',
__('Name'),
__('Is local'),
__('Can extend')
);
foreach ($sharingGroup['SharingGroupOrg'] as $sgo) {
echo '<tr>';
echo sprintf('<td>%s</td>', $this->OrgImg->getNameWithImg($sgo));
echo sprintf('<td><span class="%s"></span></td>', $sgo['Organisation']['local'] ? 'fas fa-check' : 'fas fa-times');
echo sprintf('<td><span class="%s"></span></td>', $sgo['extend'] ? 'fas fa-check' : 'fas fa-times');
echo '</tr>';
}
echo '</table>
</div>';
}
],
[
'key' => __('Instances'),
'type' => 'custom',
'requirement' => isset($sg['SharingGroupServer']),
'function' => function (array $sharingGroup) {
echo sprintf(
'<div class="span6">
<table class="table table-striped table-hover table-condensed">
<tr>
<th>%s</th>
<th>%s</th>
<th>%s</th>
</tr>',
__('Name'),
__('URL'),
__('All orgs')
);
foreach ($sharingGroup['SharingGroupServer'] as $sgs) {
echo '<tr>';
echo sprintf('<td>%s</td>', h($sgs['Server']['name']));
echo sprintf('<td>%s</td>', h($sgs['Server']['url']));
echo sprintf('<td><span class="%s"></span></td>', $sgs['all_orgs'] ? 'fas fa-check' : 'fas fa-times');
echo '</tr>';
}
echo '</table>
</div>';
}
]
]
]
);