src/Platform/SecurityBundle/Controller/Dashboard/AccountsController.php line 237

Open in your IDE?
  1. <?php
  2. namespace Platform\SecurityBundle\Controller\Dashboard;
  3. use App\Controller\Dashboard\Settings\AccountController;
  4. use Cms\BulletinBundle\Model\Bulletins\AccountCreationBulletin;
  5. use Cms\BulletinBundle\Model\Bulletins\PasswordResetBulletin;
  6. use Cms\BulletinBundle\Service\BulletinService;
  7. use Cms\ContainerBundle\Doctrine\ContainerRepository;
  8. use Cms\ContainerBundle\Doctrine\Containers\GenericContainerRepository;
  9. use Cms\ContainerBundle\Doctrine\Containers\IntranetContainerRepository;
  10. use Cms\ContainerBundle\Entity\Container;
  11. use Cms\ContainerBundle\Entity\Containers\GenericContainer;
  12. use Cms\ContainerBundle\Entity\Containers\IntranetContainer;
  13. use Cms\CoreBundle\Model\Scenes\DashboardScenes\AjaxScene;
  14. use Cms\CoreBundle\Model\Scenes\DashboardScenes\DocumentScene;
  15. use Cms\CoreBundle\Service\ContextManager;
  16. use Cms\CoreBundle\Util\Controller;
  17. use Cms\CoreBundle\Util\DateTimeUtils;
  18. use Cms\CoreBundle\Util\Doctrine\EntityRepository;
  19. use Cms\FileBundle\Service\FileManager;
  20. use Cms\TenantBundle\Model\ProductsBitwise;
  21. use Platform\SecurityBundle\Doctrine\Access\GroupAccountRepository;
  22. use Platform\SecurityBundle\Doctrine\Access\RoleAssociation\AccountRoleAssociationRepository;
  23. use Platform\SecurityBundle\Doctrine\Access\RoleRepository;
  24. use Platform\SecurityBundle\Doctrine\Identity\AccountRepository;
  25. use Platform\SecurityBundle\Doctrine\Identity\GroupRepository;
  26. use Platform\SecurityBundle\Entity\Access\GroupAccount;
  27. use Platform\SecurityBundle\Entity\Access\Role;
  28. use Platform\SecurityBundle\Entity\Access\RoleAssociation;
  29. use Platform\SecurityBundle\Entity\Access\RoleAssociation\AccountRoleAssociation;
  30. use Platform\SecurityBundle\Entity\Identity\Account;
  31. use Platform\SecurityBundle\Entity\Identity\Group;
  32. use Platform\SecurityBundle\Form\Type\Access\PermissionsAuditType;
  33. use Platform\SecurityBundle\Form\Type\Identity\AccountLocaleType;
  34. use Platform\SecurityBundle\Form\Type\Identity\AccountType;
  35. use Platform\SecurityBundle\Form\Type\Profiles\GroupsType;
  36. use Platform\SecurityBundle\Form\Type\Profiles\RolesType;
  37. use Platform\SecurityBundle\Form\Type\Profiles\SpecialPermissionsType;
  38. use Platform\SecurityBundle\Model\Permission;
  39. use Platform\SecurityBundle\Model\Permissions;
  40. use Platform\SecurityBundle\Service\PasswordService;
  41. use Platform\SecurityBundle\Service\Reporters\AccountReporter;
  42. use Platform\SecurityBundle\Service\Search\AccountSearcher;
  43. use Platform\SecurityBundle\Service\Sentry;
  44. use Symfony\Component\Routing\Annotation\Route;
  45. use Symfony\Component\HttpFoundation\RedirectResponse;
  46. use Symfony\Component\HttpFoundation\Request;
  47. use Symfony\Component\HttpFoundation\Response;
  48. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  49. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  50. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  51. /**
  52.  * Class AccountsController
  53.  * @package Platform\SecurityBundle\Controller\Dashboard
  54.  */
  55. final class AccountsController extends Controller
  56. {
  57.     const ROUTES__LIST 'campussuite.platform.security.dashboard.accounts.list';
  58.     const ROUTES__LIST_LAZY 'campussuite.platform.security.dashboard.accounts.list_lazy';
  59.     const ROUTES__CREATE 'campussuite.platform.security.dashboard.accounts.create';
  60.     const ROUTES__VIEW 'campussuite.platform.security.dashboard.accounts.view';
  61.     const ROUTES__EDIT 'campussuite.platform.security.dashboard.accounts.edit';
  62.     const ROUTES__EDIT_LOCALE 'campussuite.platform.security.dashboard.accounts.edit_locale';
  63.     const ROUTES__REACTIVATE 'campussuite.platform.security.dashboard.accounts.reactivate';
  64.     const ROUTES__DEACTIVATE 'campussuite.platform.security.dashboard.accounts.deactivate';
  65.     const ROUTES__ASSIGN_ROLES 'campussuite.platform.security.dashboard.accounts.assign_roles';
  66.     const ROUTES__REMOVE_ROLES 'campussuite.platform.security.dashboard.accounts.remove_roles';
  67.     const ROUTES__ASSIGN_GROUPS 'campussuite.platform.security.dashboard.accounts.assign_groups';
  68.     const ROUTES__REMOVE_GROUPS 'campussuite.platform.security.dashboard.accounts.remove_groups';
  69.     const ROUTES__MANAGE_PASSWORD 'campussuite.platform.security.dashboard.accounts.manage_password';
  70.     const ROUTES__RESET_PASSWORD 'campussuite.platform.security.dashboard.accounts.reset_password';
  71.     const ROUTES__CLEAR_PASSWORD 'campussuite.platform.security.dashboard.accounts.clear_password';
  72.     const ROUTES__CREDENTIALS 'campussuite.platform.security.dashboard.accounts.credentials';
  73.     const ROUTES__SPECIAL_PERMISSIONS 'campussuite.platform.security.dashboard.accounts.special_permissions';
  74.     const ROUTES__AUDIT 'campussuite.platform.security.dashboard.accounts.audit';
  75.     const ROUTES__EXPORT_XLSX 'campussuite.platform.security.dashboard.accounts.export_xlsx';
  76.     const DEFAULT_COUNT 200;
  77.     /**
  78.      * @return AccountRepository|EntityRepository
  79.      */
  80.     private function getAccountRepository()
  81.     {
  82.         return $this->getRepository(Account::class);
  83.     }
  84.     /**
  85.      * @return RoleRepository|EntityRepository
  86.      */
  87.     private function getRoleRepository()
  88.     {
  89.         return $this->getRepository(Role\CmsRole::class);
  90.     }
  91.     /**
  92.      * @return AccountRoleAssociationRepository|EntityRepository
  93.      */
  94.     private function getAccountRoleAssociationRepository()
  95.     {
  96.         return $this->getRepository(AccountRoleAssociation::class);
  97.     }
  98.     /**
  99.      * @return GroupRepository|EntityRepository
  100.      */
  101.     private function getGroupRepository()
  102.     {
  103.         return $this->getRepository(Group::class);
  104.     }
  105.     /**
  106.      * @return GroupAccountRepository|EntityRepository
  107.      */
  108.     private function getGroupAccountRepository()
  109.     {
  110.         return $this->getRepository(GroupAccount::class);
  111.     }
  112.     /**
  113.      * @return ContainerRepository|EntityRepository
  114.      */
  115.     private function getContainerRepository()
  116.     {
  117.         return $this->getRepository(Container::class);
  118.     }
  119.     /**
  120.      * @return GenericContainerRepository|EntityRepository
  121.      */
  122.     private function getGenericContainerRepository()
  123.     {
  124.         return $this->getRepository(GenericContainer::class);
  125.     }
  126.     /**
  127.      * @return IntranetContainerRepository|EntityRepository
  128.      */
  129.     private function getIntranetContainerRepository()
  130.     {
  131.         return $this->getRepository(IntranetContainer::class);
  132.     }
  133.     /**
  134.      * @return BulletinService|object
  135.      */
  136.     private function getBulletinService(): BulletinService
  137.     {
  138.         return $this->get(__METHOD__);
  139.     }
  140.     /**
  141.      * @return Sentry|object
  142.      */
  143.     private function getSentry(): Sentry
  144.     {
  145.         return $this->get(__METHOD__);
  146.     }
  147.     /**
  148.      * @return FileManager|object
  149.      */
  150.     private function getFileManager(): FileManager
  151.     {
  152.         return $this->get(__METHOD__);
  153.     }
  154.     /**
  155.      * @return AccountReporter|object
  156.      */
  157.     private function getAccountReporter(): AccountReporter
  158.     {
  159.         return $this->get(__METHOD__);
  160.     }
  161.     /**
  162.      * @return AccountSearcher|object
  163.      */
  164.     private function getAccountSearcher(): AccountSearcher
  165.     {
  166.         return $this->get(__METHOD__);
  167.     }
  168.     /**
  169.      * @return PasswordService|object
  170.      */
  171.     private function getPasswordService(): PasswordService
  172.     {
  173.         return $this->get(__METHOD__);
  174.     }
  175.     /**
  176.      * @param Account $account
  177.      * @param string|null $password
  178.      * @return array|bool
  179.      */
  180.     private function sendCreateEmail(Account $account, ?string $password null)
  181.     {
  182.         return $this->getBulletinService()->send(
  183.             (new AccountCreationBulletin())
  184.                 ->setTo($account)
  185.                 ->setAccount($account)
  186.                 ->setPassword($password)
  187.                 ->setDashboard($this->getGlobalContext()->getDashboardUrl())
  188.         );
  189.     }
  190.     /**
  191.      * @param Account $account
  192.      * @param string $password
  193.      * @return array|bool
  194.      */
  195.     private function sendResetPasswordEmail(Account $accountstring $password)
  196.     {
  197.         return $this->getBulletinService()->send(
  198.             (new PasswordResetBulletin())
  199.                 ->setTo($account)
  200.                 ->setAccount($account)
  201.                 ->setPassword($password)
  202.                 ->setDashboard($this->getGlobalContext()->getDashboardUrl())
  203.         );
  204.     }
  205.     /**
  206.      * @param Request $request
  207.      * @return DocumentScene|AjaxScene|RedirectResponse
  208.      *
  209.      * @Route("/", name = AccountsController::ROUTES__LIST)
  210.      * @Route(
  211.      *     "/lazyload",
  212.      *     name = AccountsController::ROUTES__LIST_LAZY
  213.      * )
  214.      */
  215.     public function listAction(Request $request)
  216.     {
  217.         // AUDIT
  218.         $this->denyAccessUnlessGranted('campussuite.platform.security.accounts.manage');
  219.         if ($request->get('_route') == self::ROUTES__LIST_LAZY && ! $request->isXmlHttpRequest()) {
  220.             throw new NotFoundHttpException();
  221.         }
  222.         // if we are in sn migrated mode, jump to the newer areas
  223.         if ($this->getContextManager()->getGlobalContext()->getTenant()->getProducts()->hasFlag(ProductsBitwise::SCHOOLNOW__MIGRATED)) {
  224.             return $this->redirectToRoute(AccountController::ROUTES__MAIN);
  225.         }
  226.         $search $this->getAccountSearcher()->handleRequest($request);
  227.         if ($search instanceof RedirectResponse) {
  228.             return $search;
  229.         }
  230.         $accounts $this->getAccountRepository()->search($search);
  231.         if ($request->isXmlHttpRequest()) {
  232.             return $this->viewAjax(
  233.                 '@PlatformSecurity/Dashboard/Accounts/listLazy.html.twig',
  234.                 array(
  235.                     'accounts' => $accounts,
  236.                     'search' => $search,
  237.                 )
  238.             );
  239.         }
  240.         return $this->view(
  241.             array(
  242.                 'accounts' => $accounts,
  243.                 'search' => $search,
  244.             )
  245.         );
  246.     }
  247.     /**
  248.      * @param Request $request
  249.      * @return DocumentScene|RedirectResponse
  250.      *
  251.      * @Route("/create", name = AccountsController::ROUTES__CREATE)
  252.      */
  253.     public function createAction(Request $request)
  254.     {
  255.         // AUDIT
  256.         $this->denyAccessUnlessGranted('campussuite.platform.security.accounts.manage');
  257.         // create new object
  258.         $account = new Account();
  259.         // create form for creation
  260.         $form $this->createForm(
  261.             AccountType::class,
  262.             $account,
  263.             array(
  264.                 'password' => false,
  265.                 'notify' => ($this->getGlobalContext()->getTenant()->getProducts()->getMask() !== ProductsBitwise::SMM__BASE),
  266.             )
  267.         );
  268.         // check for submission
  269.         if ($this->handleForm($form$request)) {
  270.             // merge form data to object
  271.             /** @var Account $account */
  272.             $account $form->getData();
  273.             try {
  274.                 // attempt to get a password and set it if given
  275.                 $password $form->get('password')->getData();
  276.                 if ( ! empty($password)) {
  277.                     $account->setPasswordRaw($password);
  278.                 }
  279.                 // save to db
  280.                 $this->getEntityManager()->save($account);
  281.                 if ($form->get('notify')->getData() === true) {
  282.                     $this->sendCreateEmail($account$password);
  283.                 }
  284.                 // record log
  285.                 $this->getActivityLogger()->createLog($account);
  286.                 $this->getSession()->getFlashBag()->add('success''Account was successfully saved.');
  287.                 // go to view page
  288.                 return $this->redirectToRoute(
  289.                     self::ROUTES__VIEW,
  290.                     array(
  291.                         'accountId' => $account->getId(),
  292.                     )
  293.                 );
  294.             } catch (\Exception $e) {
  295.                 $this->getSession()->getFlashBag()->add('danger'$e->getMessage());
  296.             }
  297.         }
  298.         return $this->view(
  299.             array(
  300.                 'form' => $form->createView(),
  301.             )
  302.         );
  303.     }
  304.     /**
  305.      * @param $accountId
  306.      * @return DocumentScene
  307.      * @throws \Exception
  308.      *
  309.      * @Route(
  310.      *  "/{accountId}",
  311.      *  name = AccountsController::ROUTES__VIEW,
  312.      *  requirements = {
  313.      *      "accountId" = "[1-9]\d*"
  314.      *  }
  315.      * )
  316.      */
  317.     public function viewAction($accountId)
  318.     {
  319.         // obtain the account
  320.         $account $this->getAccountRepository()->findExact($accountId);
  321.         // AUDIT
  322.         $this->denyAccessUnlessGranted(
  323.             'campussuite.platform.security.accounts.manage',
  324.             array($accountnull)
  325.         );
  326.         return $this->view(
  327.             array(
  328.                 'account' => $account,
  329.             )
  330.         );
  331.     }
  332.     /**
  333.      * @param $accountId
  334.      * @return DocumentScene|RedirectResponse
  335.      * @throws \Exception
  336.      *
  337.      * @Route(
  338.      *  "/{accountId}/edit",
  339.      *  name = AccountsController::ROUTES__EDIT,
  340.      *  requirements = {
  341.      *      "accountId" = "[1-9]\d*"
  342.      *  }
  343.      * )
  344.      */
  345.     public function editAction($accountId)
  346.     {
  347.         // load the account
  348.         $account $this->getAccountRepository()->findExact($accountId);
  349.         // AUDIT
  350.         $this->denyAccessUnlessGranted(
  351.             'campussuite.platform.security.accounts.manage',
  352.             array($accountnull)
  353.         );
  354.         // check for oneroster
  355.         if ($account->isOneRoster()) {
  356.             throw new \Exception();
  357.         }
  358.         // form for edit
  359.         $form $this->createForm(AccountType::class, $account, array(
  360.             'password' => false,
  361.         ));
  362.         // check for submission
  363.         if ($this->handleForm($form)) {
  364.             // merge the form data
  365.             /** @var Account $account */
  366.             $account $form->getData();
  367.             try {
  368.                 // save to db
  369.                 $this->getEntityManager()->save($account);
  370.                 // it is, make the new credential
  371.                 $password $form->get('password')->getData();
  372.                 if ( ! empty($password)) {
  373.                     $this->getEntityManager()->save($account->setPasswordRaw($password));
  374.                     if ($form->get('notify')->getData() === true) {
  375.                         $this->sendResetPasswordEmail($account$password);
  376.                     }
  377.                 }
  378.                 // record log
  379.                 $this->getActivityLogger()->createLog($account);
  380.                 // go to viewing this one
  381.                 return $this->redirectToRoute(
  382.                     self::ROUTES__VIEW,
  383.                     array(
  384.                         'accountId' => $accountId,
  385.                     )
  386.                 );
  387.             } catch (\Exception $e) {
  388.                 $this->getSession()->getFlashBag()->add('danger'$e->getMessage());
  389.             }
  390.         }
  391.         return $this->view(
  392.             array(
  393.                 'account' => $account,
  394.                 'form' => $form->createView(),
  395.             )
  396.         );
  397.     }
  398.     /**
  399.      * @param Request $request
  400.      * @param $accountId
  401.      * @return DocumentScene|RedirectResponse
  402.      * @throws \Exception
  403.      *
  404.      * @Route(
  405.      *  "/{accountId}/edit-locale",
  406.      *  name = AccountsController::ROUTES__EDIT_LOCALE,
  407.      *  requirements = {
  408.      *      "accountId" = "[1-9]\d*"
  409.      *  }
  410.      * )
  411.      */
  412.     public function editLocaleAction(Request $request$accountId)
  413.     {
  414.         // load the account
  415.         $account $this->getAccountRepository()->findExact($accountId);
  416.         // AUDIT
  417.         $this->denyAccessUnlessGranted(
  418.             'campussuite.platform.security.accounts.manage',
  419.             array($accountnull)
  420.         );
  421.         // form for edit
  422.         $form $this->createForm(
  423.             AccountLocaleType::class,
  424.             $account
  425.         );
  426.         // check for submission
  427.         if ($request->isMethod('POST')) {
  428.             // merge the form data
  429.             /** @var Account $account */
  430.             $account $form->handleRequest($request)->getData();
  431.             try {
  432.                 // save to db
  433.                 $this->getEntityManager()->save($account);
  434.                 // record log
  435.                 $this->getActivityLogger()->createLog($account);
  436.                 // go to viewing this one
  437.                 return $this->redirectToRoute(
  438.                     self::ROUTES__VIEW,
  439.                     array(
  440.                         'accountId' => $accountId,
  441.                     )
  442.                 );
  443.             } catch (\Exception $e) {
  444.                 $this->getSession()->getFlashBag()->add('danger'$e->getMessage());
  445.             }
  446.         }
  447.         return $this->view(
  448.             array(
  449.                 'account' => $account,
  450.                 'form' => $form->createView(),
  451.             )
  452.         );
  453.     }
  454.     /**
  455.      * @param Request $request
  456.      * @param $accountId
  457.      * @return DocumentScene|RedirectResponse
  458.      * @throws \Exception
  459.      *
  460.      * @Route(
  461.      *  "/{accountId}/reactivate",
  462.      *  name = AccountsController::ROUTES__REACTIVATE,
  463.      *  requirements = {
  464.      *      "accountId" = "[1-9]\d*"
  465.      *  }
  466.      * )
  467.      */
  468.     public function reactivateAction(Request $request$accountId)
  469.     {
  470.         // obtain the account
  471.         $account $this->getAccountRepository()->findExact($accountId);
  472.         // AUDIT
  473.         $this->denyAccessUnlessGranted(
  474.             'campussuite.platform.security.accounts.manage',
  475.             array($accountnull)
  476.         );
  477.         // if the account is already active, we want to get away from here
  478.         if ($account->isActive()) {
  479.             return $this->redirectToRoute(self::ROUTES__LIST);
  480.         }
  481.         // check for submission
  482.         if ($request->isMethod('POST')) {
  483.             // force active state
  484.             $account->setActive(true);
  485.             // save to db
  486.             $this->getEntityManager()->save($account);
  487.             // log the change
  488.             $this->getActivityLogger()->createLog($account$accountId);
  489.             // go back
  490.             return $this->redirectToRoute(self::ROUTES__LIST);
  491.         }
  492.         return $this->view(
  493.             array(
  494.                 'account' => $account,
  495.             )
  496.         );
  497.     }
  498.     /**
  499.      * @param Request $request
  500.      * @param $accountId
  501.      * @return DocumentScene|RedirectResponse
  502.      * @throws \Exception
  503.      *
  504.      * @Route(
  505.      *  "/{accountId}/deactivate",
  506.      *  name = AccountsController::ROUTES__DEACTIVATE,
  507.      *  requirements = {
  508.      *      "accountId" = "[1-9]\d*"
  509.      *  }
  510.      * )
  511.      */
  512.     public function deactivateAction(Request $request$accountId)
  513.     {
  514.         // obtain the account
  515.         $account $this->getAccountRepository()->findExact($accountId);
  516.         // AUDIT
  517.         $this->denyAccessUnlessGranted(
  518.             'campussuite.platform.security.accounts.manage',
  519.             array($accountnull)
  520.         );
  521.         // if we are not active, we just want to get away from here as nothing to do
  522.         if ($account->isActive() === false) {
  523.             return $this->redirectToRoute(self::ROUTES__LIST);
  524.         }
  525.         // check for submission
  526.         if ($request->isMethod('POST')) {
  527.             // unset the active state
  528.             $account->setActive(false);
  529.             // save
  530.             $this->getEntityManager()->save($account);
  531.             // log the action
  532.             $this->getActivityLogger()->createLog($account$accountId);
  533.             // go back
  534.             return $this->redirectToRoute(self::ROUTES__LIST);
  535.         }
  536.         return $this->view(
  537.             array(
  538.                 'account' => $account,
  539.             )
  540.         );
  541.     }
  542.     /**
  543.      * @param $accountId
  544.      * @return DocumentScene|RedirectResponse
  545.      * @throws \Exception
  546.      *
  547.      * @Route(
  548.      *  "/{accountId}/manage-password",
  549.      *  name = AccountsController::ROUTES__MANAGE_PASSWORD,
  550.      *  requirements = {
  551.      *      "accountId" = "[1-9]\d*"
  552.      *  }
  553.      * )
  554.      */
  555.     public function managePasswordAction($accountId)
  556.     {
  557.         // load up the account
  558.         $account $this->getAccountRepository()->findExact($accountId);
  559.         // AUDIT
  560.         $this->denyAccessUnlessGranted(
  561.             'campussuite.platform.security.accounts.manage',
  562.             array($accountnull)
  563.         );
  564.         // if no password, disallow
  565.         if ( ! $account->canManagePassword()) {
  566.             throw new \Exception();
  567.         }
  568.         return $this->view(
  569.             array(
  570.                 'account' => $account,
  571.             )
  572.         );
  573.     }
  574.     /**
  575.      * @param Request $request
  576.      * @param $accountId
  577.      * @return DocumentScene|RedirectResponse
  578.      * @throws \Exception
  579.      *
  580.      * @Route(
  581.      *  "/{accountId}/reset-password",
  582.      *  name = AccountsController::ROUTES__RESET_PASSWORD,
  583.      *  requirements = {
  584.      *      "accountId" = "[1-9]\d*"
  585.      *  }
  586.      * )
  587.      */
  588.     public function resetPasswordAction(Request $request$accountId)
  589.     {
  590.         // load up the account
  591.         $account $this->getAccountRepository()->findExact($accountId);
  592.         // AUDIT
  593.         $this->denyAccessUnlessGranted(
  594.             'campussuite.platform.security.accounts.manage',
  595.             array($accountnull)
  596.         );
  597.         // if no password, disallow
  598.         if ( ! $account->canManagePassword()) {
  599.             throw new \Exception();
  600.         }
  601.         // handle the submission
  602.         if ($request->isMethod('POST')) {
  603.             // setup and send reset email
  604.             $this->getPasswordService()->sendResetPasswordInitEmail(
  605.                 $request,
  606.                 $account
  607.             );
  608.             // log this
  609.             $this->getActivityLogger()->createLog($account$accountId);
  610.             // go back to where we came
  611.             return $this->redirectToRoute(self::ROUTES__LIST);
  612.         }
  613.         throw new \Exception();
  614.     }
  615.     /**
  616.      * @param Request $request
  617.      * @param $accountId
  618.      * @return DocumentScene|RedirectResponse
  619.      * @throws \Exception
  620.      *
  621.      * @Route(
  622.      *  "/{accountId}/clear-password",
  623.      *  name = AccountsController::ROUTES__CLEAR_PASSWORD,
  624.      *  requirements = {
  625.      *      "accountId" = "[1-9]\d*"
  626.      *  }
  627.      * )
  628.      */
  629.     public function clearPasswordAction(Request $request$accountId)
  630.     {
  631.         // load up the account
  632.         $account $this->getAccountRepository()->findExact($accountId);
  633.         // AUDIT
  634.         $this->denyAccessUnlessGranted(
  635.             'campussuite.platform.security.accounts.manage',
  636.             array($accountnull)
  637.         );
  638.         // if no password, disallow
  639.         if ( ! $account->canManagePassword()) {
  640.             throw new \Exception();
  641.         }
  642.         // handle the submission
  643.         if ($request->isMethod('POST')) {
  644.             // wipe the password
  645.             $this->getEntityManager()->save(
  646.                 $account->setPassword(null)
  647.             );
  648.             // log this
  649.             $this->getActivityLogger()->createLog($account$accountId);
  650.             // go back to where we came
  651.             return $this->redirectToRoute(self::ROUTES__LIST);
  652.         }
  653.         throw new \Exception();
  654.     }
  655.     /**
  656.      * @param Request $request
  657.      * @param int $accountId
  658.      * @return DocumentScene|RedirectResponse
  659.      * @throws \Exception
  660.      *
  661.      * @Route(
  662.      *  "/{accountId}/assign-roles",
  663.      *  name = AccountsController::ROUTES__ASSIGN_ROLES,
  664.      *  requirements = {
  665.      *      "accountId" = "[1-9]\d*"
  666.      *  }
  667.      * )
  668.      */
  669.     public function assignRolesAction(Request $request$accountId)
  670.     {
  671.         // get the account
  672.         $account $this->getAccountRepository()->findExact($accountId);
  673.         // AUDIT
  674.         $this->denyAccessUnlessGranted(
  675.             'campussuite.platform.security.accounts.manage',
  676.             array($accountnull)
  677.         );
  678.         // grab all of the groups in the system
  679.         $roles $this->getRoleRepository()->findBy(array(), array(
  680.             'name' => 'ASC',
  681.         ));
  682.         // grab all of the current associations
  683.         $associations $this->getAccountRoleAssociationRepository()->findByAccount($account);
  684.         $form $this->createForm(RolesType::class, [], array(
  685.             'roles' => $roles,
  686.             'containers' => array_merge(
  687.                 $this->getGenericContainerRepository()->findAllHierarchy(),
  688.                 $this->getIntranetContainerRepository()->findAllHierarchy()
  689.             ),
  690.         ));
  691.         $form->handleRequest($request);
  692.         // check for submission
  693.         if ($request->isMethod('POST') && $data $form->getData()) {
  694.             $data['container'] = (isset($data['container']) && ! empty($data['container'])) ? $data['container'] : null;
  695.             $data['inheritance'] =
  696.                 (isset($data['inheritance']) && ! empty($data['inheritance']))
  697.                     ? $data['inheritance']
  698.                     : null;
  699.             if (empty($data['role'])) {
  700.                 $this->getSession()->getFlashBag()->add('danger''Please, choose role for account.');
  701.             } else {
  702.                 if (empty(
  703.                     $this->getAccountRoleAssociationRepository()
  704.                         ->findBy(
  705.                             array('account' => $account'role' => $data['role'], 'container' => $data['container'])
  706.                         )
  707.                 )) {
  708.                     $association = (new AccountRoleAssociation())
  709.                         ->setAccount($account)
  710.                         ->setRole($data['role']);
  711.                     if ($data['container']) {
  712.                         $association
  713.                             ->setContainer($data['container'])
  714.                             ->setInheritance($data['inheritance']);
  715.                     } else {
  716.                         $association
  717.                             ->setContainer(null)
  718.                             ->setInheritance(RoleAssociation::INHERITANCES__ME_ONLY);
  719.                     }
  720.                     $this->getEntityManager()->save($association);
  721.                     // record log
  722.                     $this->getActivityLogger()->createLog($association);
  723.                     $this->getSession()->getFlashBag()->add('success''Role has been added.');
  724.                     // go back to listing
  725.                     return $this->redirectToRoute(self::ROUTES__ASSIGN_ROLES, array('accountId' => $accountId));
  726.                 } else {
  727.                     $this->getSession()->getFlashBag()->add('danger''Role with this parameters already exist.');
  728.                 }
  729.             }
  730.         }
  731.         return $this->view(
  732.             array(
  733.                 'form' => $form->createView(),
  734.                 'account' => $account,
  735.                 'roles' => $roles,
  736.                 'associations' => $associations,
  737.             )
  738.         );
  739.     }
  740.     /**
  741.      * @param Request $request
  742.      * @param int $accountId
  743.      * @param int $associationId
  744.      * @return DocumentScene|RedirectResponse
  745.      * @throws \Exception
  746.      *
  747.      * @Route(
  748.      *  "/{accountId}/remove-roles/{associationId}",
  749.      *  name = AccountsController::ROUTES__REMOVE_ROLES,
  750.      *  requirements = {
  751.      *      "accountId" = "[1-9]\d*",
  752.      *      "associationId" = "[1-9]\d*"
  753.      *  }
  754.      * )
  755.      */
  756.     public function removeRolesAction(Request $request$accountId$associationId)
  757.     {
  758.         // get the account
  759.         $account $this->getAccountRepository()->findExact($accountId);
  760.         // AUDIT
  761.         $this->denyAccessUnlessGranted(
  762.             'campussuite.platform.security.accounts.manage',
  763.             array($accountnull)
  764.         );
  765.         // get association
  766.         $roleAssociation $this->getAccountRoleAssociationRepository()->findExact($associationId);
  767.         // check for submission
  768.         if ($request->isMethod('POST')) {
  769.             // do the deletion
  770.             $this->getEntityManager()->delete($roleAssociation);
  771.             // record log
  772.             $this->getActivityLogger()->createLog($roleAssociation$associationId);
  773.             $this->getSession()->getFlashBag()->add('danger''Role has been removed.');
  774.             // go back to list
  775.             return $this->redirectToRoute(self::ROUTES__ASSIGN_ROLES, array('accountId' => $accountId));
  776.         }
  777.         return $this->view(
  778.             array(
  779.                 'account' => $account,
  780.                 'roleAssociation' => $roleAssociation,
  781.             )
  782.         );
  783.     }
  784.     /**
  785.      * @param Request $request
  786.      * @param $accountId
  787.      * @return DocumentScene|RedirectResponse
  788.      * @throws \Exception
  789.      *
  790.      * @Route(
  791.      *  "/{accountId}/assign-groups",
  792.      *  name = AccountsController::ROUTES__ASSIGN_GROUPS,
  793.      *  requirements = {
  794.      *      "accountId" = "[1-9]\d*"
  795.      *  }
  796.      * )
  797.      */
  798.     public function assignGroupsAction(Request $request$accountId)
  799.     {
  800.         // get the account
  801.         $account $this->getAccountRepository()->findExact($accountId);
  802.         // AUDIT
  803.         $this->denyAccessUnlessGranted(
  804.             'campussuite.platform.security.groups.manage',
  805.             array($accountnull)
  806.         );
  807.         // grab all of the groups in the system
  808.         $groups $this->getGroupRepository()->findBy(array(), array(
  809.             'name' => 'ASC',
  810.         ));
  811.         // grab all of the current associations
  812.         $associations $this->getGroupAccountRepository()->findByAccount($account);
  813.         $form $this->createForm(
  814.             GroupsType::class,
  815.             null,
  816.             array(
  817.                 'groups' => $groups,
  818.             )
  819.         );
  820.         $form->handleRequest($request);
  821.         // check for submission
  822.         if ($request->isMethod('POST') && $data $form->getData()) {
  823.             if (empty($data['group'])) {
  824.                 $this->getSession()->getFlashBag()->add('danger''Please, choose group for account.');
  825.             } else {
  826.                 if (empty(
  827.                     $this->getGroupAccountRepository()->findBy(
  828.                         array('account' => $account'group' => $data['group'])
  829.                     )
  830.                 )) {
  831.                     $association = (new GroupAccount())
  832.                         ->setAccount($account)
  833.                         ->setGroup($data['group']);
  834.                     // AUDIT
  835.                     $this->denyAccessUnlessGranted(
  836.                         'campussuite.platform.security.groups.manage',
  837.                         array($data['group'], null)
  838.                     );
  839.                     $this->getEntityManager()->save($association);
  840.                     // record log
  841.                     $this->getActivityLogger()->createLog($association);
  842.                     $this->getSession()->getFlashBag()->add('success''Group has been added.');
  843.                     // go back to listing
  844.                     return $this->redirectToRoute(self::ROUTES__ASSIGN_GROUPS, array('accountId' => $accountId));
  845.                 } else {
  846.                     $this->getSession()->getFlashBag()->add('danger''Group with this parameters already exist.');
  847.                 }
  848.             }
  849.         }
  850.         return $this->view(
  851.             array(
  852.                 'form' => $form->createView(),
  853.                 'account' => $account,
  854.                 'groups' => $groups,
  855.                 'associations' => $associations,
  856.             )
  857.         );
  858.     }
  859.     /**
  860.      * @param Request $request
  861.      * @param int $accountId
  862.      * @param int $associationId
  863.      * @return DocumentScene|RedirectResponse
  864.      * @throws \Exception
  865.      *
  866.      * @Route(
  867.      *  "/{accountId}/remove-groups/{associationId}",
  868.      *  name = AccountsController::ROUTES__REMOVE_GROUPS,
  869.      *  requirements = {
  870.      *      "accountId" = "[1-9]\d*",
  871.      *      "associationId" = "[1-9]\d*"
  872.      *  }
  873.      * )
  874.      */
  875.     public function removeGroupsAction(Request $request$accountId$associationId)
  876.     {
  877.         // get the account
  878.         $account $this->getAccountRepository()->findExact($accountId);
  879.         // AUDIT
  880.         $this->denyAccessUnlessGranted(
  881.             'campussuite.platform.security.groups.manage',
  882.             array($accountnull)
  883.         );
  884.         // get association
  885.         $groupAssociation $this->getGroupAccountRepository()->findExact($associationId);
  886.         // AUDIT
  887.         $this->denyAccessUnlessGranted(
  888.             'campussuite.platform.security.groups.manage',
  889.             array($groupAssociationnull)
  890.         );
  891.         // check for submission
  892.         if ($request->isMethod('POST')) {
  893.             // do the deletion
  894.             $this->getEntityManager()->delete($groupAssociation);
  895.             // record log
  896.             $this->getActivityLogger()->createLog($groupAssociation$associationId);
  897.             $this->getSession()->getFlashBag()->add('danger''Group has been removed.');
  898.             // go back to list
  899.             return $this->redirectToRoute(self::ROUTES__ASSIGN_GROUPS, array('accountId' => $accountId));
  900.         }
  901.         return $this->view(
  902.             array(
  903.                 'account' => $account,
  904.                 'groupAssociation' => $groupAssociation,
  905.             )
  906.         );
  907.     }
  908.     /**
  909.      * @param Request $request
  910.      * @param int $accountId
  911.      * @return DocumentScene|RedirectResponse
  912.      * @throws \Exception
  913.      *
  914.      * @Route(
  915.      *  "/{accountId}/special-permissions",
  916.      *  name = AccountsController::ROUTES__SPECIAL_PERMISSIONS,
  917.      *  requirements = {
  918.      *      "accountId" = "[1-9]\d*",
  919.      *  }
  920.      * )
  921.      */
  922.     public function specialPermissionsAction(Request $request$accountId)
  923.     {
  924.         // only SuperAdmin can perform this action!
  925.         if( ! $this->getSentry()->isSuperAdmin($this->getContextManager()->getGlobalContext()->getEffectiveAccount())) {
  926.             throw new AccessDeniedException();
  927.         }
  928.         $account $this->getAccountRepository()->findExact($accountId);
  929.         $form $this->createForm(SpecialPermissionsType::class, $account);
  930.         if ($this->handleForm($form$request)) {
  931.             $this->getEntityManager()->save($account);
  932.             // record log
  933.             $this->getActivityLogger()->createLog($account);
  934.             return $this->redirectToRoute(
  935.                 self::ROUTES__VIEW,
  936.                 array(
  937.                     'accountId' => $accountId,
  938.                 )
  939.             );
  940.         }
  941.         return $this->view(
  942.             array(
  943.                 'form' => $form->createView(),
  944.                 'account' => $account,
  945.             )
  946.         );
  947.     }
  948.     /**
  949.      * @param int $accountId
  950.      * @param int $containerId
  951.      * @return DocumentScene
  952.      * @throws \Exception
  953.      *
  954.      * @Route(
  955.      *  "/{accountId}/audit/{containerId}",
  956.      *  name = AccountsController::ROUTES__AUDIT,
  957.      *  requirements = {
  958.      *      "accountId" = "[1-9]\d*",
  959.      *      "containerId" = "[1-9]\d*",
  960.      *  },
  961.      *  defaults = {
  962.      *      "containerId" = null
  963.      *  }
  964.      * )
  965.      */
  966.     public function auditAction($accountId$containerId)
  967.     {
  968.         $container $containerId $this->getContainerRepository()->find($containerId) : null;
  969.         // obtain all of the permissions available in the system
  970.         $permissionsArray $this->getParameter('platform.security.permissions');
  971.         // load the account
  972.         $account $this->getAccountRepository()->findExact($accountId);
  973.         $permissions = new Permissions();
  974.         foreach ($permissionsArray as $permission) {
  975.             $permissions->addPermission(
  976.                 (new Permission())
  977.                     ->setValue(
  978.                         $this->getSentry()->check(
  979.                             $account,
  980.                             $permission['key'],
  981.                             $container,
  982.                         )
  983.                     )
  984.                     ->setLabel($permission['name'])
  985.             );
  986.         }
  987.         $form $this->createForm(PermissionsAuditType::class, $permissions, array('container' => $container));
  988.         return $this->view(
  989.             array(
  990.                 'account' => $account,
  991.                 'form' => $form->createView(),
  992.             )
  993.         );
  994.     }
  995.     /**
  996.      * @return Response
  997.      *
  998.      * @Route("/export/xlsx", name = AccountsController::ROUTES__EXPORT_XLSX)
  999.      */
  1000.     public function exportAction()
  1001.     {
  1002.         // AUDIT
  1003.         $this->denyAccessUnlessGranted('campussuite.platform.security.accounts.manage');
  1004.         /** @var Account[] $accounts */
  1005.         $accounts $this->getAccountRepository()->findAll();
  1006.         $data $this->getAccountReporter()->generateAccountList($accounts);
  1007.         $response = new Response($data);
  1008.         $contentDisposition $response->headers->makeDisposition(
  1009.             ResponseHeaderBag::DISPOSITION_ATTACHMENT,
  1010.             sprintf(
  1011.                 'accounts-%s.xlsx',
  1012.                 DateTimeUtils::format(
  1013.                     DateTimeUtils::today(),
  1014.                     'Y-m-d'
  1015.                 )
  1016.             )
  1017.         );
  1018.         $response->headers->set('Content-Disposition'$contentDisposition);
  1019.         $response->headers->set(
  1020.             'Content-type',
  1021.             $this->getFileManager()->mimeByExtension('xlsx')
  1022.         );
  1023.         return $response;
  1024.     }
  1025. }