diff --git a/app/routes.php b/app/routes.php index 186616bcf870e882c0f4ba782bd9c5598ee0abf9..ae0f4bc7f6ea37e5ab4a91c466627e5d3d132ba4 100644 --- a/app/routes.php +++ b/app/routes.php @@ -47,7 +47,7 @@ $app->group('', function (RouteCollectorProxy $group) { '/dataset/{name}/attribute/{id}/distinct', App\Action\AttributeDistinctAction::class ); -})->add(new App\Middleware\AdminMiddleware()); +})->add(new App\Middleware\AdminMiddleware($container->get(SETTINGS)['token'])); $app->get('/search/{dname}', App\Action\SearchAction::class); $app->get('/download-file/{dname}/[{fpath:.*}]', App\Action\DownloadFileAction::class); diff --git a/app/settings.php b/app/settings.php index 711f051ff0e54b9e795006aab93075226c2f7112..7f55c640a8acc197ae086f47ac32a39effbf7ab4 100644 --- a/app/settings.php +++ b/app/settings.php @@ -31,7 +31,9 @@ return [ 'level' => getenv('LOGGER_LEVEL') ], 'token' => [ - 'issuer' => getenv('TOKEN_ISSUER'), - 'public_key_file' => getenv('TOKEN_PUBLIC_KEY_FILE') + //'issuer' => getenv('TOKEN_ISSUER'), + 'enabled' => getenv('TOKEN_ENABLED'), + 'public_key_file' => getenv('TOKEN_PUBLIC_KEY_FILE'), + 'admin_role' => getenv('TOKEN_ADMIN_ROLE') ] ]; diff --git a/docker-compose.yml b/docker-compose.yml index 1ac6ee621ccdb3981c2fc32edfb2ab04f8bb73bc..6d5d9d992cfd28023ed159ed0dc34dd21fc9d119 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,8 +17,9 @@ services: LOGGER_NAME: "anis-metamodel" LOGGER_PATH: "php://stderr" LOGGER_LEVEL: "debug" - TOKEN_ISSUER: http://localhost:8180/auth/realms/anis + TOKEN_ENABLED: 1 TOKEN_PUBLIC_KEY_FILE: /data/public_key + TOKEN_ADMIN_ROLE: anis_admin ports: - 8080:80 volumes: diff --git a/doctrine-proxy/__CG__AppEntityDataset.php b/doctrine-proxy/__CG__AppEntityDataset.php index f4530d3c63764deb8261217be725c9ac17f46773..49df6da3284f430e60ec08fe908580cd49932067 100644 --- a/doctrine-proxy/__CG__AppEntityDataset.php +++ b/doctrine-proxy/__CG__AppEntityDataset.php @@ -64,10 +64,10 @@ class Dataset extends \App\Entity\Dataset implements \Doctrine\ORM\Proxy\Proxy public function __sleep() { if ($this->__isInitialized__) { - return ['__isInitialized__', 'name', 'tableRef', 'label', 'description', 'display', 'count', 'vo', 'dataPath', 'selectableRow', 'project', 'datasetFamily', 'attributes']; + return ['__isInitialized__', 'name', 'tableRef', 'label', 'description', 'display', 'count', 'vo', 'dataPath', 'config', 'public', 'project', 'datasetFamily', 'attributes']; } - return ['__isInitialized__', 'name', 'tableRef', 'label', 'description', 'display', 'count', 'vo', 'dataPath', 'selectableRow', 'project', 'datasetFamily', 'attributes']; + return ['__isInitialized__', 'name', 'tableRef', 'label', 'description', 'display', 'count', 'vo', 'dataPath', 'config', 'public', 'project', 'datasetFamily', 'attributes']; } /** @@ -345,23 +345,45 @@ class Dataset extends \App\Entity\Dataset implements \Doctrine\ORM\Proxy\Proxy /** * {@inheritDoc} */ - public function getSelectableRow() + public function getConfig() { - $this->__initializer__ && $this->__initializer__->__invoke($this, 'getSelectableRow', []); + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getConfig', []); - return parent::getSelectableRow(); + return parent::getConfig(); } /** * {@inheritDoc} */ - public function setSelectableRow($selectableRow) + public function setConfig($config) { - $this->__initializer__ && $this->__initializer__->__invoke($this, 'setSelectableRow', [$selectableRow]); + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setConfig', [$config]); - return parent::setSelectableRow($selectableRow); + return parent::setConfig($config); + } + + /** + * {@inheritDoc} + */ + public function getPublic() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getPublic', []); + + return parent::getPublic(); + } + + /** + * {@inheritDoc} + */ + public function setPublic($public) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setPublic', [$public]); + + return parent::setPublic($public); } /** diff --git a/doctrine-proxy/__CG__AppEntityGroup.php b/doctrine-proxy/__CG__AppEntityGroup.php index d0cefd24106b2d1571627907be881e1553db5686..ffd63b0ecf3875039dc5aeaf26b4aee616b3768a 100644 --- a/doctrine-proxy/__CG__AppEntityGroup.php +++ b/doctrine-proxy/__CG__AppEntityGroup.php @@ -64,10 +64,10 @@ class Group extends \App\Entity\Group implements \Doctrine\ORM\Proxy\Proxy public function __sleep() { if ($this->__isInitialized__) { - return ['__isInitialized__', 'id', 'label', 'datasetPrivileges']; + return ['__isInitialized__', 'id', 'label', 'datasets']; } - return ['__isInitialized__', 'id', 'label', 'datasetPrivileges']; + return ['__isInitialized__', 'id', 'label', 'datasets']; } /** @@ -213,12 +213,23 @@ class Group extends \App\Entity\Group implements \Doctrine\ORM\Proxy\Proxy /** * {@inheritDoc} */ - public function getDatasetPrivileges() + public function getDatasets() { - $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDatasetPrivileges', []); + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getDatasets', []); - return parent::getDatasetPrivileges(); + return parent::getDatasets(); + } + + /** + * {@inheritDoc} + */ + public function setDatasets($datasets) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setDatasets', [$datasets]); + + return parent::setDatasets($datasets); } /** diff --git a/doctrine-proxy/__CG__AppEntityInstance.php b/doctrine-proxy/__CG__AppEntityInstance.php index 6d4e85d0a5729942088be87a8e9fb91af4d8abf9..9e0937f12f6a03a6d8e541a6b7417f927835df37 100644 --- a/doctrine-proxy/__CG__AppEntityInstance.php +++ b/doctrine-proxy/__CG__AppEntityInstance.php @@ -64,10 +64,10 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy public function __sleep() { if ($this->__isInitialized__) { - return ['__isInitialized__', 'name', 'label', 'clientUrl', 'datasetFamilies']; + return ['__isInitialized__', 'name', 'label', 'clientUrl', 'config', 'datasetFamilies']; } - return ['__isInitialized__', 'name', 'label', 'clientUrl', 'datasetFamilies']; + return ['__isInitialized__', 'name', 'label', 'clientUrl', 'config', 'datasetFamilies']; } /** @@ -232,6 +232,28 @@ class Instance extends \App\Entity\Instance implements \Doctrine\ORM\Proxy\Proxy return parent::setClientUrl($clientUrl); } + /** + * {@inheritDoc} + */ + public function getConfig() + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'getConfig', []); + + return parent::getConfig(); + } + + /** + * {@inheritDoc} + */ + public function setConfig($config) + { + + $this->__initializer__ && $this->__initializer__->__invoke($this, 'setConfig', [$config]); + + return parent::setConfig($config); + } + /** * {@inheritDoc} */ diff --git a/src/Action/GroupListAction.php b/src/Action/GroupListAction.php index 84bf07b968a9594bb58ebc4c796ff1eaaaa6c08c..b95832ef66fa8ddbd1eacde55dfd4ac2314b6106 100644 --- a/src/Action/GroupListAction.php +++ b/src/Action/GroupListAction.php @@ -45,7 +45,7 @@ final class GroupListAction extends AbstractAction $parsedBody = $request->getParsedBody(); // To work this action needs group information - foreach (array('label') as $a) { + foreach (array('label', 'datasets') as $a) { if ($this->isEmptyField($a, $parsedBody)) { throw new HttpBadRequestException( $request, @@ -70,10 +70,9 @@ final class GroupListAction extends AbstractAction */ private function postGroup(array $parsedBody): Group { - $group = new Group( - $this->getDatasets($parsedBody['datasets']) - ); + $group = new Group(); $group->setLabel($parsedBody['label']); + $group->setDatasets($this->getDatasets($parsedBody['datasets'])); $this->em->persist($group); $this->em->flush(); diff --git a/src/Entity/Group.php b/src/Entity/Group.php index 161ef31ac79cd72a4ff43f0d4a39d8b9ea0cc023..501d4e824e1ec91af40f390eefc38067607c6be0 100644 --- a/src/Entity/Group.php +++ b/src/Entity/Group.php @@ -12,9 +12,6 @@ declare(strict_types=1); namespace App\Entity; -use Doctrine\Common\Collections\Collection; -use Doctrine\Common\Collections\ArrayCollection; - /** * @Entity * @Table(name="anis_group") @@ -49,11 +46,6 @@ class Group implements \JsonSerializable */ protected $datasets; - public function __construct(array $datasets) - { - $this->datasets = new ArrayCollection($datasets); - } - public function getId() { return $this->id; diff --git a/src/Middleware/AdminMiddleware.php b/src/Middleware/AdminMiddleware.php index f05395e22bc697a12674163dcf1243d237ef2a2a..cdcdc7ec68fa96ccf80e10af398ae28482a50482 100644 --- a/src/Middleware/AdminMiddleware.php +++ b/src/Middleware/AdminMiddleware.php @@ -20,20 +20,50 @@ use Nyholm\Psr7\Response as NyholmResponse; final class AdminMiddleware implements MiddlewareInterface { + /** + * Contains settings to handle Json Web Token + * + * @var array + */ + private $settings; + + /** + * Create the classe before call process to execute this middleware + * + * @param array $settings Settings about token + */ + public function __construct(array $settings) + { + $this->settings = $settings; + } + public function process(Request $request, RequestHandler $handler): Response { - if ($request->getMethod() === OPTIONS || $request->getMethod() === GET) { + if ( + $request->getMethod() === OPTIONS + || $request->getMethod() === GET + || $this->settings['enabled'] === 0 + ) { return $handler->handle($request); } $token = $request->getAttribute('token'); if (!$token) { - return (new NyholmResponse())->withStatus(401); + return $this->getResponse('HTTP 401: This url need a valid token', 401); } - if (!in_array('anis_admin', $token->getClaim('realm_access')->roles)) { - return (new NyholmResponse())->withStatus(403); + if (!in_array($this->settings['admin_role'], $token->getClaim('realm_access')->roles)) { + return $this->getResponse('HTTP 403: This url need a higher level of permission', 403); } return $handler->handle($request); } + + private function getResponse(string $message, int $code) + { + $resonse = new NyholmResponse(); + $resonse->getBody()->write(json_encode(array( + 'message' => $message + ))); + return $resonse->withStatus($code); + } } diff --git a/src/Middleware/AuthorizationMiddleware.php b/src/Middleware/AuthorizationMiddleware.php index 53fe04320d88d60c984dae8921d38e1ab0a4ad12..8f660ef6d989a2af3b039f4eb220c7fe4528d5da 100644 --- a/src/Middleware/AuthorizationMiddleware.php +++ b/src/Middleware/AuthorizationMiddleware.php @@ -15,6 +15,7 @@ namespace App\Middleware; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Server\RequestHandlerInterface as RequestHandler; +use Slim\Exception\HttpUnauthorizedException; use Nyholm\Psr7\Response as NyholmResponse; use Psr\Http\Server\MiddlewareInterface; use Lcobucci\JWT\Parser; @@ -58,7 +59,11 @@ final class AuthorizationMiddleware implements MiddlewareInterface */ public function process(Request $request, RequestHandler $handler): Response { - if ($request->getMethod() === OPTIONS || !$request->hasHeader('Authorization')) { + if ( + $request->getMethod() === OPTIONS + || !$request->hasHeader('Authorization') + || $this->settings['enabled'] === 0 + ) { return $handler->handle($request); } @@ -66,7 +71,9 @@ final class AuthorizationMiddleware implements MiddlewareInterface $bearer = $request->getHeader('Authorization'); $data = explode(' ', $bearer[0]); if ($data[0] !== 'Bearer') { - return (new NyholmResponse())->withStatus(401); + return $this->getUnauthorizedResponse( + 'HTTP 401: Authorization must contain a string with the following format -> Bearer JWT' + ); } // Parse the JWT Token @@ -74,18 +81,38 @@ final class AuthorizationMiddleware implements MiddlewareInterface // Validating token (verifying expiration date and issuer) $data = new ValidationData(); - // TODO: Ajouter une config pour vérifier ou non le issuer - // $data->setIssuer($this->settings['issuer']); if (!$token->validate($data)) { - return (new NyholmResponse())->withStatus(401); + return $this->getUnauthorizedResponse('HTTP 401: Access Token is not valid or has expired'); } // Test token signature with the public key $publicKey = new Key('file://' . $this->settings['public_key_file']); if (!$token->verify(new Sha256(), $publicKey)) { - return (new NyholmResponse())->withStatus(401); + return $this->getUnauthorizedResponse('HTTP 401: Access Token signature is not valid'); } return $handler->handle($request->withAttribute('token', $token)); } + + // private function getPublicKey(string $issuer, string $kid): string + // { + // $urlOpenIdConfiguration = $issuer . '/.well-known/openid-configuration'; + // $openIdConfiguration = json_decode(file_get_contents($urlOpenIdConfiguration), true); + // $jwksUri = $openIdConfiguration['jwks_uri']; + // $jwks = json_decode(file_get_contents($jwksUri), true); + // foreach ($jwks['keys'] as $jwk) { + // if ($jwk['kid'] === $kid) { + // return $jwk['x5c']; + // } + // } + // } + + private function getUnauthorizedResponse(string $message) + { + $resonse = new NyholmResponse(); + $resonse->getBody()->write(json_encode(array( + 'message' => $message + ))); + return $resonse->withStatus(401); + } } diff --git a/tests/Action/GroupActionTest.php b/tests/Action/GroupActionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..259ce6432725976dc1cad1a19ac186fc90340803 --- /dev/null +++ b/tests/Action/GroupActionTest.php @@ -0,0 +1,197 @@ +<?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\Tests\Action; + +use PHPUnit\Framework\TestCase; +use Nyholm\Psr7\ServerRequest; +use Nyholm\Psr7\Response; +use Slim\Exception\HttpNotFoundException; +use Slim\Exception\HttpBadRequestException; +use App\tests\EntityManagerBuilder; +use App\Entity\Group; +use App\Entity\Database; +use App\Entity\Project; +use App\Entity\Instance; +use App\Entity\DatasetFamily; +use App\Entity\Dataset; + +final class GroupActionTest extends TestCase +{ + private $action; + private $entityManager; + + protected function setUp(): void + { + $this->entityManager = EntityManagerBuilder::getInstance(); + $this->action = new \App\Action\GroupAction($this->entityManager); + } + + public function testOptionsHttpMethod(): void + { + $request = $this->getRequest('OPTIONS'); + $response = ($this->action)($request, new Response(), array()); + $this->assertSame($response->getHeaderLine('Access-Control-Allow-Methods'), 'GET, PUT, DELETE, OPTIONS'); + } + + public function testGroupIsNotFound(): void + { + $this->expectException(HttpNotFoundException::class); + $this->expectExceptionMessage('Group with id 1 is not found'); + $request = $this->getRequest('GET'); + $response = ($this->action)($request, new Response(), array('id' => 1)); + $this->assertEquals(404, (int) $response->getStatusCode()); + } + + public function testGetAGroupById(): void + { + $group = $this->addAGroup(); + $request = $this->getRequest('GET'); + $response = ($this->action)($request, new Response(), array('id' => 1)); + $this->assertSame(json_encode($group), (string) $response->getBody()); + } + + public function testEditAGroupEmptyLabelField(): void + { + $this->addAGroup(); + $this->expectException(HttpBadRequestException::class); + $this->expectExceptionMessage('Param label needed to edit the group'); + $request = $this->getRequest('PUT')->withParsedBody(array()); + $response = ($this->action)($request, new Response(), array('id' => 1)); + $this->assertEquals(400, (int) $response->getStatusCode()); + } + + public function testEditAGroupWithoutDataset(): void + { + $fields = array( + 'label' => 'New_label', + 'datasets' => array() + ); + $this->addAGroup(); + $request = $this->getRequest('PUT')->withParsedBody($fields); + $response = ($this->action)($request, new Response(), array('id' => 1)); + $this->assertSame(json_encode(array_merge(['id' => 1], $fields)), (string) $response->getBody()); + } + + public function testEditAGroupWithDataset(): void + { + $dataset = $this->addADataset(); + $fields = array( + 'label' => 'New_label', + 'datasets' => array($dataset->getName()) + ); + $this->addAGroup(); + $request = $this->getRequest('PUT')->withParsedBody($fields); + $response = ($this->action)($request, new Response(), array('id' => 1)); + $this->assertSame(json_encode(array_merge(['id' => 1], $fields)), (string) $response->getBody()); + } + + public function testDeleteAGroup(): void + { + $this->addAGroup(); + $request = $this->getRequest('DELETE'); + $response = ($this->action)($request, new Response(), array('id' => 1)); + $this->assertSame( + json_encode(array('message' => 'Group with id 1 is removed!')), + (string) $response->getBody() + ); + } + + protected function tearDown(): void + { + $this->entityManager->getConnection()->close(); + } + + private function getRequest(string $method): ServerRequest + { + return new ServerRequest($method, '/group/1', array( + 'Content-Type' => 'application/json' + )); + } + + private function addAGroup(): Group + { + $group = new Group(); + $group->setLabel('Group1'); + $group->setDatasets(array()); + $this->entityManager->persist($group); + $this->entityManager->flush(); + return $group; + } + + private function addProject(): Project + { + $database = new Database(); + $database->setLabel('Test1'); + $database->setDbName('test1'); + $database->setType('pgsql'); + $database->setHost('db'); + $database->setPort(5432); + $database->setLogin('test'); + $database->setPassword('test'); + $this->entityManager->persist($database); + + $project = new Project('anis_project'); + $project->setLabel('Test project'); + $project->setDescription('Test description'); + $project->setLink('http://test.com'); + $project->setManager('User1'); + $project->setDatabase($database); + $this->entityManager->persist($project); + + $this->entityManager->flush(); + return $project; + } + + private function addInstance(): Instance + { + $instance = new Instance('aspic', 'Aspic'); + $instance->setClientUrl('http://cesam.lam.fr/aspic'); + $this->entityManager->persist($instance); + $this->entityManager->flush(); + return $instance; + } + + private function addDatasetFamily(): DatasetFamily + { + $instance = $this->addInstance(); + + $family = new DatasetFamily($instance); + $family->setLabel('Default dataset'); + $family->setDisplay(10); + $this->entityManager->persist($family); + + $this->entityManager->flush(); + return $family; + } + + private function addADataset(): Dataset + { + $project = $this->addProject(); + $family = $this->addDatasetFamily(); + + $dataset = new Dataset('obs_cat'); + $dataset->setTableRef('v_obs_cat'); + $dataset->setLabel('Obscat label'); + $dataset->setDescription('Obscat description'); + $dataset->setDisplay(10); + $dataset->setCount(10000); + $dataset->setVo(false); + $dataset->setDataPath('/mnt/obs_cat'); + $dataset->setPublic(true); + $dataset->setProject($project); + $dataset->setDatasetFamily($family); + $this->entityManager->persist($dataset); + $this->entityManager->flush(); + return $dataset; + } +} diff --git a/tests/Action/GroupListActionTest.php b/tests/Action/GroupListActionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4058eb2ce69ab041b89bf5b7133e7cdad84a6e23 --- /dev/null +++ b/tests/Action/GroupListActionTest.php @@ -0,0 +1,190 @@ +<?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\Tests\Action; + +use PHPUnit\Framework\TestCase; +use Nyholm\Psr7\ServerRequest; +use Nyholm\Psr7\Response; +use Slim\Exception\HttpBadRequestException; +use App\tests\EntityManagerBuilder; +use App\Entity\Group; +use App\Entity\Database; +use App\Entity\Project; +use App\Entity\Instance; +use App\Entity\DatasetFamily; +use App\Entity\Dataset; + +final class GroupListActionTest extends TestCase +{ + private $action; + private $entityManager; + + protected function setUp(): void + { + $this->entityManager = EntityManagerBuilder::getInstance(); + $this->action = new \App\Action\GroupListAction($this->entityManager); + } + + public function testOptionsHttpMethod(): void + { + $request = $this->getRequest('OPTIONS'); + $response = ($this->action)($request, new Response(), array()); + $this->assertSame($response->getHeaderLine('Access-Control-Allow-Methods'), 'GET, POST, OPTIONS'); + } + + public function testGetAllGroups(): void + { + $groups = $this->addGroups(); + $request = $this->getRequest('GET'); + $response = ($this->action)($request, new Response(), array()); + $this->assertSame( + json_encode($groups), + (string) $response->getBody() + ); + } + + public function testAddANewGroupEmptyLabelField(): void + { + $this->expectException(HttpBadRequestException::class); + $this->expectExceptionMessage('Param label needed to add a new group'); + $request = $this->getRequest('POST')->withParsedBody(array()); + $response = ($this->action)($request, new Response(), array()); + $this->assertEquals(400, (int) $response->getStatusCode()); + } + + public function testAddANewGroupWithoutDataset(): void + { + $fields = array( + 'label' => 'group1', + 'datasets' => [] + ); + $request = $this->getRequest('POST')->withParsedBody($fields); + $response = ($this->action)($request, new Response(), array()); + $this->assertSame( + json_encode(array_merge(['id' => 1], $fields)), + (string) $response->getBody() + ); + $this->assertEquals(201, (int) $response->getStatusCode()); + } + + public function testAddANewGroupWithDataset(): void + { + $dataset = $this->addADataset(); + $fields = array( + 'label' => 'group1', + 'datasets' => array($dataset->getName()) + ); + $request = $this->getRequest('POST')->withParsedBody($fields); + $response = ($this->action)($request, new Response(), array()); + $this->assertSame( + json_encode(array_merge(['id' => 1], $fields)), + (string) $response->getBody() + ); + $this->assertEquals(201, (int) $response->getStatusCode()); + } + + protected function tearDown(): void + { + $this->entityManager->getConnection()->close(); + } + + private function getRequest(string $method): ServerRequest + { + return new ServerRequest($method, '/group', array( + 'Content-Type' => 'application/json' + )); + } + + private function addGroups(): array + { + $group = new Group(); + $group->setLabel('Group1'); + $group->setDatasets(array()); + $this->entityManager->persist($group); + + $group2 = new Group(); + $group2->setLabel('Group2'); + $group2->setDatasets(array()); + $this->entityManager->persist($group2); + + $this->entityManager->flush(); + return array($group, $group2); + } + + private function addProject(): Project + { + $database = new Database(); + $database->setLabel('Test1'); + $database->setDbName('test1'); + $database->setType('pgsql'); + $database->setHost('db'); + $database->setPort(5432); + $database->setLogin('test'); + $database->setPassword('test'); + $this->entityManager->persist($database); + + $project = new Project('anis_project'); + $project->setLabel('Test project'); + $project->setDescription('Test description'); + $project->setLink('http://test.com'); + $project->setManager('User1'); + $project->setDatabase($database); + $this->entityManager->persist($project); + + $this->entityManager->flush(); + return $project; + } + + private function addInstance(): Instance + { + $instance = new Instance('aspic', 'Aspic'); + $instance->setClientUrl('http://cesam.lam.fr/aspic'); + $this->entityManager->persist($instance); + $this->entityManager->flush(); + return $instance; + } + + private function addDatasetFamily(): DatasetFamily + { + $instance = $this->addInstance(); + + $family = new DatasetFamily($instance); + $family->setLabel('Default dataset'); + $family->setDisplay(10); + $this->entityManager->persist($family); + + $this->entityManager->flush(); + return $family; + } + + private function addADataset(): Dataset + { + $project = $this->addProject(); + $family = $this->addDatasetFamily(); + + $dataset = new Dataset('obs_cat'); + $dataset->setTableRef('v_obs_cat'); + $dataset->setLabel('Obscat label'); + $dataset->setDescription('Obscat description'); + $dataset->setDisplay(10); + $dataset->setCount(10000); + $dataset->setVo(false); + $dataset->setDataPath('/mnt/obs_cat'); + $dataset->setPublic(true); + $dataset->setProject($project); + $dataset->setDatasetFamily($family); + $this->entityManager->persist($dataset); + $this->entityManager->flush(); + return $dataset; + } +}