PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.2.2
Kirki – Freeform Page Builder, Website Builder & Customizer v6.2.2
6.2.3 6.2.2 6.2.1 6.2.0 6.1.1 6.1.0 6.0.14 6.0.13 6.0.12 6.0.11 6.0.10 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.19 4.0.20 4.0.21 4.0.22 4.0.23 4.0.24 4.1 4.2.0 5.0.0 5.1.0 5.1.1 5.2.0 5.2.1 5.2.2 5.2.3 6.0.0 trunk 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.1.0 3.1.1 3.1.2
kirki / libraries / framework / Managers / PolicyManager.php
kirki / libraries / framework / Managers Last commit date
EventManager.php 2 weeks ago LogManager.php 1 month ago OptionManager.php 1 month ago PolicyManager.php 5 days ago VersionUpdateManager.php 5 days ago
PolicyManager.php
247 lines
1 <?php
2
3 /**
4 * Registers and resolves authorization policies for framework models.
5 * Maps model classes to policy handlers and evaluates user abilities through the Guard facade.
6 * Centralizes access control decisions for controllers and domain services.
7 *
8 * @package Framework
9 * @subpackage Managers
10 * @since 1.0.0
11 */
12 namespace Kirki\Framework\Managers;
13
14 \defined('ABSPATH') || exit;
15 use Kirki\Framework\Concerns\DependencyResolvable;
16 use Kirki\Framework\Exceptions\AuthorizationException;
17 use InvalidArgumentException;
18 use function Kirki\Framework\app;
19 use function Kirki\Framework\config_path;
20 use function Kirki\Framework\message;
21 use function Kirki\Framework\user;
22 class PolicyManager
23 {
24 use DependencyResolvable;
25 /**
26 * The array of registered policies or the policies data from cache.
27 *
28 * @var array
29 *
30 * @since 1.0.0
31 */
32 protected $policies = [];
33 /**
34 * The currently resolved user.
35 *
36 * @var mixed
37 *
38 * @since 1.0.0
39 */
40 protected $user;
41 /**
42 * PolicyManager constructor.
43 *
44 * Loads and registers policies from the cache file.
45 *
46 * @return void
47 *
48 * @since 1.0.0
49 */
50 public function __construct()
51 {
52 $this->load_policies();
53 $this->register_policies();
54 }
55 /**
56 * Load the policies from the cached policies file.
57 *
58 * @return $this|null
59 *
60 * @since 1.0.0
61 */
62 protected function load_policies()
63 {
64 $policies_cache_path = config_path('policies.cache.php');
65 if (!\file_exists($policies_cache_path)) {
66 return;
67 }
68 $this->policies = (require $policies_cache_path);
69 return $this;
70 }
71 /**
72 * Register the loaded policies for each model.
73 *
74 * @return $this
75 *
76 * @since 1.0.0
77 */
78 public function register_policies()
79 {
80 foreach ($this->policies as $policy) {
81 $this->register_policy($policy['model'], $policy['policy']);
82 }
83 return $this;
84 }
85 /**
86 * Register an individual model-policy mapping.
87 *
88 * @param string $model The model instance.
89 * @param string $policy The policy.
90 *
91 * @return void
92 *
93 * @since 1.0.0
94 */
95 public function register_policy(string $model, string $policy)
96 {
97 $this->policies[$model] = $policy;
98 }
99 /**
100 * Resolve the policy object for a given model.
101 *
102 * @param mixed $model The model instance.
103 *
104 * @return mixed|null
105 *
106 * @since 1.0.0
107 */
108 protected function resolve_policy($model)
109 {
110 $model_name = \is_object($model) ? \get_class($model) : $model;
111 if (!$this->has_policy($model_name)) {
112 return null;
113 }
114 return app()->make($this->policy($model_name));
115 }
116 /**
117 * Determine if a policy exists for the given model.
118 *
119 * @param mixed $model The model instance.
120 *
121 * @return bool
122 *
123 * @since 1.0.0
124 */
125 protected function has_policy($model)
126 {
127 return isset($this->policies[$model]);
128 }
129 /**
130 * Get the class name of the policy for the given model.
131 *
132 * @param mixed $model The model instance.
133 *
134 * @return string
135 *
136 * @since 1.0.0
137 */
138 protected function policy($model)
139 {
140 return $this->policies[$model];
141 }
142 /**
143 * Authorize an ability against a model instance or class.
144 *
145 * @param string $ability The ability.
146 * @param mixed $model The model instance.
147 * @param array $arguments The method arguments.
148 *
149 * @return bool|mixed
150 *
151 * @throws AuthorizationException
152 * @throws InvalidArgumentException
153 *
154 * @since 1.0.0
155 */
156 public function authorize(string $ability, $model = null, ...$arguments)
157 {
158 $user = $this->get_current_user();
159 if (!$user->is_logged_in()) {
160 throw new AuthorizationException(message('auth.logged_in_required'));
161 }
162 $policy = $this->resolve_policy($model);
163 if (!$policy) {
164 throw new AuthorizationException(message('auth.no_policy'));
165 }
166 if (\method_exists($policy, 'before')) {
167 $before_result = $policy->before($user, $ability);
168 if ($before_result === \true) {
169 return \true;
170 }
171 if ($before_result === \false) {
172 throw new AuthorizationException(message('auth.unauthorized_action', $ability));
173 }
174 }
175 if (!\method_exists($policy, $ability)) {
176 throw new AuthorizationException(message('auth.ability_not_defined', $ability));
177 }
178 $dependencies = $this->resolve_method_dependencies($policy, $ability, $this->build_arguments($arguments, $user, $model));
179 $can_perform = $policy->{$ability}(...$dependencies);
180 if (!$can_perform) {
181 throw new AuthorizationException(message('auth.unauthorized_action', $ability));
182 }
183 return \true;
184 }
185 /**
186 * Build the arguments for the policy method.
187 *
188 * @param array $arguments The method arguments.
189 * @param mixed $user The user instance.
190 * @param mixed $model The model instance.
191 *
192 * @return array
193 *
194 * @since 1.0.0
195 */
196 protected function build_arguments(array $arguments, $user, $model)
197 {
198 \array_unshift($arguments, $user, $model);
199 return $arguments;
200 }
201 /**
202 * Determine if the current user is allowed to perform the given ability.
203 *
204 * @param string $ability The ability.
205 * @param mixed $model The model instance.
206 * @param array $arguments The method arguments.
207 *
208 * @return bool
209 *
210 * @since 1.0.0
211 */
212 public function allows(string $ability, $model = null, array $arguments = [])
213 {
214 try {
215 return $this->authorize($ability, $model, $arguments);
216 } catch (AuthorizationException $exception) {
217 return \false;
218 }
219 }
220 /**
221 * Determine if the current user is denied from performing the given ability.
222 *
223 * @param string $ability The ability.
224 * @param mixed $model The model instance.
225 * @param array $arguments The method arguments.
226 *
227 * @return bool
228 *
229 * @since 1.0.0
230 */
231 public function denies(string $ability, $model = null, array $arguments = [])
232 {
233 return !$this->allows($ability, $model, $arguments);
234 }
235 /**
236 * Get the current user object.
237 *
238 * @return mixed
239 *
240 * @since 1.0.0
241 */
242 protected function get_current_user()
243 {
244 return user();
245 }
246 }
247