1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace PhpAbac; |
4
|
|
|
|
5
|
|
|
use PhpAbac\Manager\AttributeManager; |
6
|
|
|
use PhpAbac\Manager\PolicyRuleManager; |
7
|
|
|
use PhpAbac\Manager\ConfigurationManager; |
8
|
|
|
use PhpAbac\Manager\CacheManager; |
9
|
|
|
use PhpAbac\Manager\ComparisonManager; |
10
|
|
|
|
11
|
|
|
use Symfony\Component\Config\FileLocator; |
12
|
|
|
|
13
|
|
|
use PhpAbac\Model\PolicyRuleAttribute; |
14
|
|
|
|
15
|
|
|
class Abac { |
16
|
|
|
/** @var \PhpAbac\Manager\ConfigurationManager * */ |
17
|
|
|
private $configuration; |
18
|
|
|
/** @var \PhpAbac\Manager\PolicyRuleManager * */ |
19
|
|
|
private $policyRuleManager; |
20
|
|
|
/** @var \PhpAbac\Manager\AttributeManager * */ |
21
|
|
|
private $attributeManager; |
22
|
|
|
/** @var \PhpAbac\Manager\CacheManager * */ |
23
|
|
|
private $cacheManager; |
24
|
|
|
/** @var \PhpAbac\Manager\ComparisonManager * */ |
25
|
|
|
private $comparisonManager; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* @param array $configPaths |
29
|
|
|
* @param array $cacheOptions Option for cache |
30
|
|
|
* @param string $configPaths_root The origin folder to find $configPaths |
31
|
|
|
* @param array $options |
32
|
|
|
*/ |
33
|
4 |
|
public function __construct( $configPaths, $cacheOptions = [], $configPaths_root = null, $options = [] ) { |
|
|
|
|
34
|
4 |
|
$this->configure( $configPaths, $configPaths_root ); |
35
|
4 |
|
$this->attributeManager = new AttributeManager( $this->configuration->getAttributes(), $options ); |
36
|
4 |
|
$this->policyRuleManager = new PolicyRuleManager( $this->attributeManager, $this->configuration->getRules() ); |
37
|
4 |
|
$this->cacheManager = new CacheManager( $cacheOptions ); |
38
|
4 |
|
$this->comparisonManager = new ComparisonManager( $this->attributeManager ); |
39
|
4 |
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @param array $configPaths |
43
|
|
|
* @param string $configPaths_root The origin folder to find $configPaths |
44
|
|
|
*/ |
45
|
4 |
|
public function configure( $configPaths, $configPaths_root = null ) { |
|
|
|
|
46
|
|
|
// foreach ( $configPaths as &$configPath ) { |
47
|
|
|
// $configPath = $configPaths_root . $configPath; |
48
|
|
|
// } |
49
|
4 |
|
$locator = new FileLocator( $configPaths_root ); |
50
|
4 |
|
$this->configuration = new ConfigurationManager( $locator ); |
51
|
4 |
|
$this->configuration->setConfigPathRoot( $configPaths_root ); |
52
|
4 |
|
$this->configuration->parseConfigurationFile( $configPaths ); |
53
|
4 |
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Return true if both user and object respects all the rules conditions |
57
|
|
|
* If the objectId is null, policy rules about its attributes will be ignored |
58
|
|
|
* In case of mismatch between attributes and expected values, |
59
|
|
|
* an array with the concerned attributes slugs will be returned. |
60
|
|
|
* |
61
|
|
|
* Available options are : |
62
|
|
|
* * dynamic_attributes: array |
63
|
|
|
* * cache_result: boolean |
64
|
|
|
* * cache_ttl: integer |
65
|
|
|
* * cache_driver: string |
66
|
|
|
* |
67
|
|
|
* Available cache drivers are : |
68
|
|
|
* * memory |
69
|
|
|
* |
70
|
|
|
* @param string $ruleName |
71
|
|
|
* @param object $user |
72
|
|
|
* @param object $resource |
73
|
|
|
* @param array $options |
74
|
|
|
* |
75
|
|
|
* @return boolean|array |
76
|
|
|
*/ |
77
|
4 |
|
public function enforce( $ruleName, $user, $resource = null, $options = [] ) { |
|
|
|
|
78
|
|
|
// If there is dynamic attributes, we pass them to the comparison manager |
79
|
|
|
// When a comparison will be performed, the passed values will be retrieved and used |
80
|
4 |
|
if ( isset( $options[ 'dynamic_attributes' ] ) ) { |
81
|
1 |
|
$this->comparisonManager->setDynamicAttributes( $options[ 'dynamic_attributes' ] ); |
82
|
1 |
|
} |
83
|
|
|
// Retrieve cache value for the current rule and values if cache item is valid |
84
|
4 |
|
if ( ( $cacheResult = isset( $options[ 'cache_result' ] ) && $options[ 'cache_result' ] === true ) === true ) { |
|
|
|
|
85
|
|
|
$cacheItem = $this->cacheManager->getItem( "$ruleName-{$user->getId()}-" . ( ( $resource !== null ) ? $resource->getId() : '' ), ( isset( $options[ 'cache_driver' ] ) ) ? $options[ 'cache_driver' ] : null, ( isset( $options[ 'cache_ttl' ] ) ) ? $options[ 'cache_ttl' ] : null ); |
86
|
|
|
// We check if the cache value s valid before returning it |
87
|
|
|
if ( ( $cacheValue = $cacheItem->get() ) !== null ) { |
|
|
|
|
88
|
|
|
return $cacheValue; |
89
|
|
|
} |
90
|
|
|
} |
91
|
4 |
|
$policyRule_a = $this->policyRuleManager->getRule( $ruleName, $user, $resource ); |
|
|
|
|
92
|
|
|
|
93
|
4 |
|
foreach ( $policyRule_a as $policyRule ) { |
|
|
|
|
94
|
|
|
// For each policy rule attribute, we retrieve the attribute value and proceed configured extra data |
95
|
4 |
|
foreach ( $policyRule->getPolicyRuleAttributes() as $pra ) { |
|
|
|
|
96
|
|
|
/** @var PolicyRuleAttribute $pra */ |
97
|
4 |
|
$attribute = $pra->getAttribute(); |
98
|
|
|
|
99
|
4 |
|
$getter_params = $this->prepareGetterParams($pra->getGetterParams(), $user, $resource); |
100
|
|
|
// var_dump($pra->getGetterParams()); |
101
|
|
|
// var_dump($getter_params); |
102
|
4 |
|
$attribute->setValue( $this->attributeManager->retrieveAttribute( $attribute, $user, $resource, $getter_params ) ); |
103
|
4 |
|
if ( count( $pra->getExtraData() ) > 0 ) { |
104
|
3 |
|
$this->processExtraData( $pra, $user, $resource ); |
|
|
|
|
105
|
3 |
|
} |
106
|
4 |
|
$this->comparisonManager->compare( $pra ); |
107
|
4 |
|
} |
108
|
|
|
// The given result could be an array of rejected attributes or true |
109
|
|
|
// True means that the rule is correctly enforced for the given user and resource |
110
|
4 |
|
$result = $this->comparisonManager->getResult(); |
111
|
4 |
|
if ( true === $result ) { |
|
|
|
|
112
|
4 |
|
break; |
113
|
|
|
} |
114
|
4 |
|
} |
115
|
4 |
|
if ( $cacheResult ) { |
|
|
|
|
116
|
|
|
$cacheItem->set( $result ); |
|
|
|
|
117
|
|
|
$this->cacheManager->save( $cacheItem ); |
118
|
|
|
} |
119
|
|
|
|
120
|
4 |
|
return $result; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Function to prepare Getter Params when getter require parameters ( this parameters must be specified in configuration file) |
125
|
|
|
* |
126
|
|
|
* @param $getter_params |
127
|
|
|
* @param $user |
128
|
|
|
* @param $resource |
129
|
|
|
* |
130
|
|
|
* @return array |
131
|
|
|
*/ |
132
|
4 |
|
private function prepareGetterParams($getter_params, $user, $resource) { |
133
|
4 |
|
if (empty($getter_params)) return []; |
|
|
|
|
134
|
2 |
|
$values = []; |
135
|
2 |
|
foreach($getter_params as $getter_name=>$params) { |
|
|
|
|
136
|
2 |
|
foreach($params as $param) { |
|
|
|
|
137
|
2 |
|
if ( '@' !== $param[ 'param_name' ][ 0 ] ) { |
|
|
|
|
138
|
|
|
$values[$getter_name][] = $param[ 'param_value' ]; |
139
|
|
|
} |
140
|
|
|
else { |
141
|
2 |
|
$values[$getter_name][] = $this->attributeManager->retrieveAttribute( $this->attributeManager->getAttribute( $param[ 'param_value' ] ) , $user, $resource ); |
|
|
|
|
142
|
|
|
} |
143
|
2 |
|
} |
144
|
2 |
|
} |
145
|
2 |
|
return $values; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* @param \PhpAbac\Model\PolicyRuleAttribute $pra |
150
|
|
|
* @param object $user |
151
|
|
|
* @param object $resource |
152
|
|
|
*/ |
153
|
3 |
|
public function processExtraData( PolicyRuleAttribute $pra, $user, $resource ) { |
|
|
|
|
154
|
3 |
|
foreach ( $pra->getExtraData() as $key => $data ) { |
|
|
|
|
155
|
|
|
switch ( $key ) { |
|
|
|
|
156
|
3 |
|
case 'with': |
157
|
|
|
// This data has to be removed for it will be stored elsewhere |
158
|
|
|
// in the policy rule attribute |
159
|
3 |
|
$pra->removeExtraData( 'with' ); |
160
|
|
|
// The "with" extra data is an array of attributes, which are objects |
161
|
|
|
// Once we process it as policy rule attributes, we set it as the main policy rule attribute value |
162
|
3 |
|
$subPolicyRuleAttributes = []; |
163
|
3 |
|
$extraData = []; |
|
|
|
|
164
|
|
|
|
165
|
3 |
|
foreach ( $this->policyRuleManager->processRuleAttributes( $data, $user, $resource ) as $subPolicyRuleAttribute ) { |
|
|
|
|
166
|
3 |
|
$subPolicyRuleAttributes[] = $subPolicyRuleAttribute; |
167
|
3 |
|
} |
168
|
3 |
|
$pra->setValue( $subPolicyRuleAttributes ); |
169
|
|
|
// This data can be used in complex comparisons |
170
|
3 |
|
$pra->addExtraData( 'attribute', $pra->getAttribute() ); |
171
|
3 |
|
$pra->addExtraData( 'user', $user ); |
|
|
|
|
172
|
3 |
|
$pra->addExtraData( 'resource', $resource ); |
|
|
|
|
173
|
3 |
|
break; |
174
|
|
|
} |
175
|
3 |
|
} |
176
|
3 |
|
} |
177
|
|
|
} |
178
|
|
|
|