From 963a3b62239b89ef79c5240a7a4e9ae554ccfb02 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 14 Feb 2017 17:29:08 +0200 Subject: [PATCH] extended classes --- app/library/App/Mvc/ExtendedApiCollection.php | 331 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- app/library/App/Mvc/ExtendedApiResource.php | 4 +--- 2 files changed, 322 insertions(+), 13 deletions(-) diff --git a/app/library/App/Mvc/ExtendedApiCollection.php b/app/library/App/Mvc/ExtendedApiCollection.php index cb6c583..066ee1a 100644 --- a/app/library/App/Mvc/ExtendedApiCollection.php +++ b/app/library/App/Mvc/ExtendedApiCollection.php @@ -1,19 +1,126 @@ initialize(); + } + + /** + * Use this method when you extend this class in order to define the collection + */ + protected function initialize() + { + } + + /** + * Returns collection with default values + * + * @param string $prefix Prefix for the collection (e.g. /auth) + * @param string $name Name for the collection (e.g. authentication) (optional) + * + * @return static + */ + public static function factory($prefix, $name = null) + { + $calledClass = get_called_class(); -class ExtendedApiCollection extends ApiCollection { + /** @var \App\Mvc\ExtendedApiCollection $collection */ + $collection = new $calledClass($prefix); + if ($name) { + $collection->name($name); + } + + return $collection; + } + + /** + * @param string $name Name for the collection + * + * @return static + */ + public function name($name) + { + $this->name = $name; + return $this; + } + + /** + * @param string $description Description of the collection + * + * @return static + */ + public function description($description) + { + $this->description = $description; + return $this; + } + + /** + * @return string Description of the collection + */ + public function getDescription() + { + return $this->description; + } + + public function setPrefix($prefix) + { + throw new Exception(ErrorCodes::GENERAL_SYSTEM, null, 'Setting prefix after initialization is prohibited.'); + } + + public function handler($handler, $lazy = true) + { + $this->setHandler($handler, $lazy); + return $this; + } + + /** + * Mounts endpoint to the collection + * + * @param \App\Mvc\ExtendedApiEndpoint $endpoint Endpoint to mount (shortcut for endpoint function) + * + * @return static + */ + public function mount(ExtendedApiEndpoint $endpoint) + { + $this->endpoint($endpoint); + return $this; + } + + /** + * Mounts endpoint to the collection + * + * @param \App\Mvc\ExtendedApiEndpoint $endpoint Endpoint to mount + * + * @return static + */ public function endpoint(ExtendedApiEndpoint $endpoint) { $this->endpointsByName[$endpoint->getName()] = $endpoint; @@ -44,4 +151,208 @@ class ExtendedApiCollection extends ApiCollection { return $this; } -} \ No newline at end of file + protected function createRouteName(ExtendedApiEndpoint $endpoint) + { + return serialize([ + 'collection' => $this->getIdentifier(), + 'endpoint' => $endpoint->getIdentifier() + ]); + } + + /** + * @return string Unique identifier for this collection (returns the prefix) + */ + public function getIdentifier() + { + return $this->getPrefix(); + } + + /** + * @return \App\Mvc\ExtendedApiEndpoint[] Array of all mounted endpoints + */ + public function getEndpoints() + { + return array_values($this->endpointsByName); + } + + /** + * @param string $name Name for the endpoint to return + * + * @return \App\Mvc\ExtendedApiEndpoint|null Endpoint with the given name + */ + public function getEndpoint($name) + { + return array_key_exists($name, $this->endpointsByName) ? $this->endpointsByName[$name] : null; + } + + /** + * @return string $method One of the method constants defined in PostedDataMethods + */ + public function getPostedDataMethod() + { + return $this->postedDataMethod; + } + + /** + * Sets the posted data method to POST + * + * @return static + */ + public function expectsPostData() + { + $this->postedDataMethod(PostedDataMethods::POST); + return $this; + } + + /** + * @param string $method One of the method constants defined in PostedDataMethods + * + * @return static + */ + public function postedDataMethod($method) + { + $this->postedDataMethod = $method; + return $this; + } + + /** + * Sets the posted data method to JSON_BODY + * + * @return static + */ + public function expectsJsonData() + { + $this->postedDataMethod(PostedDataMethods::JSON_BODY); + return $this; + } + + /** + * Allows access to this collection for role with the given names. This can be overwritten on the Endpoint level. + * + * @param ...array $roleNames Names of the roles to allow + * + * @return static + */ + public function allow() + { + $roleNames = func_get_args(); + + // Flatten array to allow array inputs + $roleNames = Core::array_flatten($roleNames); + + foreach ($roleNames as $role) { + + if (!in_array($role, $this->allowedRoles)) { + $this->allowedRoles[] = $role; + } + } + + return $this; + } + + /** + * @return string[] Array of allowed role-names + */ + public function getAllowedRoles() + { + return $this->allowedRoles; + } + + /*** + * Denies access to this collection for role with the given names. This can be overwritten on the Endpoint level. + * + * @param ...array $roleNames Names of the roles to deny + * + * @return $this + */ + public function deny() + { + $roleNames = func_get_args(); + + // Flatten array to allow array inputs + $roleNames = Core::array_flatten($roleNames); + + foreach ($roleNames as $role) { + + if (!in_array($role, $this->deniedRoles)) { + $this->deniedRoles[] = $role; + } + } + + return $this; + } + + /** + * @return string[] Array of denied role-names + */ + public function getDeniedRoles() + { + return $this->deniedRoles; + } + + public function getAclResources() + { + $apiEndpointIdentifiers = array_map(function (ExtendedApiEndpoint $apiEndpoint) { + return $apiEndpoint->getIdentifier(); + }, $this->endpointsByName); + + return [ + [new \Phalcon\Acl\Resource($this->getIdentifier(), $this->getName()), $apiEndpointIdentifiers] + ]; + } + + /** + * @return string|null Name of the collection + */ + public function getName() + { + return $this->name; + } + + public function getAclRules(array $roles) + { + $allowedResponse = []; + $deniedResponse = []; + + $defaultAllowedRoles = $this->allowedRoles; + $defaultDeniedRoles = $this->deniedRoles; + + foreach ($roles as $role) { + + /** @var ExtendedApiEndpoint $apiEndpoint */ + foreach ($this->endpointsByName as $apiEndpoint) { + + $rule = null; + + if (in_array($role, $defaultAllowedRoles)) { + $rule = true; + } + + if (in_array($role, $defaultDeniedRoles)) { + $rule = false; + } + + if (in_array($role, $apiEndpoint->getAllowedRoles())) { + $rule = true; + } + + if (in_array($role, $apiEndpoint->getDeniedRoles())) { + $rule = false; + } + + if ($rule === true) { + $allowedResponse[] = [$role, $this->getIdentifier(), $apiEndpoint->getIdentifier()]; + } + + if ($rule === false) { + $deniedResponse[] = [$role, $this->getIdentifier(), $apiEndpoint->getIdentifier()]; + } + } + } + + return [ + Acl::ALLOW => $allowedResponse, + Acl::DENY => $deniedResponse + ]; + } +} diff --git a/app/library/App/Mvc/ExtendedApiResource.php b/app/library/App/Mvc/ExtendedApiResource.php index aeeac0c..2fdf940 100644 --- a/app/library/App/Mvc/ExtendedApiResource.php +++ b/app/library/App/Mvc/ExtendedApiResource.php @@ -2,8 +2,6 @@ namespace App\Mvc; -use App\Mvc\ExtendedApiCollection; -use App\Mvc\ExtendedApiEndpoint; use Phalcon\Di; use Phalcon\Mvc\Micro\CollectionInterface; use PhalconApi\Acl\MountableInterface; @@ -11,7 +9,7 @@ use PhalconRest\Constants\Services; use PhalconRest\Mvc\Controllers\CrudResourceController; use PhalconRest\Transformers\ModelTransformer; -class ExtendedApiResource extends ExtendedApiCollection implements MountableInterface, CollectionInterface +class ExtendedApiResource extends ExtendedApiCollection implements MountableInterface, CollectionInterface { protected $model; protected $transformer; -- libgit2 0.21.4