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 | <?php | 1 | <?php |
2 | -/** | ||
3 | - * Created by PhpStorm. | ||
4 | - * User: Alex Savenko | ||
5 | - * Date: 14.02.2017 | ||
6 | - * Time: 16:32 | ||
7 | - */ | ||
8 | 2 | ||
9 | namespace App\Mvc; | 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 | use PhalconApi\Constants\HttpMethods; | 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 | public function endpoint(ExtendedApiEndpoint $endpoint) | 124 | public function endpoint(ExtendedApiEndpoint $endpoint) |
18 | { | 125 | { |
19 | $this->endpointsByName[$endpoint->getName()] = $endpoint; | 126 | $this->endpointsByName[$endpoint->getName()] = $endpoint; |
@@ -44,4 +151,208 @@ class ExtendedApiCollection extends ApiCollection { | @@ -44,4 +151,208 @@ class ExtendedApiCollection extends ApiCollection { | ||
44 | return $this; | 151 | return $this; |
45 | } | 152 | } |
46 | 153 | ||
47 | -} | ||
48 | \ No newline at end of file | 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,8 +2,6 @@ | ||
2 | 2 | ||
3 | namespace App\Mvc; | 3 | namespace App\Mvc; |
4 | 4 | ||
5 | -use App\Mvc\ExtendedApiCollection; | ||
6 | -use App\Mvc\ExtendedApiEndpoint; | ||
7 | use Phalcon\Di; | 5 | use Phalcon\Di; |
8 | use Phalcon\Mvc\Micro\CollectionInterface; | 6 | use Phalcon\Mvc\Micro\CollectionInterface; |
9 | use PhalconApi\Acl\MountableInterface; | 7 | use PhalconApi\Acl\MountableInterface; |
@@ -11,7 +9,7 @@ use PhalconRest\Constants\Services; | @@ -11,7 +9,7 @@ use PhalconRest\Constants\Services; | ||
11 | use PhalconRest\Mvc\Controllers\CrudResourceController; | 9 | use PhalconRest\Mvc\Controllers\CrudResourceController; |
12 | use PhalconRest\Transformers\ModelTransformer; | 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 | protected $model; | 14 | protected $model; |
17 | protected $transformer; | 15 | protected $transformer; |