src/Controller/ApiClientController.php line 198

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\ApiClient;
  4. use App\Form\ApiClientType;
  5. use App\Repository\ApiClientRepository;
  6. use App\Repository\ApiRequestLogRepository;
  7. use App\Repository\QuestionApplicationRepository;
  8. use App\Repository\SettingsRepository;
  9. use App\Service\Api\EndpointCatalog;
  10. use App\Service\Api\IpWhitelistChecker;
  11. use App\Service\Api\TokenGenerator;
  12. use Doctrine\ORM\EntityManagerInterface;
  13. use Knp\Snappy\Pdf;
  14. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpFoundation\Response;
  17. use Symfony\Component\Routing\Annotation\Route;
  18. use Symfony\Component\String\Slugger\SluggerInterface;
  19. /**
  20.  * @Route("/api-client")
  21.  */
  22. class ApiClientController extends AbstractController
  23. {
  24.     /**
  25.      * @Route("/", name="api_client_index", methods={"GET"})
  26.      */
  27.     public function index(ApiClientRepository $clientsApiRequestLogRepository $logs): Response
  28.     {
  29.         $this->denyAccessUnlessGranted('ROLE_ADMIN');
  30.         $all $clients->findBy([], ['name' => 'ASC']);
  31.         $since = (new \DateTime())->modify('-24 hours');
  32.         $stats = [];
  33.         foreach ($all as $c) {
  34.             $stats[$c->getId()] = $logs->countByClientSince($c$since);
  35.         }
  36.         return $this->render('api_client/index.html.twig', [
  37.             'clients' => $all,
  38.             'stats_24h' => $stats,
  39.         ]);
  40.     }
  41.     /**
  42.      * @Route("/new", name="api_client_new", methods={"GET", "POST"})
  43.      */
  44.     public function new(Request $requestEntityManagerInterface $emTokenGenerator $tokensIpWhitelistChecker $ipCheck): Response
  45.     {
  46.         $this->denyAccessUnlessGranted('ROLE_ADMIN');
  47.         $client = new ApiClient();
  48.         $form $this->createForm(ApiClientType::class, $client);
  49.         $form->handleRequest($request);
  50.         if ($form->isSubmitted() && $form->isValid()) {
  51.             [$rules$errors] = $ipCheck->parseRules($form->get('ipWhitelistText')->getData());
  52.             if (count($errors) > 0) {
  53.                 foreach ($errors as $e) {
  54.                     $this->addFlash('error'$e);
  55.                 }
  56.                 return $this->render('api_client/new.html.twig', ['form' => $form->createView()]);
  57.             }
  58.             $client->setIpWhitelist(count($rules) > $rules null);
  59.             $client->setCreatedBy($this->getUser());
  60.             $raw $tokens->generateRaw(TokenGenerator::PREFIX_LIVE);
  61.             $client->setTokenHash($tokens->hash($raw));
  62.             $client->setTokenLookup($tokens->lookup($raw));
  63.             $client->setTokenPrefix($tokens->prefixOf($raw));
  64.             $em->persist($client);
  65.             $em->flush();
  66.             $this->addFlash('success''API client "' $client->getName() . '" is aangemaakt.');
  67.             $request->getSession()->set('api_client_raw_token_' $client->getId(), $raw);
  68.             return $this->redirectToRoute('api_client_show', ['id' => $client->getId(), 'justCreated' => 1]);
  69.         }
  70.         return $this->render('api_client/new.html.twig', ['form' => $form->createView()]);
  71.     }
  72.     /**
  73.      * @Route("/{id}", name="api_client_show", methods={"GET"}, requirements={"id"="\d+"})
  74.      */
  75.     public function show(ApiClient $clientRequest $requestApiRequestLogRepository $logs): Response
  76.     {
  77.         $this->denyAccessUnlessGranted('ROLE_ADMIN');
  78.         $justCreated $request->query->getBoolean('justCreated');
  79.         $rawToken null;
  80.         if ($justCreated) {
  81.             $rawToken $request->getSession()->remove('api_client_raw_token_' $client->getId());
  82.         }
  83.         $since24 = (new \DateTime())->modify('-24 hours');
  84.         $stats = [
  85.             'total_24h' => $logs->countByClientSince($client$since24),
  86.             'errors_4xx_24h' => $logs->countErrorsByClientSince($client$since24400499),
  87.             'errors_5xx_24h' => $logs->countErrorsByClientSince($client$since24500599),
  88.         ];
  89.         $daily $logs->dailyCountForClient($client30);
  90.         $recent $logs->findRecentByClient($client50);
  91.         return $this->render('api_client/show.html.twig', [
  92.             'client' => $client,
  93.             'rawToken' => $rawToken,
  94.             'stats' => $stats,
  95.             'daily' => $daily,
  96.             'recentLogs' => $recent,
  97.         ]);
  98.     }
  99.     /**
  100.      * @Route("/{id}/edit", name="api_client_edit", methods={"GET", "POST"}, requirements={"id"="\d+"})
  101.      */
  102.     public function edit(Request $requestApiClient $clientEntityManagerInterface $emIpWhitelistChecker $ipCheck): Response
  103.     {
  104.         $this->denyAccessUnlessGranted('ROLE_ADMIN');
  105.         $form $this->createForm(ApiClientType::class, $client);
  106.         $rules $client->getIpWhitelist();
  107.         $form->get('ipWhitelistText')->setData($rules implode("\n"$rules) : '');
  108.         $form->handleRequest($request);
  109.         if ($form->isSubmitted() && $form->isValid()) {
  110.             [$parsedRules$errors] = $ipCheck->parseRules($form->get('ipWhitelistText')->getData());
  111.             if (count($errors) > 0) {
  112.                 foreach ($errors as $e) {
  113.                     $this->addFlash('error'$e);
  114.                 }
  115.                 return $this->render('api_client/edit.html.twig', [
  116.                     'form' => $form->createView(),
  117.                     'client' => $client,
  118.                 ]);
  119.             }
  120.             $client->setIpWhitelist(count($parsedRules) > $parsedRules null);
  121.             $em->flush();
  122.             $this->addFlash('success''Instellingen bijgewerkt.');
  123.             return $this->redirectToRoute('api_client_show', ['id' => $client->getId()]);
  124.         }
  125.         return $this->render('api_client/edit.html.twig', [
  126.             'form' => $form->createView(),
  127.             'client' => $client,
  128.         ]);
  129.     }
  130.     /**
  131.      * @Route("/{id}/suspend", name="api_client_suspend", methods={"POST"}, requirements={"id"="\d+"})
  132.      */
  133.     public function suspend(Request $requestApiClient $clientEntityManagerInterface $em): Response
  134.     {
  135.         $this->denyAccessUnlessGranted('ROLE_ADMIN');
  136.         $reason trim((string) $request->request->get('reason'''));
  137.         $client->setSuspended(true);
  138.         $client->setSuspendReason($reason ?: null);
  139.         $em->flush();
  140.         $this->addFlash('success''Client opgeschort.');
  141.         return $this->redirectToRoute('api_client_show', ['id' => $client->getId()]);
  142.     }
  143.     /**
  144.      * @Route("/{id}/resume", name="api_client_resume", methods={"POST"}, requirements={"id"="\d+"})
  145.      */
  146.     public function resume(ApiClient $clientEntityManagerInterface $em): Response
  147.     {
  148.         $this->denyAccessUnlessGranted('ROLE_ADMIN');
  149.         $client->setSuspended(false);
  150.         $client->setSuspendReason(null);
  151.         $em->flush();
  152.         $this->addFlash('success''Client opnieuw geactiveerd.');
  153.         return $this->redirectToRoute('api_client_show', ['id' => $client->getId()]);
  154.     }
  155.     /**
  156.      * @Route("/{id}/revoke", name="api_client_revoke", methods={"POST"}, requirements={"id"="\d+"})
  157.      */
  158.     public function revoke(Request $requestApiClient $clientEntityManagerInterface $em): Response
  159.     {
  160.         $this->denyAccessUnlessGranted('ROLE_ADMIN');
  161.         $confirm = (string) $request->request->get('confirm_name''');
  162.         if ($confirm !== $client->getName()) {
  163.             $this->addFlash('error''Bevestig door de naam exact in te typen.');
  164.             return $this->redirectToRoute('api_client_show', ['id' => $client->getId()]);
  165.         }
  166.         $client->setStatus(0);
  167.         $em->flush();
  168.         $this->addFlash('success''Client ingetrokken (key werkt niet meer).');
  169.         return $this->redirectToRoute('api_client_index');
  170.     }
  171.     /**
  172.      * @Route("/docs.pdf", name="api_client_docs_pdf", methods={"GET"})
  173.      */
  174.     public function docsPdf(
  175.         QuestionApplicationRepository $apps,
  176.         EndpointCatalog $catalog,
  177.         SettingsRepository $settings,
  178.         Pdf $snappy,
  179.         SluggerInterface $slugger
  180.     ): Response {
  181.         $this->denyAccessUnlessGranted('ROLE_ADMIN');
  182.         $domainSetting $settings->findOneBy(['name' => 'domain']);
  183.         $domain $domainSetting rtrim($domainSetting->getValue(), '/') : 'https://dev.jotop.nl';
  184.         $applications $apps->findAllApiEnabled();
  185.         $html $this->renderView('api_client/docs_pdf.html.twig', [
  186.             'domain' => $domain,
  187.             'applications' => $applications,
  188.             'endpoints' => $catalog->list(),
  189.             'generatedAt' => new \DateTime(),
  190.         ]);
  191.         $slug $slugger->slug('jotop-api-v1-docs-' date('Ymd'));
  192.         $filename $slug '-' uniqid();
  193.         $path $this->getParameter('kernel.project_dir') . '/public/downloads/' $filename '.pdf';
  194.         $snappy->setOption('encoding''UTF-8');
  195.         $snappy->setOption('margin-top'18);
  196.         $snappy->setOption('margin-bottom'18);
  197.         $snappy->setOption('margin-left'15);
  198.         $snappy->setOption('margin-right'15);
  199.         $snappy->generateFromHtml($html$path, [], true);
  200.         return $this->file($path'Jotop-API-v1-documentatie.pdf');
  201.     }
  202. }