forked from oroinc/platform
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAvailableOwnerAccessRule.php
100 lines (87 loc) · 3.53 KB
/
AvailableOwnerAccessRule.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?php
namespace Oro\Bundle\SecurityBundle\AccessRule;
use Oro\Bundle\SecurityBundle\AccessRule\Expr\AccessDenied;
use Oro\Bundle\SecurityBundle\AccessRule\Expr\Comparison;
use Oro\Bundle\SecurityBundle\AccessRule\Expr\Path;
use Oro\Bundle\SecurityBundle\ORM\Walker\AclConditionDataBuilderInterface;
use Oro\Bundle\SecurityBundle\Owner\Metadata\OwnershipMetadataProviderInterface;
/**
* Limits entities that can be used as an owner by CREATE or ASSIGN permission.
*/
class AvailableOwnerAccessRule implements AccessRuleInterface
{
/** The option that allows to enable the rule. Default value is false. */
const ENABLE_RULE = 'availableOwnerEnable';
/** The option that contains the target class name whose access level should be used for the check. */
const TARGET_ENTITY_CLASS = 'availableOwnerTargetEntityClass';
/** The option that contains the ID of owner that should be available even if ACL check denies access. */
const CURRENT_OWNER = 'availableOwnerCurrentOwner';
/** @var AclConditionDataBuilderInterface */
private $builder;
/** @var OwnershipMetadataProviderInterface */
private $ownershipMetadataProvider;
/**
* @param AclConditionDataBuilderInterface $builder
* @param OwnershipMetadataProviderInterface $ownershipMetadataProvider
*/
public function __construct(
AclConditionDataBuilderInterface $builder,
OwnershipMetadataProviderInterface $ownershipMetadataProvider
) {
$this->builder = $builder;
$this->ownershipMetadataProvider = $ownershipMetadataProvider;
}
/**
* {@inheritdoc}
*/
public function isApplicable(Criteria $criteria): bool
{
return
$criteria->getOption(self::ENABLE_RULE, false)
&& ($criteria->getPermission() === 'ASSIGN' || $criteria->getPermission() === 'CREATE')
&& $criteria->isRoot()
&& $criteria->hasOption(self::TARGET_ENTITY_CLASS);
}
/**
* {@inheritdoc}
*/
public function process(Criteria $criteria): void
{
$alias = $criteria->getAlias();
$conditionData = $this->builder->getAclConditionData(
$criteria->getOption(self::TARGET_ENTITY_CLASS),
$criteria->getPermission()
);
if (!empty($conditionData)) {
list(, $ownerValue, , $organizationValue, $ignoreOwner) = $conditionData;
if (!$ignoreOwner) {
if (empty($ownerValue)) {
$criteria->andExpression(new AccessDenied());
} else {
$criteria->andExpression(
new Comparison(
new Path('id', $alias),
is_array($ownerValue) ? Comparison::IN : Comparison::EQ,
$ownerValue
)
);
}
}
if (null !== $organizationValue) {
$metadata = $this->ownershipMetadataProvider->getMetadata($criteria->getEntityClass());
$criteria->andExpression(
new Comparison(
new Path($metadata->getOrganizationFieldName(), $alias),
Comparison::EQ,
$organizationValue
)
);
}
}
if ($criteria->hasOption(self::CURRENT_OWNER)) {
$criteria->orExpression(
new Comparison(new Path('id', $alias), Comparison::EQ, $criteria->getOption(self::CURRENT_OWNER))
);
}
}
}