From c0e3192fd7a536138202fd59a10bcf09a4798240 Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Mon, 18 Mar 2019 17:45:21 +0100 Subject: [PATCH 01/13] Basic requirements - maker-bundle to easily create Entities - validator and annotations to enforce requirements on Entities - migrations - behat for E2E testing (needs some adjustements to make it work) ``` docker-compose exec php composer require symfony/maker-bundle --dev docker-compose exec php composer require symfony/validator doctrine/annotations docker-compose exec php composer require migrations docker-compose exec php composer require --dev behat/behat docker-compose exec php vendor/bin/behat --init ``` --- api/composer.json | 5 + api/composer.lock | 926 ++++++++++++++++++- api/config/bundles.php | 2 + api/config/packages/doctrine_migrations.yaml | 5 + api/config/packages/translation.yaml | 6 + api/config/services.yaml | 1 + api/features/bootstrap/FeatureContext.php | 22 + api/src/Migrations/.gitignore | 0 api/symfony.lock | 60 ++ api/translations/.gitignore | 0 10 files changed, 980 insertions(+), 47 deletions(-) create mode 100644 api/config/packages/doctrine_migrations.yaml create mode 100644 api/config/packages/translation.yaml create mode 100644 api/features/bootstrap/FeatureContext.php create mode 100644 api/src/Migrations/.gitignore create mode 100644 api/translations/.gitignore diff --git a/api/composer.json b/api/composer.json index a8e0d73e0ba..ea91352c5b8 100644 --- a/api/composer.json +++ b/api/composer.json @@ -6,15 +6,20 @@ "ext-ctype": "*", "ext-iconv": "*", "api-platform/api-pack": "^1.1", + "doctrine/annotations": "^1.6", + "doctrine/doctrine-migrations-bundle": "^2.0", "guzzlehttp/guzzle": "^6.3", "symfony/console": "4.2.*", "symfony/dotenv": "4.2.*", "symfony/flex": "^1.1", "symfony/framework-bundle": "4.2.*", + "symfony/validator": "4.2.*", "symfony/yaml": "4.2.*" }, "require-dev": { "api-platform/schema-generator": "^2.1", + "behat/behat": "^3.5", + "symfony/maker-bundle": "^1.11", "symfony/profiler-pack": "^1.0" }, "config": { diff --git a/api/composer.lock b/api/composer.lock index dad2f500b1a..2e26174b1b0 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "716c78850e9ac3e24563c839d199b5be", + "content-hash": "7d45df86cd77b9c053baa25fb18c8486", "packages": [ { "name": "api-platform/api-pack", @@ -714,6 +714,71 @@ ], "time": "2018-11-09T06:25:35+00:00" }, + { + "name": "doctrine/doctrine-migrations-bundle", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineMigrationsBundle.git", + "reference": "4c9579e0e43df1fb3f0ca29b9c20871c824fac71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/4c9579e0e43df1fb3f0ca29b9c20871c824fac71", + "reference": "4c9579e0e43df1fb3f0ca29b9c20871c824fac71", + "shasum": "" + }, + "require": { + "doctrine/doctrine-bundle": "~1.0", + "doctrine/migrations": "^2.0", + "php": "^7.1", + "symfony/framework-bundle": "~3.4|~4.0" + }, + "require-dev": { + "doctrine/coding-standard": "^5.0", + "mikey179/vfsstream": "^1.6", + "phpstan/phpstan": "^0.9.2", + "phpstan/phpstan-strict-rules": "^0.9", + "phpunit/phpunit": "^5.7|^6.4|^7.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\MigrationsBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony DoctrineMigrationsBundle", + "homepage": "https://www.doctrine-project.org", + "keywords": [ + "dbal", + "migrations", + "schema" + ], + "time": "2019-01-09T18:49:50+00:00" + }, { "name": "doctrine/event-manager", "version": "v1.0.0", @@ -963,6 +1028,88 @@ ], "time": "2014-09-09T13:34:57+00:00" }, + { + "name": "doctrine/migrations", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/migrations.git", + "reference": "0101f5bd7f4e5043bf8630db2930f8fd7da552b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/0101f5bd7f4e5043bf8630db2930f8fd7da552b6", + "reference": "0101f5bd7f4e5043bf8630db2930f8fd7da552b6", + "shasum": "" + }, + "require": { + "doctrine/dbal": "^2.6", + "ocramius/package-versions": "^1.3", + "ocramius/proxy-manager": "^2.0.2", + "php": "^7.1", + "symfony/console": "^3.4||^4.0", + "symfony/stopwatch": "^3.4||^4.0" + }, + "require-dev": { + "doctrine/coding-standard": "^5.0", + "doctrine/orm": "^2.6", + "ext-pdo_sqlite": "*", + "jdorn/sql-formatter": "^1.1", + "mikey179/vfsstream": "^1.6", + "phpstan/phpstan": "^0.10", + "phpstan/phpstan-deprecation-rules": "^0.10", + "phpstan/phpstan-phpunit": "^0.10", + "phpstan/phpstan-strict-rules": "^0.10", + "phpunit/phpunit": "^7.0", + "symfony/process": "^3.4||^4.0", + "symfony/yaml": "^3.4||^4.0" + }, + "suggest": { + "jdorn/sql-formatter": "Allows to generate formatted SQL with the diff command.", + "symfony/yaml": "Allows the use of yaml for migration configuration files." + }, + "bin": [ + "bin/doctrine-migrations" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Migrations\\": "lib/Doctrine/Migrations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Michael Simonson", + "email": "contact@mikesimonson.com" + } + ], + "description": "PHP Doctrine Migrations project offer additional functionality on top of the database abstraction layer (DBAL) for versioning your database schema and easily deploying changes to it. It is a very easy to use and a powerful tool.", + "homepage": "https://www.doctrine-project.org/projects/migrations.html", + "keywords": [ + "database", + "dbal", + "migrations", + "php" + ], + "time": "2019-01-03T18:59:09+00:00" + }, { "name": "doctrine/orm", "version": "v2.6.3", @@ -1493,6 +1640,126 @@ ], "time": "2017-12-11T18:41:54+00:00" }, + { + "name": "ocramius/package-versions", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/PackageVersions.git", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0.0", + "php": "^7.1.0" + }, + "require-dev": { + "composer/composer": "^1.6.3", + "doctrine/coding-standard": "^5.0.1", + "ext-zip": "*", + "infection/infection": "^0.7.1", + "phpunit/phpunit": "^7.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "time": "2019-02-21T12:16:21+00:00" + }, + { + "name": "ocramius/proxy-manager", + "version": "2.2.2", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/ProxyManager.git", + "reference": "14b137b06b0f911944132df9d51e445a35920ab1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/14b137b06b0f911944132df9d51e445a35920ab1", + "reference": "14b137b06b0f911944132df9d51e445a35920ab1", + "shasum": "" + }, + "require": { + "ocramius/package-versions": "^1.1.3", + "php": "^7.2.0", + "zendframework/zend-code": "^3.3.0" + }, + "require-dev": { + "couscous/couscous": "^1.6.1", + "ext-phar": "*", + "humbug/humbug": "1.0.0-RC.0@RC", + "nikic/php-parser": "^3.1.1", + "padraic/phpunit-accelerator": "dev-master@DEV", + "phpbench/phpbench": "^0.12.2", + "phpstan/phpstan": "dev-master#856eb10a81c1d27c701a83f167dc870fd8f4236a as 0.9.999", + "phpstan/phpstan-phpunit": "dev-master#5629c0a1f4a9c417cb1077cf6693ad9753895761", + "phpunit/phpunit": "^6.4.3", + "squizlabs/php_codesniffer": "^2.9.1" + }, + "suggest": { + "ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects", + "zendframework/zend-json": "To have the JsonRpc adapter (Remote Object feature)", + "zendframework/zend-soap": "To have the Soap adapter (Remote Object feature)", + "zendframework/zend-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "ProxyManager\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.io/" + } + ], + "description": "A library providing utilities to generate, instantiate and generally operate with Object Proxies", + "homepage": "https://github.com/Ocramius/ProxyManager", + "keywords": [ + "aop", + "lazy loading", + "proxy", + "proxy pattern", + "service proxies" + ], + "time": "2018-09-27T13:45:01+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "1.0.1", @@ -3804,6 +4071,56 @@ "homepage": "https://symfony.com", "time": "2019-01-03T09:07:35+00:00" }, + { + "name": "symfony/stopwatch", + "version": "v4.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/af62b35760fc92c8dbdce659b4eebdfe0e6a0472", + "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/contracts": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "time": "2019-01-03T09:07:35+00:00" + }, { "name": "symfony/twig-bridge", "version": "v4.2.2", @@ -3974,16 +4291,16 @@ }, { "name": "symfony/validator", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "f89d2fab883a6a20d0d0093537392763cf52f0ba" + "reference": "ba50866242d992f0dd818e2c34c5088f163c974d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/f89d2fab883a6a20d0d0093537392763cf52f0ba", - "reference": "f89d2fab883a6a20d0d0093537392763cf52f0ba", + "url": "https://api.github.com/repos/symfony/validator/zipball/ba50866242d992f0dd818e2c34c5088f163c974d", + "reference": "ba50866242d992f0dd818e2c34c5088f163c974d", "shasum": "" }, "require": { @@ -4059,7 +4376,7 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com", - "time": "2019-01-06T14:13:54+00:00" + "time": "2019-03-03T18:11:24+00:00" }, { "name": "symfony/var-exporter", @@ -4349,49 +4666,156 @@ "negotiation" ], "time": "2017-05-14T17:21:12+00:00" - } - ], - "packages-dev": [ + }, { - "name": "api-platform/schema-generator", - "version": "v2.1.0", + "name": "zendframework/zend-code", + "version": "3.3.1", "source": { "type": "git", - "url": "https://github.com/api-platform/schema-generator.git", - "reference": "849d34cc19fd86851d3015a8cbd3d8fe00da3ef8" + "url": "https://github.com/zendframework/zend-code.git", + "reference": "c21db169075c6ec4b342149f446e7b7b724f95eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/schema-generator/zipball/849d34cc19fd86851d3015a8cbd3d8fe00da3ef8", - "reference": "849d34cc19fd86851d3015a8cbd3d8fe00da3ef8", + "url": "https://api.github.com/repos/zendframework/zend-code/zipball/c21db169075c6ec4b342149f446e7b7b724f95eb", + "reference": "c21db169075c6ec4b342149f446e7b7b724f95eb", "shasum": "" }, "require": { - "doctrine/inflector": "^1.0", - "easyrdf/easyrdf": "^0.9", - "ext-json": "*", - "friendsofphp/php-cs-fixer": "^2.10", - "league/html-to-markdown": "^4.0", - "php": ">=7.1", - "psr/log": "^1.0", - "symfony/config": "^3.3 || ^4.0", - "symfony/console": "^2.7 || ^3.0 || ^4.0", - "symfony/yaml": "^2.7 || ^3.0 || ^4.0", - "twig/twig": "^1.35 || ^2.0" + "php": "^7.1", + "zendframework/zend-eventmanager": "^2.6 || ^3.0" }, "require-dev": { - "api-platform/core": "^2.0", - "doctrine/orm": "^2.2", - "myclabs/php-enum": "^1.0", - "symfony/doctrine-bridge": "^2.7 || ^3.0 || ^4.0", - "symfony/filesystem": "^2.7 || ^3.0 || ^4.0", - "symfony/serializer": "^2.7 || ^3.0 || ^4.0", - "symfony/validator": "^2.7 || ^3.0 || ^4.0" + "doctrine/annotations": "~1.0", + "ext-phar": "*", + "phpunit/phpunit": "^6.2.3", + "zendframework/zend-coding-standard": "^1.0.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" }, - "bin": [ - "bin/schema" - ], - "type": "library", + "suggest": { + "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", + "zendframework/zend-stdlib": "Zend\\Stdlib component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3.x-dev", + "dev-develop": "3.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Code\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides facilities to generate arbitrary code using an object oriented interface", + "homepage": "https://github.com/zendframework/zend-code", + "keywords": [ + "code", + "zf2" + ], + "time": "2018-08-13T20:36:59+00:00" + }, + { + "name": "zendframework/zend-eventmanager", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-eventmanager.git", + "reference": "a5e2583a211f73604691586b8406ff7296a946dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/a5e2583a211f73604691586b8406ff7296a946dd", + "reference": "a5e2583a211f73604691586b8406ff7296a946dd", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "athletic/athletic": "^0.1", + "container-interop/container-interop": "^1.1.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-stdlib": "^2.7.3 || ^3.0" + }, + "suggest": { + "container-interop/container-interop": "^1.1.0, to use the lazy listeners feature", + "zendframework/zend-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev", + "dev-develop": "3.3-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\EventManager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Trigger and listen to events within a PHP application", + "homepage": "https://github.com/zendframework/zend-eventmanager", + "keywords": [ + "event", + "eventmanager", + "events", + "zf2" + ], + "time": "2018-04-25T15:33:34+00:00" + } + ], + "packages-dev": [ + { + "name": "api-platform/schema-generator", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/api-platform/schema-generator.git", + "reference": "849d34cc19fd86851d3015a8cbd3d8fe00da3ef8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/api-platform/schema-generator/zipball/849d34cc19fd86851d3015a8cbd3d8fe00da3ef8", + "reference": "849d34cc19fd86851d3015a8cbd3d8fe00da3ef8", + "shasum": "" + }, + "require": { + "doctrine/inflector": "^1.0", + "easyrdf/easyrdf": "^0.9", + "ext-json": "*", + "friendsofphp/php-cs-fixer": "^2.10", + "league/html-to-markdown": "^4.0", + "php": ">=7.1", + "psr/log": "^1.0", + "symfony/config": "^3.3 || ^4.0", + "symfony/console": "^2.7 || ^3.0 || ^4.0", + "symfony/yaml": "^2.7 || ^3.0 || ^4.0", + "twig/twig": "^1.35 || ^2.0" + }, + "require-dev": { + "api-platform/core": "^2.0", + "doctrine/orm": "^2.2", + "myclabs/php-enum": "^1.0", + "symfony/doctrine-bridge": "^2.7 || ^3.0 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.0 || ^4.0", + "symfony/serializer": "^2.7 || ^3.0 || ^4.0", + "symfony/validator": "^2.7 || ^3.0 || ^4.0" + }, + "bin": [ + "bin/schema" + ], + "type": "library", "autoload": { "psr-4": { "ApiPlatform\\SchemaGenerator\\": "src/" @@ -4420,6 +4844,187 @@ ], "time": "2018-01-23T13:41:27+00:00" }, + { + "name": "behat/behat", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/Behat/Behat.git", + "reference": "e4bce688be0c2029dc1700e46058d86428c63cab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Behat/zipball/e4bce688be0c2029dc1700e46058d86428c63cab", + "reference": "e4bce688be0c2029dc1700e46058d86428c63cab", + "shasum": "" + }, + "require": { + "behat/gherkin": "^4.5.1", + "behat/transliterator": "^1.2", + "container-interop/container-interop": "^1.2", + "ext-mbstring": "*", + "php": ">=5.3.3", + "psr/container": "^1.0", + "symfony/class-loader": "~2.1||~3.0", + "symfony/config": "~2.3||~3.0||~4.0", + "symfony/console": "~2.7.40||^2.8.33||~3.3.15||^3.4.3||^4.0.3", + "symfony/dependency-injection": "~2.1||~3.0||~4.0", + "symfony/event-dispatcher": "~2.1||~3.0||~4.0", + "symfony/translation": "~2.3||~3.0||~4.0", + "symfony/yaml": "~2.1||~3.0||~4.0" + }, + "require-dev": { + "herrera-io/box": "~1.6.1", + "phpunit/phpunit": "^4.8.36|^6.3", + "symfony/process": "~2.5|~3.0|~4.0" + }, + "bin": [ + "bin/behat" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Behat": "src/", + "Behat\\Testwork": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Scenario-oriented BDD framework for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "Agile", + "BDD", + "ScenarioBDD", + "Scrum", + "StoryBDD", + "User story", + "business", + "development", + "documentation", + "examples", + "symfony", + "testing" + ], + "time": "2018-08-10T18:56:51+00:00" + }, + { + "name": "behat/gherkin", + "version": "v4.6.0", + "source": { + "type": "git", + "url": "https://github.com/Behat/Gherkin.git", + "reference": "ab0a02ea14893860bca00f225f5621d351a3ad07" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/ab0a02ea14893860bca00f225f5621d351a3ad07", + "reference": "ab0a02ea14893860bca00f225f5621d351a3ad07", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "~4.5|~5", + "symfony/phpunit-bridge": "~2.7|~3|~4", + "symfony/yaml": "~2.3|~3|~4" + }, + "suggest": { + "symfony/yaml": "If you want to parse features, represented in YAML files" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Gherkin": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Gherkin DSL parser for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "BDD", + "Behat", + "Cucumber", + "DSL", + "gherkin", + "parser" + ], + "time": "2019-01-16T14:22:17+00:00" + }, + { + "name": "behat/transliterator", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/Behat/Transliterator.git", + "reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Transliterator/zipball/826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c", + "reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "chuyskywalker/rolling-curl": "^3.1", + "php-yaoi/php-yaoi": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Transliterator": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Artistic-1.0" + ], + "description": "String transliterator", + "keywords": [ + "i18n", + "slug", + "transliterator" + ], + "time": "2017-04-04T11:38:05+00:00" + }, { "name": "composer/semver", "version": "1.4.2", @@ -4526,6 +5131,37 @@ ], "time": "2018-11-29T10:59:02+00:00" }, + { + "name": "container-interop/container-interop", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "shasum": "" + }, + "require": { + "psr/container": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "homepage": "https://github.com/container-interop/container-interop", + "time": "2017-02-14T19:40:03+00:00" + }, { "name": "easyrdf/easyrdf", "version": "0.9.1", @@ -4748,6 +5384,57 @@ ], "time": "2018-12-24T17:21:44+00:00" }, + { + "name": "nikic/php-parser", + "version": "v4.2.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/5221f49a608808c1e4d436df32884cbc1b821ac0", + "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2019-02-16T20:54:15+00:00" + }, { "name": "php-cs-fixer/diff", "version": "v1.3.0", @@ -4799,6 +5486,128 @@ ], "time": "2018-02-15T16:58:55+00:00" }, + { + "name": "symfony/class-loader", + "version": "v3.4.23", + "source": { + "type": "git", + "url": "https://github.com/symfony/class-loader.git", + "reference": "4459eef5298dedfb69f771186a580062b8516497" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/4459eef5298dedfb69f771186a580062b8516497", + "reference": "4459eef5298dedfb69f771186a580062b8516497", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "require-dev": { + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/polyfill-apcu": "~1.1" + }, + "suggest": { + "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\ClassLoader\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony ClassLoader Component", + "homepage": "https://symfony.com", + "time": "2019-01-16T09:39:14+00:00" + }, + { + "name": "symfony/maker-bundle", + "version": "v1.11.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/maker-bundle.git", + "reference": "186ffc80b8f363e04ea3c2ebf49e1263a84b4e39" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/186ffc80b8f363e04ea3c2ebf49e1263a84b4e39", + "reference": "186ffc80b8f363e04ea3c2ebf49e1263a84b4e39", + "shasum": "" + }, + "require": { + "doctrine/inflector": "^1.2", + "nikic/php-parser": "^4.0", + "php": "^7.0.8", + "symfony/config": "^3.4|^4.0", + "symfony/console": "^3.4|^4.0", + "symfony/dependency-injection": "^3.4|^4.0", + "symfony/filesystem": "^3.4|^4.0", + "symfony/finder": "^3.4|^4.0", + "symfony/framework-bundle": "^3.4|^4.0", + "symfony/http-kernel": "^3.4|^4.0" + }, + "require-dev": { + "allocine/twigcs": "^3.0", + "doctrine/doctrine-bundle": "^1.8", + "doctrine/orm": "^2.3", + "friendsofphp/php-cs-fixer": "^2.8", + "symfony/phpunit-bridge": "^3.4|^4.0", + "symfony/process": "^3.4|^4.0", + "symfony/yaml": "^3.4|^4.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\MakerBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Maker helps you create empty commands, controllers, form classes, tests and more so you can forget about writing boilerplate code.", + "homepage": "https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html", + "keywords": [ + "code generator", + "generator", + "scaffold", + "scaffolding" + ], + "time": "2019-03-11T15:55:09+00:00" + }, { "name": "symfony/options-resolver", "version": "v4.2.2", @@ -4986,22 +5795,45 @@ "time": "2018-12-10T12:11:44+00:00" }, { - "name": "symfony/stopwatch", - "version": "v4.2.2", + "name": "symfony/translation", + "version": "v4.2.4", "source": { "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472" + "url": "https://github.com/symfony/translation.git", + "reference": "748464177a77011f8f4cdd076773862ce4915f8f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/af62b35760fc92c8dbdce659b4eebdfe0e6a0472", - "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472", + "url": "https://api.github.com/repos/symfony/translation/zipball/748464177a77011f8f4cdd076773862ce4915f8f", + "reference": "748464177a77011f8f4cdd076773862ce4915f8f", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/contracts": "^1.0" + "symfony/contracts": "^1.0.2", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/config": "<3.4", + "symfony/dependency-injection": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "symfony/translation-contracts-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/intl": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" }, "type": "library", "extra": { @@ -5011,7 +5843,7 @@ }, "autoload": { "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" + "Symfony\\Component\\Translation\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -5031,9 +5863,9 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Stopwatch Component", + "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-27T03:31:50+00:00" }, { "name": "symfony/var-dumper", diff --git a/api/config/bundles.php b/api/config/bundles.php index 3519f09424f..fe7392f7e3e 100644 --- a/api/config/bundles.php +++ b/api/config/bundles.php @@ -9,4 +9,6 @@ ApiPlatform\Core\Bridge\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true], Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true], Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], + Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], + Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], ]; diff --git a/api/config/packages/doctrine_migrations.yaml b/api/config/packages/doctrine_migrations.yaml new file mode 100644 index 00000000000..3bf0fbcae9e --- /dev/null +++ b/api/config/packages/doctrine_migrations.yaml @@ -0,0 +1,5 @@ +doctrine_migrations: + dir_name: '%kernel.project_dir%/src/Migrations' + # namespace is arbitrary but should be different from App\Migrations + # as migrations classes should NOT be autoloaded + namespace: DoctrineMigrations diff --git a/api/config/packages/translation.yaml b/api/config/packages/translation.yaml new file mode 100644 index 00000000000..e6b1cd66734 --- /dev/null +++ b/api/config/packages/translation.yaml @@ -0,0 +1,6 @@ +framework: + default_locale: '%locale%' + translator: + default_path: '%kernel.project_dir%/translations' + fallbacks: + - '%locale%' diff --git a/api/config/services.yaml b/api/config/services.yaml index 5c4b41757c2..10bca7de381 100644 --- a/api/config/services.yaml +++ b/api/config/services.yaml @@ -4,6 +4,7 @@ # Put parameters here that don't need to change on each machine where the app is deployed # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration parameters: + locale: 'en' services: # default configuration for services in *this* file diff --git a/api/features/bootstrap/FeatureContext.php b/api/features/bootstrap/FeatureContext.php new file mode 100644 index 00000000000..fcde4c1eecb --- /dev/null +++ b/api/features/bootstrap/FeatureContext.php @@ -0,0 +1,22 @@ + Date: Wed, 20 Mar 2019 11:34:03 +0100 Subject: [PATCH 02/13] Greeting Migration --- api/src/Migrations/Version20190322160602.php | 38 ++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 api/src/Migrations/Version20190322160602.php diff --git a/api/src/Migrations/Version20190322160602.php b/api/src/Migrations/Version20190322160602.php new file mode 100644 index 00000000000..50e91cd2f38 --- /dev/null +++ b/api/src/Migrations/Version20190322160602.php @@ -0,0 +1,38 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + + $this->addSql('CREATE SEQUENCE greeting_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE greeting (id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + } + + public function down(Schema $schema) : void + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + + $this->addSql('CREATE SCHEMA public'); + $this->addSql('DROP SEQUENCE greeting_id_seq CASCADE'); + $this->addSql('DROP TABLE greeting'); + } +} From 893fa7ae78960075e061ed1a19a6ad2b6de90720 Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Mon, 18 Mar 2019 22:53:29 +0100 Subject: [PATCH 03/13] Requirements for Heroku deployment ``` docker-compose exec php composer require symfony/translation docker-compose exec php composer require symfony/apache-pack ``` --- api/composer.json | 2 + api/composer.lock | 170 ++++++++++++++++++++++++------------------- api/public/.htaccess | 68 +++++++++++++++++ api/symfony.lock | 9 +++ 4 files changed, 175 insertions(+), 74 deletions(-) create mode 100644 api/public/.htaccess diff --git a/api/composer.json b/api/composer.json index ea91352c5b8..8bf786fa836 100644 --- a/api/composer.json +++ b/api/composer.json @@ -9,10 +9,12 @@ "doctrine/annotations": "^1.6", "doctrine/doctrine-migrations-bundle": "^2.0", "guzzlehttp/guzzle": "^6.3", + "symfony/apache-pack": "^1.0", "symfony/console": "4.2.*", "symfony/dotenv": "4.2.*", "symfony/flex": "^1.1", "symfony/framework-bundle": "4.2.*", + "symfony/translation": "4.2.*", "symfony/validator": "4.2.*", "symfony/yaml": "4.2.*" }, diff --git a/api/composer.lock b/api/composer.lock index 2e26174b1b0..e14deaba71d 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7d45df86cd77b9c053baa25fb18c8486", + "content-hash": "c68949ed96c3d9a9bac477d11cb0c4f7", "packages": [ { "name": "api-platform/api-pack", @@ -2192,6 +2192,28 @@ "description": "A polyfill for getallheaders.", "time": "2016-02-11T07:05:27+00:00" }, + { + "name": "symfony/apache-pack", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/apache-pack.git", + "reference": "3aa5818d73ad2551281fc58a75afd9ca82622e6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/apache-pack/zipball/3aa5818d73ad2551281fc58a75afd9ca82622e6c", + "reference": "3aa5818d73ad2551281fc58a75afd9ca82622e6c", + "shasum": "" + }, + "type": "symfony-pack", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A pack for Apache support in Symfony", + "time": "2017-12-12T01:46:35+00:00" + }, { "name": "symfony/asset", "version": "v4.2.2", @@ -4121,6 +4143,79 @@ "homepage": "https://symfony.com", "time": "2019-01-03T09:07:35+00:00" }, + { + "name": "symfony/translation", + "version": "v4.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "748464177a77011f8f4cdd076773862ce4915f8f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/748464177a77011f8f4cdd076773862ce4915f8f", + "reference": "748464177a77011f8f4cdd076773862ce4915f8f", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/contracts": "^1.0.2", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/config": "<3.4", + "symfony/dependency-injection": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "symfony/translation-contracts-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/intl": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Translation Component", + "homepage": "https://symfony.com", + "time": "2019-02-27T03:31:50+00:00" + }, { "name": "symfony/twig-bridge", "version": "v4.2.2", @@ -5794,79 +5889,6 @@ "description": "A pack for the Symfony web profiler", "time": "2018-12-10T12:11:44+00:00" }, - { - "name": "symfony/translation", - "version": "v4.2.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "748464177a77011f8f4cdd076773862ce4915f8f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/748464177a77011f8f4cdd076773862ce4915f8f", - "reference": "748464177a77011f8f4cdd076773862ce4915f8f", - "shasum": "" - }, - "require": { - "php": "^7.1.3", - "symfony/contracts": "^1.0.2", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/config": "<3.4", - "symfony/dependency-injection": "<3.4", - "symfony/yaml": "<3.4" - }, - "provide": { - "symfony/translation-contracts-implementation": "1.0" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~3.4|~4.0", - "symfony/console": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/finder": "~2.8|~3.0|~4.0", - "symfony/intl": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" - }, - "suggest": { - "psr/log-implementation": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Translation\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Translation Component", - "homepage": "https://symfony.com", - "time": "2019-02-27T03:31:50+00:00" - }, { "name": "symfony/var-dumper", "version": "v4.2.2", diff --git a/api/public/.htaccess b/api/public/.htaccess new file mode 100644 index 00000000000..bcce7fccfd1 --- /dev/null +++ b/api/public/.htaccess @@ -0,0 +1,68 @@ +# Use the front controller as index file. It serves as a fallback solution when +# every other rewrite/redirect fails (e.g. in an aliased environment without +# mod_rewrite). Additionally, this reduces the matching process for the +# start page (path "/") because otherwise Apache will apply the rewriting rules +# to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl). +DirectoryIndex index.php + +# By default, Apache does not evaluate symbolic links if you did not enable this +# feature in your server configuration. Uncomment the following line if you +# install assets as symlinks or if you experience problems related to symlinks +# when compiling LESS/Sass/CoffeScript assets. +# Options FollowSymlinks + +# Disabling MultiViews prevents unwanted negotiation, e.g. "/index" should not resolve +# to the front controller "/index.php" but be rewritten to "/index.php/index". + + Options -MultiViews + + + + RewriteEngine On + + # Determine the RewriteBase automatically and set it as environment variable. + # If you are using Apache aliases to do mass virtual hosting or installed the + # project in a subdirectory, the base path will be prepended to allow proper + # resolution of the index.php file and to redirect to the correct URI. It will + # work in environments without path prefix as well, providing a safe, one-size + # fits all solution. But as you do not need it in this case, you can comment + # the following 2 lines to eliminate the overhead. + RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$ + RewriteRule ^(.*) - [E=BASE:%1] + + # Sets the HTTP_AUTHORIZATION header removed by Apache + RewriteCond %{HTTP:Authorization} . + RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect to URI without front controller to prevent duplicate content + # (with and without `/index.php`). Only do this redirect on the initial + # rewrite by Apache and not on subsequent cycles. Otherwise we would get an + # endless redirect loop (request -> rewrite to front controller -> + # redirect -> request -> ...). + # So in case you get a "too many redirects" error or you always get redirected + # to the start page because your Apache does not expose the REDIRECT_STATUS + # environment variable, you have 2 choices: + # - disable this feature by commenting the following 2 lines or + # - use Apache >= 2.3.9 and replace all L flags by END flags and remove the + # following RewriteCond (best solution) + RewriteCond %{ENV:REDIRECT_STATUS} ^$ + RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L] + + # If the requested filename exists, simply serve it. + # We only want to let Apache serve files and not directories. + RewriteCond %{REQUEST_FILENAME} -f + RewriteRule ^ - [L] + + # Rewrite all other queries to the front controller. + RewriteRule ^ %{ENV:BASE}/index.php [L] + + + + + # When mod_rewrite is not available, we instruct a temporary redirect of + # the start page to the front controller explicitly so that the website + # and the generated links can still be used. + RedirectMatch 307 ^/$ /index.php/ + # RedirectTemp cannot be used instead + + diff --git a/api/symfony.lock b/api/symfony.lock index 627012fa105..2cfc6b9efc5 100644 --- a/api/symfony.lock +++ b/api/symfony.lock @@ -173,6 +173,15 @@ "ralouphie/getallheaders": { "version": "2.0.5" }, + "symfony/apache-pack": { + "version": "1.0", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "master", + "version": "1.0", + "ref": "c82bead70f9a4f656354a193df7bf0ca2114efa0" + } + }, "symfony/asset": { "version": "v4.0.3" }, From 3cf7aaa288a361cdad4ca20cd250225ebb37fa05 Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Mon, 18 Mar 2019 22:11:21 +0100 Subject: [PATCH 04/13] Config for Heroku deployment Makefile target to create app ``` provision/api/app: heroku apps:create \ --team $(HEROKU_TEAM) \ --region $(HEROKU_REGION) \ --remote $(DEPLOYMENT_ENV) \ --buildpack https://github.com/negativetwelve/heroku-buildpack-subdir \ --addons heroku-postgresql:hobby-dev \ $(API_APP_NAME) ``` Makefile target to setup environment ``` provision/api/environment: provision/api/app heroku config:set -a $(API_APP_NAME) \ APP_ENV=prod \ APP_SECRET=$(shell openssl rand -base64 32) \ CORS_ALLOW_ORIGIN=$(ADMIN_URL) \ TRUSTED_HOSTS=$(API_HOST) ``` --- .buildpacks | 1 + Procfile | 2 ++ api/config/packages/api_platform.yaml | 9 -------- app.json | 31 +++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 .buildpacks create mode 100644 Procfile create mode 100644 app.json diff --git a/.buildpacks b/.buildpacks new file mode 100644 index 00000000000..f518ed2edf6 --- /dev/null +++ b/.buildpacks @@ -0,0 +1 @@ +api=https://github.com/heroku/heroku-buildpack-php.git#v148 diff --git a/Procfile b/Procfile new file mode 100644 index 00000000000..4cef8ff9cd2 --- /dev/null +++ b/Procfile @@ -0,0 +1,2 @@ +release: ./api/bin/console doctrine:migrations:migrate --no-interaction +web: pushd api && $(composer config bin-dir)/heroku-php-apache2 public/ diff --git a/api/config/packages/api_platform.yaml b/api/config/packages/api_platform.yaml index 8a8c3b41f9c..96f8604bfc4 100644 --- a/api/config/packages/api_platform.yaml +++ b/api/config/packages/api_platform.yaml @@ -10,12 +10,3 @@ api_platform: paths: ['%kernel.project_dir%/src/Entity'] title: Hello API Platform version: 1.0.0 - # Enable the Varnish integration - http_cache: - invalidation: - enabled: true - varnish_urls: ['%env(VARNISH_URL)%'] - max_age: 0 - shared_max_age: 3600 - vary: ['Content-Type', 'Authorization'] - public: true diff --git a/app.json b/app.json new file mode 100644 index 00000000000..eeddea2eb95 --- /dev/null +++ b/app.json @@ -0,0 +1,31 @@ +{ + "success_url": "/", + "env": { + "APP_ENV": "prod", + "APP_SECRET": { + "generator": "secret", + }, + "CORS_ALLOW_ORIGIN": { + "required": true, + }, + "TRUSTED_HOSTS": { + "required": true, + } + }, + "formation": { + "web": { + "quantity": 1 + } + }, + "addons": [ + "heroku-postgresql" + ], + "buildpacks": [ + { + "url": "https://github.com/negativetwelve/heroku-buildpack-subdir" + } + ], + "scripts": { + "postdeploy": "php bin/console doctrine:schema:create" + } +} From cbed3f411a9e0d8a145927f7c5f26b374acead5b Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Tue, 19 Mar 2019 07:39:21 +0100 Subject: [PATCH 05/13] Requirements for JWT setup Mostly inspired from [doc](https://api-platform.com/docs/core/jwt/). - use Lexik for JWT authentication - use FOSUserBundle for User entity - FOSUserBundle config depends on SwiftMailer - add doctrine fixtures to provision users ``` docker-compose exec php composer require "lexik/jwt-authentication-bundle" docker-compose exec php composer require friendsofsymfony/user-bundle docker-compose exec php composer require swiftmailer-bundle docker-compose exec php composer require --dev doctrine/doctrine-fixtures-bundle ``` --- api/.env | 13 + api/.gitignore | 4 + api/composer.json | 4 + api/composer.lock | 1259 ++++++++++++++--- api/config/bundles.php | 4 + api/config/packages/dev/swiftmailer.yaml | 4 + .../packages/lexik_jwt_authentication.yaml | 4 + api/config/packages/swiftmailer.yaml | 3 + api/config/packages/test/swiftmailer.yaml | 2 + api/src/DataFixtures/AppFixtures.php | 17 + api/symfony.lock | 60 + 11 files changed, 1210 insertions(+), 164 deletions(-) create mode 100644 api/config/packages/dev/swiftmailer.yaml create mode 100644 api/config/packages/lexik_jwt_authentication.yaml create mode 100644 api/config/packages/swiftmailer.yaml create mode 100644 api/config/packages/test/swiftmailer.yaml create mode 100644 api/src/DataFixtures/AppFixtures.php diff --git a/api/.env b/api/.env index 421a1527f4d..b4ea271e429 100644 --- a/api/.env +++ b/api/.env @@ -23,3 +23,16 @@ CORS_ALLOW_ORIGIN=^https?://localhost(:[0-9]+)?$ ###< nelmio/cors-bundle ### VARNISH_URL=http://cache-proxy + +###> lexik/jwt-authentication-bundle ### +JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem +JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem +JWT_PASSPHRASE=e9503436f63f37f6381616b3e8080536 +###< lexik/jwt-authentication-bundle ### + +###> symfony/swiftmailer-bundle ### +# For Gmail as a transport, use: "gmail://username:password@localhost" +# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode=" +# Delivery is disabled by default via "null://localhost" +MAILER_URL=null://localhost +###< symfony/swiftmailer-bundle ### diff --git a/api/.gitignore b/api/.gitignore index 7bf09395af9..f6be2e2de2c 100644 --- a/api/.gitignore +++ b/api/.gitignore @@ -12,3 +12,7 @@ .php_cs .php_cs.cache ###< friendsofphp/php-cs-fixer ### + +###> lexik/jwt-authentication-bundle ### +/config/jwt/*.pem +###< lexik/jwt-authentication-bundle ### diff --git a/api/composer.json b/api/composer.json index 8bf786fa836..98cce1ee7f6 100644 --- a/api/composer.json +++ b/api/composer.json @@ -8,12 +8,15 @@ "api-platform/api-pack": "^1.1", "doctrine/annotations": "^1.6", "doctrine/doctrine-migrations-bundle": "^2.0", + "friendsofsymfony/user-bundle": "^2.1", "guzzlehttp/guzzle": "^6.3", + "lexik/jwt-authentication-bundle": "^2.6", "symfony/apache-pack": "^1.0", "symfony/console": "4.2.*", "symfony/dotenv": "4.2.*", "symfony/flex": "^1.1", "symfony/framework-bundle": "4.2.*", + "symfony/swiftmailer-bundle": "^3.2", "symfony/translation": "4.2.*", "symfony/validator": "4.2.*", "symfony/yaml": "4.2.*" @@ -21,6 +24,7 @@ "require-dev": { "api-platform/schema-generator": "^2.1", "behat/behat": "^3.5", + "doctrine/doctrine-fixtures-bundle": "^3.1", "symfony/maker-bundle": "^1.11", "symfony/profiler-pack": "^1.0" }, diff --git a/api/composer.lock b/api/composer.lock index e14deaba71d..2d74aecb7e3 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c68949ed96c3d9a9bac477d11cb0c4f7", + "content-hash": "6864d4c67613c04f344767aabcf3d1b5", "packages": [ { "name": "api-platform/api-pack", @@ -1349,6 +1349,139 @@ ], "time": "2018-06-14T14:45:07+00:00" }, + { + "name": "egulias/email-validator", + "version": "2.1.7", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/709f21f92707308cdf8f9bcfa1af4cb26586521e", + "reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.0.1", + "php": ">= 5.5" + }, + "require-dev": { + "dominicsayers/isemail": "dev-master", + "phpunit/phpunit": "^4.8.35||^5.7||^6.0", + "satooshi/php-coveralls": "^1.0.1" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "EmailValidator" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "time": "2018-12-04T22:38:24+00:00" + }, + { + "name": "friendsofsymfony/user-bundle", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfSymfony/FOSUserBundle.git", + "reference": "1049935edd24ec305cc6cfde1875372fa9600446" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSUserBundle/zipball/1049935edd24ec305cc6cfde1875372fa9600446", + "reference": "1049935edd24ec305cc6cfde1875372fa9600446", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "^1 || ^2", + "php": "^5.5.9 || ^7.0", + "symfony/form": "^2.8 || ^3.0 || ^4.0", + "symfony/framework-bundle": "^2.8 || ^3.0 || ^4.0", + "symfony/security-bundle": "^2.8 || ^3.0 || ^4.0", + "symfony/templating": "^2.8 || ^3.0 || ^4.0", + "symfony/twig-bundle": "^2.8 || ^3.0 || ^4.0", + "symfony/validator": "^2.8 || ^3.0 || ^4.0", + "twig/twig": "^1.28 || ^2.0" + }, + "conflict": { + "doctrine/doctrine-bundle": "<1.3", + "symfony/doctrine-bridge": "<2.7" + }, + "require-dev": { + "doctrine/doctrine-bundle": "^1.3", + "friendsofphp/php-cs-fixer": "^2.2", + "phpunit/phpunit": "^4.8.35|^5.7.11|^6.5", + "swiftmailer/swiftmailer": "^4.3 || ^5.0 || ^6.0", + "symfony/console": "^2.8 || ^3.0 || ^4.0", + "symfony/phpunit-bridge": "^2.8 || ^3.0 || ^4.0", + "symfony/yaml": "^2.8 || ^3.0 || ^4.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "FOS\\UserBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christophe Coevoet", + "email": "stof@notk.org" + }, + { + "name": "FriendsOfSymfony Community", + "homepage": "https://github.com/friendsofsymfony/FOSUserBundle/contributors" + }, + { + "name": "Thibault Duplessis" + } + ], + "description": "Symfony FOSUserBundle", + "homepage": "http://friendsofsymfony.github.com", + "keywords": [ + "User management" + ], + "time": "2018-03-08T08:59:27+00:00" + }, { "name": "guzzlehttp/guzzle", "version": "6.3.3", @@ -1582,6 +1715,224 @@ ], "time": "2014-01-12T16:20:24+00:00" }, + { + "name": "lcobucci/jwt", + "version": "3.2.5", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "82be04b4753f8b7693b62852b7eab30f97524f9b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/82be04b4753f8b7693b62852b7eab30f97524f9b", + "reference": "82be04b4753f8b7693b62852b7eab30f97524f9b", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "php": ">=5.5" + }, + "require-dev": { + "mdanter/ecc": "~0.3.1", + "mikey179/vfsstream": "~1.5", + "phpmd/phpmd": "~2.2", + "phpunit/php-invoker": "~1.1", + "phpunit/phpunit": "~4.5", + "squizlabs/php_codesniffer": "~2.3" + }, + "suggest": { + "mdanter/ecc": "Required to use Elliptic Curves based algorithms." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Lcobucci\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Luís Otávio Cobucci Oblonczyk", + "email": "lcobucci@gmail.com", + "role": "Developer" + } + ], + "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "keywords": [ + "JWS", + "jwt" + ], + "time": "2018-11-11T12:22:26+00:00" + }, + { + "name": "lexik/jwt-authentication-bundle", + "version": "v2.6.1", + "source": { + "type": "git", + "url": "https://github.com/lexik/LexikJWTAuthenticationBundle.git", + "reference": "ba179c2f876b96e5cffe5ee75cac883cfe3f8847" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lexik/LexikJWTAuthenticationBundle/zipball/ba179c2f876b96e5cffe5ee75cac883cfe3f8847", + "reference": "ba179c2f876b96e5cffe5ee75cac883cfe3f8847", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "lcobucci/jwt": "^3.2", + "namshi/jose": "^7.2", + "php": "^5.5|^7.0", + "symfony/framework-bundle": "^3.4|^4.0", + "symfony/security-bundle": "^3.4|^4.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^1.1|^2.8", + "symfony/browser-kit": "^3.4|^4.0", + "symfony/console": "^3.4|^4.0", + "symfony/dom-crawler": "^3.4|^4.0", + "symfony/phpunit-bridge": "^3.4|^4.0", + "symfony/var-dumper": "^3.4|^4.0", + "symfony/yaml": "^3.4|^4.0" + }, + "suggest": { + "gesdinet/jwt-refresh-token-bundle": "Implements a refresh token system over Json Web Tokens in Symfony", + "spomky-labs/lexik-jose-bridge": "Provides a JWT Token encoder with encryption support" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Lexik\\Bundle\\JWTAuthenticationBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Robin Chalas", + "email": "robin.chalas@gmail.com", + "homepage": "https://github.com/chalasr" + }, + { + "name": "Jeremy Barthe", + "email": "j.barthe@lexik.fr", + "homepage": "https://github.com/jeremyb" + }, + { + "name": "Nicolas Cabot", + "email": "n.cabot@lexik.fr", + "homepage": "https://github.com/slashfan" + }, + { + "name": "Cedric Girard", + "email": "c.girard@lexik.fr", + "homepage": "https://github.com/cedric-g" + }, + { + "name": "Lexik Community", + "homepage": "https://github.com/lexik/LexikJWTAuthenticationBundle/graphs/contributors" + }, + { + "name": "Dev Lexik", + "email": "dev@lexik.fr", + "homepage": "https://github.com/lexik" + } + ], + "description": "This bundle provides JWT authentication for your Symfony REST API", + "homepage": "https://github.com/lexik/LexikJWTAuthenticationBundle", + "keywords": [ + "Authentication", + "JWS", + "api", + "bundle", + "jwt", + "rest", + "symfony" + ], + "time": "2018-11-18T21:13:33+00:00" + }, + { + "name": "namshi/jose", + "version": "7.2.3", + "source": { + "type": "git", + "url": "https://github.com/namshi/jose.git", + "reference": "89a24d7eb3040e285dd5925fcad992378b82bcff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/namshi/jose/zipball/89a24d7eb3040e285dd5925fcad992378b82bcff", + "reference": "89a24d7eb3040e285dd5925fcad992378b82bcff", + "shasum": "" + }, + "require": { + "ext-date": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-spl": "*", + "php": ">=5.5", + "symfony/polyfill-php56": "^1.0" + }, + "require-dev": { + "phpseclib/phpseclib": "^2.0", + "phpunit/phpunit": "^4.5|^5.0", + "satooshi/php-coveralls": "^1.0" + }, + "suggest": { + "ext-openssl": "Allows to use OpenSSL as crypto engine.", + "phpseclib/phpseclib": "Allows to use Phpseclib as crypto engine, use version ^2.0." + }, + "type": "library", + "autoload": { + "psr-4": { + "Namshi\\JOSE\\": "src/Namshi/JOSE/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Nadalin", + "email": "alessandro.nadalin@gmail.com" + }, + { + "name": "Alessandro Cinelli (cirpo)", + "email": "alessandro.cinelli@gmail.com" + } + ], + "description": "JSON Object Signing and Encryption library for PHP.", + "keywords": [ + "JSON Web Signature", + "JSON Web Token", + "JWS", + "json", + "jwt", + "token" + ], + "time": "2016-12-05T07:27:31+00:00" + }, { "name": "nelmio/cors-bundle", "version": "1.5.4", @@ -2192,6 +2543,68 @@ "description": "A polyfill for getallheaders.", "time": "2016-02-11T07:05:27+00:00" }, + { + "name": "swiftmailer/swiftmailer", + "version": "v6.2.0", + "source": { + "type": "git", + "url": "https://github.com/swiftmailer/swiftmailer.git", + "reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707", + "reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707", + "shasum": "" + }, + "require": { + "egulias/email-validator": "~2.0", + "php": ">=7.0.0", + "symfony/polyfill-iconv": "^1.0", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.1", + "symfony/phpunit-bridge": "^3.4.19|^4.1.8" + }, + "suggest": { + "ext-intl": "Needed to support internationalized email addresses", + "true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.2-dev" + } + }, + "autoload": { + "files": [ + "lib/swift_required.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Corbyn" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Swiftmailer, free feature-rich PHP mailer", + "homepage": "https://swiftmailer.symfony.com", + "keywords": [ + "email", + "mail", + "mailer" + ], + "time": "2019-03-10T07:52:41+00:00" + }, { "name": "symfony/apache-pack", "version": "v1.0.1", @@ -3083,30 +3496,112 @@ "time": "2018-11-15T06:11:38+00:00" }, { - "name": "symfony/framework-bundle", - "version": "v4.2.2", + "name": "symfony/form", + "version": "v4.2.4", "source": { "type": "git", - "url": "https://github.com/symfony/framework-bundle.git", - "reference": "6cba25ea9489d62addb9971a4bdcf42a5639e641" + "url": "https://github.com/symfony/form.git", + "reference": "d44ad1ac671fb79fe5b3093b61779476da8b63f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/6cba25ea9489d62addb9971a4bdcf42a5639e641", - "reference": "6cba25ea9489d62addb9971a4bdcf42a5639e641", + "url": "https://api.github.com/repos/symfony/form/zipball/d44ad1ac671fb79fe5b3093b61779476da8b63f9", + "reference": "d44ad1ac671fb79fe5b3093b61779476da8b63f9", "shasum": "" }, "require": { - "ext-xml": "*", "php": "^7.1.3", - "symfony/cache": "~4.2", - "symfony/config": "~4.2", - "symfony/contracts": "^1.0.2", - "symfony/dependency-injection": "^4.2", - "symfony/event-dispatcher": "^4.1", - "symfony/filesystem": "~3.4|~4.0", - "symfony/finder": "~3.4|~4.0", - "symfony/http-foundation": "^4.1.2", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/intl": "~3.4|~4.0", + "symfony/options-resolver": "~4.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/property-access": "~3.4|~4.0" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/dependency-injection": "<3.4", + "symfony/doctrine-bridge": "<3.4", + "symfony/framework-bundle": "<3.4", + "symfony/http-kernel": "<3.4", + "symfony/translation": "<4.2", + "symfony/twig-bridge": "<3.4.5|<4.0.5,>=4.0" + }, + "require-dev": { + "doctrine/collections": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/http-foundation": "~3.4|~4.0", + "symfony/http-kernel": "~3.4|~4.0", + "symfony/security-csrf": "~3.4|~4.0", + "symfony/translation": "~4.2", + "symfony/validator": "~3.4|~4.0", + "symfony/var-dumper": "~3.4|~4.0" + }, + "suggest": { + "symfony/framework-bundle": "For templating with PHP.", + "symfony/security-csrf": "For protecting forms against CSRF attacks.", + "symfony/twig-bridge": "For templating with Twig.", + "symfony/validator": "For form validation." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Form\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Form Component", + "homepage": "https://symfony.com", + "time": "2019-02-23T15:42:05+00:00" + }, + { + "name": "symfony/framework-bundle", + "version": "v4.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/framework-bundle.git", + "reference": "6cba25ea9489d62addb9971a4bdcf42a5639e641" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/6cba25ea9489d62addb9971a4bdcf42a5639e641", + "reference": "6cba25ea9489d62addb9971a4bdcf42a5639e641", + "shasum": "" + }, + "require": { + "ext-xml": "*", + "php": "^7.1.3", + "symfony/cache": "~4.2", + "symfony/config": "~4.2", + "symfony/contracts": "^1.0.2", + "symfony/dependency-injection": "^4.2", + "symfony/event-dispatcher": "^4.1", + "symfony/filesystem": "~3.4|~4.0", + "symfony/finder": "~3.4|~4.0", + "symfony/http-foundation": "^4.1.2", "symfony/http-kernel": "^4.2", "symfony/polyfill-mbstring": "~1.0", "symfony/routing": "^4.1" @@ -3402,6 +3897,255 @@ ], "time": "2019-01-03T09:07:35+00:00" }, + { + "name": "symfony/intl", + "version": "v4.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/intl.git", + "reference": "b2af5ce379781fd4811f79746512fc1934333fbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/intl/zipball/b2af5ce379781fd4811f79746512fc1934333fbb", + "reference": "b2af5ce379781fd4811f79746512fc1934333fbb", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-intl-icu": "~1.0" + }, + "require-dev": { + "symfony/filesystem": "~3.4|~4.0" + }, + "suggest": { + "ext-intl": "to use the component with locales other than \"en\"" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Intl\\": "" + }, + "classmap": [ + "Resources/stubs" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Eriksen Costa", + "email": "eriksen.costa@infranology.com.br" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A PHP replacement layer for the C intl extension that includes additional data from the ICU library.", + "homepage": "https://symfony.com", + "keywords": [ + "i18n", + "icu", + "internationalization", + "intl", + "l10n", + "localization" + ], + "time": "2019-02-23T15:17:42+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v4.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "fbcb106aeee72f3450298bf73324d2cc00d083d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/fbcb106aeee72f3450298bf73324d2cc00d083d1", + "reference": "fbcb106aeee72f3450298bf73324d2cc00d083d1", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "time": "2019-01-03T09:07:35+00:00" + }, + { + "name": "symfony/polyfill-intl-icu", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-icu.git", + "reference": "f22a90256d577c7ef7efad8df1f0201663d57644" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/f22a90256d577c7ef7efad8df1f0201663d57644", + "reference": "f22a90256d577c7ef7efad8df1f0201663d57644", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/intl": "~2.3|~3.0|~4.0" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's ICU-related data and classes", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "icu", + "intl", + "polyfill", + "portable", + "shim" + ], + "time": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/89de1d44f2c059b266f22c9cc9124ddc4cd0987a", + "reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php72": "^1.9" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "time": "2018-09-30T16:36:12+00:00" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.10.0", @@ -3461,6 +4205,61 @@ ], "time": "2018-09-21T13:07:52+00:00" }, + { + "name": "symfony/polyfill-php72", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-09-21T13:07:52+00:00" + }, { "name": "symfony/property-access", "version": "v4.2.2", @@ -4039,37 +4838,149 @@ "symfony/yaml": "<3.4" }, "require-dev": { - "doctrine/annotations": "~1.0", - "doctrine/cache": "~1.0", - "phpdocumentor/reflection-docblock": "^3.0|^4.0", - "symfony/cache": "~3.4|~4.0", - "symfony/config": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/http-foundation": "~3.4|~4.0", - "symfony/property-access": "~3.4|~4.0", - "symfony/property-info": "~3.4|~4.0", - "symfony/validator": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" + "doctrine/annotations": "~1.0", + "doctrine/cache": "~1.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0", + "symfony/cache": "~3.4|~4.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/http-foundation": "~3.4|~4.0", + "symfony/property-access": "~3.4|~4.0", + "symfony/property-info": "~3.4|~4.0", + "symfony/validator": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "psr/cache-implementation": "For using the metadata cache.", + "symfony/config": "For using the XML mapping loader.", + "symfony/http-foundation": "To use the DataUriNormalizer.", + "symfony/property-access": "For using the ObjectNormalizer.", + "symfony/property-info": "To deserialize relations.", + "symfony/yaml": "For using the default YAML mapping loader." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Serializer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Serializer Component", + "homepage": "https://symfony.com", + "time": "2019-01-03T09:07:35+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v4.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/af62b35760fc92c8dbdce659b4eebdfe0e6a0472", + "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/contracts": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "time": "2019-01-03T09:07:35+00:00" + }, + { + "name": "symfony/swiftmailer-bundle", + "version": "v3.2.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/swiftmailer-bundle.git", + "reference": "ac4f38c2ec7957f2dec8b6c2f24a060b10a254f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/swiftmailer-bundle/zipball/ac4f38c2ec7957f2dec8b6c2f24a060b10a254f2", + "reference": "ac4f38c2ec7957f2dec8b6c2f24a060b10a254f2", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "swiftmailer/swiftmailer": "^6.1.3", + "symfony/config": "~2.8|~3.3|~4.0", + "symfony/dependency-injection": "~2.7|~3.3|~4.0", + "symfony/http-kernel": "~2.7|~3.3|~4.0" + }, + "require-dev": { + "symfony/console": "~2.7|~3.3|~4.0", + "symfony/framework-bundle": "~2.7|~3.3|~4.0", + "symfony/phpunit-bridge": "~3.3|~4.0", + "symfony/yaml": "~2.7|~3.3|~4.0" }, "suggest": { - "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", - "doctrine/cache": "For using the default cached annotation reader and metadata cache.", - "psr/cache-implementation": "For using the metadata cache.", - "symfony/config": "For using the XML mapping loader.", - "symfony/http-foundation": "To use the DataUriNormalizer.", - "symfony/property-access": "For using the ObjectNormalizer.", - "symfony/property-info": "To deserialize relations.", - "symfony/yaml": "For using the default YAML mapping loader." + "psr/log": "Allows logging" }, - "type": "library", + "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "3.2-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\Serializer\\": "" + "Symfony\\Bundle\\SwiftmailerBundle\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -4081,35 +4992,41 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], - "description": "Symfony Serializer Component", - "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "description": "Symfony SwiftmailerBundle", + "homepage": "http://symfony.com", + "time": "2019-01-05T11:51:59+00:00" }, { - "name": "symfony/stopwatch", - "version": "v4.2.2", + "name": "symfony/templating", + "version": "v4.2.4", "source": { "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472" + "url": "https://github.com/symfony/templating.git", + "reference": "1bb2d2eda3136fff122b8810ac1357440411abeb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/af62b35760fc92c8dbdce659b4eebdfe0e6a0472", - "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472", + "url": "https://api.github.com/repos/symfony/templating/zipball/1bb2d2eda3136fff122b8810ac1357440411abeb", + "reference": "1bb2d2eda3136fff122b8810ac1357440411abeb", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/contracts": "^1.0" + "symfony/polyfill-ctype": "~1.8" + }, + "require-dev": { + "psr/log": "~1.0" + }, + "suggest": { + "psr/log-implementation": "For using debug logging in loaders" }, "type": "library", "extra": { @@ -4119,7 +5036,7 @@ }, "autoload": { "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" + "Symfony\\Component\\Templating\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -4139,9 +5056,9 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Stopwatch Component", + "description": "Symfony Templating Component", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/translation", @@ -5257,6 +6174,129 @@ "homepage": "https://github.com/container-interop/container-interop", "time": "2017-02-14T19:40:03+00:00" }, + { + "name": "doctrine/data-fixtures", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/data-fixtures.git", + "reference": "3a1e2c3c600e615a2dffe56d4ca0875cc5233e0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/3a1e2c3c600e615a2dffe56d4ca0875cc5233e0a", + "reference": "3a1e2c3c600e615a2dffe56d4ca0875cc5233e0a", + "shasum": "" + }, + "require": { + "doctrine/common": "~2.2", + "php": "^7.1" + }, + "conflict": { + "doctrine/phpcr-odm": "<1.3.0" + }, + "require-dev": { + "doctrine/dbal": "^2.5.4", + "doctrine/orm": "^2.5.4", + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "For using MongoDB ODM with PHP 7", + "doctrine/mongodb-odm": "For loading MongoDB ODM fixtures", + "doctrine/orm": "For loading ORM fixtures", + "doctrine/phpcr-odm": "For loading PHPCR ODM fixtures" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\DataFixtures\\": "lib/Doctrine/Common/DataFixtures" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Data Fixtures for all Doctrine Object Managers", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database" + ], + "time": "2018-03-20T09:06:36+00:00" + }, + { + "name": "doctrine/doctrine-fixtures-bundle", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineFixturesBundle.git", + "reference": "f016565b251c2dfa32a8d6da44d1650dc9ec1498" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/f016565b251c2dfa32a8d6da44d1650dc9ec1498", + "reference": "f016565b251c2dfa32a8d6da44d1650dc9ec1498", + "shasum": "" + }, + "require": { + "doctrine/data-fixtures": "^1.3", + "doctrine/doctrine-bundle": "^1.6", + "php": "^7.1", + "symfony/doctrine-bridge": "~3.4|^4.1", + "symfony/framework-bundle": "^3.4|^4.1" + }, + "require-dev": { + "doctrine/coding-standard": "^5.0", + "phpunit/phpunit": "^7.4", + "symfony/phpunit-bridge": "^4.1" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\FixturesBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony DoctrineFixturesBundle", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "Fixture", + "persistence" + ], + "time": "2018-12-21T10:10:51+00:00" + }, { "name": "easyrdf/easyrdf", "version": "0.9.1", @@ -5703,115 +6743,6 @@ ], "time": "2019-03-11T15:55:09+00:00" }, - { - "name": "symfony/options-resolver", - "version": "v4.2.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "fbcb106aeee72f3450298bf73324d2cc00d083d1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/fbcb106aeee72f3450298bf73324d2cc00d083d1", - "reference": "fbcb106aeee72f3450298bf73324d2cc00d083d1", - "shasum": "" - }, - "require": { - "php": "^7.1.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony OptionsResolver Component", - "homepage": "https://symfony.com", - "keywords": [ - "config", - "configuration", - "options" - ], - "time": "2019-01-03T09:07:35+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.10.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-09-21T13:07:52+00:00" - }, { "name": "symfony/process", "version": "v4.2.2", diff --git a/api/config/bundles.php b/api/config/bundles.php index fe7392f7e3e..a6f879308cb 100644 --- a/api/config/bundles.php +++ b/api/config/bundles.php @@ -11,4 +11,8 @@ Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], + Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], + FOS\UserBundle\FOSUserBundle::class => ['all' => true], + Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle::class => ['all' => true], + Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true], ]; diff --git a/api/config/packages/dev/swiftmailer.yaml b/api/config/packages/dev/swiftmailer.yaml new file mode 100644 index 00000000000..b98158ee1b8 --- /dev/null +++ b/api/config/packages/dev/swiftmailer.yaml @@ -0,0 +1,4 @@ +# See https://symfony.com/doc/current/email/dev_environment.html +swiftmailer: + # send all emails to a specific address + #delivery_addresses: ['me@example.com'] diff --git a/api/config/packages/lexik_jwt_authentication.yaml b/api/config/packages/lexik_jwt_authentication.yaml new file mode 100644 index 00000000000..edfb69dc897 --- /dev/null +++ b/api/config/packages/lexik_jwt_authentication.yaml @@ -0,0 +1,4 @@ +lexik_jwt_authentication: + secret_key: '%env(resolve:JWT_SECRET_KEY)%' + public_key: '%env(resolve:JWT_PUBLIC_KEY)%' + pass_phrase: '%env(JWT_PASSPHRASE)%' diff --git a/api/config/packages/swiftmailer.yaml b/api/config/packages/swiftmailer.yaml new file mode 100644 index 00000000000..cae65084a21 --- /dev/null +++ b/api/config/packages/swiftmailer.yaml @@ -0,0 +1,3 @@ +swiftmailer: + url: '%env(MAILER_URL)%' + spool: { type: 'memory' } diff --git a/api/config/packages/test/swiftmailer.yaml b/api/config/packages/test/swiftmailer.yaml new file mode 100644 index 00000000000..f43807805e0 --- /dev/null +++ b/api/config/packages/test/swiftmailer.yaml @@ -0,0 +1,2 @@ +swiftmailer: + disable_delivery: true diff --git a/api/src/DataFixtures/AppFixtures.php b/api/src/DataFixtures/AppFixtures.php new file mode 100644 index 00000000000..fece4758e9d --- /dev/null +++ b/api/src/DataFixtures/AppFixtures.php @@ -0,0 +1,17 @@ +persist($product); + + $manager->flush(); + } +} diff --git a/api/symfony.lock b/api/symfony.lock index 2cfc6b9efc5..598634de02d 100644 --- a/api/symfony.lock +++ b/api/symfony.lock @@ -50,6 +50,9 @@ "doctrine/common": { "version": "v2.8.1" }, + "doctrine/data-fixtures": { + "version": "v1.3.1" + }, "doctrine/dbal": { "version": "v2.6.3" }, @@ -65,6 +68,15 @@ "doctrine/doctrine-cache-bundle": { "version": "1.3.2" }, + "doctrine/doctrine-fixtures-bundle": { + "version": "3.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "3.0", + "ref": "fc52d86631a6dfd9fdf3381d0b7e3df2069e51b3" + } + }, "doctrine/doctrine-migrations-bundle": { "version": "1.2", "recipe": { @@ -101,6 +113,9 @@ "easyrdf/easyrdf": { "version": "0.9.1" }, + "egulias/email-validator": { + "version": "2.1.7" + }, "friendsofphp/php-cs-fixer": { "version": "2.2", "recipe": { @@ -110,6 +125,9 @@ "ref": "bb31a3bbec00a8fc8aa1c9fbf9b0ef9fc492f93d" } }, + "friendsofsymfony/user-bundle": { + "version": "v2.1.2" + }, "guzzlehttp/guzzle": { "version": "6.3.0" }, @@ -122,9 +140,24 @@ "jdorn/sql-formatter": { "version": "v1.2.17" }, + "lcobucci/jwt": { + "version": "3.2.5" + }, "league/html-to-markdown": { "version": "4.6.2" }, + "lexik/jwt-authentication-bundle": { + "version": "2.5", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "2.5", + "ref": "509b1542f3180a1cfe248ade8b7bf5092c2d4127" + } + }, + "namshi/jose": { + "version": "7.2.3" + }, "nelmio/cors-bundle": { "version": "1.5", "recipe": { @@ -173,6 +206,9 @@ "ralouphie/getallheaders": { "version": "2.0.5" }, + "swiftmailer/swiftmailer": { + "version": "v6.2.0" + }, "symfony/apache-pack": { "version": "1.0", "recipe": { @@ -239,6 +275,9 @@ "ref": "cc1afd81841db36fbef982fe56b48ade6716fac4" } }, + "symfony/form": { + "version": "v4.2.4" + }, "symfony/framework-bundle": { "version": "3.3", "recipe": { @@ -257,6 +296,9 @@ "symfony/inflector": { "version": "v4.0.3" }, + "symfony/intl": { + "version": "v4.2.4" + }, "symfony/maker-bundle": { "version": "1.0", "recipe": { @@ -272,6 +314,12 @@ "symfony/polyfill-ctype": { "version": "v1.8.0" }, + "symfony/polyfill-intl-icu": { + "version": "v1.10.0" + }, + "symfony/polyfill-intl-idn": { + "version": "v1.10.0" + }, "symfony/polyfill-mbstring": { "version": "v1.6.0" }, @@ -326,6 +374,18 @@ "symfony/stopwatch": { "version": "v4.0.3" }, + "symfony/swiftmailer-bundle": { + "version": "2.5", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "2.5", + "ref": "3db029c03e452b4a23f7fc45cec7c922c2247eb8" + } + }, + "symfony/templating": { + "version": "v4.2.4" + }, "symfony/translation": { "version": "3.3", "recipe": { From dc4edef80d6422325188bb110cee46f6ba29d869 Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Tue, 19 Mar 2019 11:37:41 +0100 Subject: [PATCH 06/13] Config for JWT & Security --- api/config/packages/api_platform.yaml | 6 ++++ api/config/packages/fos_user.yml | 10 +++++++ api/config/packages/framework.yaml | 7 +++++ api/config/packages/security.yaml | 41 +++++++++++++++++---------- api/config/routes.yaml | 3 ++ 5 files changed, 52 insertions(+), 15 deletions(-) create mode 100644 api/config/packages/fos_user.yml diff --git a/api/config/packages/api_platform.yaml b/api/config/packages/api_platform.yaml index 96f8604bfc4..cf4b6313a68 100644 --- a/api/config/packages/api_platform.yaml +++ b/api/config/packages/api_platform.yaml @@ -10,3 +10,9 @@ api_platform: paths: ['%kernel.project_dir%/src/Entity'] title: Hello API Platform version: 1.0.0 + enable_fos_user: true + swagger: + api_keys: + apiKey: + name: Authorization + type: header diff --git a/api/config/packages/fos_user.yml b/api/config/packages/fos_user.yml new file mode 100644 index 00000000000..e39a6a793b1 --- /dev/null +++ b/api/config/packages/fos_user.yml @@ -0,0 +1,10 @@ +parameters: + env(MAILER_EMAIL): '' + +fos_user: + db_driver: orm + firewall_name: main + user_class: App\Entity\User + from_email: + address: '%env(resolve:MAILER_EMAIL)%' + sender_name: '%env(resolve:MAILER_EMAIL)%' diff --git a/api/config/packages/framework.yaml b/api/config/packages/framework.yaml index d3f884c4b65..99058ce1dc0 100644 --- a/api/config/packages/framework.yaml +++ b/api/config/packages/framework.yaml @@ -15,3 +15,10 @@ framework: #fragments: true php_errors: log: true + + # Required for FOSUserBundle + form: { enabled: true } + + # Required for FOSUserBundle + templating: + engines: ['twig'] diff --git a/api/config/packages/security.yaml b/api/config/packages/security.yaml index fb4c593ef1b..6a466c7f64d 100644 --- a/api/config/packages/security.yaml +++ b/api/config/packages/security.yaml @@ -1,24 +1,35 @@ security: - # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers + encoders: + FOS\UserBundle\Model\UserInterface: bcrypt + role_hierarchy: + ROLE_ADMIN: ROLE_USER providers: - in_memory: { memory: ~ } + users: + entity: + class: 'App\Entity\User' + property: 'email' firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false + login: + pattern: ^/login + stateless: true + anonymous: true + provider: users + json_login: + check_path: /login_check + username_path: login + password_path: password + success_handler: lexik_jwt_authentication.handler.authentication_success + failure_handler: lexik_jwt_authentication.handler.authentication_failure main: + pattern: ^/ + provider: users + stateless: true anonymous: true - - # activate different ways to authenticate - - # http_basic: true - # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate - - # form_login: true - # https://symfony.com/doc/current/security/form_login_setup.html - - # Easy way to control access for large sections of your site - # Note: Only the *first* access control that matches will be used + guard: + authenticators: + - lexik_jwt_authentication.jwt_token_authenticator access_control: - # - { path: ^/admin, roles: ROLE_ADMIN } - # - { path: ^/profile, roles: ROLE_USER } + - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } diff --git a/api/config/routes.yaml b/api/config/routes.yaml index c3283aa2e33..f8cabd2ac83 100644 --- a/api/config/routes.yaml +++ b/api/config/routes.yaml @@ -1,3 +1,6 @@ #index: # path: / # controller: App\Controller\DefaultController::index +api_login_check: + path: /login_check + methods: [POST] From 3ea2bee7186044a7e157a09d6da97392cb44b62d Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Tue, 19 Mar 2019 11:36:54 +0100 Subject: [PATCH 07/13] User Entity - table is `fos_user` to avoid conflict w/ Postgres `user` - enable users by default - add ACLs on User - fixtures for admin & user --- api/src/DataFixtures/AppFixtures.php | 17 ------- api/src/DataFixtures/UserFixtures.php | 28 ++++++++++++ api/src/Entity/User.php | 66 +++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 17 deletions(-) delete mode 100644 api/src/DataFixtures/AppFixtures.php create mode 100644 api/src/DataFixtures/UserFixtures.php create mode 100644 api/src/Entity/User.php diff --git a/api/src/DataFixtures/AppFixtures.php b/api/src/DataFixtures/AppFixtures.php deleted file mode 100644 index fece4758e9d..00000000000 --- a/api/src/DataFixtures/AppFixtures.php +++ /dev/null @@ -1,17 +0,0 @@ -persist($product); - - $manager->flush(); - } -} diff --git a/api/src/DataFixtures/UserFixtures.php b/api/src/DataFixtures/UserFixtures.php new file mode 100644 index 00000000000..47494715840 --- /dev/null +++ b/api/src/DataFixtures/UserFixtures.php @@ -0,0 +1,28 @@ +setUsername('admin@example.com'); + $admin->setEmail('admin@example.com'); + $admin->setPlainPassword('123456'); + $admin->setRoles(['ROLE_ADMIN']); + $manager->persist($admin); + + $user = new \App\Entity\User(); + $user->setUsername('user@example.com'); + $user->setEmail('user@example.com'); + $user->setPlainPassword('123456'); + $user->setRoles(['ROLE_USER']); + $manager->persist($user); + + $manager->flush(); + } +} diff --git a/api/src/Entity/User.php b/api/src/Entity/User.php new file mode 100644 index 00000000000..6fb60515370 --- /dev/null +++ b/api/src/Entity/User.php @@ -0,0 +1,66 @@ +id === $this->id; + } + + public function __construct() + { + parent::__construct(); + $this->enabled = true; + } +} From 2594cac3e0f33e374f7478401b74e5c78367d5e3 Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Fri, 22 Mar 2019 17:18:01 +0100 Subject: [PATCH 08/13] User Migration --- api/src/Migrations/Version20190322161629.php | 41 ++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 api/src/Migrations/Version20190322161629.php diff --git a/api/src/Migrations/Version20190322161629.php b/api/src/Migrations/Version20190322161629.php new file mode 100644 index 00000000000..0127a942719 --- /dev/null +++ b/api/src/Migrations/Version20190322161629.php @@ -0,0 +1,41 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + + $this->addSql('CREATE SEQUENCE fos_user_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE fos_user (id INT NOT NULL, username VARCHAR(180) NOT NULL, username_canonical VARCHAR(180) NOT NULL, email VARCHAR(180) NOT NULL, email_canonical VARCHAR(180) NOT NULL, enabled BOOLEAN NOT NULL, salt VARCHAR(255) DEFAULT NULL, password VARCHAR(255) NOT NULL, last_login TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, confirmation_token VARCHAR(180) DEFAULT NULL, password_requested_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, roles TEXT NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_957A647992FC23A8 ON fos_user (username_canonical)'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_957A6479A0D96FBF ON fos_user (email_canonical)'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_957A6479C05FB297 ON fos_user (confirmation_token)'); + $this->addSql('COMMENT ON COLUMN fos_user.roles IS \'(DC2Type:array)\''); + } + + public function down(Schema $schema) : void + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + + $this->addSql('DROP SEQUENCE fos_user_id_seq CASCADE'); + $this->addSql('DROP TABLE fos_user'); + } +} From 002a65d714ca5f5793452c533d6c1d59e4ac9214 Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Tue, 19 Mar 2019 14:50:17 +0100 Subject: [PATCH 09/13] Plug JWT authentication in the admin app --- admin/src/Admin.js | 54 +++++++++++++++++++++++++++++++++++++++ admin/src/App.js | 6 +++-- admin/src/authProvider.js | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 admin/src/Admin.js create mode 100644 admin/src/authProvider.js diff --git a/admin/src/Admin.js b/admin/src/Admin.js new file mode 100644 index 00000000000..06c4a92acda --- /dev/null +++ b/admin/src/Admin.js @@ -0,0 +1,54 @@ +import React from 'react'; +import parseHydraDocumentation from '@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation'; +import { + HydraAdmin, + hydraClient, + fetchHydra as baseFetchHydra, +} from '@api-platform/admin'; +import authProvider from './authProvider'; +import { Redirect } from 'react-router-dom'; + +const entrypoint = process.env.REACT_APP_API_ENTRYPOINT; +const fetchHeaders = { + Authorization: `Bearer ${window.localStorage.getItem('token')}`, +}; +const fetchHydra = (url, options = {}) => + baseFetchHydra(url, { + ...options, + headers: new Headers(fetchHeaders), + }); +const dataProvider = api => hydraClient(api, fetchHydra); +const apiDocumentationParser = entrypoint => + parseHydraDocumentation(entrypoint, { + headers: new Headers(fetchHeaders), + }).then( + ({ api }) => ({ api }), + result => { + switch (result.status) { + case 401: + return Promise.resolve({ + api: result.api, + customRoutes: [ + { + props: { + path: '/', + render: () => , + }, + }, + ], + }); + + default: + return Promise.reject(result); + } + }, + ); + +export default props => ( + +); diff --git a/admin/src/App.js b/admin/src/App.js index ef9c09670b5..3a6125d2dcb 100644 --- a/admin/src/App.js +++ b/admin/src/App.js @@ -1,4 +1,6 @@ import React from 'react'; -import { HydraAdmin } from '@api-platform/admin'; +import Admin from './Admin'; -export default () => ; +export default () => { + return ; +}; diff --git a/admin/src/authProvider.js b/admin/src/authProvider.js new file mode 100644 index 00000000000..91f4c0918a8 --- /dev/null +++ b/admin/src/authProvider.js @@ -0,0 +1,49 @@ +import { AUTH_LOGIN, AUTH_LOGOUT, AUTH_ERROR, AUTH_CHECK } from 'react-admin'; + +// Change this to be your own login check route. +const login_uri = `${process.env.REACT_APP_API_ENTRYPOINT}/login_check`; + +export default (type, params) => { + switch (type) { + case AUTH_LOGIN: + const { username, password } = params; + const request = new Request(`${login_uri}`, { + method: 'POST', + body: JSON.stringify({ login: username, password }), + headers: new Headers({ 'Content-Type': 'application/json' }), + }); + + return fetch(request) + .then(response => { + if (response.status < 200 || response.status >= 300) { + throw new Error(response.statusText); + } + + return response.json(); + }) + .then(({ token }) => { + localStorage.setItem('token', token); // The JWT token is stored in the browser's local storage + window.location.replace('/'); + }); + + case AUTH_LOGOUT: + localStorage.removeItem('token'); + break; + + case AUTH_ERROR: + if (401 === params.status) { + localStorage.removeItem('token'); + + return Promise.reject(); + } + break; + + case AUTH_CHECK: + return localStorage.getItem('token') + ? Promise.resolve() + : Promise.reject(); + + default: + return Promise.resolve(); + } +}; From 0124390e8123a613043ee0ee39b2d41930e65edb Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Wed, 20 Mar 2019 01:47:49 +0100 Subject: [PATCH 10/13] Fix JWT setup for Heroku deployment Issue is that JWT keys cannot be store on the filesystem. Proposal is to read them from ENV. --- api/.env | 6 +++--- api/config/packages/lexik_jwt_authentication.yaml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api/.env b/api/.env index b4ea271e429..bddb495b75f 100644 --- a/api/.env +++ b/api/.env @@ -25,9 +25,9 @@ CORS_ALLOW_ORIGIN=^https?://localhost(:[0-9]+)?$ VARNISH_URL=http://cache-proxy ###> lexik/jwt-authentication-bundle ### -JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem -JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem -JWT_PASSPHRASE=e9503436f63f37f6381616b3e8080536 +# JWT_PRIVATE_KEY=$(cat %kernel.project_dir%/config/jwt/private.pem | base64 | tr -d '\n') +# JWT_PUBLIC_KEY=$(cat %kernel.project_dir%/config/jwt/public.pem | base64 | tr -d '\n') +# JWT_PASSPHRASE=!ChangeMe! ###< lexik/jwt-authentication-bundle ### ###> symfony/swiftmailer-bundle ### diff --git a/api/config/packages/lexik_jwt_authentication.yaml b/api/config/packages/lexik_jwt_authentication.yaml index edfb69dc897..45a38337cfc 100644 --- a/api/config/packages/lexik_jwt_authentication.yaml +++ b/api/config/packages/lexik_jwt_authentication.yaml @@ -1,4 +1,4 @@ lexik_jwt_authentication: - secret_key: '%env(resolve:JWT_SECRET_KEY)%' - public_key: '%env(resolve:JWT_PUBLIC_KEY)%' + secret_key: '%env(base64:JWT_PRIVATE_KEY)%' + public_key: '%env(base64:JWT_PUBLIC_KEY)%' pass_phrase: '%env(JWT_PASSPHRASE)%' From 0017c19fc0a05a41bbd305c469349699fbf364a2 Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Tue, 19 Mar 2019 08:10:53 +0100 Subject: [PATCH 11/13] Makefile Start on localhost ``` make start fixtures EMAIL=admin@example.com make token EMAIL=user@example.com make token ``` Provision & Deploy ``` JWT_DIR=provision/jwt JWT_PASSPHRASE=$(openssl rand -base64 32) make provision # to provision deployment env make deploy ``` Cleaning ``` make clean make clean/all ``` Destroy (requires confirmation) ``` make destroy/api # interactive confirmation FORCE="--force" make destroy/admin # requires --force to confirm ``` --- .editorconfig | 3 + .gitignore | 8 +++ Makefile | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 Makefile diff --git a/.editorconfig b/.editorconfig index 975656e99aa..66437178111 100644 --- a/.editorconfig +++ b/.editorconfig @@ -78,3 +78,6 @@ indent_size = 2 [phpunit.xml{,.dist}] indent_style = space indent_size = 4 + +[Makefile] +indent_style = tab diff --git a/.gitignore b/.gitignore index 48bb83f67e9..8443f71b798 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,10 @@ +# Docker /docker-compose.override.yaml /docker-compose.override.yml + +# IDEs +.idea/ +.code/ + +# Makefile targets +provision diff --git a/Makefile b/Makefile new file mode 100644 index 00000000000..1859074cfec --- /dev/null +++ b/Makefile @@ -0,0 +1,178 @@ +#=============================================================================# +# JWT CONFIGURATION +#=============================================================================# +ifndef EMAIL +EMAIL=admin@example.com +endif +ifndef PASSWORD +PASSWORD=123456 +endif + +ifndef JWT_DIR +JWT_DIR=api/config/jwt +endif +JWT_PRIVATE_KEY=${JWT_DIR}/private.pem +JWT_PUBLIC_KEY=${JWT_DIR}/public.pem + +ifndef JWT_PASSPHRASE +JWT_PASSPHRASE=!ChangeMe! +endif + +${JWT_DIR}: + mkdir -p ${JWT_DIR} + +${JWT_PRIVATE_KEY}: ${JWT_DIR} + openssl genrsa -passout pass:${JWT_PASSPHRASE} -out $@ -aes256 4096 + +${JWT_PUBLIC_KEY}: ${JWT_PRIVATE_KEY} + openssl rsa -passin pass:${JWT_PASSPHRASE} -pubout -in $< -out $@ + +api/.env.local: ${JWT_PRIVATE_KEY} ${JWT_PUBLIC_KEY} + rm -f $@ + echo JWT_PASSPHRASE=$(JWT_PASSPHRASE) >> $@ + echo JWT_PRIVATE_KEY=`cat ${JWT_PRIVATE_KEY} | base64 | tr -d '\n'` >> $@ + echo JWT_PUBLIC_KEY=`cat ${JWT_PUBLIC_KEY} | base64 | tr -d '\n'` >> $@ + echo JWT_PRIVATE_KEY_FILE=%kernel.project_dir%/config/jwt/private.pem >> $@ + echo JWT_PUBLIC_KEY_FILE=%kernel.project_dir%/config/jwt/public.pem >> $@ + +clean/jwt: + rm -rf $(JWT_DIR) + + +#=============================================================================# +# INIT DEPLOYMENT TARGETS +#=============================================================================# +ifndef DEPLOYMENT_ENV +DEPLOYMENT_ENV=staging +endif +ifndef HEROKU_TEAM +HEROKU_TEAM=YOUR_TEAM +endif +ifndef HEROKU_REGION +HEROKU_REGION=eu +endif +ifndef AWS_REGION +AWS_REGION=eu-west-3 +endif + +API_APP_NAME=$(HEROKU_TEAM)-api-$(DEPLOYMENT_ENV) +API_HOST=$(HEROKU_TEAM)-api-$(DEPLOYMENT_ENV).herokuapp.com +API_URL=https://$(API_HOST) + +ADMIN_APP_NAME=$(HEROKU_TEAM)-admin-$(DEPLOYMENT_ENV) +ADMIN_BUCKET_URL=s3://$(ADMIN_APP_NAME) +ADMIN_URL=http://$(ADMIN_APP_NAME).s3-website.$(AWS_REGION).amazonaws.com + +provision/api/app: + heroku apps:create \ + --team $(HEROKU_TEAM) \ + --region $(HEROKU_REGION) \ + --remote $(DEPLOYMENT_ENV) \ + --buildpack https://github.com/negativetwelve/heroku-buildpack-subdir \ + --addons heroku-postgresql:hobby-dev \ + $(API_APP_NAME) + mkdir -p $@ + +provision/api/environment: provision/api/app ${JWT_PUBLIC_KEY} + heroku config:set -a $(API_APP_NAME) \ + APP_ENV=prod \ + APP_SECRET=$(shell openssl rand -base64 32) \ + CORS_ALLOW_ORIGIN=$(ADMIN_URL) \ + JWT_PASSPHRASE=$(JWT_PASSPHRASE) \ + JWT_PRIVATE_KEY=`cat ${JWT_PRIVATE_KEY} | base64 | tr -d '\n'` \ + JWT_PUBLIC_KEY=`cat ${JWT_PUBLIC_KEY} | base64 | tr -d '\n'` \ + TRUSTED_HOSTS=$(API_HOST) + mkdir -p $@ + +provision/api: provision/api/environment + +provision/admin: + aws s3 mb --region $(AWS_REGION) s3://$(HEROKU_TEAM)-admin-staging + aws s3 website $(ADMIN_BUCKET_URL) --index-document index.html --error-document index.html + mkdir -p $@ + +provision: provision/api provision/admin + +clean/provision: + rm -rf provision + +destroy/api: + heroku apps:destroy -a $(API_APP_NAME) + +destroy/admin: + aws s3 rb $(ADMIN_BUCKET_URL) $(FORCE) + +destroy: destroy/api destroy/admin + + +#=============================================================================# +# DEPLOYMENT TARGETS +#=============================================================================# +deploy/api: + git push $(FORCE) $(DEPLOYMENT_ENV) HEAD:master + +api/user: + heroku run -r $(DEPLOYMENT_ENV) ./api/bin/console fos:user:create + +api/token: + curl -X POST \ + -H "Content-Type: application/json" $(API_URL)/login_check \ + -d '{"login":"$(EMAIL)","password":"$(PASSWORD)"}' 2>/dev/null + +admin/build: install + echo REACT_APP_API_ENTRYPOINT=$(API_URL) >> admin/.env.production.local + docker-compose run admin /bin/sh -c 'yarn build' + +deploy/admin: admin/build + aws s3 sync $< $(ADMIN_BUCKET_URL) --acl public-read + # aws cloudfront create-invalidation --distribution-id $(AWS_CLOUDFRONT_DISTRIBUTION_ID) --paths "/*" + +deploy: deploy/api deploy/admin + +clean/deploy: + rm -f admin/.env.production.local + rm -rf admin/build + + +#=============================================================================# +# DOCKER TARGETS +#=============================================================================# +clean/docker/volumes: + docker system prune --volumes + +clean/docker: + docker system prune --all --force --volumes + + +#=============================================================================# +# GENERAL TARGETS +#=============================================================================# +update: + # update-deps.sh + +test: + @echo "TODO test" + +install: api/.env.local + +start: test install + docker-compose up -d + +fixtures: start + docker-compose exec php ./bin/console doctrine:fixtures:load + +token: + curl -X POST \ + -H "Content-Type: application/json" http://localhost:8080/login_check \ + -d '{"login":"$(EMAIL)","password":"$(PASSWORD)"}' + +stop: + docker-compose down + +clean: stop clean/deploy clean/jwt clean/docker/volumes + +clean/all: clean clean/provision clean/docker + +all: start + +.DEFAULT_GOAL := start From a97403100d7a18a8b7b8b64f0d8c243ec99ffefb Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Wed, 20 Mar 2019 16:45:38 +0100 Subject: [PATCH 12/13] sf make:subscriber --- api/src/EventSubscriber/UserSubscriber.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 api/src/EventSubscriber/UserSubscriber.php diff --git a/api/src/EventSubscriber/UserSubscriber.php b/api/src/EventSubscriber/UserSubscriber.php new file mode 100644 index 00000000000..a09a479585a --- /dev/null +++ b/api/src/EventSubscriber/UserSubscriber.php @@ -0,0 +1,21 @@ + 'onKernelRequest', + ]; + } +} From 6a9056ec71f35a7526561bc9e187ecf8b895a0b6 Mon Sep 17 00:00:00 2001 From: Pierre Beauhaire Date: Wed, 20 Mar 2019 16:49:42 +0100 Subject: [PATCH 13/13] /users/me --- api/src/EventSubscriber/UserSubscriber.php | 31 ++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/api/src/EventSubscriber/UserSubscriber.php b/api/src/EventSubscriber/UserSubscriber.php index a09a479585a..7d302af1d80 100644 --- a/api/src/EventSubscriber/UserSubscriber.php +++ b/api/src/EventSubscriber/UserSubscriber.php @@ -2,20 +2,47 @@ namespace App\EventSubscriber; +use ApiPlatform\Core\EventListener\EventPriorities; +use App\Entity\User; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\Security\Core\Security; class UserSubscriber implements EventSubscriberInterface { + private $security; + + public function __construct(Security $security) + { + $this->security = $security; + } + public function onKernelRequest(GetResponseEvent $event) { - // ... + $request = $event->getRequest(); + + if ('api_users_get_item' !== $request->attributes->get('_route')) { + return; + } + + if ('me' !== $request->attributes->get('id')) { + return; + } + + $user = $this->security->getUser(); + + if (!$user instanceof User) { + return; + } + + $request->attributes->set('id', $user->getId()); } public static function getSubscribedEvents() { return [ - 'kernel.request' => 'onKernelRequest', + 'kernel.request' => ['onKernelRequest', EventPriorities::PRE_READ] ]; } }