refs #379. Fixed error UserInput create
parent
82ea76a557
commit
b652f70973
12
README.md
12
README.md
|
@ -5,6 +5,14 @@
|
|||
ogCore es el servicio central de OpenGnsys, diseñado para proporcionar funcionalidades a través de una API RESTful. Esta herramienta utiliza tecnología PHP, aprovechando el framework Symfony y el ORM Doctrine para gestionar la base de datos.
|
||||
A continuación, se detallan los pasos necesarios para desplegar el proyecto en un entorno de desarrollo.
|
||||
|
||||
## Versiones y tecnologías utilizadas
|
||||
|
||||
- PHP 8.3
|
||||
- Symfony 6.4
|
||||
- Doctrine 2.19
|
||||
- API Platform 3.2
|
||||
- MariaDB 10.11
|
||||
|
||||
## Requisitos
|
||||
|
||||
Antes de comenzar, asegúrate de tener los siguientes requisitos:
|
||||
|
@ -46,7 +54,7 @@ Comprobamos, que el contenedor de Nginx, tiene el puerto 8080 levantado correcta
|
|||
acceder a la siguiente URL:
|
||||
|
||||
```sh
|
||||
http://127.0.0.1:8080/api/docs
|
||||
http://127.0.0.1:8080/docs
|
||||
```
|
||||
Si todo ha ido bien, deberiamos ver la documentación de la API de ogCore.
|
||||
|
||||
|
@ -68,7 +76,7 @@ docker exec ogcore-php php bin/console app:load-default-user-groups
|
|||
Api Platform proporciona una interfaz de usuario para interactuar con la API de ogCore. Para acceder a la interfaz de usuario, accede a la siguiente URL:
|
||||
|
||||
```sh
|
||||
http://127.0.0.1:8080/api/docs
|
||||
http://127.0.0.1:8080/docs
|
||||
```
|
||||
|
||||
Para poder autenticarte, necesitas un token JWT. Para obtenerlo, accedemos al endpoint de autenticación "auth/login":
|
||||
|
|
|
@ -27,7 +27,7 @@ security:
|
|||
|
||||
access_control:
|
||||
- { path: ^/$, roles: PUBLIC_ACCESS } # Allows accessing the Swagger UI
|
||||
- { path: ^/api/docs, roles: PUBLIC_ACCESS } # Allows accessing the Swagger UI docs
|
||||
- { path: ^/docs, roles: PUBLIC_ACCESS } # Allows accessing the Swagger UI docs
|
||||
- { path: ^/auth/login, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/auth/refresh, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
api_platform:
|
||||
resource: .
|
||||
type: api_platform
|
||||
prefix: /api
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20240529131520 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
|
||||
$this->addSql('ALTER TABLE organizational_unit DROP FOREIGN KEY FK_749AEB2D727ACA70');
|
||||
$this->addSql('ALTER TABLE organizational_unit ADD CONSTRAINT FK_749AEB2D727ACA70 FOREIGN KEY (parent_id) REFERENCES organizational_unit (id) ON DELETE SET NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE organizational_unit DROP FOREIGN KEY FK_749AEB2D727ACA70');
|
||||
$this->addSql('ALTER TABLE organizational_unit ADD CONSTRAINT FK_749AEB2D727ACA70 FOREIGN KEY (parent_id) REFERENCES organizational_unit (id)');
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\DataFixtures;
|
||||
|
||||
use App\Entity\OrganizationalUnit;
|
||||
use App\Factory\OrganizationalUnitFactory;
|
||||
use App\Factory\UserFactory;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
|
@ -10,12 +12,22 @@ class AppFixtures extends Fixture
|
|||
{
|
||||
CONST ADMIN_USER = 'ogadmin';
|
||||
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
UserFactory::createOne(['username' => self::ADMIN_USER]);
|
||||
$rootUnit = OrganizationalUnitFactory::createOne(['name' => 'Centro de Computación', 'parent' => null]);
|
||||
|
||||
$roomUnit = OrganizationalUnitFactory::createOne([
|
||||
'name' => 'Aula 1',
|
||||
'parent' => $rootUnit
|
||||
]);
|
||||
|
||||
OrganizationalUnitFactory::createOne([
|
||||
'name' => 'Aula 2',
|
||||
'parent' => $roomUnit
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Dto\Input;
|
||||
|
||||
use ApiPlatform\Metadata\ApiProperty;
|
||||
use App\Dto\Output\UserGroupOutput;
|
||||
use App\Entity\OrganizationalUnit;
|
||||
use App\Entity\User;
|
||||
use App\Entity\UserGroup;
|
||||
|
@ -14,13 +16,11 @@ final class UserInput
|
|||
#[Groups(['user:write'])]
|
||||
public ?string $username = null;
|
||||
|
||||
#[Groups(['user:write'])]
|
||||
public array $roles = [];
|
||||
|
||||
/**
|
||||
* @var OrganizationalUnit[]
|
||||
*/
|
||||
#[Groups(['user:write'])]
|
||||
#[ApiProperty(readableLink: false, writableLink: false)]
|
||||
public array $allowedOrganizationalUnits = [];
|
||||
|
||||
#[Assert\NotBlank(groups: ['user:post'])]
|
||||
|
@ -36,6 +36,7 @@ final class UserInput
|
|||
* @var UserGroup[]
|
||||
*/
|
||||
#[Groups(['user:write'])]
|
||||
#[ApiProperty(readableLink: false, writableLink: false)]
|
||||
public array $userGroups = [];
|
||||
|
||||
public function __construct(?User $user = null)
|
||||
|
@ -45,7 +46,6 @@ final class UserInput
|
|||
}
|
||||
|
||||
$this->username = $user->getUsername();
|
||||
$this->roles = $user->getRoles();
|
||||
$this->enabled= $user->isEnabled();
|
||||
$this->userGroups = $user->getUserGroups()->toArray();
|
||||
$this->allowedOrganizationalUnits = $user->getAllowedOrganizationalUnits()->toArray();
|
||||
|
@ -58,7 +58,6 @@ final class UserInput
|
|||
}
|
||||
|
||||
$user->setUsername($this->username);
|
||||
$user->setRoles($this->roles);
|
||||
$user->setEnabled($this->enabled);
|
||||
|
||||
foreach ($this->userGroups as $userGroup) {
|
||||
|
|
|
@ -35,6 +35,7 @@ class OrganizationalUnit extends AbstractEntity
|
|||
|
||||
#[Gedmo\TreeParent]
|
||||
#[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'organizationalUnits')]
|
||||
#[ORM\JoinColumn( onDelete: 'SET NULL')]
|
||||
private ?self $parent = null;
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace App\Factory;
|
||||
|
||||
use App\Entity\OrganizationalUnit;
|
||||
use Gedmo\Tree\Entity\Repository\MaterializedPathRepository;
|
||||
use Zenstruck\Foundry\ModelFactory;
|
||||
use Zenstruck\Foundry\Proxy;
|
||||
use Zenstruck\Foundry\RepositoryProxy;
|
||||
|
||||
/**
|
||||
* @extends ModelFactory<OrganizationalUnit>
|
||||
*/
|
||||
final class OrganizationalUnitFactory extends ModelFactory
|
||||
{
|
||||
/**
|
||||
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services
|
||||
*
|
||||
* @todo inject services if required
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories
|
||||
*
|
||||
* @todo add your default values here
|
||||
*/
|
||||
protected function getDefaults(): array
|
||||
{
|
||||
return [
|
||||
'createdAt' => self::faker()->dateTime(),
|
||||
'name' => self::faker()->text(255),
|
||||
'updatedAt' => self::faker()->dateTime(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization
|
||||
*/
|
||||
protected function initialize(): self
|
||||
{
|
||||
return $this
|
||||
// ->afterInstantiate(function(OrganizationalUnit $organizationalUnit): void {})
|
||||
;
|
||||
}
|
||||
|
||||
protected static function getClass(): string
|
||||
{
|
||||
return OrganizationalUnit::class;
|
||||
}
|
||||
}
|
|
@ -38,12 +38,12 @@ class UserGroupTest extends AbstractTest
|
|||
UserGroupFactory::createOne(['name' => 'Operador de aulas', 'permissions' => ['ROLE_ORGANIZATIONAL_UNIT_OPERATOR'], 'enabled' => true]);
|
||||
UserGroupFactory::createOne(['name' => 'Usuario', 'permissions' => ['ROLE_USER'], 'enabled' => true]);
|
||||
|
||||
$this->createClientWithCredentials()->request('GET', '/api/user-groups');
|
||||
$this->createClientWithCredentials()->request('GET', '/user-groups');
|
||||
$this->assertResponseStatusCodeSame(Response::HTTP_OK);
|
||||
$this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
|
||||
$this->assertJsonContains([
|
||||
'@context' => '/api/contexts/UserGroup',
|
||||
'@id' => '/api/user-groups',
|
||||
'@context' => '/contexts/UserGroup',
|
||||
'@id' => '/user-groups',
|
||||
'@type' => 'hydra:Collection',
|
||||
'hydra:totalItems' => 4,
|
||||
]);
|
||||
|
@ -59,7 +59,7 @@ class UserGroupTest extends AbstractTest
|
|||
public function testCreateUserGroup(): void
|
||||
{
|
||||
UserFactory::createOne(['username' => self::USER_ADMIN]);
|
||||
$this->createClientWithCredentials()->request('POST', '/api/user-groups',['json' => [
|
||||
$this->createClientWithCredentials()->request('POST', '/user-groups',['json' => [
|
||||
'name' => self::USER_GROUP_CREATE,
|
||||
'enabled' => true,
|
||||
]]);
|
||||
|
@ -67,7 +67,7 @@ class UserGroupTest extends AbstractTest
|
|||
$this->assertResponseStatusCodeSame(201);
|
||||
$this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
|
||||
$this->assertJsonContains([
|
||||
'@context' => '/api/contexts/UserGroupOutput',
|
||||
'@context' => '/contexts/UserGroupOutput',
|
||||
'@type' => 'UserGroup',
|
||||
'name' => self::USER_GROUP_CREATE,
|
||||
'enabled' => true,
|
||||
|
|
|
@ -30,12 +30,12 @@ class UserTest extends AbstractTest
|
|||
UserFactory::createOne(['username' => self::USER_ADMIN]);
|
||||
UserFactory::createMany(10);
|
||||
|
||||
$this->createClientWithCredentials()->request('GET', '/api/users');
|
||||
$this->createClientWithCredentials()->request('GET', '/users');
|
||||
$this->assertResponseStatusCodeSame(Response::HTTP_OK);
|
||||
$this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
|
||||
$this->assertJsonContains([
|
||||
'@context' => '/api/contexts/User',
|
||||
'@id' => '/api/users',
|
||||
'@context' => '/contexts/User',
|
||||
'@id' => '/users',
|
||||
'@type' => 'hydra:Collection',
|
||||
'hydra:totalItems' => 11,
|
||||
]);
|
||||
|
@ -51,7 +51,7 @@ class UserTest extends AbstractTest
|
|||
public function testCreateUser(): void
|
||||
{
|
||||
UserFactory::createOne(['username' => self::USER_ADMIN]);
|
||||
$this->createClientWithCredentials()->request('POST', '/api/users',['json' => [
|
||||
$this->createClientWithCredentials()->request('POST', '/users',['json' => [
|
||||
'username' => self::USER_CREATE,
|
||||
'password' => '12345678',
|
||||
'enabled' => true,
|
||||
|
@ -60,7 +60,7 @@ class UserTest extends AbstractTest
|
|||
$this->assertResponseStatusCodeSame(201);
|
||||
$this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
|
||||
$this->assertJsonContains([
|
||||
'@context' => '/api/contexts/UserOutput',
|
||||
'@context' => '/contexts/UserOutput',
|
||||
'@type' => 'User',
|
||||
'username' => self::USER_CREATE,
|
||||
'enabled' => true,
|
||||
|
|
Loading…
Reference in New Issue