diff --git a/application/Espo/Controllers/Layout.php b/application/Espo/Controllers/Layout.php index bcbed006b5..71c114c57e 100644 --- a/application/Espo/Controllers/Layout.php +++ b/application/Espo/Controllers/Layout.php @@ -39,11 +39,7 @@ class Layout extends \Espo\Core\Controllers\Base { public function actionRead($params, $data) { - $data = $this->getContainer()->get('layout')->get($params['scope'], $params['name']); - if (empty($data)) { - throw new NotFound("Layout " . $params['scope'] . ":" . $params['name'] . ' is not found.'); - } - return $data; + return $this->getServiceFactory()->create('Layout')->getForFrontend($params['scope'], $params['name']); } public function actionUpdate($params, $data, $request) diff --git a/application/Espo/Services/Layout.php b/application/Espo/Services/Layout.php new file mode 100644 index 0000000000..e5b7b3e17e --- /dev/null +++ b/application/Espo/Services/Layout.php @@ -0,0 +1,79 @@ +addDependency('acl'); + $this->addDependency('layout'); + $this->addDependency('metadata'); + } + + protected function getAcl() + { + return $this->getInjection('acl'); + } + + protected function getMetadata() + { + return $this->getInjection('metadata'); + } + + public function getForFrontend(string $scope, string $name) + { + $dataString = $this->getInjection('layout')->get($scope, $name); + + if (!$dataString) { + throw new NotFound("Layout {$scope}:{$scope} is not found."); + } + + if (!$this->getUser()->isAdmin()) { + if ($name === 'relationships') { + $data = json_decode($dataString); + if (is_array($data)) { + foreach ($data as $i => $link) { + $foreignEntityType = $this->getMetadata()->get(['entityDefs', $scope, 'links', $link, 'entity']); + if ($foreignEntityType) { + if (!$this->getAcl()->check($foreignEntityType)) { + unset($data[$i]); + } + } + } + $data = array_values($data); + $dataString = json_encode($data); + } + } + } + + return $dataString; + } +} diff --git a/application/Espo/Services/Metadata.php b/application/Espo/Services/Metadata.php index 935765c9af..48917a2de9 100644 --- a/application/Espo/Services/Metadata.php +++ b/application/Espo/Services/Metadata.php @@ -72,6 +72,57 @@ class Metadata extends \Espo\Core\Services\Base } } + $entityTypeList = array_keys(get_object_vars($data->entityDefs)); + foreach ($entityTypeList as $entityType) { + $linksDefs = $this->getMetadata()->get(['entityDefs', $entityType, 'links'], []); + + $fobiddenFieldList = $this->getAcl()->getScopeForbiddenFieldList($entityType); + + foreach ($linksDefs as $link => $defs) { + $type = $defs['type'] ?? null; + + $hasField = !!$this->getMetadata()->get(['entityDefs', $entityType, 'fields', $link]); + + if ($type === 'belongsToParent') { + if ($hasField) { + $parentEntityList = $this->getMetadata()->get(['entityDefs', $entityType, 'fields', $link, 'entityList']); + if (is_array($parentEntityList)) { + foreach ($parentEntityList as $i => $e) { + if (!$this->getAcl()->check($e)) { + unset($parentEntityList[$i]); + } + } + $parentEntityList = array_values($parentEntityList); + $data->entityDefs->$entityType->fields->$link->entityList = $parentEntityList; + } + } + continue; + } + + $foreignEntityType = $defs['entity'] ?? null; + if ($this->getAcl()->check($foreignEntityType)) continue; + + if ($hasField) { + if (!in_array($link, $fobiddenFieldList)) { + continue; + } + unset($data->entityDefs->$entityType->fields->$link); + } + + unset($data->entityDefs->$entityType->links->$link); + + if ( + isset($data->clientDefs) + && + isset($data->clientDefs->$entityType) + && + isset($data->clientDefs->$entityType->relationshipPanels) + ) { + unset($data->clientDefs->$entityType->relationshipPanels->$link); + } + } + } + unset($data->entityDefs->Settings); $dashletList = array_keys($this->getMetadata()->get(['dashlets'], []));