7
7
8
8
namespace Magento \Authorization \Model \Acl \Loader ;
9
9
10
+ use Magento \Framework \Acl ;
10
11
use Magento \Framework \Acl \Data \CacheInterface ;
11
12
use Magento \Framework \Acl \LoaderInterface ;
12
13
use Magento \Framework \Acl \RootResource ;
@@ -21,7 +22,12 @@ class Rule implements LoaderInterface
21
22
/**
22
23
* Rules array cache key
23
24
*/
24
- const ACL_RULE_CACHE_KEY = 'authorization_rule_cached_data ' ;
25
+ public const ACL_RULE_CACHE_KEY = 'authorization_rule_cached_data ' ;
26
+
27
+ /**
28
+ * Allow everything resource id
29
+ */
30
+ private const ALLOW_EVERYTHING = 'Magento_Backend::all ' ;
25
31
26
32
/**
27
33
* @var ResourceConnection
@@ -75,27 +81,74 @@ public function __construct(
75
81
/**
76
82
* Populate ACL with rules from external storage
77
83
*
78
- * @param \Magento\Framework\ Acl $acl
84
+ * @param Acl $acl
79
85
* @return void
80
86
*/
81
- public function populateAcl (\ Magento \ Framework \ Acl $ acl )
87
+ public function populateAcl (Acl $ acl )
82
88
{
89
+ $ result = $ this ->applyPermissionsAccordingToRules ($ acl );
90
+ $ this ->applyDenyPermissionsForMissingRules ($ acl , ...$ result );
91
+ }
92
+
93
+ /**
94
+ * Apply ACL with rules
95
+ *
96
+ * @param Acl $acl
97
+ * @return array[]
98
+ */
99
+ private function applyPermissionsAccordingToRules (Acl $ acl ): array
100
+ {
101
+ $ foundResources = $ foundDeniedRoles = [];
83
102
foreach ($ this ->getRulesArray () as $ rule ) {
84
103
$ role = $ rule ['role_id ' ];
85
104
$ resource = $ rule ['resource_id ' ];
86
105
$ privileges = !empty ($ rule ['privileges ' ]) ? explode (', ' , $ rule ['privileges ' ]) : null ;
87
106
88
107
if ($ acl ->has ($ resource )) {
108
+ $ foundResources [$ resource ] = $ resource ;
89
109
if ($ rule ['permission ' ] == 'allow ' ) {
90
110
if ($ resource === $ this ->_rootResource ->getId ()) {
91
111
$ acl ->allow ($ role , null , $ privileges );
92
112
}
93
113
$ acl ->allow ($ role , $ resource , $ privileges );
94
114
} elseif ($ rule ['permission ' ] == 'deny ' ) {
115
+ $ foundDeniedRoles [$ role ] = $ role ;
95
116
$ acl ->deny ($ role , $ resource , $ privileges );
96
117
}
97
118
}
98
119
}
120
+ return [$ foundResources , $ foundDeniedRoles ];
121
+ }
122
+
123
+ /**
124
+ * Apply deny permissions for missing rules
125
+ *
126
+ * For all rules that were not regenerated in authorization_rule table,
127
+ * when adding a new module and without re-saving all roles,
128
+ * consider not present rules with deny permissions
129
+ *
130
+ * @param Acl $acl
131
+ * @param array $resources
132
+ * @param array $deniedRoles
133
+ * @return void
134
+ */
135
+ private function applyDenyPermissionsForMissingRules (
136
+ Acl $ acl ,
137
+ array $ resources ,
138
+ array $ deniedRoles
139
+ ) {
140
+ if (count ($ resources ) && count ($ deniedRoles )
141
+ //ignore denying missing permission if all are allowed
142
+ && !(count ($ resources ) === 1 && isset ($ resources [static ::ALLOW_EVERYTHING ]))
143
+ ) {
144
+ foreach ($ acl ->getResources () as $ resource ) {
145
+ if (!isset ($ resources [$ resource ])) {
146
+ foreach ($ deniedRoles as $ role ) {
147
+ $ acl ->deny ($ role , $ resource , null );
148
+ }
149
+ }
150
+ }
151
+ }
99
152
}
100
153
101
154
/**
0 commit comments