Skip to content
Snippets Groups Projects
DatasetListByInstanceAction.php 3.83 KiB
Newer Older
  • Learn to ignore specific revisions
  • François Agneray's avatar
    François Agneray committed
    <?php
    
    /*
     * This file is part of Anis Server.
     *
     * (c) Laboratoire d'Astrophysique de Marseille / CNRS
     *
     * For the full copyright and license information, please view the LICENSE
     * file that was distributed with this source code.
     */
    declare(strict_types=1);
    
    namespace App\Action;
    
    
    use Psr\Http\Message\ServerRequestInterface;
    use Psr\Http\Message\ResponseInterface;
    
    François Agneray's avatar
    François Agneray committed
    use Doctrine\ORM\EntityManagerInterface;
    use Slim\Exception\HttpNotFoundException;
    
    /**
     * @author François Agneray <francois.agneray@lam.fr>
     * @package App\Action
     */
    final class DatasetListByInstanceAction extends AbstractAction
    {
        /**
         * Contains settings to handle Json Web Token
         *
         * @var array
         */
        private $settings;
    
        /**
         * Create the classe before call __invoke to execute the action
         *
         * @param EntityManagerInterface $em Doctrine Entity Manager Interface
         * @param array $settings Settings about token
         */
        public function __construct(EntityManagerInterface $em, array $settings)
        {
            parent::__construct($em);
            $this->settings = $settings;
        }
    
        /**
         * `GET`  Returns a list of all datasets for a given instance
         *
         * @param  ServerRequestInterface $request  PSR-7 This object represents the HTTP request
         * @param  ResponseInterface      $response PSR-7 This object represents the HTTP response
         * @param  string[]               $args     This table contains information transmitted in the URL (see routes.php)
         *
         * @return ResponseInterface
         */
    
        public function __invoke(
            ServerRequestInterface $request,
            ResponseInterface $response,
            array $args
        ): ResponseInterface {
    
    François Agneray's avatar
    François Agneray committed
            if ($request->getMethod() === OPTIONS) {
                return $response->withHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
            }
    
            $instance = $this->em->find('App\Entity\Instance', $args['name']);
    
            // Returns HTTP 404 if the dataset is not found
            if (is_null($instance)) {
                throw new HttpNotFoundException(
                    $request,
                    'Instance with name ' . $args['name'] . ' is not found'
                );
            }
    
            if ($request->getMethod() === GET) {
                $token = $request->getAttribute('token');
    
                $qb = $this->em->createQueryBuilder();
                $qb->select('d')
                    ->from('App\Entity\Dataset', 'd')
                    ->join('d.datasetFamily', 'f')
                    ->where($qb->expr()->eq('IDENTITY(f.instance)', ':instanceName'));
    
                if (boolval($this->settings['enabled'])) {
                    if (!$token) {
                        // If user is not connected return public datasets
                        $qb->andWhere($qb->expr()->eq('d.public', 'true'));
                    } else {
    
                        $adminRoles = explode(',', $this->settings['admin_roles']);
    
    François Agneray's avatar
    François Agneray committed
                        $roles = $token->realm_access->roles;
    
                        if (!$this->isAdmin($adminRoles, $roles)) {
    
    François Agneray's avatar
    François Agneray committed
                            // If user is not an admin return public datasets
                            // And returns datasets from user's groups
                            $qb->andWhere($qb->expr()->eq('d.public', 'true'));
                            $qb2 = $this->em->createQueryBuilder();
                            $qb2->select('d2.name')
    
                                ->from('App\Entity\DatasetGroup', 'g')
    
    François Agneray's avatar
    François Agneray committed
                                ->join('g.datasets', 'd2')
                                ->where($qb2->expr()->in('g.role', $roles));
                            $qb->orWhere($qb->expr()->in('d.name', $qb2->getDQL()));
                        }
                    }
                }
    
                $qb->setParameter('instanceName', $instance->getName());
                $datasets = $qb->getQuery()->getResult();
                $payload = json_encode($datasets);
            }
    
            $response->getBody()->write($payload);
            return $response;
        }
    }