From 0b8d4ffc87fa03c56c0f37762ad8c9c000aa6220 Mon Sep 17 00:00:00 2001 From: Alex Savenko Date: Tue, 11 Apr 2017 17:23:51 +0300 Subject: [PATCH] Add Roles. --- app/library/App/Bootstrap/AclBootstrap.php | 21 ++++++++++++++------- app/library/App/Constants/AclRoles.php | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- app/library/App/Controllers/ProjectController.php | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ app/library/App/Controllers/UserController.php | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- app/library/App/Model/Album.php | 29 ----------------------------- app/library/App/Model/Photo.php | 31 ------------------------------- app/library/App/Model/Project.php | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- app/library/App/Model/User.php | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------- app/library/App/Model/UserProject.php | 30 ++++++++++++++++++++++++++++++ app/library/App/Resources/AlbumResource.php | 32 -------------------------------- app/library/App/Resources/PhotoResource.php | 32 -------------------------------- app/library/App/Resources/ProjectResource.php | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- app/library/App/Resources/UserResource.php | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- app/library/App/Transformers/AlbumTransformer.php | 28 ---------------------------- app/library/App/Transformers/PhotoTransformer.php | 39 --------------------------------------- 15 files changed, 744 insertions(+), 284 deletions(-) create mode 100644 app/library/App/Controllers/ProjectController.php delete mode 100755 app/library/App/Model/Album.php delete mode 100755 app/library/App/Model/Photo.php create mode 100644 app/library/App/Model/UserProject.php delete mode 100755 app/library/App/Resources/AlbumResource.php delete mode 100755 app/library/App/Resources/PhotoResource.php delete mode 100755 app/library/App/Transformers/AlbumTransformer.php delete mode 100755 app/library/App/Transformers/PhotoTransformer.php diff --git a/app/library/App/Bootstrap/AclBootstrap.php b/app/library/App/Bootstrap/AclBootstrap.php index 0411680..66bf35d 100755 --- a/app/library/App/Bootstrap/AclBootstrap.php +++ b/app/library/App/Bootstrap/AclBootstrap.php @@ -5,6 +5,8 @@ namespace App\Bootstrap; use App\BootstrapInterface; use App\Constants\Services; use Phalcon\Acl; +use Phalcon\Acl\Resource; +use Phalcon\Acl\Role; use Phalcon\Config; use Phalcon\DiInterface; use PhalconRest\Api; @@ -17,17 +19,22 @@ class AclBootstrap implements BootstrapInterface /** @var \PhalconApi\Acl\MountingEnabledAdapterInterface $acl */ $acl = $di->get(Services::ACL); - $unauthorizedRole = new Acl\Role(AclRoles::UNAUTHORIZED); - $authorizedRole = new Acl\Role(AclRoles::AUTHORIZED); + $unauthorizedRole = new Role(AclRoles::UNAUTHORIZED); + $authorizedRole = new Role(AclRoles::AUTHORIZED); $acl->addRole($unauthorizedRole); $acl->addRole($authorizedRole); - $acl->addRole(new Acl\Role(AclRoles::ADMINISTRATOR), $authorizedRole); - $acl->addRole(new Acl\Role(AclRoles::MANAGER), $authorizedRole); - $acl->addRole(new Acl\Role(AclRoles::USER), $authorizedRole); - $acl->addRole(new Acl\Role(AclRoles::EDITOR), $authorizedRole); - $acl->addRole(new Acl\Role(AclRoles::AUTHOR), $authorizedRole); + $administrator = new Role(AclRoles::ADMINISTRATOR); + $user = new Role(AclRoles::USER); + $editor = new Role(AclRoles::EDITOR); + $author = new Role(AclRoles::AUTHOR); + + + $acl->addRole($administrator, $authorizedRole); + $acl->addRole($user, $authorizedRole); + $acl->addRole($editor, $authorizedRole); + $acl->addRole($author, $authorizedRole); $acl->mountMany($api->getCollections()); } diff --git a/app/library/App/Constants/AclRoles.php b/app/library/App/Constants/AclRoles.php index 0333707..36457ca 100755 --- a/app/library/App/Constants/AclRoles.php +++ b/app/library/App/Constants/AclRoles.php @@ -9,9 +9,55 @@ class AclRoles const AUTHOR = 'Author'; const EDITOR = 'Editor'; const USER = 'User'; - const MANAGER = 'Manager'; const ADMINISTRATOR = 'Administrator'; - const ALL_ROLES = [self::UNAUTHORIZED, self::AUTHORIZED, self::USER, self::MANAGER, self::ADMINISTRATOR]; - const ALL_REAL_ROLES = [self::AUTHOR, self::EDITOR, self::USER, self::MANAGER, self::ADMINISTRATOR]; + const ALL_ROLES = [ + self::UNAUTHORIZED, + self::AUTHORIZED, + self::AUTHOR, + self::EDITOR, + self::USER, + self::ADMINISTRATOR + ]; + + const ALL_REAL_ROLES = [ + self::AUTHOR, + self::EDITOR, + self::USER, + self::ADMINISTRATOR + ]; + + /** + * Check if $role can remove user with role $role_to_remove + * + * @param $role + * @param $role_to_remove + * @return bool + */ + static public function access_user_delete($role, $role_to_remove) + { + $is_accessible = true; + switch ($role) + { + case self::AUTHOR: + if (in_array($role_to_remove, [self::EDITOR, self::USER, self::ADMINISTRATOR])) + { + $is_accessible = false; + } + break; + case self::EDITOR: + if (in_array($role_to_remove, [self::USER, self::ADMINISTRATOR])) + { + $is_accessible = false; + } + break; + case self::USER: + if (in_array($role_to_remove, [self::ADMINISTRATOR])) + { + $is_accessible = false; + } + break; + } + return $is_accessible; + } } \ No newline at end of file diff --git a/app/library/App/Controllers/ProjectController.php b/app/library/App/Controllers/ProjectController.php new file mode 100644 index 0000000..86a9f2d --- /dev/null +++ b/app/library/App/Controllers/ProjectController.php @@ -0,0 +1,141 @@ +userService->getIdentity(); + $projects = Project::find(["user_id = '$user_id'"]); + if (count($projects) == 0) + { + $projects = User::findFirst([$user_id])->projects; + if (count($projects) == 0) + { + throw new Exception(ErrorCodes::GENERAL_NOT_FOUND, 'Projects not found'); + } + else + { + var_dump($projects); + return $this->createArrayResponse($projects, 'projects'); + } + } + else + { + return $this->createArrayResponse($projects, 'projects'); + } + } + + /** + * @param $data + * @param $isUpdate + * @return bool + * @throws Exception + */ + public function postDataValid($data, $isUpdate) + { + if ($isUpdate) + { + if (isset($data['user_id'])) + { + throw new Exception(ErrorCodes::ACCESS_DENIED, 'Find user_id value in post-data. Operation is not allowed.'); + } + return true; + } + else + { + if (isset($data['user_id'])) + { + throw new Exception(ErrorCodes::ACCESS_DENIED, 'Find user_id value in post-data. Operation is not allowed.'); + } + return true; + } + } + + /** + * + * @param Project $item + */ + protected function beforeCreate(Project $item) + { + $user_id = $this->userService->getIdentity(); + $item->user_id = $user_id; + } + + /** + * @param Project $item + * @return bool|void + */ + protected function afterCreate(Project $item) + { + $data = ['project_id' => $item->id, 'user_id' => $item->user_id]; + $junction = new UserProject(); + $junction->user_id = $item->user_id; + $junction->project_id = $item->id; + if (!$junction->save()) + { + return $this->onCreateFailed($junction, $data); + } + return true; + } + + /** + * @param $id + * @throws Exception + */ + protected function beforeHandleUpdate($id) + { + $user_id = $this->userService->getIdentity(); + + if(!UserProject::findFirst(["user_id = '$user_id'"]) && $this->userService->getRole() !== AclRoles::ADMINISTRATOR) + { + throw new Exception(ErrorCodes::ACCESS_DENIED, 'Operation is not allowed'); + } + } + + /** + * @param $id + * @throws Exception + */ + protected function beforeHandleRemove($id) + { + $project = Project::findFirst($id)->id; + + if (empty($project)) + { + throw new Exception(ErrorCodes::GENERAL_NOT_FOUND, 'Project with `id`='.$id.' not found'); + } + + $user_id = $this->userService->getIdentity(); + + $project = Project::findFirst(["user_id = '$user_id' AND id = '$id'"]); + + if (empty($project) && $this->userService->getRole() !== AclRoles::ADMINISTRATOR) + { + throw new Exception(ErrorCodes::ACCESS_DENIED, 'Operation is not allowed'); + } + else + { + $project_links = UserProject::find(["project_id = '$id'"]); + foreach ($project_links as $project_link) { + $this->removeItem($project_link); + } + } + } +} \ No newline at end of file diff --git a/app/library/App/Controllers/UserController.php b/app/library/App/Controllers/UserController.php index 6e9255f..59836bb 100755 --- a/app/library/App/Controllers/UserController.php +++ b/app/library/App/Controllers/UserController.php @@ -2,6 +2,14 @@ namespace App\Controllers; +use App\Auth\UsernameAccountType; +use App\Constants\AclRoles; +use App\Model\Project; +use App\Model\User; +use App\Model\UserProject; +use App\Transformers\UserTransformer; +use PhalconApi\Constants\ErrorCodes; +use PhalconApi\Exception; use PhalconRest\Mvc\Controllers\CrudResourceController; class UserController extends CrudResourceController @@ -22,6 +30,48 @@ class UserController extends CrudResourceController } /** + * Возвращает всех зарегистрированных пользователей c ролью AclRoles::EDITOR + * + * @return mixed + */ + public function editorsAction() + { + $current_projects = $this->userService->getDetails()->projects; + $editors = []; + foreach ($current_projects as $project) + { + foreach ($project->users as $user) { + if ($user->role == AclRoles::EDITOR) + { + $editors[$project->id][] = $this->createItemResponse($user, new UserTransformer()); + } + } + } + return $this->createResponse($editors); + } + + /** + * Возвращает всех зарегистрированных пользователей c ролью AclRoles::AUTHOR + * + * @return mixed + */ + public function authorsAction() + { + $current_projects = $this->userService->getDetails()->projects; + $authors = []; + foreach ($current_projects as $project) + { + foreach ($project->users as $user) { + if ($user->role == AclRoles::AUTHOR) + { + $authors[$project->id][] = $this->createItemResponse($user, new UserTransformer()); + } + } + } + return $this->createResponse($authors); + } + + /** * Возвращает текущего залогиненного пользователя * * @return mixed @@ -32,6 +82,46 @@ class UserController extends CrudResourceController } /** + * Изменение данных пользователя + * + * @param $id + * @throws Exception + */ + public function updateAction($id) + { + if ($this->userService->getRole() == AclRoles::ADMINISTRATOR || $id == $this->userService->getIdentity()) + { + return $this->update($id); + } + else + { + throw new Exception(ErrorCodes::ACCESS_DENIED, 'Operation is not allowed'); + } + } + + /** + * Удаление пользователя + * + * @param $id + * @throws Exception + */ + public function removeAction($id) + { + $user_role = $this->userService->getRole(); + $user_id = $this->userService->getIdentity(); + $role_to_delete = User::findFirst($id)->role; + + if (AclRoles::access_user_delete($user_role, $role_to_delete) || $user_id == $id) + { + return $this->remove($id); + } + else + { + throw new Exception(ErrorCodes::ACCESS_DENIED, 'Operation is not allowed'); + } + } + + /** * Авторизация пользователя через BasicAuth и возвращает токен доступа * * @return mixed @@ -41,13 +131,13 @@ class UserController extends CrudResourceController $username = $this->request->getUsername(); $password = $this->request->getPassword(); - $session = $this->authManager->loginWithUsernamePassword(\App\Auth\UsernameAccountType::NAME, $username, + $session = $this->authManager->loginWithUsernamePassword(UsernameAccountType::NAME, $username, $password); - $transformer = new \App\Transformers\UserTransformer; + $transformer = new UserTransformer; $transformer->setModelClass('App\Model\User'); - $user = $this->createItemResponse(\App\Model\User::findFirst($session->getIdentity()), $transformer); + $user = $this->createItemResponse(User::findFirst($session->getIdentity()), $transformer); $response = [ 'token' => $session->getToken(), @@ -63,7 +153,8 @@ class UserController extends CrudResourceController * * @return mixed */ - public function registerAction() { + public function registerAction() + { $this->beforeHandle(); $this->beforeHandleWrite(); @@ -106,16 +197,72 @@ class UserController extends CrudResourceController } /** + * Приглашение существующего пользователя в проэкт + * + * @throws Exception + */ + public function inviteAction() + { + $user_id = $this->request->get('user_id'); + $project_id = $this->request->get('project_id'); + + if (empty($user_id) || empty($project_id)) + { + throw new Exception(ErrorCodes::DATA_NOT_FOUND, 'Empty post-data'); + } + elseif (!User::findFirst($user_id)) + { + throw new Exception(ErrorCodes::GENERAL_NOT_FOUND, 'User with requested id not found'); + } + elseif (!Project::findFirst($project_id)) + { + throw new Exception(ErrorCodes::GENERAL_NOT_FOUND, 'Project with requested id not found'); + } + elseif (UserProject::findFirst(["user_id = '$user_id' AND project_id = '$project_id'"])) + { + throw new Exception(ErrorCodes::POST_DATA_INVALID, 'User already invited'); + } + else + { + $userProject = new UserProject(); + $data = ['project_id' => $project_id, 'user_id' => $user_id]; + $userProject->user_id = $user_id; + $userProject->project_id = $project_id; + if (!$userProject->save()) + { + return $this->onCreateFailed($userProject, $data); + } + else + { + return $this->createResponse($data); + } + } + } + + /** * Переопределение входных данных * * @param $data * @return array + * @throws Exception */ protected function transformPostData($data) { $result = []; - foreach ($data as $key => $value) { + foreach ($data as $key => $value) + { + /** --- Менять роли может только админ ---- **/ + if ($this->userService->getRole() !== AclRoles::ADMINISTRATOR && $key == 'role') + { + $msg = 'You have not access for field `role`'; + throw new Exception( + ErrorCodes::POST_DATA_INVALID, + $msg, + ['post data field' => $key, 'value' => $value] + ); + } + /** -------------------------------------- **/ $result[$key] = $this->transformPostDataValue($key, $value, $data); } @@ -139,4 +286,17 @@ class UserController extends CrudResourceController } } + /** + * Сопутствующее удаление из перелинковочной таблицы проэкт-пользователь + * + * @param $id + */ + protected function beforeHandleRemove($id) + { + $junctions = UserProject::findFirst("user_id = '$id'"); + if ($junctions) + { + $junctions->delete(); + } + } } \ No newline at end of file diff --git a/app/library/App/Model/Album.php b/app/library/App/Model/Album.php deleted file mode 100755 index 9b33d03..0000000 --- a/app/library/App/Model/Album.php +++ /dev/null @@ -1,29 +0,0 @@ - 'id', - 'title' => 'title' - ]; - } - - public function initialize() { - - $this->hasMany('id', Photo::class, 'albumId', [ - 'alias' => 'Photos', - ]); - } -} diff --git a/app/library/App/Model/Photo.php b/app/library/App/Model/Photo.php deleted file mode 100755 index f5e3937..0000000 --- a/app/library/App/Model/Photo.php +++ /dev/null @@ -1,31 +0,0 @@ - 'id', - 'title' => 'title', - 'album_id' => 'albumId' - ]; - } - - public function initialize() { - - $this->belongsTo('albumId', Album::class, 'id', [ - 'alias' => 'Album', - ]); - } -} diff --git a/app/library/App/Model/Project.php b/app/library/App/Model/Project.php index 3b177e0..b3bde9d 100644 --- a/app/library/App/Model/Project.php +++ b/app/library/App/Model/Project.php @@ -2,7 +2,11 @@ namespace App\Model; -class Project extends \App\Mvc\DateTrackingModel +use App\Mvc\DateTrackingModel; +use PhalconApi\Constants\ErrorCodes; +use PhalconApi\Exception; + +class Project extends DateTrackingModel { public $id; public $name; @@ -31,5 +35,94 @@ class Project extends \App\Mvc\DateTrackingModel $this->belongsTo('user_id', User::class, 'id', [ 'alias' => 'User', ]); + + $this->hasManyToMany( + 'id', + UserProject::class, + 'project_id', + 'user_id', + User::class, + 'id', + array('alias' => 'users') + ); } + + /** ------- Getters and Setters ------- **/ + + /** validation: non-empty, 4+ letters * + * @param $name + * @throws Exception + */ + public function setName($name) + { + if (empty($name)) + { + $msg = 'Post-data is invalid, trying to use empty value of `name`'; + throw new Exception(ErrorCodes::POST_DATA_INVALID, $msg, ['name' => $name]); + } + elseif (strlen($name) < 4) + { + $msg = 'Post-data is invalid, value of `name` should be more than 4 letters'; + throw new Exception(ErrorCodes::POST_DATA_INVALID, $msg, ['name' => $name]); + } + + $this->name = $name; + } + + /** validation: non-empty, integer * + * @param $ga_view_id + * @throws Exception + */ + public function setGa_view_id($ga_view_id) + { + if (empty($ga_view_id)) + { + $msg = 'Post-data is invalid, trying to use empty value of `ga_view_id`'; + throw new Exception(ErrorCodes::POST_DATA_INVALID, $msg, ['ga_view_id' => $ga_view_id]); + } + elseif (!is_integer($ga_view_id)) + { + $msg = 'Post-data is invalid, type of `ga_view_id` should be integer'; + throw new Exception(ErrorCodes::POST_DATA_INVALID, $msg, ['ga_view_id' => $ga_view_id]); + } + + $this->ga_view_id = $ga_view_id; + } + + /** validation: non-empty, integer * + * @param $group + * @throws Exception + */ + public function setGroup($group) + { + if (empty($group)) + { + $msg = 'Post-data is invalid, trying to use empty value of `group`'; + throw new Exception(ErrorCodes::POST_DATA_INVALID, $msg, ['group' => $group]); + } + elseif (!is_integer($group)) + { + $msg = 'Post-data is invalid, type of `group` should be integer'; + throw new Exception(ErrorCodes::POST_DATA_INVALID, $msg, ['group' => $group]); + } + + $this->group = $group; + } + + public function getName() + { + return $this->name; + } + + public function getGa_view_id() + { + return $this->ga_view_id; + } + + public function getGroup() + { + return $this->group; + } + + /** ----------------------------------- **/ } diff --git a/app/library/App/Model/User.php b/app/library/App/Model/User.php index 87c1767..0ed0c3b 100755 --- a/app/library/App/Model/User.php +++ b/app/library/App/Model/User.php @@ -34,19 +34,35 @@ class User extends DateTrackingModel public function initialize() { - $this->hasMany('id', Project::class, 'user_id', [ - 'alias' => 'Projects', - ]); + $this->hasMany( + 'id', + Project::class, + 'user_id', + [ + 'alias' => 'Projects', + ] + ); + + $this->hasManyToMany( + 'id', + UserProject::class, + 'user_id', + 'project_id', + Project::class, + 'id', + array('alias' => 'projects') + ); } - public function getUsername() - { - return $this->username; - } + /** ------- Getters and Setters ------- **/ + + /** validation: unique, non-empty, 4+ letters * + * @param $username + * @throws Exception + */ + public function setUsername($username) + { - public function setUsername($username) - { - /** validation: unique, non-empty, 4+ letters **/ $same_user = User::find(["username = '".$username."'"]); if (isset($same_user[0]) && !empty($same_user[0]->username)) { @@ -56,45 +72,38 @@ class User extends DateTrackingModel elseif (empty($username)) { $msg = 'Post-data is invalid, trying to use empty value of `username`'; - throw new Exception(ErrorCodes::DATA_NOT_FOUND, $msg, ['username' => $username]); + throw new Exception(ErrorCodes::POST_DATA_INVALID, $msg, ['username' => $username]); } elseif (strlen($username) < 4) { $msg = 'Post-data is invalid, value of `username` should be more than 4 letters'; throw new Exception(ErrorCodes::POST_DATA_INVALID, $msg, ['username' => $username]); } - /** ---------------------------------------- **/ - $this->username = $username; - } + $this->username = $username; + } - public function getEmail() - { - return $this->email; - } - - public function setEmail($email) - { - /** validation: FILTER_VALIDATE_EMAIL **/ + /** validation: FILTER_VALIDATE_EMAIL * + * @param $email + * @throws Exception + */ + public function setEmail($email) + { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $msg = 'Post-data is invalid, bad email value'; throw new Exception(ErrorCodes::POST_DATA_INVALID, $msg, ['email' => $email]); } - /** ---------- */ - $this->email = $email; - } + $this->email = $email; + } - public function getRole() - { - $service = new Service(); - return $service->getRole(); - } - - public function setRole($role) - { - /** validation: constant value **/ + /** validation: constant value * + * @param $role + * @throws Exception + */ + public function setRole($role) + { if (!in_array($role, AclRoles::ALL_REAL_ROLES)) { $msg = 'Post-data is invalid, bad `role` value'; @@ -104,9 +113,27 @@ class User extends DateTrackingModel ['role' => $role, 'valid values' => AclRoles::ALL_REAL_ROLES] ); } - /** -------------------------- **/ - $this->role = $role; - } + $this->role = $role; + } + + + public function getUsername() + { + return $this->username; + } + + public function getEmail() + { + return $this->email; + } + + public function getRole() + { + $service = new Service(); + return $service->getRole(); + } + + /** ----------------------------------- **/ } diff --git a/app/library/App/Model/UserProject.php b/app/library/App/Model/UserProject.php new file mode 100644 index 0000000..827c76d --- /dev/null +++ b/app/library/App/Model/UserProject.php @@ -0,0 +1,30 @@ +belongsTo('project_id', Project::class, 'id', + array('alias' => 'project') + ); + $this->belongsTo('user_id', User::class, 'id', + array('alias' => 'user') + ); + } +} \ No newline at end of file diff --git a/app/library/App/Resources/AlbumResource.php b/app/library/App/Resources/AlbumResource.php deleted file mode 100755 index ccf890b..0000000 --- a/app/library/App/Resources/AlbumResource.php +++ /dev/null @@ -1,32 +0,0 @@ -name('Album') - ->model(Album::class) - ->expectsJsonData() - ->transformer(AlbumTransformer::class) - ->itemKey('album') - ->collectionKey('albums') - ->deny(AclRoles::UNAUTHORIZED) - ->handler(CrudResourceController::class) - - ->endpoint(ApiEndpoint::all()) - ->endpoint(ApiEndpoint::create()) - ->endpoint(ApiEndpoint::find()) - ->endpoint(ApiEndpoint::update()) - ->endpoint(ApiEndpoint::remove()); - } -} diff --git a/app/library/App/Resources/PhotoResource.php b/app/library/App/Resources/PhotoResource.php deleted file mode 100755 index 3f113fe..0000000 --- a/app/library/App/Resources/PhotoResource.php +++ /dev/null @@ -1,32 +0,0 @@ -name('Photo') - ->model(Photo::class) - ->expectsJsonData() - ->transformer(PhotoTransformer::class) - ->itemKey('photo') - ->collectionKey('photos') - ->deny(AclRoles::UNAUTHORIZED) - ->handler(CrudResourceController::class) - - ->endpoint(ApiEndpoint::all()) - ->endpoint(ApiEndpoint::create()) - ->endpoint(ApiEndpoint::find()) - ->endpoint(ApiEndpoint::update()) - ->endpoint(ApiEndpoint::remove()); - } -} diff --git a/app/library/App/Resources/ProjectResource.php b/app/library/App/Resources/ProjectResource.php index 887143f..8143d8f 100644 --- a/app/library/App/Resources/ProjectResource.php +++ b/app/library/App/Resources/ProjectResource.php @@ -8,12 +8,13 @@ namespace App\Resources; +use App\Controllers\ProjectController; +use PhalconApi\Constants\HttpMethods; use PhalconRest\Api\ApiEndpoint; use PhalconRest\Api\ApiResource; use App\Model\Project; use PhalconRest\Transformers\ModelTransformer; use App\Constants\AclRoles; -use PhalconRest\Mvc\Controllers\CrudResourceController; class ProjectResource extends ApiResource { @@ -26,14 +27,60 @@ class ProjectResource extends ApiResource { ->transformer(ModelTransformer::class) ->itemKey('project') ->collectionKey('projects') - ->deny(AclRoles::UNAUTHORIZED) - ->handler(CrudResourceController::class) - - ->endpoint(ApiEndpoint::all()) - ->endpoint(ApiEndpoint::create()) - ->endpoint(ApiEndpoint::find()) - ->endpoint(ApiEndpoint::update()) - ->endpoint(ApiEndpoint::remove()); + ->deny(AclRoles::ALL_ROLES) + ->handler(ProjectController::class) + + /** -------------------- [GET] projects ----------------------------- **/ + ->endpoint(ApiEndpoint::factory('/', HttpMethods::GET, 'allAction') + ->name(ApiEndpoint::ALL) + ->description('Returns all items') + ->allow( + AclRoles::ADMINISTRATOR, + AclRoles::USER, + AclRoles::EDITOR, + AclRoles::AUTHOR + ) + ) + /** ----------------------------------------------------------------- **/ + + /** -------------------- [POST] projects ---------------------------- **/ + ->endpoint(ApiEndpoint::factory('/', HttpMethods::POST, 'create') + ->name(ApiEndpoint::CREATE) + ->description('Creates a new item using the posted data') + ->allow( + AclRoles::ADMINISTRATOR, + AclRoles::USER + ) + ) + /** ----------------------------------------------------------------- **/ + + /** -------------------- [GET] projects/{id} ------------------------ **/ + ->endpoint(ApiEndpoint::find() + ->allow(AclRoles::ADMINISTRATOR) + ) + /** ----------------------------------------------------------------- **/ + + /** -------------------- [PUT] projects/{id} ------------------------ **/ + ->endpoint(ApiEndpoint::factory('/{id}', HttpMethods::PUT, 'update') + ->name(ApiEndpoint::UPDATE) + ->description('Updates an existing item identified by {id}, using the posted data') + ->allow( + AclRoles::ADMINISTRATOR, + AclRoles::USER + ) + ) + /** ----------------------------------------------------------------- **/ + + /** -------------------- [DELETE] projects/{id} --------------------- **/ + ->endpoint(ApiEndpoint::factory('/{id}', HttpMethods::DELETE, 'remove') + ->name(ApiEndpoint::REMOVE) + ->description('Removes the item identified by {id}') + ->allow( + AclRoles::ADMINISTRATOR, + AclRoles::USER + ) + ); + /** ----------------------------------------------------------------- **/ } } \ No newline at end of file diff --git a/app/library/App/Resources/UserResource.php b/app/library/App/Resources/UserResource.php index f0c799d..bb85893 100755 --- a/app/library/App/Resources/UserResource.php +++ b/app/library/App/Resources/UserResource.php @@ -21,53 +21,132 @@ class UserResource extends ApiResource { ->transformer(UserTransformer::class) ->itemKey('user') ->collectionKey('users') - ->deny(AclRoles::UNAUTHORIZED, AclRoles::USER) ->handler(UserController::class) + ->deny(AclRoles::ALL_ROLES) /** -------------------- [GET] users -------------------------------- **/ ->endpoint(ApiEndpoint::all() - ->allow(AclRoles::USER) ->name('all') ->description('Возвращает всех зарегистрированных пользователей') + ->allow( + AclRoles::ADMINISTRATOR + ) + ) + /** ----------------------------------------------------------------- **/ + + /** -------------------- [GET] users/editors ------------------------ **/ + ->endpoint(ApiEndpoint::factory('/editors', HttpMethods::GET, 'editorsAction') + ->name('all editors') + ->description('Возвращает всех зарегистрированных пользователей c ролью "'.AclRoles::EDITOR.'" по каждому проэкту') + ->allow( + AclRoles::ADMINISTRATOR, + AclRoles::USER + ) + ->exampleResponse([ + "68" => [ + [ + "id" => 4, + "username" => "Tim2", + "email" => "timTEST2@awd.awd", + "role" => "Editor", + "createdAt" => "2017-02-16 19:05:18", + "updatedAt" => "2017-03-21 14:31:48" + ], + [ + "id" => 5, + "username" => "Tim3", + "email" => "timTEST3@awd.awd", + "role" => "Editor", + "createdAt" => "2017-02-16 19:05:18", + "updatedAt" => "2017-03-21 14:31:48" + ] + ] + ]) + ) + /** ----------------------------------------------------------------- **/ + + /** -------------------- [GET] users/authors ------------------------ **/ + ->endpoint(ApiEndpoint::factory('/authors', HttpMethods::GET, 'authorsAction') + ->name('all authors') + ->description('Возвращает всех зарегистрированных пользователей c ролью "'.AclRoles::AUTHOR.'" по каждому проэкту') + ->allow( + AclRoles::ADMINISTRATOR, + AclRoles::USER, + AclRoles::EDITOR + ) + ->exampleResponse([ + "68" => [ + [ + "id" => 4, + "username" => "Tim2", + "email" => "timTEST2@awd.awd", + "role" => "Author", + "createdAt" => "2017-02-16 19:05:18", + "updatedAt" => "2017-03-21 14:31:48" + ], + [ + "id" => 5, + "username" => "Tim3", + "email" => "timTEST3@awd.awd", + "role" => "Author", + "createdAt" => "2017-02-16 19:05:18", + "updatedAt" => "2017-03-21 14:31:48" + ] + ] + ]) ) /** ----------------------------------------------------------------- **/ /** -------------------- [GET] users/me ----------------------------- **/ ->endpoint(ApiEndpoint::factory('/me', HttpMethods::GET, 'meAction') - ->name('me') - ->description('Возвращает текущего залогиненного пользователя') - ->allow(AclRoles::USER) - ) + ->name('me') + ->description('Возвращает текущего залогиненного пользователя') + ->allow( + AclRoles::ADMINISTRATOR, + AclRoles::USER, + AclRoles::EDITOR, + AclRoles::AUTHOR + ) + ) /** ----------------------------------------------------------------- **/ /** -------------------- [PUT] users/{id} -------------------------- **/ - ->endpoint(ApiEndpoint::update() - ->name('update') - ->description('Изменение данных пользователя') - ->allow(AclRoles::ADMINISTRATOR) - ->deny(AclRoles::MANAGER) - ->exampleRequest([ - 'role' => 'Manager' - ]) - ->exampleResponse([ - "result" => "OK", - "user" => [ - "id" => 101, - "username" => "qwerty", - "email" => "1a23@awd.awd", - "role" => "Manager", - "createdAt" => "2017-02-16 19:05:18", - "updatedAt" => "2017-03-21 14:31:48" - ] - ]) - ) + ->endpoint(ApiEndpoint::factory('/{id}', HttpMethods::PUT, 'updateAction') + ->name('update') + ->description('Изменение данных пользователя') + ->allow( + AclRoles::ADMINISTRATOR, + AclRoles::USER, + AclRoles::EDITOR, + AclRoles::AUTHOR + ) + ->exampleRequest([ + 'role' => 'User' + ]) + ->exampleResponse([ + "result" => "OK", + "user" => [ + "id" => 101, + "username" => "qwerty", + "email" => "1a23@awd.awd", + "role" => "User", + "createdAt" => "2017-02-16 19:05:18", + "updatedAt" => "2017-03-21 14:31:48" + ] + ]) + ) /** ----------------------------------------------------------------- **/ /** -------------------- [DELETE] users/{id} ------------------------ **/ - ->endpoint(ApiEndpoint::remove() + ->endpoint(ApiEndpoint::factory('/{id}', HttpMethods::DELETE, 'removeAction') ->name('remove') ->description('Удаление пользователя') - ->allow(AclRoles::USER) + ->allow( + AclRoles::ADMINISTRATOR, + AclRoles::USER, + AclRoles::EDITOR, + AclRoles::AUTHOR + ) ->exampleResponse([ "result" => "OK" ]) @@ -79,7 +158,6 @@ class UserResource extends ApiResource { ->name('authenticate') ->description('Авторизация пользователя через BasicAuth и возвращает токен доступа') ->allow(AclRoles::UNAUTHORIZED) - ->deny(AclRoles::AUTHORIZED) ->exampleResponse([ 'data' => [ 'token' => 'co126bbm40wqp41i3bo7pj1gfsvt9lp6', @@ -99,12 +177,11 @@ class UserResource extends ApiResource { ) /** ----------------------------------------------------------------- **/ - /** -------------------- [POST] users -------------------------------- **/ + /** -------------------- [POST] users ------------------------------- **/ ->endpoint(ApiEndpoint::factory('/', HttpMethods::POST, 'registerAction') ->name('register') ->description('Регистрация нового пользователя') ->allow(AclRoles::UNAUTHORIZED) - ->deny(AclRoles::AUTHORIZED) ->exampleResponse([ "result" => "OK", "user" => [ @@ -118,6 +195,29 @@ class UserResource extends ApiResource { ]) ) /** ----------------------------------------------------------------- **/ + + /** -------------------- [POST] users/invite ------------------------ **/ + ->endpoint(ApiEndpoint::factory('/invite', HttpMethods::POST, 'inviteAction') + ->name('invite') + ->description('Приглашение существующего пользователя в проэкт') + ->allow( + AclRoles::ADMINISTRATOR, + AclRoles::USER, + AclRoles::EDITOR + ) + ->exampleResponse([ + "result" => "OK", + "user" => [ + "id" => "95", + "username" => "MyLogin", + "email" => "myGmail@gmail.com", + "role" => "User", + "createdAt" => "2017-02-16 17:57:52", + "updatedAt" => "2017-02-16 17:57:52" + ] + ]) + ) + /** ----------------------------------------------------------------- **/ ; } } \ No newline at end of file diff --git a/app/library/App/Transformers/AlbumTransformer.php b/app/library/App/Transformers/AlbumTransformer.php deleted file mode 100755 index 43c3403..0000000 --- a/app/library/App/Transformers/AlbumTransformer.php +++ /dev/null @@ -1,28 +0,0 @@ -collection($album->getPhotos(), new PhotoTransformer); - } - - public function transform(Album $album) - { - return [ - 'id' => $this->int($album->id), - 'title' => $album->title, - 'updated_at' => $album->updatedAt, - 'created_at' => $album->createdAt - ]; - } -} diff --git a/app/library/App/Transformers/PhotoTransformer.php b/app/library/App/Transformers/PhotoTransformer.php deleted file mode 100755 index b80b1ff..0000000 --- a/app/library/App/Transformers/PhotoTransformer.php +++ /dev/null @@ -1,39 +0,0 @@ -item($photo->getAlbum(), new AlbumTransformer()); - } - - /** - * You can always transform manually by using - * the following code (below): - * - public function transform(Photo $photo) - { - return [ - 'id' => $this->int($photo->id), - 'title' => $photo->title, - 'albumId' => $this->int($photo->albumId) - ]; - } - */ -} -- libgit2 0.21.4