11<?php
22/**
3- * Copyright © Magento, Inc. All rights reserved.
4- * See COPYING.txt for license details .
3+ * Copyright 2012 Adobe
4+ * All Rights Reserved .
55 */
66declare (strict_types=1 );
77
@@ -87,7 +87,7 @@ public function __construct(
8787 public function populateAcl (Acl $ acl )
8888 {
8989 $ result = $ this ->applyPermissionsAccordingToRules ($ acl );
90- $ this ->applyDenyPermissionsForMissingRules ($ acl , ... $ result );
90+ $ this ->denyPermissionsForMissingRules ($ acl , $ result );
9191 }
9292
9393 /**
@@ -98,56 +98,84 @@ public function populateAcl(Acl $acl)
9898 */
9999 private function applyPermissionsAccordingToRules (Acl $ acl ): array
100100 {
101- $ foundResources = $ foundDeniedRoles = [];
101+ $ appliedRolePermissionsPerResource = [];
102102 foreach ($ this ->getRulesArray () as $ rule ) {
103103 $ role = $ rule ['role_id ' ];
104104 $ resource = $ rule ['resource_id ' ];
105105 $ privileges = !empty ($ rule ['privileges ' ]) ? explode (', ' , $ rule ['privileges ' ]) : null ;
106106
107107 if ($ acl ->hasResource ($ resource )) {
108- $ foundResources [$ resource ] = $ resource ;
108+
109+ $ appliedRolePermissionsPerResource [$ resource ]['allow ' ] =
110+ $ appliedRolePermissionsPerResource [$ resource ]['allow ' ] ?? [];
111+ $ appliedRolePermissionsPerResource [$ resource ]['deny ' ] =
112+ $ appliedRolePermissionsPerResource [$ resource ]['deny ' ] ?? [];
113+
109114 if ($ rule ['permission ' ] == 'allow ' ) {
110115 if ($ resource === $ this ->_rootResource ->getId ()) {
111116 $ acl ->allow ($ role , null , $ privileges );
112117 }
113118 $ acl ->allow ($ role , $ resource , $ privileges );
119+ $ appliedRolePermissionsPerResource [$ resource ]['allow ' ][] = $ role ;
114120 } elseif ($ rule ['permission ' ] == 'deny ' ) {
115- $ foundDeniedRoles [$ role ] = $ role ;
116121 $ acl ->deny ($ role , $ resource , $ privileges );
122+ $ appliedRolePermissionsPerResource [$ resource ]['deny ' ][] = $ role ;
117123 }
118124 }
119125 }
120- return [$ foundResources , $ foundDeniedRoles ];
126+
127+ return $ appliedRolePermissionsPerResource ;
121128 }
122129
123130 /**
124- * Apply deny permissions for missing rules
131+ * Deny permissions for missing rules
125132 *
126133 * For all rules that were not regenerated in authorization_rule table,
127134 * when adding a new module and without re-saving all roles,
128135 * consider not present rules with deny permissions
129136 *
130137 * @param Acl $acl
131- * @param array $resources
132- * @param array $deniedRoles
138+ * @param array $appliedRolePermissionsPerResource
133139 * @return void
134140 */
135- private function applyDenyPermissionsForMissingRules (
136- Acl $ acl ,
137- array $ resources ,
138- array $ deniedRoles
141+ private function denyPermissionsForMissingRules (
142+ Acl $ acl ,
143+ array $ appliedRolePermissionsPerResource ,
139144 ) {
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- }
145+ $ consolidatedDeniedRoleIds = array_unique (
146+ array_merge (
147+ ...array_column ($ appliedRolePermissionsPerResource , 'deny ' )
148+ )
149+ );
150+
151+ $ hasAppliedPermissions = count ($ appliedRolePermissionsPerResource ) > 0 ;
152+ $ hasDeniedRoles = count ($ consolidatedDeniedRoleIds ) > 0 ;
153+ $ allAllowed = count ($ appliedRolePermissionsPerResource ) === 1
154+ && isset ($ appliedRolePermissionsPerResource [static ::ALLOW_EVERYTHING ]);
155+
156+ if ($ hasAppliedPermissions && $ hasDeniedRoles && !$ allAllowed ) {
157+ // Add the resources that are not present in the rules at all,
158+ // assuming that they must be denied for all roles by default
159+ $ resourcesUndefinedInAuthorizationRules =
160+ array_diff ($ acl ->getResources (), array_keys ($ appliedRolePermissionsPerResource ));
161+ $ assumeDeniedRoleListPerResource =
162+ array_fill_keys ($ resourcesUndefinedInAuthorizationRules , $ consolidatedDeniedRoleIds );
163+
164+ // Add the resources that are permitted for one role and not present in others at all,
165+ // assuming that they must be denied for all other roles by default
166+ foreach ($ appliedRolePermissionsPerResource as $ resource => $ permissions ) {
167+ $ allowedRoles = $ permissions ['allow ' ];
168+ $ deniedRoles = $ permissions ['deny ' ];
169+ $ assumedDeniedRoles = array_diff ($ consolidatedDeniedRoleIds , $ allowedRoles , $ deniedRoles );
170+ if ($ assumedDeniedRoles ) {
171+ $ assumeDeniedRoleListPerResource [$ resource ] = $ assumedDeniedRoles ;
149172 }
150173 }
174+
175+ // Deny permissions for missing rules
176+ foreach ($ assumeDeniedRoleListPerResource as $ resource => $ denyRoles ) {
177+ $ acl ->deny ($ denyRoles , $ resource , null );
178+ }
151179 }
152180 }
153181
0 commit comments