- /EasyGardenCDA
symfony new api
- Supprimer le .git dans /EasyGardenCDA/api
- /EasyGardenCDA
git init
- /EasyGardenCDA/api
composer install
composer update
- /EasyGardenCDA/api
composer req api
- /EasyGardenCDA/api
composer require symfony/orm-pack
- /EasyGardenCDA/api
composer require symfony/maker-bundle --dev
- /EasyGardenCDA/api
composer require sensio/framework-extra-bundle
- /EasyGardenCDA/api
composer require --dev symfony/profiler-pack
- /EasyGardenCDA/.env.local
Commenter DATABASE_URL="postgresql://symfony:ChangeMe@127.0.0.1:5432/app?serverVersion=13&charset=utf8"
Décommenter DATABASE_URL="mysql://root:@127.0.0.1:3306/EasyGardenCDA?serverVersion=mariadb-10.5.8"
Noter APP_ENV=dev - /EasyGardenCDA/api/.env
Commenter DATABASE_URL="postgresql://symfony:ChangeMe@127.0.0.1:5432/app?serverVersion=13&charset=utf8"
Décommenter DATABASE_URL="mysql://root:@127.0.0.1:3306/EasyGardenCDA?serverVersion=mariadb-10.5.8"
NoterAPP_ENV=prod - /EasyGardenCDA/api
composer require symfony/mailer
- /EasyGardenCDA/api
composer require --dev symfony/google-mailer
- /EasyGardenCDA/api
composer require symfony/http-client
- Lancer serveur en local
symfony local:server:start --allow-http
php -S 127.0.0.1:8000 -t ./public
- Créer entity User
php bin/console make:user
- Créer autres entity
php bin/console make:entity
- Créer les relations entre entity
- Créer les #Groups et exposer les propriétés
- /EasyGardenCDA/api/config/packages/api_platform.yaml
Configuration =>
api_platform:
title: 'EasyGarden API'
description: 'API to deal with Vue.js'
version: '1.0'
show_webby: false
mapping:
paths: ['%kernel.project_dir%/src/Entity']
patch_formats:
json: ['application/merge-patch+json']
swagger:
versions: [3]
eager_loading:
force_eager: false
fetch_partial: true
php bin/console doctrine:database:create
php bin/console doctrine:database:drop --force
php bin/console make:migration --no-interaction
php bin/console doctrine:migrations:migrate --no-interaction
- /EasyGardenCDA/api/config/packages/prod/doctrine.yaml
when@prod:
doctrine:
orm:
auto_generate_proxy_classes: false
query_cache_driver:
type: pool
pool: doctrine.system_cache_pool
result_cache_driver:
type: pool
pool: doctrine.result_cache_pool
framework:
cache:
pools:
doctrine.result_cache_pool:
adapter: cache.app
doctrine.system_cache_pool:
adapter: cache.system
- /EasyGardenCDA/api/config/packages/test/doctrine.yaml
when@test:
doctrine:
dbal:
# "TEST_TOKEN" is typically set by ParaTest
dbname_suffix: '_test%env(default::TEST_TOKEN)%'
- Supprimer les blocs .yaml du dessus dans =>
/EasyGardenCDA/api/config/packages/doctrine.yaml
- /EasyGardenCDA/api
composer require orm-fixtures --dev
- /EasyGardenCDA/api
composer require fakerphp/faker
- /EasyGardenCDA/api
composer require symfony/rate-limiter
- Load fixture =>
php bin/console doctrine:fixtures:load --no-interaction
- Créer dossier jwt
/EasyGardenCDA/api/config - /EasyGardenCDA/api
composer require lexik/jwt-authentication-bundle
- Générer la clé privé et publique
openssl genrsa -out config/jwt/private.pem 4096
openssl pkey -in config/jwt/private.pem -out config/jwt/public.pem -pubout
- /EasyGardenCDA/api/config/packages/lexik_jwt_authentication.yaml
lexik_jwt_authentication:
secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
token_ttl: "%env(JWT_TTL)%"
user_identity_field: email
- /EasyGardenCDA/api/config/routes.yaml
authentication_token:
path: /authentication_token
methods: ['GET','POST']
- /EasyGardenCDA/api/config/packages/security.yaml
firewalls:
login:
pattern: ^/authentication_token
stateless: true
provider: app_user_provider
json_login:
check_path: /authentication_token
username_path: email
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api
stateless: true
jwt: ~
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/users, roles: PUBLIC_ACCESS,
methods: [POST] }
- { path: ^/api/users, roles: IS_AUTHENTICATED_FULLY,
methods: [GET, PUT, DELETE] }
- { path: ^/api/gardens, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/lawnmowers, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/lightnings, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/pools, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/portals, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/waterings, roles: IS_AUTHENTICATED_FULLY }
role_hierarchy:
ROLE_ADMIN: ROLE_USER
/EasyGardenCDA/api/src/DataProvider/UserDataProvider.php
namespace App\DataProvider;
use App\Entity\User;
use App\Repository\UserRepository;
use ApiPlatform\Core\DataProvider\ContextAwareCollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\DenormalizedIdentifiersAwareItemDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
final class UserDataProvider implements DenormalizedIdentifiersAwareItemDataProviderInterface, ContextAwareCollectionDataProviderInterface, RestrictedDataProviderInterface
{
private $userRepository;
private $tokenStorage;
public function __construct(UserRepository $userRepository, TokenStorageInterface $tokenStorage)
{
$this->userRepository = $userRepository;
$this->tokenStorage = $tokenStorage;
}
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return User::class === $resourceClass;
}
public function getCollection(string $resourceClass, string $operationName = null, array $context = []): iterable
{
$token = $this->tokenStorage->getToken();
if (!$token) {
if (array_key_exists('filters',$context)) {
if (array_key_exists('email',$context['filters'])) {
if ($this->userRepository->findOneBy(['email'=>$context['filters']['email']])) {
return true;
} else {
return false;
}
}
}
return null;
}
$user = $token->getUser();
$roles = $user->getRoles();
if ($user && in_array("ROLE_ADMIN", $roles)) {
return $this->userRepository->findAll();
}
elseif ($user && in_array("ROLE_USER", $roles)) {
return [$user];
}
}
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?User
{
$token = $this->tokenStorage->getToken();
if (!$token) {
return null;
}
$user = $token->getUser();
return $user;
}
}
/EasyGardenCDA/api/src/DataPersister/UserDataPersister.php
namespace App\DataPersister;
use App\Entity\User;
use ApiPlatform\Core\DataPersister\DataPersisterInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Doctrine\ORM\EntityManagerInterface;
class UserDataPersister implements DataPersisterInterface
{
private $entityManager;
private $userPasswordEncoder;
public function __construct (EntityManagerInterface $entityManager, UserPasswordHasherInterface $userPasswordEncoder)
{
$this->entityManager = $entityManager;
$this->userPasswordEncoder = $userPasswordEncoder;
}
public function supports($data, array $context = []): bool
{
return $data instanceof User;
}
/**
* @param User $data
*/
public function persist($data, array $context = [])
{
if ($data->getPlainPassword()) {
$data->setPassword(
$this->userPasswordEncoder->hashPassword($data, $data->getPlainPassword())
);
$data->eraseCredentials();
}
$this->entityManager->persist($data);
$this->entityManager->flush();
}
public function remove($data, array $context = [])
{
$this->entityManager->remove($data);
$this->entityManager->flush();
}
}