Commit 963a3b62239b89ef79c5240a7a4e9ae554ccfb02
1 parent
eaa74332
extended classes
Showing
2 changed files
with
322 additions
and
13 deletions
Show diff stats
app/library/App/Mvc/ExtendedApiCollection.php
1 | 1 | <?php |
2 | -/** | |
3 | - * Created by PhpStorm. | |
4 | - * User: Alex Savenko | |
5 | - * Date: 14.02.2017 | |
6 | - * Time: 16:32 | |
7 | - */ | |
8 | 2 | |
9 | 3 | namespace App\Mvc; |
10 | 4 | |
11 | - | |
5 | +use Phalcon\Acl; | |
6 | +use Phalcon\Mvc\Micro\CollectionInterface; | |
7 | +use PhalconApi\Acl\MountableInterface; | |
8 | +use PhalconApi\Constants\ErrorCodes; | |
12 | 9 | use PhalconApi\Constants\HttpMethods; |
13 | -use PhalconRest\Api\ApiCollection; | |
10 | +use PhalconApi\Constants\PostedDataMethods; | |
11 | +use PhalconApi\Core; | |
12 | +use PhalconApi\Exception; | |
13 | + | |
14 | +class ExtendedApiCollection extends \Phalcon\Mvc\Micro\Collection implements MountableInterface, CollectionInterface | |
15 | +{ | |
16 | + protected $name; | |
17 | + protected $description; | |
18 | + | |
19 | + protected $allowedRoles = []; | |
20 | + protected $deniedRoles = []; | |
21 | + | |
22 | + protected $postedDataMethod = PostedDataMethods::AUTO; | |
23 | + | |
24 | + protected $endpointsByName = []; | |
25 | + | |
26 | + | |
27 | + public function __construct($prefix) | |
28 | + { | |
29 | + parent::setPrefix($prefix); | |
30 | + | |
31 | + $this->initialize(); | |
32 | + } | |
33 | + | |
34 | + /** | |
35 | + * Use this method when you extend this class in order to define the collection | |
36 | + */ | |
37 | + protected function initialize() | |
38 | + { | |
39 | + } | |
40 | + | |
41 | + /** | |
42 | + * Returns collection with default values | |
43 | + * | |
44 | + * @param string $prefix Prefix for the collection (e.g. /auth) | |
45 | + * @param string $name Name for the collection (e.g. authentication) (optional) | |
46 | + * | |
47 | + * @return static | |
48 | + */ | |
49 | + public static function factory($prefix, $name = null) | |
50 | + { | |
51 | + $calledClass = get_called_class(); | |
14 | 52 | |
15 | -class ExtendedApiCollection extends ApiCollection { | |
53 | + /** @var \App\Mvc\ExtendedApiCollection $collection */ | |
54 | + $collection = new $calledClass($prefix); | |
16 | 55 | |
56 | + if ($name) { | |
57 | + $collection->name($name); | |
58 | + } | |
59 | + | |
60 | + return $collection; | |
61 | + } | |
62 | + | |
63 | + /** | |
64 | + * @param string $name Name for the collection | |
65 | + * | |
66 | + * @return static | |
67 | + */ | |
68 | + public function name($name) | |
69 | + { | |
70 | + $this->name = $name; | |
71 | + return $this; | |
72 | + } | |
73 | + | |
74 | + /** | |
75 | + * @param string $description Description of the collection | |
76 | + * | |
77 | + * @return static | |
78 | + */ | |
79 | + public function description($description) | |
80 | + { | |
81 | + $this->description = $description; | |
82 | + return $this; | |
83 | + } | |
84 | + | |
85 | + /** | |
86 | + * @return string Description of the collection | |
87 | + */ | |
88 | + public function getDescription() | |
89 | + { | |
90 | + return $this->description; | |
91 | + } | |
92 | + | |
93 | + public function setPrefix($prefix) | |
94 | + { | |
95 | + throw new Exception(ErrorCodes::GENERAL_SYSTEM, null, 'Setting prefix after initialization is prohibited.'); | |
96 | + } | |
97 | + | |
98 | + public function handler($handler, $lazy = true) | |
99 | + { | |
100 | + $this->setHandler($handler, $lazy); | |
101 | + return $this; | |
102 | + } | |
103 | + | |
104 | + /** | |
105 | + * Mounts endpoint to the collection | |
106 | + * | |
107 | + * @param \App\Mvc\ExtendedApiEndpoint $endpoint Endpoint to mount (shortcut for endpoint function) | |
108 | + * | |
109 | + * @return static | |
110 | + */ | |
111 | + public function mount(ExtendedApiEndpoint $endpoint) | |
112 | + { | |
113 | + $this->endpoint($endpoint); | |
114 | + return $this; | |
115 | + } | |
116 | + | |
117 | + /** | |
118 | + * Mounts endpoint to the collection | |
119 | + * | |
120 | + * @param \App\Mvc\ExtendedApiEndpoint $endpoint Endpoint to mount | |
121 | + * | |
122 | + * @return static | |
123 | + */ | |
17 | 124 | public function endpoint(ExtendedApiEndpoint $endpoint) |
18 | 125 | { |
19 | 126 | $this->endpointsByName[$endpoint->getName()] = $endpoint; |
... | ... | @@ -44,4 +151,208 @@ class ExtendedApiCollection extends ApiCollection { |
44 | 151 | return $this; |
45 | 152 | } |
46 | 153 | |
47 | -} | |
48 | 154 | \ No newline at end of file |
155 | + protected function createRouteName(ExtendedApiEndpoint $endpoint) | |
156 | + { | |
157 | + return serialize([ | |
158 | + 'collection' => $this->getIdentifier(), | |
159 | + 'endpoint' => $endpoint->getIdentifier() | |
160 | + ]); | |
161 | + } | |
162 | + | |
163 | + /** | |
164 | + * @return string Unique identifier for this collection (returns the prefix) | |
165 | + */ | |
166 | + public function getIdentifier() | |
167 | + { | |
168 | + return $this->getPrefix(); | |
169 | + } | |
170 | + | |
171 | + /** | |
172 | + * @return \App\Mvc\ExtendedApiEndpoint[] Array of all mounted endpoints | |
173 | + */ | |
174 | + public function getEndpoints() | |
175 | + { | |
176 | + return array_values($this->endpointsByName); | |
177 | + } | |
178 | + | |
179 | + /** | |
180 | + * @param string $name Name for the endpoint to return | |
181 | + * | |
182 | + * @return \App\Mvc\ExtendedApiEndpoint|null Endpoint with the given name | |
183 | + */ | |
184 | + public function getEndpoint($name) | |
185 | + { | |
186 | + return array_key_exists($name, $this->endpointsByName) ? $this->endpointsByName[$name] : null; | |
187 | + } | |
188 | + | |
189 | + /** | |
190 | + * @return string $method One of the method constants defined in PostedDataMethods | |
191 | + */ | |
192 | + public function getPostedDataMethod() | |
193 | + { | |
194 | + return $this->postedDataMethod; | |
195 | + } | |
196 | + | |
197 | + /** | |
198 | + * Sets the posted data method to POST | |
199 | + * | |
200 | + * @return static | |
201 | + */ | |
202 | + public function expectsPostData() | |
203 | + { | |
204 | + $this->postedDataMethod(PostedDataMethods::POST); | |
205 | + return $this; | |
206 | + } | |
207 | + | |
208 | + /** | |
209 | + * @param string $method One of the method constants defined in PostedDataMethods | |
210 | + * | |
211 | + * @return static | |
212 | + */ | |
213 | + public function postedDataMethod($method) | |
214 | + { | |
215 | + $this->postedDataMethod = $method; | |
216 | + return $this; | |
217 | + } | |
218 | + | |
219 | + /** | |
220 | + * Sets the posted data method to JSON_BODY | |
221 | + * | |
222 | + * @return static | |
223 | + */ | |
224 | + public function expectsJsonData() | |
225 | + { | |
226 | + $this->postedDataMethod(PostedDataMethods::JSON_BODY); | |
227 | + return $this; | |
228 | + } | |
229 | + | |
230 | + /** | |
231 | + * Allows access to this collection for role with the given names. This can be overwritten on the Endpoint level. | |
232 | + * | |
233 | + * @param ...array $roleNames Names of the roles to allow | |
234 | + * | |
235 | + * @return static | |
236 | + */ | |
237 | + public function allow() | |
238 | + { | |
239 | + $roleNames = func_get_args(); | |
240 | + | |
241 | + // Flatten array to allow array inputs | |
242 | + $roleNames = Core::array_flatten($roleNames); | |
243 | + | |
244 | + foreach ($roleNames as $role) { | |
245 | + | |
246 | + if (!in_array($role, $this->allowedRoles)) { | |
247 | + $this->allowedRoles[] = $role; | |
248 | + } | |
249 | + } | |
250 | + | |
251 | + return $this; | |
252 | + } | |
253 | + | |
254 | + /** | |
255 | + * @return string[] Array of allowed role-names | |
256 | + */ | |
257 | + public function getAllowedRoles() | |
258 | + { | |
259 | + return $this->allowedRoles; | |
260 | + } | |
261 | + | |
262 | + /*** | |
263 | + * Denies access to this collection for role with the given names. This can be overwritten on the Endpoint level. | |
264 | + * | |
265 | + * @param ...array $roleNames Names of the roles to deny | |
266 | + * | |
267 | + * @return $this | |
268 | + */ | |
269 | + public function deny() | |
270 | + { | |
271 | + $roleNames = func_get_args(); | |
272 | + | |
273 | + // Flatten array to allow array inputs | |
274 | + $roleNames = Core::array_flatten($roleNames); | |
275 | + | |
276 | + foreach ($roleNames as $role) { | |
277 | + | |
278 | + if (!in_array($role, $this->deniedRoles)) { | |
279 | + $this->deniedRoles[] = $role; | |
280 | + } | |
281 | + } | |
282 | + | |
283 | + return $this; | |
284 | + } | |
285 | + | |
286 | + /** | |
287 | + * @return string[] Array of denied role-names | |
288 | + */ | |
289 | + public function getDeniedRoles() | |
290 | + { | |
291 | + return $this->deniedRoles; | |
292 | + } | |
293 | + | |
294 | + public function getAclResources() | |
295 | + { | |
296 | + $apiEndpointIdentifiers = array_map(function (ExtendedApiEndpoint $apiEndpoint) { | |
297 | + return $apiEndpoint->getIdentifier(); | |
298 | + }, $this->endpointsByName); | |
299 | + | |
300 | + return [ | |
301 | + [new \Phalcon\Acl\Resource($this->getIdentifier(), $this->getName()), $apiEndpointIdentifiers] | |
302 | + ]; | |
303 | + } | |
304 | + | |
305 | + /** | |
306 | + * @return string|null Name of the collection | |
307 | + */ | |
308 | + public function getName() | |
309 | + { | |
310 | + return $this->name; | |
311 | + } | |
312 | + | |
313 | + public function getAclRules(array $roles) | |
314 | + { | |
315 | + $allowedResponse = []; | |
316 | + $deniedResponse = []; | |
317 | + | |
318 | + $defaultAllowedRoles = $this->allowedRoles; | |
319 | + $defaultDeniedRoles = $this->deniedRoles; | |
320 | + | |
321 | + foreach ($roles as $role) { | |
322 | + | |
323 | + /** @var ExtendedApiEndpoint $apiEndpoint */ | |
324 | + foreach ($this->endpointsByName as $apiEndpoint) { | |
325 | + | |
326 | + $rule = null; | |
327 | + | |
328 | + if (in_array($role, $defaultAllowedRoles)) { | |
329 | + $rule = true; | |
330 | + } | |
331 | + | |
332 | + if (in_array($role, $defaultDeniedRoles)) { | |
333 | + $rule = false; | |
334 | + } | |
335 | + | |
336 | + if (in_array($role, $apiEndpoint->getAllowedRoles())) { | |
337 | + $rule = true; | |
338 | + } | |
339 | + | |
340 | + if (in_array($role, $apiEndpoint->getDeniedRoles())) { | |
341 | + $rule = false; | |
342 | + } | |
343 | + | |
344 | + if ($rule === true) { | |
345 | + $allowedResponse[] = [$role, $this->getIdentifier(), $apiEndpoint->getIdentifier()]; | |
346 | + } | |
347 | + | |
348 | + if ($rule === false) { | |
349 | + $deniedResponse[] = [$role, $this->getIdentifier(), $apiEndpoint->getIdentifier()]; | |
350 | + } | |
351 | + } | |
352 | + } | |
353 | + | |
354 | + return [ | |
355 | + Acl::ALLOW => $allowedResponse, | |
356 | + Acl::DENY => $deniedResponse | |
357 | + ]; | |
358 | + } | |
359 | +} | ... | ... |
app/library/App/Mvc/ExtendedApiResource.php
... | ... | @@ -2,8 +2,6 @@ |
2 | 2 | |
3 | 3 | namespace App\Mvc; |
4 | 4 | |
5 | -use App\Mvc\ExtendedApiCollection; | |
6 | -use App\Mvc\ExtendedApiEndpoint; | |
7 | 5 | use Phalcon\Di; |
8 | 6 | use Phalcon\Mvc\Micro\CollectionInterface; |
9 | 7 | use PhalconApi\Acl\MountableInterface; |
... | ... | @@ -11,7 +9,7 @@ use PhalconRest\Constants\Services; |
11 | 9 | use PhalconRest\Mvc\Controllers\CrudResourceController; |
12 | 10 | use PhalconRest\Transformers\ModelTransformer; |
13 | 11 | |
14 | -class ExtendedApiResource extends ExtendedApiCollection implements MountableInterface, CollectionInterface | |
12 | +class ExtendedApiResource extends ExtendedApiCollection implements MountableInterface, CollectionInterface | |
15 | 13 | { |
16 | 14 | protected $model; |
17 | 15 | protected $transformer; | ... | ... |