mirror of
https://github.com/espocrm/espocrm.git
synced 2026-03-03 02:27:01 +00:00
metadata aclDependency anyScopeList
This commit is contained in:
@@ -31,10 +31,14 @@ namespace Espo\Tools\App\Metadata;
|
||||
|
||||
class AclDependencyItem
|
||||
{
|
||||
/**
|
||||
* @param ?string[] $anyScopeList
|
||||
*/
|
||||
public function __construct(
|
||||
private string $target,
|
||||
private string $scope,
|
||||
private ?string $field
|
||||
private ?string $scope,
|
||||
private ?string $field,
|
||||
private ?array $anyScopeList = null,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -45,7 +49,7 @@ class AclDependencyItem
|
||||
return $this->target;
|
||||
}
|
||||
|
||||
public function getScope(): string
|
||||
public function getScope(): ?string
|
||||
{
|
||||
return $this->scope;
|
||||
}
|
||||
@@ -54,4 +58,13 @@ class AclDependencyItem
|
||||
{
|
||||
return $this->field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?string[]
|
||||
* @since 9.2.5
|
||||
*/
|
||||
public function getAnyScopeList(): ?array
|
||||
{
|
||||
return $this->anyScopeList;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,15 +95,13 @@ class AclDependencyProvider
|
||||
$data = [];
|
||||
|
||||
foreach (($this->metadata->get(['app', 'metadata', 'aclDependencies']) ?? []) as $target => $item) {
|
||||
$anyScopeList = $item['anyScopeList'] ?? null;
|
||||
$scope = $item['scope'] ?? null;
|
||||
$field = $item['field'] ?? null;
|
||||
|
||||
if (!$scope) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data[] = [
|
||||
'target' => $target,
|
||||
'anyScopeList' => $anyScopeList,
|
||||
'scope' => $scope,
|
||||
'field' => $field,
|
||||
];
|
||||
@@ -196,8 +194,14 @@ class AclDependencyProvider
|
||||
$target = $rawItem['target'] ?? null;
|
||||
$scope = $rawItem['scope'] ?? null;
|
||||
$field = $rawItem['field'] ?? null;
|
||||
$anyScopeList = $rawItem['anyScopeList'] ?? null;
|
||||
|
||||
$list[] = new AclDependencyItem($target, $scope, $field);
|
||||
$list[] = new AclDependencyItem(
|
||||
target: $target,
|
||||
scope: $scope,
|
||||
field: $field,
|
||||
anyScopeList: $anyScopeList,
|
||||
);
|
||||
}
|
||||
|
||||
return $list;
|
||||
|
||||
@@ -178,20 +178,32 @@ class MetadataService
|
||||
foreach ($this->aclDependencyProvider->get() as $dependencyItem) {
|
||||
$aclScope = $dependencyItem->getScope();
|
||||
$aclField = $dependencyItem->getField();
|
||||
$anyScopeList = $dependencyItem->getAnyScopeList();
|
||||
|
||||
if (!$aclScope) {
|
||||
continue;
|
||||
if ($anyScopeList) {
|
||||
$skip = true;
|
||||
|
||||
foreach ($anyScopeList as $itemScope) {
|
||||
if ($this->acl->tryCheck($itemScope)) {
|
||||
$skip = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($skip) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->acl->tryCheck($aclScope)) {
|
||||
continue;
|
||||
}
|
||||
if ($aclScope) {
|
||||
if (!$this->acl->tryCheck($aclScope)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
$aclField &&
|
||||
in_array($aclField, $this->acl->getScopeForbiddenFieldList($aclScope))
|
||||
) {
|
||||
continue;
|
||||
if ($aclField && in_array($aclField, $this->acl->getScopeForbiddenFieldList($aclScope))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$targetArr = explode('.', $dependencyItem->getTarget());
|
||||
|
||||
@@ -44,21 +44,21 @@
|
||||
},
|
||||
"aclDependencies": {
|
||||
"type": "object",
|
||||
"description": "Rules making a metadata sections available for a user when they don't have access to a scope.",
|
||||
"description": "Rules making a metadata sections available for the user when they don't have access to the scope.",
|
||||
"additionalProperties": {
|
||||
"description": "A metadata path, items are separated by dots.",
|
||||
"properties": {
|
||||
"scope": {
|
||||
"type": "string",
|
||||
"description": "If a user have access to the scope, they will have access to a metadata section defined by a key."
|
||||
"description": "If the user has access to the scope, they will have access to the metadata section defined by the key."
|
||||
},
|
||||
"field": {
|
||||
"type": "string",
|
||||
"description": "If a user have access to the field (of a scope), they will have access to a metadata section defined by a key."
|
||||
"description": "If the user has access to the field (of the scope), they will have access to the metadata section defined by the key."
|
||||
},
|
||||
"anyScopeList": {
|
||||
"type": "array",
|
||||
"description": "Not supported. TBD.",
|
||||
"description": "If the user has access to any of the list scopes, they will have access to the metadata section defined by the key. As of v9.2.5.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
namespace tests\integration\Espo\Tools\App;
|
||||
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Tools\App\MetadataService;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
@@ -36,6 +37,20 @@ class MetadataTest extends BaseTestCase
|
||||
{
|
||||
public function testAclDependency(): void
|
||||
{
|
||||
$metadata = $this->getContainer()->getByClass(Metadata::class);
|
||||
|
||||
$metadata->set('app', 'metadata', [
|
||||
'aclDependencies' => [
|
||||
'entityDefs.Campaign' => [
|
||||
'anyScopeList' => ['Opportunity'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$metadata->save();
|
||||
|
||||
$this->reCreateApplication();
|
||||
|
||||
$this->createUser('tester', [
|
||||
'data' => [
|
||||
'Lead' => false,
|
||||
@@ -55,6 +70,7 @@ class MetadataTest extends BaseTestCase
|
||||
$data = $this->getInjectableFactory()->create(MetadataService::class)->getDataForFrontend();
|
||||
|
||||
$this->assertIsArray($data?->entityDefs?->Lead?->fields?->source?->options);
|
||||
$this->assertNull($data->entityDefs->Lead->fields?->name ?? null);
|
||||
$this->assertNull($data->entityDefs->Lead->fields->name ?? null);
|
||||
$this->assertNotNull($data?->entityDefs->Campaign ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user