From b8ab5bb3c0f3c9cef44b9c9e437f4702e9e3fbf7 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 9 May 2019 04:24:05 +0000 Subject: [PATCH] Add comments for the Generator and Voter classes in the auth bundle. Add support for add, update, and delete API Role. #194 --- catalyst/auth-bundle/Service/Generator.php | 9 +- catalyst/auth-bundle/Service/Voter.php | 2 + src/Controller/APIRoleController.php | 187 ++++++++++++++++++++- templates/api-role/form.html.twig | 165 ++++++++++++++++++ 4 files changed, 352 insertions(+), 11 deletions(-) create mode 100644 templates/api-role/form.html.twig diff --git a/catalyst/auth-bundle/Service/Generator.php b/catalyst/auth-bundle/Service/Generator.php index 1ec72f35..f79c736e 100644 --- a/catalyst/auth-bundle/Service/Generator.php +++ b/catalyst/auth-bundle/Service/Generator.php @@ -9,9 +9,10 @@ use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Routing\RouterInterface; +// NOTES: This class is inherited by the API Bundle and the main site + abstract class Generator { - // TODO: make api_acl and acl yaml generator have its own bundle protected $router; protected $cache_dir; protected $config_dir; @@ -44,14 +45,14 @@ abstract class Generator try { - // get location of api_acl.yaml - // $path = $this->config_dir . '/api_acl.yaml'; + // get location of the yaml file with the acls + // $path = $this->config_dir . '/'; $path = $this->config_dir . '/' . $this->acl_file; $files[] = $path; $resources[] = new FileResource($path); - // process api acl config file + // process acl config file $data = $this->parseACL($path, $key); } catch (\InvalidArgumentException $e) diff --git a/catalyst/auth-bundle/Service/Voter.php b/catalyst/auth-bundle/Service/Voter.php index a369137e..4346d094 100644 --- a/catalyst/auth-bundle/Service/Voter.php +++ b/catalyst/auth-bundle/Service/Voter.php @@ -5,6 +5,8 @@ namespace Catalyst\AuthBundle\Service; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter as BaseVoter; +// NOTES: This class is inherited by the API Bundle and the main site + abstract class Voter extends BaseVoter { protected $acl_gen; diff --git a/src/Controller/APIRoleController.php b/src/Controller/APIRoleController.php index 4fd1d2b0..f842c056 100644 --- a/src/Controller/APIRoleController.php +++ b/src/Controller/APIRoleController.php @@ -5,6 +5,7 @@ namespace App\Controller; use App\Ramcar\BaseController; use Catalyst\APIBundle\Entity\Role as APIRole; +use Catalyst\APIBundle\Access\Generator as APIACLGenerator; use Doctrine\ORM\Query; use Symfony\Component\HttpFoundation\Request; @@ -17,10 +18,12 @@ use App\Access\Generator as ACLGenerator; class APIRoleController extends BaseController { protected $acl_gen; + protected $api_acl_gen; - public function __construct(MenuGenerator $menu_gen, ACLGenerator $acl_gen) + public function __construct(MenuGenerator $menu_gen, ACLGenerator $acl_gen, APIACLGenerator $api_acl_gen) { $this->acl_gen = $acl_gen; + $this->api_acl_gen = $api_acl_gen; parent::__construct($menu_gen); } @@ -127,12 +130,185 @@ class APIRoleController extends BaseController ]); } + public function addForm() + { + $this->denyAccessUnlessGranted('apirole.add', null, 'No access.'); - protected function padACLHierarchy(&$params) + $params = $this->initParameters('apirole_list'); + $this->padAPIACLHierarchy($params); + $params['obj'] = new APIRole(); + $params['mode'] = 'create'; + + // response + return $this->render('api-role/form.html.twig', $params); + } + + public function addSubmit(Request $req, ValidatorInterface $validator) + { + $this->denyAccessUnlessGranted('apirole.add', null, 'No access.'); + + // create new row + $em = $this->getDoctrine()->getManager(); + $row = new APIRole(); + + // set and save values + $row->setID($req->request->get('id')) + ->setName($req->request->get('name')); + + // acl attributes + $acl_attribs = $req->request->get('acl'); + + if (!empty($acl_attribs)) + { + foreach ($acl_attribs as $acl_key) + { + $row->addACLAccess($acl_key); + } + } + + // validate + $errors = $validator->validate($row); + + // initialize error list + $error_array = []; + + // add errors to list + foreach ($errors as $error) { + $error_array[$error->getPropertyPath()] = $error->getMessage(); + } + + // check if any errors were found + if (!empty($error_array)) { + // return validation failure response + return $this->json([ + 'success' => false, + 'errors' => $error_array + ], 422); + } else { + // validated! save the entity + $em->persist($row); + $em->flush(); + + // return successful response + return $this->json([ + 'success' => 'Changes have been saved!' + ]); + } + } + + public function updateForm($id) + { + $this->denyAccessUnlessGranted('apirole.update', null, 'No access.'); + + $params = $this->initParameters('api_role_list'); + $this->padAPIACLHierarchy($params); + $params['mode'] = 'update'; + + // get row data + $em = $this->getDoctrine()->getManager(); + $row = $em->getRepository(APIRole::class)->find($id); + + // make sure this row exists + if (empty($row)) + throw $this->createNotFoundException('The item does not exist'); + + $params['obj'] = $row; + + // response + return $this->render('api-role/form.html.twig', $params); + } + + public function updateSubmit(Request $req, ValidatorInterface $validator, $id) + { + $this->denyAccessUnlessGranted('apirole.update', null, 'No access.'); + + // get row data + $em = $this->getDoctrine()->getManager(); + $row = $em->getRepository(APIRole::class)->find($id); + + // make sure this row exists + if (empty($row)) + throw $this->createNotFoundException('The item does not exist'); + + // set and save values + $row->setID($req->request->get('id')) + ->setName($req->request->get('name')); + + // don't update acl attributes for super user since they don't need it + if (!$row->isSuperAdmin()) + { + // clear first + $row->clearACLAttributes(); + + // then add + $acl_attribs = $req->request->get('acl'); + + if (!empty($acl_attribs)) + { + foreach ($acl_attribs as $acl_key) + { + $row->addACLAccess($acl_key); + } + } + } + + // validate + $errors = $validator->validate($row); + + // initialize error list + $error_array = []; + + // add errors to list + foreach ($errors as $error) { + $error_array[$error->getPropertyPath()] = $error->getMessage(); + } + + // check if any errors were found + if (!empty($error_array)) { + // return validation failure response + return $this->json([ + 'success' => false, + 'errors' => $error_array + ], 422); + } else { + // validated! save the entity + $em->flush(); + + // return successful response + return $this->json([ + 'success' => 'Changes have been saved!' + ]); + } + } + + public function destroy($id) + { + $this->denyAccessUnlessGranted('apirole.delete', null, 'No access.'); + + $params = $this->initParameters('apirole_list'); + + // get row data + $em = $this->getDoctrine()->getManager(); + $row = $em->getRepository(APIRole::class)->find($id); + + if (empty($row)) + throw $this->createNotFoundException('The item does not exist'); + + // delete this row + $em->remove($row); + $em->flush(); + + // response + $response = new Response(); + $response->setStatusCode(Response::HTTP_OK); + $response->send(); + } + + protected function padAPIACLHierarchy(&$params) { // get acl keys hierarchy - $acl_data = $this->acl_gen->getACL(); - $params['acl_hierarchy'] = $acl_data['hierarchy']; + $api_acl_data = $this->api_acl_gen->getACL(); + $params['api_acl_hierarchy'] = $api_acl_data['hierarchy']; } // check if datatable filter is present and append to query @@ -145,7 +321,4 @@ class APIRoleController extends BaseController ->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%'); } } - - - } diff --git a/templates/api-role/form.html.twig b/templates/api-role/form.html.twig new file mode 100644 index 00000000..ae79ba34 --- /dev/null +++ b/templates/api-role/form.html.twig @@ -0,0 +1,165 @@ +{% extends 'base.html.twig' %} + +{% block body %} + +
+
+
+

API Roles

+
+
+
+ +
+ +
+
+
+
+
+
+ + + +

+ {% if mode == 'update' %} + Edit API Role + {{ obj.getID() }} + {% else %} + New API Role + {% endif %} +

+
+
+
+
+
+
+ +
+ + + Unique identifier for this role +
+
+
+ +
+ + + Display name for this role +
+
+
+ +
+
+ {% for api_acl_layer in api_acl_hierarchy %} + {{ api_acl_layer.label }}
+ {% for key, label in api_acl_layer.acls %} + + {% endfor %} +
+ {% endfor %} +
+
+
+
+
+
+
+
+ + Back +
+
+
+
+
+
+
+
+
+{% endblock %} + +{% block scripts %} + +{% endblock %} +