From 29b496e3e08d87e853118d78eac9697f1c4c2efa Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 5 Nov 2019 11:11:30 +0100 Subject: [PATCH 001/182] Updated tutorial with Travis --- .github/IMAGES/travis activate repository.PNG | Bin 0 -> 27995 bytes .../travis enviroment variables filed in.PNG | Bin 0 -> 59461 bytes .../IMAGES/travis enviroment variables.PNG | Bin 0 -> 28840 bytes DESIGN.md | 2 +- TUTORIAL.md | 31 +++++++++++++----- 5 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 .github/IMAGES/travis activate repository.PNG create mode 100644 .github/IMAGES/travis enviroment variables filed in.PNG create mode 100644 .github/IMAGES/travis enviroment variables.PNG diff --git a/.github/IMAGES/travis activate repository.PNG b/.github/IMAGES/travis activate repository.PNG new file mode 100644 index 0000000000000000000000000000000000000000..cd2f8b12afbae594e1eab220e140086742346301 GIT binary patch literal 27995 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�R0Y?x^TLJG^HkNXr07`A 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 literal 0 HcmV?d00001 diff --git a/.github/IMAGES/travis enviroment variables filed in.PNG b/.github/IMAGES/travis enviroment variables filed in.PNG new file mode 100644 index 0000000000000000000000000000000000000000..ddd960df6ef959290e5bfc51714fc33cf0b40e00 GIT binary patch literal 59461 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 literal 0 HcmV?d00001 diff --git a/.github/IMAGES/travis enviroment variables.PNG b/.github/IMAGES/travis enviroment variables.PNG new file mode 100644 index 0000000000000000000000000000000000000000..894de1a51ba1cdd60a8b3304e8f9f7c6c536fd1e GIT binary patch literal 28840 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 CubM6Z literal 0 HcmV?d00001 diff --git a/DESIGN.md b/DESIGN.md index 154ca104..84f37496 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -1,4 +1,4 @@ -#Design Considerations +# Design Considerations This component was designed inline with the [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index), [commonground principles](https://vng.nl/onderwerpenindex/bestuur/samen-organiseren-2019/common-ground) and international standards. diff --git a/TUTORIAL.md b/TUTORIAL.md index 2152ac73..45c1a8eb 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -1,11 +1,13 @@ # Tutorial What do you need for this tutorial? -* browser -* github account -* git client -* docker account -* docker for desktop +* Browser +* Github account +* Git client +* Docker account +* Docker for desktop + +## Bevore you begin ## Setting up your enviroment @@ -301,9 +303,22 @@ When using Github. To set up a webhook, go to the settings page of your reposito Now every time you update your repository the commonground dev page will allerted, rescan your repository and do al the apropriate platform actions. It just as easy as that. -Automated Testing +Automated Testing and Deployment (continues integration) ------- -adasd +The following bit of the tutorial requires two additional accounts +- [https://hub.docker.com/](https://hub.docker.com/) (You might already have this for docker for desktop) +- [https://travis-ci.org](https://travis-ci.org) (You can use you github account) + +The proto component ships with a pre-fab continues integration script based on travis. What does this mean you ask? Continues integration (or CI for short) is an optimized and automated way for your code to become part of your projects. In the case of your commonground component that means that we will automatically validate new code commites or pushes and (if everything checks out) build that code and deploy the containers thereof to docker hub. Making is possible to update al the environments that use those components. + +Oke that’s nice, but how do we do that? Actually it is verily simple. First of all make sure you have a docker account, log into [docker hub](https://hub.docker.com/) and have a look around. We don’t need to create anything just yet'but it is nice to get a feeling of the place. As you can see docker hub also uses repositories etc. So that recognizable. + +Next we need to prepare our github repository that holds our code. For the travis script to work as intended we need to create a couple of branches(if we don’t have those already) open up yout git interface and create a branch called 'development' and a branch called 'staging'. Don't forget to push the branches so that they are present on github (and not just on your local machine). + +Oke just one more place to go and that is travis, head over to [https://travis-ci.org](https://travis-ci.org) and login with your gitacount. If everything is alright you should see your repositoriy there. Activate it by pressing 'activate repository' and then go to 'More options' -> 'Settings' and scroll down to enviroment variables. Here we can present travis wit the variables that it need to execute our build script. Lets first set the common variables that we need for all our branches: `DOCKER_PASSWORD` your docker password,`DOCKER_REGISTRY` docker.io/[your username] ,`DOCKER_USERNAME` your docker user name. This will be used by travis to push the completed containers into docker hub. Next we need to specify a couple of variables that are branch specific. Or to be more exact, set the same variable `APP_ENV` with different values for different branches. It needs to be 'staging'->stag,'master'->prod,'development'->dev. + +And all done! Head over back to the code on your computer and make a small change. Then commit push that change into github. Travis should automatically pick op your change and start a build. + ### Unit / Behat @@ -316,7 +331,7 @@ Audittrail ------- as -Setting up continues integration and continues delivery +Setting up automated deployment (continues delivery) ------- adasd From 4be3d163d6c494bee1d7244d9b92549fb80f3770 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 5 Nov 2019 11:17:06 +0100 Subject: [PATCH 002/182] Updated the example entity --- api/src/Entity/ExampleEntity.php | 44 +++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php index f63f7a99..d70c98c4 100644 --- a/api/src/Entity/ExampleEntity.php +++ b/api/src/Entity/ExampleEntity.php @@ -20,21 +20,53 @@ */ class ExampleEntity { - /** - * @ORM\Id() - * @ORM\GeneratedValue() - * @ORM\Column(type="integer") - */ - private $id; + /** + * @var \Ramsey\Uuid\UuidInterface + * + * @ApiProperty( + * identifier=true, + * attributes={ + * "swagger_context"={ + * "description" = "The UUID identifier of this object", + * "type"="string", + * "format"="uuid", + * "example"="e2984465-190a-4562-829e-a8cca81aa35d" + * } + * } + * ) + * + * @Assert\Uuid + * @Groups({"read"}) + * @ORM\Id + * @ORM\Column(type="uuid", unique=true) + * @ORM\GeneratedValue(strategy="CUSTOM") + * @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator") + */ + private $id; /** + * @var string $name The name of this example property + * @example My Group + * + * @Assert\NotNull + * @Assert\Length( + * max = 255 + * ) * @Gedmo\Versioned + * @Groups({"read","write"}) * @ORM\Column(type="string", length=255) */ private $name; /** + * @var string $description The description of this example property + * @example Is the best group ever + * + * @Assert\Length( + * max = 2555 + * ) * @Gedmo\Versioned + * @Groups({"read","write"}) * @ORM\Column(type="text", nullable=true) */ private $description; From a968c69cf69ffeaf96404d012bc9fb075aef3304 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 5 Nov 2019 11:49:57 +0100 Subject: [PATCH 003/182] Added audit trail to documentation --- TUTORIAL.md | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/TUTORIAL.md b/TUTORIAL.md index 45c1a8eb..4f361b66 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -7,7 +7,8 @@ What do you need for this tutorial? * Docker account * Docker for desktop -## Bevore you begin +## Before you begin +For the steps consirning the generation of entities an example entity a availale, feel free to [take a look](https://github.com/ConductionNL/Proto-component-commonground/blob/master/api/src/Entity/ExampleEntity.php) at it if you have trouble figuring out the code. ## Setting up your enviroment @@ -327,9 +328,70 @@ adas ### Postman ad +Documentation and dockblocks +------- +asdsa + Audittrail ------- -as +As you might expect the proto-component ships with a neat function for generating audit trails, that basically exist of three parts. + +First we need to activate logging on the entities that we want logged (for obius security reasons we don’t log entity changes by default) to do that by adding the `@Gedmo\Loggable` annotation to our php class, which should then look something like: + +```PHP +//... +/** + * @ApiResource( + * normalizationContext={"groups"={"read"}, "enable_max_depth"=true}, + * denormalizationContext={"groups"={"write"}, "enable_max_depth"=true} + * ) + * @ORM\Entity(repositoryClass="App\Repository\ExampleEntityRepository") + * @Gedmo\Loggable + */ +class ExampleEntity + { +//... +``` + +Next we need to tell the specific properties that we want to log that they are loggable (again this is a conscious choice, to prevent us from accidently logging stuff like bsn numbers), we do that by adding the `@Gedmo\Versioned` annotation to those specific properties. That would then look something like this: + +```PHP +//... + /** + * @var string $name The name of this example property + * @example My Group + * + * @Assert\NotNull + * @Assert\Length( + * max = 255 + * ) + * @Gedmo\Versioned + * @Groups({"read","write"}) + * @ORM\Column(type="string", length=255) + */ + private $name; +//... +``` + +Okay actually we are now good to go, at least we are logging those things that we want logged. But.... How do we view those logs? In commonground we have a [convention](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail) to expose a /audittrail subresource on resources that are logged. So lets add that trough our `@ApiResource` anotation. + +```PHP +//... +/** + * @ApiResource( + * normalizationContext={"groups"={"read"}, "enable_max_depth"=true}, + * denormalizationContext={"groups"={"write"}, "enable_max_depth"=true} + * ) + * @ORM\Entity(repositoryClass="App\Repository\ExampleEntityRepository") + * @Gedmo\Loggable + */ +class ExampleEntity + { +//... +``` + +And now we have a fully nl api strategie integrated audit trail! + Setting up automated deployment (continues delivery) ------- From 1fff480f0eca12bf0da9609dd59f45c31a0fa6a9 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 5 Nov 2019 12:09:15 +0100 Subject: [PATCH 004/182] Added Doctrine Associations to tutorial --- TUTORIAL.md | 48 +++++++++++++++++++++++++++++++- api/src/Entity/ExampleEntity.php | 6 +++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/TUTORIAL.md b/TUTORIAL.md index 4f361b66..736a64e8 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -271,7 +271,7 @@ into this and your all done -### trouble shooting +### Rrouble shooting If you have already spunn your component including your new entity your going to run into some trouble becouse doctrine is going to try changing your primary key collum (id) from an integer to string (tables tend not to like that). In that case its best to just drop your database and reinstall it using the following commands: ```CLI @@ -279,6 +279,52 @@ $ bin/console doctrine:schema:drop $ bin/console doctrine:schema:update --force ``` +## Advanced data sets + +Oke lets make it complex, until now we have just added some simple entities to our component, but what if we want to ataches one entity to another? Fortunatly our build in database engine support rather complex senarios called associations. So let [take a look](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html) at that. + +Bafled? Wel its rather complex. But remember that Make:entity command that we used earlier? That actuelly accepts relations as a data type. Or to but it simply instead of using the default 'string' we could just type "ManyToOne" and it will just fire up some qoustions that will help it determine how you want your relations to be. + + +### Trouble shooting +A very common error when linking entities togehter is circle refrances, those will break our serializatoin. Furtunaltly we have a need way to prevent that. Even better symfony gives us exact control of how deep we want the circular refereance to go. To do this we need to use the `MaxDepth()` annotation. So lets import that + +```PHP +//... +use Symfony\Component\Serializer\Annotation\MaxDepth; +//... +``` + +And tell our serializer to use it. + +```PHP +//... +/** + * @ApiResource( + * normalizationContext={"groups"={"read"}, "enable_max_depth"=true}, + * denormalizationContext={"groups"={"write"}, "enable_max_depth"=true} + * ) + * @ORM\Entity(repositoryClass="App\Repository\ExampleEntityRepository") + */ +class ExampleEntity + { +//... +``` + +We can now prevent circular referances by setting a max depth on the properties cousing the circular refrance. + +//... + /** + * @var ArrayCollection $stuffs Some stuff that is atached to this example object + * + * @MaxDepth(1) + * @Groups({"read","write"}) + * @ORM\ManyToOne(targetEntity="App\Entity\Stuff", inversedBy="examples") + */ + private $stuffs; +//... +``` + ## Datafixtures For testing cases it can be usefull to use datafixtures a predefined set of data that fills the database of your component at startup. Since we use php classes to describe our objects creating fixtures is easy (you can find an example in your project folder at api/src/DataFixtures). We simply go trough some classes asign values and persist them to the database. Once we have written our fixtures we can use a single command to load them diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php index d70c98c4..3046b523 100644 --- a/api/src/Entity/ExampleEntity.php +++ b/api/src/Entity/ExampleEntity.php @@ -8,12 +8,16 @@ use ApiPlatform\Core\Annotation\ApiProperty; use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; +use Symfony\Component\Serializer\Annotation\MaxDepth; use App\Filter\LikeFilter; /** - * @ApiResource() + * @ApiResource( + * normalizationContext={"groups"={"read"}, "enable_max_depth"=true}, + * denormalizationContext={"groups"={"write"}, "enable_max_depth"=true} + * ) * @ORM\Entity(repositoryClass="App\Repository\ExampleEntityRepository") * @Gedmo\Loggable * @ApiFilter(LikeFilter::class, properties={"name","description"}) From 395a8269f3f14fcfeece84be6deb5bedaf0671f5 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 5 Nov 2019 14:00:06 +0100 Subject: [PATCH 005/182] Updated installation documentation --- INSTALLATION.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/INSTALLATION.md b/INSTALLATION.md index 2f8937c6..8370a085 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -65,17 +65,23 @@ $ helm dependency update ./api/helm If you want to create a new instance ```CLI -$ helm install ./api/helm --name protocomponent --kubeconfig="api/helm/kubeconfig.yaml" +$ helm install ./api/helm --name protocomponent-dev --kubeconfig="api/helm/kubeconfig.yaml --set settings.env=dev, settings.debug=1" +$ helm install ./api/helm --name protocomponent-stag --kubeconfig="api/helm/kubeconfig.yaml --set settings.env=stag, settings.debug=0" +$ helm install ./api/helm --name protocomponent-prod --kubeconfig="api/helm/kubeconfig.yaml --set settings.env=prod, settings.debug=0" ``` Or update if you want to update an existing one ```CLI -$ helm upgrade protocomponent ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" +$ helm upgrade protocomponent-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml --set settings.env=dev, settings.debug=1" +$ helm upgrade protocomponent-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml -set settings.env=stag, settings.debug=0" +$ helm upgrade protocomponent-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml --set settings.env=prod, settings.debug=0" ``` Or del if you want to delete an existing one ```CLI -$ helm del protocomponent --purge --kubeconfig="api/helm/kubeconfig.yaml" +$ helm del protocomponent-dev --purge --kubeconfig="api/helm/kubeconfig.yaml" +$ helm del protocomponent-stag --purge --kubeconfig="api/helm/kubeconfig.yaml" +$ helm del protocomponent-prod --purge --kubeconfig="api/helm/kubeconfig.yaml" ``` Note that you can replace commonground with the namespace that you want to use (normally the name of your component). From f43d22fc243cb36b5c5893779a6e125ebd2215b0 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 5 Nov 2019 15:16:49 +0100 Subject: [PATCH 006/182] Fix in helm docs --- INSTALLATION.md | 18 +++++++++--------- TUTORIAL.md | 3 +++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/INSTALLATION.md b/INSTALLATION.md index 8370a085..f78930a1 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -65,23 +65,23 @@ $ helm dependency update ./api/helm If you want to create a new instance ```CLI -$ helm install ./api/helm --name protocomponent-dev --kubeconfig="api/helm/kubeconfig.yaml --set settings.env=dev, settings.debug=1" -$ helm install ./api/helm --name protocomponent-stag --kubeconfig="api/helm/kubeconfig.yaml --set settings.env=stag, settings.debug=0" -$ helm install ./api/helm --name protocomponent-prod --kubeconfig="api/helm/kubeconfig.yaml --set settings.env=prod, settings.debug=0" +$ helm install --name pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1 +$ helm install --name pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0 +$ helm install --name pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0 ``` Or update if you want to update an existing one ```CLI -$ helm upgrade protocomponent-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml --set settings.env=dev, settings.debug=1" -$ helm upgrade protocomponent-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml -set settings.env=stag, settings.debug=0" -$ helm upgrade protocomponent-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml --set settings.env=prod, settings.debug=0" +$ helm upgrade pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml --namespace=dev --set settings.env=dev, settings.debug=1" +$ helm upgrade pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml --namespace=stag --set settings.env=stag, settings.debug=0" +$ helm upgrade pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml --namespace=prod --set settings.env=prod, settings.debug=0" ``` Or del if you want to delete an existing one ```CLI -$ helm del protocomponent-dev --purge --kubeconfig="api/helm/kubeconfig.yaml" -$ helm del protocomponent-stag --purge --kubeconfig="api/helm/kubeconfig.yaml" -$ helm del protocomponent-prod --purge --kubeconfig="api/helm/kubeconfig.yaml" +$ helm del pc-dev --purge --kubeconfig="api/helm/kubeconfig.yaml --namespace=dev" +$ helm del pc-stag --purge --kubeconfig="api/helm/kubeconfig.yaml --namespace=stag" +$ helm del pp-prod --purge --kubeconfig="api/helm/kubeconfig.yaml --namespace=prod" ``` Note that you can replace commonground with the namespace that you want to use (normally the name of your component). diff --git a/TUTORIAL.md b/TUTORIAL.md index 736a64e8..c3938e33 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -374,6 +374,9 @@ adas ### Postman ad +### Trouble shooting +Please make sure that your github repositry is set to public, and keep in mind that a complex travis build (and sertenly one that includes a pushing of containers can take up to 20 minutes) + Documentation and dockblocks ------- asdsa From 305c099dbd22c44e1a9dfd27dfdfc990e4172922 Mon Sep 17 00:00:00 2001 From: rjzondervan Date: Tue, 5 Nov 2019 15:23:45 +0100 Subject: [PATCH 007/182] Fixed some spelling mistakes in TUTORIAL.MD --- TUTORIAL.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/TUTORIAL.md b/TUTORIAL.md index c3938e33..63c93da6 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -30,7 +30,7 @@ Before we can spin up our component we must first get a local copy from our repo For this example where going to use GitKraken but you can use any tool you like, feel free to skip this part if you are already familiar with setting up a local clone of your repository. -Open gitkraken press "clone a repro" and fill in the form (select where on your local machine you want the repository to be stored, and fill in the link of your repository on github), press "clone a repro" and you should then see GitKraken downloading your code. After it's done press "open now" (in the box on top) and voilá your codebase (you should see an initial commit on a master branche). +Open gitkraken press "clone a repro" and fill in the form (select where on your local machine you want the repository to be stored, and fill in the link of your repository on github), press "clone a repro" and you should then see GitKraken downloading your code. After it's done press "open now" (in the box on top) and voilá your codebase (you should see an initial commit on a master branche). You can now navigate to the folder where you just installed your code, it should contain some folders and files and generally look like this. We will get into the files later, lets first spin up our component! @@ -356,13 +356,13 @@ The following bit of the tutorial requires two additional accounts - [https://hub.docker.com/](https://hub.docker.com/) (You might already have this for docker for desktop) - [https://travis-ci.org](https://travis-ci.org) (You can use you github account) -The proto component ships with a pre-fab continues integration script based on travis. What does this mean you ask? Continues integration (or CI for short) is an optimized and automated way for your code to become part of your projects. In the case of your commonground component that means that we will automatically validate new code commites or pushes and (if everything checks out) build that code and deploy the containers thereof to docker hub. Making is possible to update al the environments that use those components. +The proto component ships with a pre-fab continues integration script based on travis. What does this mean you ask? Continuous integration (or CI for short) is an optimized and automated way for your code to become part of your projects. In the case of your commonground component that means that we will automatically validate new code commites or pushes and (if everything checks out) build that code and deploy the containers thereof to docker hub. Making is possible to update al the environments that use those components. -Oke that’s nice, but how do we do that? Actually it is verily simple. First of all make sure you have a docker account, log into [docker hub](https://hub.docker.com/) and have a look around. We don’t need to create anything just yet'but it is nice to get a feeling of the place. As you can see docker hub also uses repositories etc. So that recognizable. +Oke that's nice, but how do we do that? Actually it is very simple. First of all make sure you have a docker account, log into [docker hub](https://hub.docker.com/) and have a look around. We don't need to create anything just yet'but it is nice to get a feeling of the place. As you can see docker hub also uses repositories etc. So that recognizable. -Next we need to prepare our github repository that holds our code. For the travis script to work as intended we need to create a couple of branches(if we don’t have those already) open up yout git interface and create a branch called 'development' and a branch called 'staging'. Don't forget to push the branches so that they are present on github (and not just on your local machine). +Next we need to prepare our github repository that holds our code. For the travis script to work as intended we need to create a couple of branches(if we don't have those already) open up yout git interface and create a branch called 'development' and a branch called 'staging'. Don't forget to push the branches so that they are present on github (and not just on your local machine). -Oke just one more place to go and that is travis, head over to [https://travis-ci.org](https://travis-ci.org) and login with your gitacount. If everything is alright you should see your repositoriy there. Activate it by pressing 'activate repository' and then go to 'More options' -> 'Settings' and scroll down to enviroment variables. Here we can present travis wit the variables that it need to execute our build script. Lets first set the common variables that we need for all our branches: `DOCKER_PASSWORD` your docker password,`DOCKER_REGISTRY` docker.io/[your username] ,`DOCKER_USERNAME` your docker user name. This will be used by travis to push the completed containers into docker hub. Next we need to specify a couple of variables that are branch specific. Or to be more exact, set the same variable `APP_ENV` with different values for different branches. It needs to be 'staging'->stag,'master'->prod,'development'->dev. +Oke just one more place to go and that is travis, head over to [https://travis-ci.org](https://travis-ci.org) and login with your gitacount. If everything is alright you should see your repository there. Activate it by pressing 'activate repository' and then go to 'More options' -> 'Settings' and scroll down to enviroment variables. Here we can present travis wit the variables that it need to execute our build script. Lets first set the common variables that we need for all our branches: `DOCKER_PASSWORD` your docker password,`DOCKER_REGISTRY` docker.io/[your username] ,`DOCKER_USERNAME` your docker user name. This will be used by travis to push the completed containers into docker hub. Next we need to specify a couple of variables that are branch specific. Or to be more exact, set the same variable `APP_ENV` with different values for different branches. It needs to be 'staging'->stag,'master'->prod,'development'->dev. And all done! Head over back to the code on your computer and make a small change. Then commit push that change into github. Travis should automatically pick op your change and start a build. @@ -385,7 +385,7 @@ Audittrail ------- As you might expect the proto-component ships with a neat function for generating audit trails, that basically exist of three parts. -First we need to activate logging on the entities that we want logged (for obius security reasons we don’t log entity changes by default) to do that by adding the `@Gedmo\Loggable` annotation to our php class, which should then look something like: +First we need to activate logging on the entities that we want logged (for obius security reasons we donÂ’t log entity changes by default) to do that by adding the `@Gedmo\Loggable` annotation to our php class, which should then look something like: ```PHP //... From 8b6bd1d64982e1b6bd09754d61c64a40af193fdb Mon Sep 17 00:00:00 2001 From: rjzondervan Date: Tue, 5 Nov 2019 16:19:33 +0100 Subject: [PATCH 008/182] Some more typofixing --- TUTORIAL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TUTORIAL.md b/TUTORIAL.md index 63c93da6..b55d4f66 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -30,7 +30,7 @@ Before we can spin up our component we must first get a local copy from our repo For this example where going to use GitKraken but you can use any tool you like, feel free to skip this part if you are already familiar with setting up a local clone of your repository. -Open gitkraken press "clone a repro" and fill in the form (select where on your local machine you want the repository to be stored, and fill in the link of your repository on github), press "clone a repro" and you should then see GitKraken downloading your code. After it's done press "open now" (in the box on top) and voilá your codebase (you should see an initial commit on a master branche). +Open gitkraken press "clone a repro" and fill in the form (select where on your local machine you want the repository to be stored, and fill in the link of your repository on github), press "clone a repro" and you should then see GitKraken downloading your code. After it's done press "open now" (in the box on top) and voilá your codebase (you should see an initial commit on a master branche). You can now navigate to the folder where you just installed your code, it should contain some folders and files and generally look like this. We will get into the files later, lets first spin up our component! @@ -385,7 +385,7 @@ Audittrail ------- As you might expect the proto-component ships with a neat function for generating audit trails, that basically exist of three parts. -First we need to activate logging on the entities that we want logged (for obius security reasons we donÂ’t log entity changes by default) to do that by adding the `@Gedmo\Loggable` annotation to our php class, which should then look something like: +First we need to activate logging on the entities that we want logged (for obvious security reasons we don't log entity changes by default) to do that by adding the `@Gedmo\Loggable` annotation to our php class, which should then look something like: ```PHP //... From 384081c92cdcfff2b05340b62d80b2c293599710 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 6 Nov 2019 07:12:31 +0100 Subject: [PATCH 009/182] Test for configurable varnish container --- DESIGN.md | 9 +++ INSTALLATION.md | 6 +- TUTORIAL.md | 5 +- api/Dockerfile | 1 + api/docker/varnish/conf/agent_secret | 1 + api/docker/varnish/conf/varnish.vcl | 83 ++++++++++++++++++++++ api/helm/templates/api-deployment.yaml | 10 +++ api/helm/templates/varnish-deployment.yaml | 11 +++ docker-compose.yml | 4 +- 9 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 api/docker/varnish/conf/agent_secret create mode 100644 api/docker/varnish/conf/varnish.vcl diff --git a/DESIGN.md b/DESIGN.md index 84f37496..edcb7692 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -4,6 +4,15 @@ This component was designed inline with the [NL API Strategie](https://docs.geos The spefic goal of this component is to provide a common architecture for common ground components as such the common ground principles are leading in design choices, and within those principles technological invoation and international complyancy is deemd most inportant. WE DO NOT WANT TO MAKE CONSESIONS TO CURRENT INFRASTRUCTURE. As such the component might differ on [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index) and other standards if they are deemed incompatible or out of line with international standards. +The European factor +------- +The proto-component isn't just a Dutch Component, it is in easance a dutch translation of european components, nowhere is this more obvius than in the core code. Our component is based on [API Platform](https://api-platform.com/) an API specific version of the symfony framework. This framework is build by the lovely people of []() and is build with support of the Euroean Commision trough the [EU-FOSSA Hackathon](https://ec.europa.eu/info/news/first-eu-fossa-hackathon-it-happened-2019-may-03_en) and Digital Ocean trough [Hacktoberfest].(https://hacktoberfest.digitalocean.com/). + +But it dosn't just end there the [varnish container](https://hub.docker.com/r/eeacms/varnish/) that we use to speed up the API responce it build and maintained by [EEA]() (The European Environment Agency) and the development team at conduction itself is attached to the [Odyssey program](https://www.odyssey.org/) and originated from the [startupinresidence](https://startupinresidence.com/) program. + +So you could say that both change and a european perspective is in our blood. + + Domain Build-up and routing ------- By convention the component assumes that you follow the common ground domain name build up, meaning {enviroment}.{component}.{rest of domain}. That means that only the first two url parts are used for routing. It is also assumed that when no envirment is supplied the production enviroment should be offerd E.g. a propper domain for the production API of the verzoeken registratie component would be prod.vrc.zaakonline.nl but it should also be reachable under vrc.zaakonline.nl. The proper location for the development enviroment shoud always be dev.vrc.zaakonlin.nl diff --git a/INSTALLATION.md b/INSTALLATION.md index f78930a1..8b25f6c1 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -72,9 +72,9 @@ $ helm install --name pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" Or update if you want to update an existing one ```CLI -$ helm upgrade pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml --namespace=dev --set settings.env=dev, settings.debug=1" -$ helm upgrade pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml --namespace=stag --set settings.env=stag, settings.debug=0" -$ helm upgrade pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml --namespace=prod --set settings.env=prod, settings.debug=0" +$ helm upgrade pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1 +$ helm upgrade pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0 +$ helm upgrade pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0 ``` Or del if you want to delete an existing one diff --git a/TUTORIAL.md b/TUTORIAL.md index c3938e33..e7bff411 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -358,7 +358,7 @@ The following bit of the tutorial requires two additional accounts The proto component ships with a pre-fab continues integration script based on travis. What does this mean you ask? Continues integration (or CI for short) is an optimized and automated way for your code to become part of your projects. In the case of your commonground component that means that we will automatically validate new code commites or pushes and (if everything checks out) build that code and deploy the containers thereof to docker hub. Making is possible to update al the environments that use those components. -Oke that’s nice, but how do we do that? Actually it is verily simple. First of all make sure you have a docker account, log into [docker hub](https://hub.docker.com/) and have a look around. We don’t need to create anything just yet'but it is nice to get a feeling of the place. As you can see docker hub also uses repositories etc. So that recognizable. +Oke that’s nice, but how do we do that? Actually it is verily simple. First of all make sure you have a docker account, log into [docker hub](https://hub.docker.com/) and have a look around. We don’t need to create anything just yet'but it is nice to get a feeling of the place. As you can see docker hub also uses repositories etc. So that recognizable. But we do need to inform the component that the containers need to be pushed to YOUR docker hub. So take a look at the .env file in your repositor root and find the `CONTAINER_REGISTRY_BASE` that probably now states something like 'docker.io/conduction' change that into 'docker.io/[your docker user name]'. Next we need to prepare our github repository that holds our code. For the travis script to work as intended we need to create a couple of branches(if we don’t have those already) open up yout git interface and create a branch called 'development' and a branch called 'staging'. Don't forget to push the branches so that they are present on github (and not just on your local machine). @@ -375,8 +375,7 @@ adas ad ### Trouble shooting -Please make sure that your github repositry is set to public, and keep in mind that a complex travis build (and sertenly one that includes a pushing of containers can take up to 20 minutes) - +Please make sure that your github repositry is set to public, and keep in mind that a complex travis build (and sertenly one that includes a pushing of containers can take up to 20 minutes). Documentation and dockblocks ------- asdsa diff --git a/api/Dockerfile b/api/Dockerfile index 3e02fac6..dc0614c1 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -147,6 +147,7 @@ RUN apk --no-cache add gettext COPY docker/varnish/conf /usr/local/etc/varnish/ RUN envsubst '$PHP_SERVICE' < /usr/local/etc/varnish/default.vcl.template > /usr/local/etc/varnish/default.vcl +#RUN reload # Lets parse the toml file # RUN envsubst < /usr/local/etc/varnish/default.vcl.template > /usr/local/etc/varnish/default.vcl diff --git a/api/docker/varnish/conf/agent_secret b/api/docker/varnish/conf/agent_secret new file mode 100644 index 00000000..8a5c9a66 --- /dev/null +++ b/api/docker/varnish/conf/agent_secret @@ -0,0 +1 @@ +admin:admin diff --git a/api/docker/varnish/conf/varnish.vcl b/api/docker/varnish/conf/varnish.vcl new file mode 100644 index 00000000..cfb1c06a --- /dev/null +++ b/api/docker/varnish/conf/varnish.vcl @@ -0,0 +1,83 @@ +vcl 4.0; + +import std; + + +# Hosts allowed to send BAN requests +acl invalidators { + "localhost"; + "php"; + # local Kubernetes network + "10.0.0.0"/8; + "172.16.0.0"/12; + "192.168.0.0"/16; +} + +sub vcl_recv { + if (req.restarts > 0) { + set req.hash_always_miss = true; + } + + # Remove the "Forwarded" HTTP header if exists (security) + unset req.http.forwarded; + + # To allow API Platform to ban by cache tags + if (req.method == "BAN") { + if (client.ip !~ invalidators) { + return (synth(405, "Not allowed")); + } + + if (req.http.ApiPlatform-Ban-Regex) { + ban("obj.http.Cache-Tags ~ " + req.http.ApiPlatform-Ban-Regex); + + return (synth(200, "Ban added")); + } + + return (synth(400, "ApiPlatform-Ban-Regex HTTP header must be set.")); + } + + # For health checks + if (req.method == "GET" && req.url == "/healthz") { + return (synth(200, "OK")); + } +} + +sub vcl_hit { + if (obj.ttl >= 0s) { + # A pure unadulterated hit, deliver it + return (deliver); + } + + if (std.healthy(req.backend_hint)) { + # The backend is healthy + # Fetch the object from the backend + return (restart); + } + + # No fresh object and the backend is not healthy + if (obj.ttl + obj.grace > 0s) { + # Deliver graced object + # Automatically triggers a background fetch + return (deliver); + } + + # No valid object to deliver + # No healthy backend to handle request + # Return error + return (synth(503, "API is down")); +} + +sub vcl_deliver { + # Don't send cache tags related headers to the client + unset resp.http.url; + # Comment the following line to send the "Cache-Tags" header to the client (e.g. to use CloudFlare cache tags) + unset resp.http.Cache-Tags; +} + +sub vcl_backend_response { + # Ban lurker friendly header + set beresp.http.url = bereq.url; + + # Add a grace in case the backend is down + set beresp.grace = 1h; +} diff --git a/api/helm/templates/api-deployment.yaml b/api/helm/templates/api-deployment.yaml index 28a49457..78a34dfb 100644 --- a/api/helm/templates/api-deployment.yaml +++ b/api/helm/templates/api-deployment.yaml @@ -31,6 +31,16 @@ spec: configMapKeyRef: name: {{ template "fullname" . }} key: php-service + - name: NGINX_HOST + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: php-service + - name: BACKENDS + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: php-service resources: {{ toYaml .Values.resources | indent 12 }} {{- if .Values.nodeSelector }} diff --git a/api/helm/templates/varnish-deployment.yaml b/api/helm/templates/varnish-deployment.yaml index 87a4bcb7..73933c05 100644 --- a/api/helm/templates/varnish-deployment.yaml +++ b/api/helm/templates/varnish-deployment.yaml @@ -27,6 +27,17 @@ spec: args: ["-F", "-f", "/usr/local/etc/varnish/default.vcl", "-p", "http_resp_hdr_len=65536", "-p", "http_resp_size=98304"] ports: - containerPort: 80 + env: + - name: PHP_SERVICE + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: php-service + - name: NGINX_HOST + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: php-service livenessProbe: httpGet: path: /healthz diff --git a/docker-compose.yml b/docker-compose.yml index 0663610f..70cc9c42 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -79,7 +79,9 @@ services: ports: - "8081:80" environment: - - PHP_SERVICE=api + - PHP_SERVICE=php + - BACKENDS=php + - BACKENDS_PORT=80 nlx-outway: image: ${CONTAINER_REGISTRY_BASE}/${CONTAINER_PROJECT_NAME}-nlx-outway:${APP_ENV} From d432e535d3db5c7933f92bc0e465fa41256c2af7 Mon Sep 17 00:00:00 2001 From: rjzondervan Date: Thu, 7 Nov 2019 14:22:43 +0100 Subject: [PATCH 010/182] Added missing uses to prevent build or execution errors --- api/src/Entity/ExampleEntity.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php index 3046b523..6fde0bc3 100644 --- a/api/src/Entity/ExampleEntity.php +++ b/api/src/Entity/ExampleEntity.php @@ -8,6 +8,8 @@ use ApiPlatform\Core\Annotation\ApiProperty; use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; +use Symfony\Component\Validator\Constraints as Assert; +use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Annotation\MaxDepth; From d596297b9782719e2b409c0ea738c4508a472753 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 11 Nov 2019 08:06:07 +0100 Subject: [PATCH 011/182] Update to the "main" component service That is now inline with deployment strategy --- api/helm/templates/api-service.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/helm/templates/api-service.yaml b/api/helm/templates/api-service.yaml index 5eaba6fb..7f198043 100644 --- a/api/helm/templates/api-service.yaml +++ b/api/helm/templates/api-service.yaml @@ -1,9 +1,9 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-api + name: {{ include "name" . }}-{{ .Values.settings.env }} labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-api + app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }} app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} helm.sh/chart: {{ include "chart" . }} app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} From 6e0e0b7690ed15413408e5164d33e64e52874e07 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 11 Nov 2019 12:07:41 +0100 Subject: [PATCH 012/182] Test for varnish trough the eeacms/varnish component --- CHANGELOG.md | 5 + api/Dockerfile | 11 +- api/docker/varnish/conf/agent_secret | 1 + api/docker/varnish/conf/default.vcl | 30 +-- api/helm/templates/api-deployment.yaml | 16 +- api/helm/templates/api-loadbalancer.yaml | 6 +- api/helm/templates/api-service.yaml | 12 +- api/helm/templates/php-deployment.yaml | 21 +- api/helm/templates/php-service.yaml | 12 +- api/helm/templates/varnish-deployment.yaml | 17 +- api/helm/templates/varnish-service.yaml | 12 +- api/helm/values.yaml | 1 + api/public/schema/openapi.yaml | 224 +++++++++++++++------ docker-compose.yml | 2 +- 14 files changed, 235 insertions(+), 135 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 api/docker/varnish/conf/agent_secret diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..12501b42 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 2019-11-11 (v.0.0.1) + +- Initial public release \ No newline at end of file diff --git a/api/Dockerfile b/api/Dockerfile index 3e02fac6..1b028ba9 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -137,16 +137,17 @@ COPY --from=api_platform_php /srv/api/public public/ # "varnish" stage # ############################# # does not depend on any of the above stages, but placed here to keep everything in one Dockerfile -FROM cooptilleuls/varnish:${VARNISH_VERSION}-alpine AS api_platform_varnish -#FROM eeacms/varnish AS api_platform_varnish +#FROM cooptilleuls/varnish:${VARNISH_VERSION}-alpine AS api_platform_varnish +FROM eeacms/varnish AS api_platform_varnish #FROM varnish:6.3 AS api_platform_varnish +COPY docker/varnish/conf/default.vcl /etc/varnish/conf.d/ # Lets install envsubst -RUN apk --no-cache add gettext +#RUN apk --no-cache add gettext -COPY docker/varnish/conf /usr/local/etc/varnish/ +#COPY docker/varnish/conf /usr/local/etc/varnish/ -RUN envsubst '$PHP_SERVICE' < /usr/local/etc/varnish/default.vcl.template > /usr/local/etc/varnish/default.vcl +#RUN envsubst '$PHP_SERVICE' < /usr/local/etc/varnish/default.vcl.template > /usr/local/etc/varnish/default.vcl # Lets parse the toml file # RUN envsubst < /usr/local/etc/varnish/default.vcl.template > /usr/local/etc/varnish/default.vcl diff --git a/api/docker/varnish/conf/agent_secret b/api/docker/varnish/conf/agent_secret new file mode 100644 index 00000000..8a5c9a66 --- /dev/null +++ b/api/docker/varnish/conf/agent_secret @@ -0,0 +1 @@ +admin:admin diff --git a/api/docker/varnish/conf/default.vcl b/api/docker/varnish/conf/default.vcl index ee4b45c3..ff8d2496 100644 --- a/api/docker/varnish/conf/default.vcl +++ b/api/docker/varnish/conf/default.vcl @@ -1,10 +1,10 @@ vcl 4.0; -import std; +#import std; -backend default { - .host = "php"; - .port = "80"; +#backend default { + # .host = "php"; + # .port = "80"; # Health check #.probe = { # .url = "/"; @@ -13,17 +13,17 @@ backend default { # .window = 5; # .threshold = 3; #} -} +#} # Hosts allowed to send BAN requests -acl invalidators { - "localhost"; - "php"; +#acl invalidators { +# "localhost"; +# "php"; # local Kubernetes network - "10.0.0.0"/8; - "172.16.0.0"/12; - "192.168.0.0"/16; -} +# "10.0.0.0"/8; +# "172.16.0.0"/12; +# "192.168.0.0"/16; +#} sub vcl_recv { if (req.restarts > 0) { @@ -35,9 +35,9 @@ sub vcl_recv { # To allow API Platform to ban by cache tags if (req.method == "BAN") { - if (client.ip !~ invalidators) { - return (synth(405, "Not allowed")); - } + #if (client.ip !~ invalidators) { + # return (synth(405, "Not allowed")); + #} if (req.http.ApiPlatform-Ban-Regex) { ban("obj.http.Cache-Tags ~ " + req.http.ApiPlatform-Ban-Regex); diff --git a/api/helm/templates/api-deployment.yaml b/api/helm/templates/api-deployment.yaml index 28a49457..2a195137 100644 --- a/api/helm/templates/api-deployment.yaml +++ b/api/helm/templates/api-deployment.yaml @@ -1,26 +1,26 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx + name: {{ include "name" . }}-nginx labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-nginx + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: replicas: 1 template: metadata: labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-nginx + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: containers: - - name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx + - name: {{ include "name" . }}-nginx image: "{{ .Values.settings.registryBase }}/{{ .Values.settings.projectName }}-nginx:{{ .Values.settings.env }}" imagePullPolicy: {{ .Values.settings.pullPolicy }} ports: diff --git a/api/helm/templates/api-loadbalancer.yaml b/api/helm/templates/api-loadbalancer.yaml index 770eb5bd..67a2f44a 100644 --- a/api/helm/templates/api-loadbalancer.yaml +++ b/api/helm/templates/api-loadbalancer.yaml @@ -2,11 +2,11 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-api-loadbalancer + name: {{ include "name" . }}-api-loadbalancer spec: selector: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-nginx + app.kubernetes.io/instance: {{ .Release.Name }} type: LoadBalancer ports: - protocol: TCP diff --git a/api/helm/templates/api-service.yaml b/api/helm/templates/api-service.yaml index 7f198043..6915c2ca 100644 --- a/api/helm/templates/api-service.yaml +++ b/api/helm/templates/api-service.yaml @@ -1,12 +1,12 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }} + name: {{ include "name" . }} labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }} - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . } + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: type: NodePort @@ -15,5 +15,5 @@ spec: targetPort: 80 protocol: TCP selector: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-nginx + app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index 4baa30aa..bd471b70 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -1,26 +1,26 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-php + name: {{ include "name" . }}-php labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-php - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-php + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: replicas: {{ .Values.php.replicaCount }} template: metadata: labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-php - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-php + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: containers: - - name: {{ include "name" . }}-{{ .Values.settings.env }}-php + - name: {{ include "name" . }}-php image: "{{ .Values.settings.registryBase }}/{{ .Values.settings.projectName }}-php:{{ .Values.settings.env }}" imagePullPolicy: {{ .Values.settings.pullPolicy }} ports: @@ -63,10 +63,7 @@ spec: name: {{ template "fullname" . }} key: cors-allow-origin - name: VARNISH_URL - valueFrom: - configMapKeyRef: - name: {{ template "fullname" . }} - key: varnish-url + value: {{ include "name" . }}-varnish - name: APP_SECRET valueFrom: secretKeyRef: diff --git a/api/helm/templates/php-service.yaml b/api/helm/templates/php-service.yaml index ce957939..7f213a47 100644 --- a/api/helm/templates/php-service.yaml +++ b/api/helm/templates/php-service.yaml @@ -1,17 +1,17 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-php + name: {{ include "name" . }}-php labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-php - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-php + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: type: ClusterIP ports: - port: 9000 selector: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-php - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-php + app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/api/helm/templates/varnish-deployment.yaml b/api/helm/templates/varnish-deployment.yaml index 87a4bcb7..325f938f 100644 --- a/api/helm/templates/varnish-deployment.yaml +++ b/api/helm/templates/varnish-deployment.yaml @@ -2,19 +2,19 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish + name: {{ include "name" . }}-varnish labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-varnish + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: replicas: {{ .Values.varnish.replicaCount }} template: metadata: labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish + app.kubernetes.io/name: {{ include "name" . }}-varnish helm.sh/chart: {{ include "chart" . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} @@ -23,8 +23,11 @@ spec: - name: {{ include "name" . }}-varnish image: "{{ .Values.settings.registryBase }}/{{ .Values.settings.projectName }}-varnish:{{ .Values.settings.env }}" imagePullPolicy: {{ .Values.settings.pullPolicy }} - command: ["varnishd"] - args: ["-F", "-f", "/usr/local/etc/varnish/default.vcl", "-p", "http_resp_hdr_len=65536", "-p", "http_resp_size=98304"] + env: + - name: BACKENDS + value: {{ include "name" . }}-php + #command: ["varnishd"] + #args: ["-F", "-f", "/usr/local/etc/varnish/default.vcl", "-p", "http_resp_hdr_len=65536", "-p", "http_resp_size=98304"] ports: - containerPort: 80 livenessProbe: diff --git a/api/helm/templates/varnish-service.yaml b/api/helm/templates/varnish-service.yaml index 9c90c4da..7943479f 100644 --- a/api/helm/templates/varnish-service.yaml +++ b/api/helm/templates/varnish-service.yaml @@ -2,12 +2,12 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish + name: {{ include "name" . }}-varnish labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-varnish + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: type: NodePort @@ -16,6 +16,6 @@ spec: targetPort: 80 protocol: TCP selector: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-varnish + app.kubernetes.io/instance: {{ .Release.Name }} {{- end -}} diff --git a/api/helm/values.yaml b/api/helm/values.yaml index b53a056a..fd5426c0 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -5,6 +5,7 @@ settings: registryBase: docker.io/conduction projectName: pc + version: dev env: dev debug: 1 replicaCount: 1 diff --git a/api/public/schema/openapi.yaml b/api/public/schema/openapi.yaml index 753a595d..cb1cc166 100644 --- a/api/public/schema/openapi.yaml +++ b/api/public/schema/openapi.yaml @@ -32,42 +32,42 @@ paths: schema: type: array items: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/ld+json: schema: type: array items: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/vnd.api+json: schema: type: array items: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/json: schema: type: array items: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/xml: schema: type: array items: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/x-yaml: schema: type: array items: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' text/csv: schema: type: array items: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' text/html: schema: type: array items: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' parameters: - name: like_name @@ -117,6 +117,44 @@ paths: name: X-Audit-Clarification description: 'A clarification as to why a request has been made (doelbinding)' in: header + - + name: 'extend[]' + required: false + description: 'An array of nested objects to include in the return object' + in: query + schema: + type: array + - + name: 'fields[]' + required: false + description: 'An array of fields to return in output, wil return all fields is not supplied' + in: query + schema: + type: array + - + name: validOn + required: false + description: 'Returns object as valid on a given date time' + schema: + type: string + format: date-time + in: query + - + name: validFrom + required: false + description: 'Returns objects valid from a given date time' + schema: + type: string + format: date-time + in: query + - + name: validUntil + required: false + description: 'Returns objects valid until a given date time' + schema: + type: string + format: date-time + in: query post: tags: - ExampleEntity @@ -128,28 +166,28 @@ paths: content: application/hal+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/vnd.api+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/xml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/x-yaml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' text/csv: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' text/html: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' links: GetExampleEntityItem: parameters: @@ -164,28 +202,28 @@ paths: content: application/hal+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/vnd.api+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/xml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/x-yaml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' text/csv: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' text/html: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' description: 'The new ExampleEntity resource' parameters: - @@ -259,34 +297,72 @@ paths: name: X-Audit-Clarification description: 'A clarification as to why a request has been made (doelbinding)' in: header + - + name: 'extend[]' + required: false + description: 'An array of nested objects to include in the return object' + in: query + schema: + type: array + - + name: 'fields[]' + required: false + description: 'An array of fields to return in output, wil return all fields is not supplied' + in: query + schema: + type: array + - + name: validOn + required: false + description: 'Returns object as valid on a given date time' + schema: + type: string + format: date-time + in: query + - + name: validFrom + required: false + description: 'Returns objects valid from a given date time' + schema: + type: string + format: date-time + in: query + - + name: validUntil + required: false + description: 'Returns objects valid until a given date time' + schema: + type: string + format: date-time + in: query responses: 200: description: 'ExampleEntity resource response' content: application/hal+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/vnd.api+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/xml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/x-yaml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' text/csv: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' text/html: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' 404: description: 'Resource not found' delete: @@ -382,28 +458,28 @@ paths: content: application/hal+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/vnd.api+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/xml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/x-yaml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' text/csv: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' text/html: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' 400: description: 'Invalid input' 404: @@ -412,28 +488,28 @@ paths: content: application/hal+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/vnd.api+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/xml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/x-yaml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' text/csv: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' text/html: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' description: 'The updated ExampleEntity resource' patch: tags: @@ -482,28 +558,28 @@ paths: content: application/hal+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/vnd.api+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/xml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' application/x-yaml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' text/csv: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' text/html: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-read' 400: description: 'Invalid input' 404: @@ -512,41 +588,57 @@ paths: content: application/hal+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/vnd.api+json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/json: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/xml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' application/x-yaml: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' text/csv: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' text/html: schema: - $ref: '#/components/schemas/ExampleEntity' + $ref: '#/components/schemas/ExampleEntity-write' description: 'The updated ExampleEntity resource' components: schemas: - ExampleEntity: + ExampleEntity-read: type: object description: '' properties: id: readOnly: true - type: integer + type: string + name: + description: 'The name of this example property' + type: string + description: + description: 'The description of this example property' + type: string + required: + - name + ExampleEntity-write: + type: object + description: '' + required: + - name + properties: name: + description: 'The name of this example property' type: string description: + description: 'The description of this example property' type: string host: irc.zaakonline.nl servers: diff --git a/docker-compose.yml b/docker-compose.yml index 0663610f..1506d754 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -79,7 +79,7 @@ services: ports: - "8081:80" environment: - - PHP_SERVICE=api + - BACKENDS=php nlx-outway: image: ${CONTAINER_REGISTRY_BASE}/${CONTAINER_PROJECT_NAME}-nlx-outway:${APP_ENV} From 68ca8649728edc08362dcf0420d651cfe308b770 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 11 Nov 2019 14:55:09 +0100 Subject: [PATCH 013/182] Helm fixes --- api/helm/templates/api-deployment.yaml | 15 +++------------ api/helm/templates/api-service.yaml | 2 +- api/helm/templates/varnish-deployment.yaml | 19 ------------------- 3 files changed, 4 insertions(+), 32 deletions(-) diff --git a/api/helm/templates/api-deployment.yaml b/api/helm/templates/api-deployment.yaml index 463cc175..11cca3fb 100644 --- a/api/helm/templates/api-deployment.yaml +++ b/api/helm/templates/api-deployment.yaml @@ -27,20 +27,11 @@ spec: - containerPort: 80 env: - name: PHP_SERVICE - valueFrom: - configMapKeyRef: - name: {{ template "fullname" . }} - key: php-service + value: {{ include "name" . }}-php - name: NGINX_HOST - valueFrom: - configMapKeyRef: - name: {{ template "fullname" . }} - key: php-service + value: {{ include "name" . }}-php - name: BACKENDS - valueFrom: - configMapKeyRef: - name: {{ template "fullname" . }} - key: php-service + value: {{ include "name" . }}-php resources: {{ toYaml .Values.resources | indent 12 }} {{- if .Values.nodeSelector }} diff --git a/api/helm/templates/api-service.yaml b/api/helm/templates/api-service.yaml index 6915c2ca..321b9345 100644 --- a/api/helm/templates/api-service.yaml +++ b/api/helm/templates/api-service.yaml @@ -3,7 +3,7 @@ kind: Service metadata: name: {{ include "name" . }} labels: - app.kubernetes.io/name: {{ include "name" . } + app.kubernetes.io/name: {{ include "name" . }} app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/api/helm/templates/varnish-deployment.yaml b/api/helm/templates/varnish-deployment.yaml index da8894f0..5e41a9b4 100644 --- a/api/helm/templates/varnish-deployment.yaml +++ b/api/helm/templates/varnish-deployment.yaml @@ -30,25 +30,6 @@ spec: #args: ["-F", "-f", "/usr/local/etc/varnish/default.vcl", "-p", "http_resp_hdr_len=65536", "-p", "http_resp_size=98304"] ports: - containerPort: 80 - env: - - name: PHP_SERVICE - valueFrom: - configMapKeyRef: - name: {{ template "fullname" . }} - key: php-service - - name: NGINX_HOST - valueFrom: - configMapKeyRef: - name: {{ template "fullname" . }} - key: php-service - livenessProbe: - httpGet: - path: /healthz - port: 80 - readinessProbe: - httpGet: - path: /healthz - port: 80 resources: {{ toYaml .Values.resources | indent 12 }} {{- if .Values.nodeSelector }} From 85598c9fb18f6b0459b55fd7960c471caed7d4e6 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 11 Nov 2019 15:24:24 +0100 Subject: [PATCH 014/182] Removed the auto generation of helm charts from entrypoint --- api/docker/php/docker-entrypoint.sh | 13 +++++++------ api/helm/templates/configmap.yaml | 8 ++++---- api/helm/templates/ingress.yaml | 8 ++++---- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/api/docker/php/docker-entrypoint.sh b/api/docker/php/docker-entrypoint.sh index 3c5a644b..459dee21 100755 --- a/api/docker/php/docker-entrypoint.sh +++ b/api/docker/php/docker-entrypoint.sh @@ -62,13 +62,14 @@ if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then echo "Loading fixtures" bin/console doctrine:fixtures:load --no-interaction - echo "Creating OAS documentation" - # Let update the docs to show the latest chages - bin/console api:openapi:export --output=/srv/api/public/schema/openapi.yaml --yaml --spec-version=3 + # echo "Creating OAS documentation" + # Lets update the docs to show the latest chages + # bin/console api:openapi:export --output=/srv/api/public/schema/openapi.yaml --yaml --spec-version=3 - echo "Updating Helm charts" - # Let update the docs to show the latest chages - bin/console app:helm:update --location=/srv/api/helm --spec-version=3 + # this should only be done in an build + # echo "Updating Helm charts" + # Lets update the docs to show the latest chages + # bin/console app:helm:update --location=/srv/api/helm --spec-version=3 fi fi diff --git a/api/helm/templates/configmap.yaml b/api/helm/templates/configmap.yaml index d691cc9f..462fedb6 100644 --- a/api/helm/templates/configmap.yaml +++ b/api/helm/templates/configmap.yaml @@ -2,12 +2,12 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ template "fullname" . }} - namespace: {{ .Values.settings.env }} + #namespace: {{ .Values.settings.env }} labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }} - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }} + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} data: project_name: {{ .Values.settings.projectName | quote }} diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index 4019c797..4437f785 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -1,12 +1,12 @@ apiVersion: extensions/v1beta1 kind: Ingress metadata: - name: {{ template "fullname" . }}-{{ .Values.settings.env }} + name: {{ template "fullname" . }} labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-ingress - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-ingress + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- with .Values.ingress.annotations }} annotations: From 648c6fc10b10cf9c520f7300c9f13dc1845ce6cc Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Thu, 14 Nov 2019 11:14:56 +0100 Subject: [PATCH 015/182] Fixed language errors in Installation.md --- INSTALLATION.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/INSTALLATION.md b/INSTALLATION.md index 8b25f6c1..285d3696 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -1,17 +1,17 @@ # Installation -This document dives a litle bit deeper into installing your component on a kubernetes cluster, looking for information on setting up your component on a lookal maschine? Take a look at the [tutorial](TUTORIAL.md) instead. +This document dives a little bit deeper into installing your component on a kubernetes cluster, looking for information on setting up your component on a local machine? Take a look at the [tutorial](TUTORIAL.md) instead. ## Setting up helm ## Setting up tiller -Create the tiller serviceaccount: +Create the tiller service account: ```CLI $ kubectl -n kube-system create serviceaccount tiller --kubeconfig="api/helm/kubeconfig.yaml" ``` -Next, bind the tiller serviceaccount to the cluster-admin role: +Next, bind the tiller service account to the cluster-admin role: ```CLI $ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller --kubeconfig="api/helm/kubeconfig.yaml" ``` @@ -21,30 +21,30 @@ Now we can run helm init, which installs Tiller on our cluster, along with some $ helm init --service-account tiller --kubeconfig="api/helm/kubeconfig.yaml" ``` -To verify that Tiller is running, list the pods in thekube-system namespace: +To verify that Tiller is running, list the pods in the kube-system namespace: ```CLI $ kubectl get pods --namespace kube-system --kubeconfig="api/helm/kubeconfig.yaml" ``` The Tiller pod name begins with the prefix tiller-deploy-. -Now that we’ve installed both Helm components, we’re ready to use helm to install our first application. +Now that we've installed both Helm components, we're ready to use helm to install our first application. ## Setting up Kubernetes Dashboard -Afhter we installed helm and tiller we can easyallty use both to install kubernets dashboard +After we installed helm and tiller we can easily use both to install kubernetes dashboard ```CLI $ helm install stable/kubernetes-dashboard --name dashboard --kubeconfig="api/helm/kubeconfig.yaml" --namespace="kube-system" ``` -But before we can login to tille we need a token, we can get one of those trough the secrets. Get yourself a secret list by running the following command +But before we can login to tiller we need a token, we can get one of those trough the secrets. Get yourself a secret list by running the following command ```CLI $ kubectl -n kube-system get secret --kubeconfig="api/helm/kubeconfig.yaml" ``` -Becouse we just bound tiller to our admin acount and use tiller (trough helm) to manage our code deployment it makes sence to use the tiller token, lets look uo the tilles secret (it should loo something like "tiller-token-XXXXX" and ask for the coresponding token. +Because we just bound tiller to our admin account and use tiller (trough helm) to manage our code deployment it makes sense to use the tiller token, lets look at the tiller secret (it should look something like "tiller-token-XXXXX" and ask for the corresponding token. ```CLI -$ kubectl -n kube-system describe secrets tiller-token-5m4tg --kubeconfig="api/helm/kubeconfig.yaml" +$ kubectl -n kube-system describe secrets tiller-token-xxxxx --kubeconfig="api/helm/kubeconfig.yaml" ``` This should return the token, copy it to somewhere save (just the token not the other returned information) and start up a dashboard connection @@ -59,10 +59,10 @@ http://localhost:8001/api/v1/namespaces/kube-system/services/https:dashboard-kub ``` ## Deploying trough helm -First we always need to update our dependencys +First we always need to update our dependencies ```CLI $ helm dependency update ./api/helm - +``` If you want to create a new instance ```CLI $ helm install --name pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1 @@ -88,19 +88,19 @@ Note that you can replace commonground with the namespace that you want to use ( ## Making your app known on NLX -The proto component commes with an default NLX setup, if you made your own component however you might want to provide it trough the [NLX](https://www.nlx.io/) service. Furntunatly the proto component commes with an nice setup for NLX integration. +The proto component comes with an default NLX setup, if you made your own component however you might want to provide it trough the [NLX](https://www.nlx.io/) service. Fortunately the proto component comes with an nice setup for NLX integration. -First of all change the nececery lines in the [.env](.env) file, basiccaly everything under the NLX setup tag. Keep in mind that you wil need to have your component available on an (sub)domain name (a simple IP wont sufice). +First of all change the necessary lines in the [.env](.env) file, basically everything under the NLX setup tag. Keep in mind that you wil need to have your component available on an (sub)domain name (a simple IP wont sufice). -To force the re-generation of certificates simply delete the org.crt en org.key in the api/nlx-setup folder +To force the re-generation of certificates simply delete the org.crt en org.key in the api/nlx-setup folder. ## Deploying trough common-ground.dev ## Setting up analytics and a help chat function -As a developer you might be intrested to know how your application documentation is used, so you can see which parts of your documentation are most read and which parts might need some additional love. You can measure this (and other user interactions) with google tag manager. Just add your google tag id to the .env file (replacing the default) under GOOGLE_TAG_MANAGER_ID. +As a developer you might be interested to know how your application documentation is used, so you can see which parts of your documentation are most read and which parts might need some additional love. You can measure this (and other user interactions) with google tag manager. Just add your google tag id to the .env file (replacing the default) under GOOGLE_TAG_MANAGER_ID. -Have you seen our sweet support-chat on the documentation page? We didn't build that ourselves ;) We use a Hubspot chat for that, just head over to Hubspot, create an account and enter your Hubspot embed code in het .env file (replacing the default) under HUBSPOT_EMBED_CODE. +Have you seen our sweet support-chat on the documentation page? We didn't build that ourselves ;). We use a Hubspot chat for that, just head over to Hubspot, create an account and enter your Hubspot embed code in het .env file (replacing the default) under HUBSPOT_EMBED_CODE. -Would you like to use a different analytics or chat-tool? Just shoot us a [feature request](https://github.com/ConductionNL/commonground-component/issues/new?assignees=&labels=&template=feature_request.md&title=New Analytics or Chat provider) +Would you like to use a different analytics or chat-tool? Just shoot us a [feature request](https://github.com/ConductionNL/commonground-component/issues/new?assignees=&labels=&template=feature_request.md&title=New%20Analytics%20or%20Chat%20provider)! From 1abaf66797c7e69beb729989f1b38216098a97a0 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Thu, 14 Nov 2019 13:09:46 +0100 Subject: [PATCH 016/182] Checked DESIGN.md for language errors --- DESIGN.md | 34 +++++++++++++++++----------------- INSTALLATION.md | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index edcb7692..ac705c08 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -1,49 +1,49 @@ # Design Considerations -This component was designed inline with the [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index), [commonground principles](https://vng.nl/onderwerpenindex/bestuur/samen-organiseren-2019/common-ground) and international standards. +This component was designed in line with the [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index), [commonground principles](https://vng.nl/onderwerpenindex/bestuur/samen-organiseren-2019/common-ground) and international standards. -The spefic goal of this component is to provide a common architecture for common ground components as such the common ground principles are leading in design choices, and within those principles technological invoation and international complyancy is deemd most inportant. WE DO NOT WANT TO MAKE CONSESIONS TO CURRENT INFRASTRUCTURE. As such the component might differ on [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index) and other standards if they are deemed incompatible or out of line with international standards. +The specific goal of this component is to provide a common architecture for common ground components as such the common ground principles are leading in design choices, and within those principles technological invocation and international compliancy is deemed most important. **We do not want to mace consessions to the current infrastructure.** As such the component might differ on [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index) and other standards if they are deemed incompatible or out of line with international standards. The European factor ------- -The proto-component isn't just a Dutch Component, it is in easance a dutch translation of european components, nowhere is this more obvius than in the core code. Our component is based on [API Platform](https://api-platform.com/) an API specific version of the symfony framework. This framework is build by the lovely people of []() and is build with support of the Euroean Commision trough the [EU-FOSSA Hackathon](https://ec.europa.eu/info/news/first-eu-fossa-hackathon-it-happened-2019-may-03_en) and Digital Ocean trough [Hacktoberfest].(https://hacktoberfest.digitalocean.com/). +The proto-component isn't just a Dutch Component, it is in essence a dutch translation of european components, nowhere is this more obvious than in the core code. Our component is based on [API Platform](https://api-platform.com/) an API specific version of the symfony framework. This framework is build by the lovely people of []() and is build with support of the European Commission trough the [EU-FOSSA Hackathon](https://ec.europa.eu/info/news/first-eu-fossa-hackathon-it-happened-2019-may-03_en) and Digital Ocean trough [Hacktoberfest](https://hacktoberfest.digitalocean.com/). -But it dosn't just end there the [varnish container](https://hub.docker.com/r/eeacms/varnish/) that we use to speed up the API responce it build and maintained by [EEA]() (The European Environment Agency) and the development team at conduction itself is attached to the [Odyssey program](https://www.odyssey.org/) and originated from the [startupinresidence](https://startupinresidence.com/) program. +But it doesn't just end there. The [varnish container](https://hub.docker.com/r/eeacms/varnish/) that we use to speed up the API responce it build and maintained by [EEA]() (The European Environment Agency) and the development team at conduction itself is attached to the [Odyssey program](https://www.odyssey.org/) and originated from the [startupinresidence](https://startupinresidence.com/) program. So you could say that both change and a european perspective is in our blood. Domain Build-up and routing ------- -By convention the component assumes that you follow the common ground domain name build up, meaning {enviroment}.{component}.{rest of domain}. That means that only the first two url parts are used for routing. It is also assumed that when no envirment is supplied the production enviroment should be offerd E.g. a propper domain for the production API of the verzoeken registratie component would be prod.vrc.zaakonline.nl but it should also be reachable under vrc.zaakonline.nl. The proper location for the development enviroment shoud always be dev.vrc.zaakonlin.nl +By convention the component assumes that you follow the common ground domain name build up, meaning {environment}.{component}.{rest of domain}. That means that only the first two url parts are used for routing. It is also assumed that when no environment is supplied the production environment should be offered E.g. a proper domain for the production API of the verzoeken registratie component would be prod.vrc.zaakonline.nl but it should also be reachable under vrc.zaakonline.nl. The proper location for the development environment should always be dev.vrc.zaakonlin.nl -Enviroments and namespacing +Environments and namespacing ------- -We assume that for that you want to run several enviroments for development purposes. We identify the following namespaces for support. +We assume that for that you want to run several environments for development purposes. We identify the following namespaces for support. - prod (Production) - acce (Acceptation) - stag (Staging) - test (Testing) - dev (Development) -Becouse we base the commonground infastructure on kubernetes, and we want to keep a hard sepperation between enviroment we also assume that you are using your enviroment as a namespace +Because we base the common ground infrastructure on kubernetes, and we want to keep a hard separation between environment we also assume that you are using your environment as a namespace -Symfony libary managment gives us the optoin to define the libbarys on a per envirmoent base, you can find that definition in the [bundle config](api/config/bundles.php) +Symfony library management gives us the option to define the libraries on a per environment base, you can find that definition in the [bundle config](api/config/bundles.php) -Besides the API envormiments the component also ships with aditional tools/enviroments but those are not meant to be deployed +Besides the API environments the component also ships with additional tools/environments but those are not meant to be deployed - client (An react client frontend) -- admin ( An read admin interface) +- admin (An read admin interface) -On the local development docker deploy the client enviroment is used as default in stead of the production version of the api. +On the local development docker deploy the client environment is used as default instead of the production version of the api. -Loging Headers (NLX Audit trail) +Logging Headers (NLX Audit trail) ------- @todo update, a reaction about this has been given by the NLX team. -We inherit a couple of headers from the transaction logging within the [NLX schema](https://docs.nlx.io/further-reading/transaction-logs/), we strongly discurage the use of the `X-NLX-Request-Data-Subject` header as it might allow private data (such as BSN's) to show up in logging. +We inherit a couple of headers from the transaction logging within the [NLX schema](https://docs.nlx.io/further-reading/transaction-logs/), we strongly discourage the use of the `X-NLX-Request-Data-Subject` header as it might allow private data (such as BSNs) to show up in logging. __solution__ -The follwoing X-NLX headers have been implemented `X-NLX-Logrecord-ID`,`X-NLX-Request-Process-Id`,`X-NLX-Request-Data-Elements` and `X-NLX-Request-Data-Subject`, these are tied to the internal audit trail (see audit trail for more information), and `X-Audit-Toelichting` (from the ZGW API's) is implemented as `X-Audit-Clarification` +The following X-NLX headers have been implemented `X-NLX-Logrecord-ID`,`X-NLX-Request-Process-Id`,`X-NLX-Request-Data-Elements` and `X-NLX-Request-Data-Subject`, these are tied to the internal audit trail (see audit trail for more information), and `X-Audit-Toelichting` (from the ZGW APIs) is implemented as `X-Audit-Clarification` Api versioning ------- @@ -79,7 +79,7 @@ In compliance with [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achter Notifications ------- @todo this needs to be implemented -For notifications we do not use the current [ZGW standard](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/notificaties) since we deem it insecure to send properties or data objects along with a notification. This is a potential security breach explained [here](https://github.com/VNG-Realisatie/gemma-zaken/issues/1427#issuecomment-549272696). It also doesn’t follow the [web standard](https://www.w3.org/TR/websub/). Instead we are developing our own subscriber service that is tailored for the NLX / VNG environment and based on current web standards [here](). +For notifications we do not use the current [ZGW standard](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/notificaties) since we deem it insecure to send properties or data objects along with a notification. This is a potential security breach explained [here](https://github.com/VNG-Realisatie/gemma-zaken/issues/1427#issuecomment-549272696). It also doesn�t follow the [web standard](https://www.w3.org/TR/websub/). Instead we are developing our own subscriber service that is tailored for the NLX / VNG environment and based on current web standards [here](). __solution__ In compliance with [w3.org](https://www.w3.org/TR/websub/) each endpoint returns an header containing an subscribtion url. That can be used in acordanse with the application to subscribe to both individual objects as collections. whereby collections serve as 'kanalen'. @@ -122,7 +122,7 @@ Comma Notation versus Bracket Notation on arrays's ------- The NL API standard uses comma notation on array's in http requests. E.g. fields=id,name,description however common browsers(based on chromium e.g. chrome and edge) use bracket notation for query style array's e.g. fields[]=id&fields[]=name,&fields[]=description. The difference of course is obvious since comma notation doesn't allow you to index arrays. [Interestingly enough there isn't actually a rfc spec for this](https://stackoverflow.com/questions/15854017/what-rfc-defines-arrays-transmitted-over-http). -It is perceivable that in future iterations we would like to use indexed array in situations where the index of the array can't be assumed on basis of url notation, when indexes aren’t numerical, when we don’t want an index to start at 0 or when indexes are purpusly missing (comma notation of id,name,description would always refert to the equivalent of fields: [ +It is perceivable that in future iterations we would like to use indexed array in situations where the index of the array can't be assumed on basis of url notation, when indexes aren�t numerical, when we don�t want an index to start at 0 or when indexes are purpusly missing (comma notation of id,name,description would always refert to the equivalent of fields: [ 0 => id, 1 => name, 2 => description diff --git a/INSTALLATION.md b/INSTALLATION.md index 285d3696..63989676 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -84,7 +84,7 @@ $ helm del pc-stag --purge --kubeconfig="api/helm/kubeconfig.yaml --namespace=st $ helm del pp-prod --purge --kubeconfig="api/helm/kubeconfig.yaml --namespace=prod" ``` -Note that you can replace commonground with the namespace that you want to use (normally the name of your component). +Note that you can replace common ground with the namespace that you want to use (normally the name of your component). ## Making your app known on NLX From a9eb60b56d0781c7899db2e5ee7e6136106aea9a Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Thu, 14 Nov 2019 13:48:53 +0100 Subject: [PATCH 017/182] Checked TUTORIAL.md for typos --- SECURITY.md | 2 +- TUTORIAL.md | 88 +++++++++++++++++++++++++++-------------------------- 2 files changed, 46 insertions(+), 44 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 0c41cb8e..f72a06d9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,6 +1,6 @@ # SECURITY -Security of your common ground component henchmen’s on a few factors and is (in fact) for the most part provided by the common ground ecosystem. But there are definitely some steps that you should undertake yourself. We will however first briefly explain the security principles set in place so that you understand how you are being supported and what the limitation of that support is. +Security of your common ground component henchmens on a few factors and is (in fact) for the most part provided by the common ground ecosystem. But there are definitely some steps that you should undertake yourself. We will however first briefly explain the security principles set in place so that you understand how you are being supported and what the limitation of that support is. ## Codebase First of the code base, if you are extending the common ground-proto-component your code base will exist out of three parts. diff --git a/TUTORIAL.md b/TUTORIAL.md index 8c4f391c..74aad7ba 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -8,7 +8,7 @@ What do you need for this tutorial? * Docker for desktop ## Before you begin -For the steps consirning the generation of entities an example entity a availale, feel free to [take a look](https://github.com/ConductionNL/Proto-component-commonground/blob/master/api/src/Entity/ExampleEntity.php) at it if you have trouble figuring out the code. +For the steps considering the generation of entities an example entity a availale, feel free to [take a look](https://github.com/ConductionNL/Proto-component-commonground/blob/master/api/src/Entity/ExampleEntity.php) at it if you have trouble figuring out the code. ## Setting up your enviroment @@ -28,9 +28,9 @@ We ran a fork of the base Common Ground component, that means that we copied the ## Spinning up your component Before we can spin up our component we must first get a local copy from our repository, we can either do this through the command line (example here) or use a Git client. -For this example where going to use GitKraken but you can use any tool you like, feel free to skip this part if you are already familiar with setting up a local clone of your repository. +For this example we're going to use GitKraken but you can use any tool you like, feel free to skip this part if you are already familiar with setting up a local clone of your repository. -Open gitkraken press "clone a repro" and fill in the form (select where on your local machine you want the repository to be stored, and fill in the link of your repository on github), press "clone a repro" and you should then see GitKraken downloading your code. After it's done press "open now" (in the box on top) and voilá your codebase (you should see an initial commit on a master branche). +Open gitkraken press "clone a repo" and fill in the form (select where on your local machine you want the repository to be stored, and fill in the link of your repository on github), press "clone a repo" and you should then see GitKraken downloading your code. After it's done press "open now" (in the box on top) and voilá your codebase (you should see an initial commit on a master branch). You can now navigate to the folder where you just installed your code, it should contain some folders and files and generally look like this. We will get into the files later, lets first spin up our component! @@ -46,7 +46,7 @@ Your computer should now start up your local development environment. Don't worr Open your browser type http://localhost/ as address and hit enter, you should now see your common ground component up and running. ### trouble shooting -When spinning up components we make extensive use of the cashing of docker, and use volumes to reprecent server disks. When running in to unexpected trouble always remmember to clear your local docker vm with the -a command (removing image cash) +When spinning up components we make extensive use of the cashing of docker, and use volumes to represent server disks. When running in to unexpected trouble always remember to clear your local docker vm with the -a command (removing image cash) ```CLI $ docker system prune -a ``` @@ -69,18 +69,18 @@ Let's open a new command line window and navigate to our root folder, exactly li ```CLI $ docker-compose exec php bin/console make:entity ``` -We should now see a wizward that allows us to either make new entities, or add parameters to existing entities (by supplying the name of an existing entity). +We should now see a wizard that allows us to either make new entities, or add parameters to existing entities (by supplying the name of an existing entity). ## Keeping your repository up to date with the Conduction Common Ground component There are basically three reasons why you should want to keep your repository up to date with the Conduction proto component * Security, Conduction performs regular security updates on * Functionality we strive to make regular -* Compliance, as discussions in the broader Common Ground community progress API standars might advance or change. Conduction will regularly update the Common Ground component with those changes. +* Compliance, as discussions in the broader Common Ground community progress API standards might advance or change. Conduction will regularly update the Common Ground component with those changes. Best practice is to fetch the Conduction Common Ground component into a local upstream/master branch through Git. So let's first add the original Common Ground component as an remote called upstream, and create a local branch for that remote. -__Please make sure the you have commited al your changes to your current codebase and pushed a backup copy to your Git repo before continuing__ +__Please make sure the you have committed al your changes to your current codebase and pushed a backup copy to your Git repo before continuing__ ```CLI git remote add upstream https://github.com/ConductionNL/Proto-component-commonground.git @@ -88,7 +88,7 @@ git fetch upstream git branch upstream upstream/master ``` -You can then use your favorite Git tool to merge this branch into your normal working branche without the danger of overwriting your local code. Or alternatively you can use your GIT CLI (not recommended) +You can then use your favorite Git tool to merge this branch into your normal working branch without the danger of overwriting your local code. Or alternatively you can use your GIT CLI (not recommended) ```CLI git checkout master @@ -107,9 +107,9 @@ git merge upstream --allow-unrelated-histories Keep in mind that you wil need to make sure to stay up to date about changes on the Common Ground component repository. ## Renaming your component -Right now the name of your component is 'commonground' that's thats fine while running it localy or in its own kubernetes cluster but wil get you in when running it with other components when it without using a name space. So its good practice to name your component distinctifly. But besides al of these practical reasons its of course also just cool to name your child before you unleas it on the unsuspecting commonground community. +Right now the name of your component is 'commonground' that's that's fine while running it locally or in its own kubernetes cluster but wil get you in when running it with other components when it without using a name space. So its good practice to name your component distinctly. But besides al of these practical reasons its of course also just cool to name your child before you unleash it on the unsuspecting common ground community. -Oke, so before we can nae the component we need to come up with a name. There are a couple of conventions here. Firts of the name should tell us what the component does, or is suposede to do with one or two words. So we would normaly call an componant aboute dogs the DogComponent and one about cats te CatComponent. The second convention is that we don't usually actually name our component 'component' but indicate its position in de commonground architecture. For that we have the following options +Oke, so before we can nae the component we need to come up with a name. There are a couple of conventions here. First of the name should tell us what the component does, or is supposed to do with one or two words. So we would normally call an component about dogs the DogComponent and one about cats te CatComponent. The second convention is that we don't usually actually name our component 'component' but indicate its position in de common ground architecture. For that we have the following options: * Catalogus * RegistratieComponent * Service @@ -143,7 +143,7 @@ The we need to touch te following files //... ``` -## Setting up security and acces (also helps with serialization) +## Setting up security and access (also helps with serialization) ```PHP // src/Entity/Organisation.php @@ -193,12 +193,12 @@ class Organisation Keep in mind that we need to add the assert annotation to our class dependencies under 'use'. -More inforation on using validation can be found at the [symfony website](https://symfony.com/doc/current/validation.html), but it is als worth notting that tis commonent comes pre packed with some typical NL valdidators like BSN. You can find those [here](). +More inforation on using validation can be found at the [symfony website](https://symfony.com/doc/current/validation.html), but it is als worth nothing that tis component comes pre packed with some typical NL validators like BSN. You can find those [here](). ## Using UUID -As default doctrine uses auto increment integers as identifiers (1,2, etc). For modern webapplications we howver prefer the use of UUID's. (e.g. e2984465-190a-4562-829e-a8cca81aa35d). Why? Wel for one it is more secure integer id's are easly gasable and make it posible to "aks" endpoint about objects that you should know about. But UUID's also have a benifit in futere proofing the application. If we in the futere want to merge a table with another table (for example becouse two organisations using a component perform a merger) then we would have to reasign al id's and relations if we where using int based id's (both tables would have a row 1,2 etc) with UUID's however the change of doubles range somwhere in the biljons. Meaning that it i likly that we oly need to either re identify only a handful of rows or more likely none at al! Turning our entire migration into a copy pase action. +As default doctrine uses auto increment integers as identifiers (1,2, etc). For modern web applications we however prefer the use of UUID's. (e.g. e2984465-190a-4562-829e-a8cca81aa35d). Why? Wel for one it is more secure integer id's are easily guessable and make it possible to "ask" endpoint about objects that you should not know about. But UUID's also have a benefit in future proofing the application. If we in the future want to merge a table with another table (for example because two organisations using a component perform a merger) then we would have to reassign al id's and relations if we where using int based id's (both tables would have a row 1,2 etc) with UUID's however the change of doubles range somewhere in the billions. Meaning that it is likely that we only need to either reidentify only a handful of rows or more likely none at al! Turning our entire migration into a copy paste action. -The proto component supports ramsy's uuid objects stratagy out of the box, so to use UUID's as intifier simply we need to add the ApiProperty as a dependecy +The proto component supports Ramsey's uuid objects strategy out of the box, so to use UUID's as identifier simply we need to add the ApiProperty as a dependency ```PHP @@ -269,10 +269,10 @@ into this //... ``` -and your all done +and you're all done -### Rrouble shooting -If you have already spunn your component including your new entity your going to run into some trouble becouse doctrine is going to try changing your primary key collum (id) from an integer to string (tables tend not to like that). In that case its best to just drop your database and reinstall it using the following commands: +### Trouble shooting +If you have already spun your component including your new entity your going to run into some trouble because doctrine is going to try changing your primary key column (id) from an integer to string (tables tend not to like that). In that case its best to just drop your database and reinstall it using the following commands: ```CLI $ bin/console doctrine:schema:drop @@ -281,13 +281,13 @@ $ bin/console doctrine:schema:update --force ## Advanced data sets -Oke lets make it complex, until now we have just added some simple entities to our component, but what if we want to ataches one entity to another? Fortunatly our build in database engine support rather complex senarios called associations. So let [take a look](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html) at that. +Oke lets make it complex, until now we have just added some simple entities to our component, but what if we want to attaches one entity to another? Fortunately our build in database engine support rather complex scenarios called associations. So let [take a look](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html) at that. -Bafled? Wel its rather complex. But remember that Make:entity command that we used earlier? That actuelly accepts relations as a data type. Or to but it simply instead of using the default 'string' we could just type "ManyToOne" and it will just fire up some qoustions that will help it determine how you want your relations to be. +Baffled? Wel its rather complex. But remember that Make:entity command that we used earlier? That actually accepts relations as a data type. Or to but it simply instead of using the default 'string' we could just type "ManyToOne" and it will just fire up some questions that will help it determine how you want your relations to be. ### Trouble shooting -A very common error when linking entities togehter is circle refrances, those will break our serializatoin. Furtunaltly we have a need way to prevent that. Even better symfony gives us exact control of how deep we want the circular refereance to go. To do this we need to use the `MaxDepth()` annotation. So lets import that +A very common error when linking entities together is circle references, those will break our serialization. Fortunately we have a need way to prevent that. Even better symfony gives us exact control of how deep we want the circular reference to go. To do this we need to use the `MaxDepth()` annotation. So lets import that ```PHP //... @@ -311,11 +311,11 @@ class ExampleEntity //... ``` -We can now prevent circular referances by setting a max depth on the properties cousing the circular refrance. - +We can now prevent circular references by setting a max depth on the properties causing the circular reference. +```PHP //... /** - * @var ArrayCollection $stuffs Some stuff that is atached to this example object + * @var ArrayCollection $stuffs Some stuff that is attached to this example object * * @MaxDepth(1) * @Groups({"read","write"}) @@ -325,21 +325,21 @@ We can now prevent circular referances by setting a max depth on the properties //... ``` -## Datafixtures -For testing cases it can be usefull to use datafixtures a predefined set of data that fills the database of your component at startup. Since we use php classes to describe our objects creating fixtures is easy (you can find an example in your project folder at api/src/DataFixtures). We simply go trough some classes asign values and persist them to the database. Once we have written our fixtures we can use a single command to load them +## Data fixtures +For testing cases it can be useful to use data fixtures a predefined set of data that fills the database of your component at startup. Since we use php classes to describe our objects creating fixtures is easy (you can find an example in your project folder at api/src/DataFixtures). We simply go trough some classes assign values and persist them to the database. Once we have written our fixtures we can use a single command to load them ```CLI $ bin/console doctrine:fixtures:load --env=dev ``` -Be mindfull of the --env=dev here! Doctrine wil only allow fixture loading on a dev enviroment (for obvius security reasons) +Be mindful of the --env=dev here! Doctrine wil only allow fixture loading on a dev environment (for obvious security reasons) -More inforation on using datafixtures can be found at the [symfony website](https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html)(you can skipp the instalation instructions) we also enourage you to take a look at the [tabbelen component](https://github.com/ConductionNL/landelijketabellencatalogus) that makes extansive use of datafixtures. +More information on using data fixtures can be found at the [symfony website](https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html) (you can skipp the installation instructions) we also encourage you to take a look at the [tabellen component](https://github.com/ConductionNL/landelijketabellencatalogus) that makes extensive use of data fixtures. ## Sharing your work -A vital part of te common ground community is sharing your work, and telling other people what you are working. This way people can help you wiht problems that you run into. And keep tabs on any (security) updates that you make to you code. Sounds like a lot of work right? +A vital part of te common ground community is sharing your work, and telling other people what you are working. This way people can help you with problems that you run into. And keep tabs on any (security) updates that you make to you code. Sounds like a lot of work right? -Wel it actually isn't, there is a specific commonground platform over at common-gorund.dev that reads repositorys and updates user. So the only thing we need to do is tell this platform that we have started a new common ground repository. And tell it when we have updates ours. We can do all that by simply adding a webhook to our component. +Wel it actually isn't, there is a specific common ground platform over at common-ground.dev that reads repositories and updates user. So the only thing we need to do is tell this platform that we have started a new common ground repository. And tell it when we have updates ours. We can do all that by simply adding a webhook to our component. When using Github. To set up a webhook, go to the settings page of your repository or organization. From there, click Webhooks, then Add webhook. Use te following settings: * Payload URL: https://www.common-ground.dev/webhook/github @@ -347,7 +347,7 @@ When using Github. To set up a webhook, go to the settings page of your reposito * Secret: [leave blanck] * Events: [just the push event] -Now every time you update your repository the commonground dev page will allerted, rescan your repository and do al the apropriate platform actions. It just as easy as that. +Now every time you update your repository the commonground dev page will alerted, rescan your repository and do al the appropriate platform actions. It just as easy as that. Automated Testing and Deployment (continues integration) @@ -356,29 +356,30 @@ The following bit of the tutorial requires two additional accounts - [https://hub.docker.com/](https://hub.docker.com/) (You might already have this for docker for desktop) - [https://travis-ci.org](https://travis-ci.org) (You can use you github account) -The proto component ships with a pre-fab continues integration script based on travis. What does this mean you ask? Continuous integration (or CI for short) is an optimized and automated way for your code to become part of your projects. In the case of your commonground component that means that we will automatically validate new code commites or pushes and (if everything checks out) build that code and deploy the containers thereof to docker hub. Making is possible to update al the environments that use those components. +The proto component ships with a pre-fab continues integration script based on travis. What does this mean you ask? Continuous integration (or CI for short) is an optimized and automated way for your code to become part of your projects. In the case of your commonground component that means that we will automatically validate new code commits or pushes and (if everything checks out) build that code and deploy the containers thereof to docker hub. Making is possible to update al the environments that use those components. -Oke that's nice, but how do we do that? Actually it is very simple. First of all make sure you have a docker account, log into [docker hub](https://hub.docker.com/) and have a look around. We don't need to create anything just yet'but it is nice to get a feeling of the place. As you can see docker hub also uses repositories etc. So that recognizable. +Okay, that's nice, but how do we do that? Actually it is very simple. First of all make sure you have a docker account, log into [docker hub](https://hub.docker.com/) and have a look around. We don't need to create anything just yet, but it is nice to get a feeling of the place. As you can see docker hub also uses repositories etc. So that recognizable. -Next we need to prepare our github repository that holds our code. For the travis script to work as intended we need to create a couple of branches(if we don't have those already) open up yout git interface and create a branch called 'development' and a branch called 'staging'. Don't forget to push the branches so that they are present on github (and not just on your local machine). +Next we need to prepare our github repository that holds our code. For the travis script to work as intended we need to create a couple of branches(if we don't have those already) open up your git interface and create a branch called 'development' and a branch called 'staging'. Don't forget to push the branches so that they are present on github (and not just on your local machine). -Oke just one more place to go and that is travis, head over to [https://travis-ci.org](https://travis-ci.org) and login with your gitacount. If everything is alright you should see your repository there. Activate it by pressing 'activate repository' and then go to 'More options' -> 'Settings' and scroll down to enviroment variables. Here we can present travis wit the variables that it need to execute our build script. Lets first set the common variables that we need for all our branches: `DOCKER_PASSWORD` your docker password,`DOCKER_REGISTRY` docker.io/[your username] ,`DOCKER_USERNAME` your docker user name. This will be used by travis to push the completed containers into docker hub. Next we need to specify a couple of variables that are branch specific. Or to be more exact, set the same variable `APP_ENV` with different values for different branches. It needs to be 'staging'->stag,'master'->prod,'development'->dev. +Oke just one more place to go and that is travis, head over to [https://travis-ci.org](https://travis-ci.org) and login with your github account. If everything is alright you should see your repository there. Activate it by pressing 'activate repository' and then go to 'More options' -> 'Settings' and scroll down to environment variables. Here we can present travis wit the variables that it need to execute our build script. Lets first set the common variables that we need for all our branches: `DOCKER_PASSWORD` your docker password,`DOCKER_REGISTRY` docker.io/[your username] ,`DOCKER_USERNAME` your docker user name. This will be used by travis to push the completed containers into docker hub. Next we need to specify a couple of variables that are branch specific. Or to be more exact, set the same variable `APP_ENV` with different values for different branches. It needs to be 'staging'->stag,'master'->prod,'development'->dev. And all done! Head over back to the code on your computer and make a small change. Then commit push that change into github. Travis should automatically pick op your change and start a build. ### Unit / Behat -adas +TODO ### Postman -ad +TODO ### Trouble shooting -Please make sure that your github repositry is set to public, and keep in mind that a complex travis build (and sertenly one that includes a pushing of containers can take up to 20 minutes). +Please make sure that your github repository is set to public, and keep in mind that a complex travis build (and certainly one that includes a pushing of containers can take up to 20 minutes). + Documentation and dockblocks ------- -asdsa +TODO Audittrail ------- @@ -401,7 +402,7 @@ class ExampleEntity //... ``` -Next we need to tell the specific properties that we want to log that they are loggable (again this is a conscious choice, to prevent us from accidently logging stuff like bsn numbers), we do that by adding the `@Gedmo\Versioned` annotation to those specific properties. That would then look something like this: +Next we need to tell the specific properties that we want to log that they are loggable (again this is a conscious choice, to prevent us from accidentally logging stuff like bsn numbers), we do that by adding the `@Gedmo\Versioned` annotation to those specific properties. That would then look something like this: ```PHP //... @@ -421,7 +422,7 @@ Next we need to tell the specific properties that we want to log that they are l //... ``` -Okay actually we are now good to go, at least we are logging those things that we want logged. But.... How do we view those logs? In commonground we have a [convention](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail) to expose a /audittrail subresource on resources that are logged. So lets add that trough our `@ApiResource` anotation. +Okay actually we are now good to go, at least we are logging those things that we want logged. But.... How do we view those logs? In common ground we have a [convention](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail) to expose a /audittrail subresource on resources that are logged. So lets add that trough our `@ApiResource` annotation. ```PHP //... @@ -438,17 +439,18 @@ class ExampleEntity //... ``` -And now we have a fully nl api strategie integrated audit trail! +And now we have a fully nl api strategy integrated audit trail! Setting up automated deployment (continues delivery) ------- -adasd +TODO ## Commonground specific data types - +TODO ### incompleteDate + ### underInvestigation From 87d6b828ebecb842cb1908abd246ec8e8ccabc5c Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sat, 16 Nov 2019 17:50:54 +0100 Subject: [PATCH 018/182] Started development on annotation parsing - healtcheck - audittrail - validators to docs - entity description to tag description --- .gitignore | 2 + api/src/Swagger/SwaggerDecorator.php | 83 ++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index c4dd0691..baa17284 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ api/helm/kubeconfig.yaml !/api/public/bundle/* + +.idea/ diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index f0c871be..be6ac767 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -3,27 +3,71 @@ namespace App\Swagger; +use ApiPlatform\Core\Swagger\Serializer\DocumentationNormalizer; +use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Cache\Adapter\AdapterInterface as CacheInterface; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\Common\Annotations\AnnotationReader ; final class SwaggerDecorator implements NormalizerInterface { + private $metadataFactory; + private $documentationNormalizer; private $decorated; private $params; private $cash; + private $em; + private $annotationReader; - public function __construct(NormalizerInterface $decorated, ParameterBagInterface $params, CacheInterface $cache) + public function __construct( + ResourceMetadataFactoryInterface $metadataFactory, + DocumentationNormalizer $documentationNormalizer, + NormalizerInterface $decorated, + ParameterBagInterface $params, + CacheInterface $cache, + EntityManagerInterface $em, + AnnotationReader $annotationReader + ) { + $this->metadataFactory = $metadataFactory; + $this->documentationNormalizer = $documentationNormalizer; $this->decorated = $decorated; $this->params = $params; $this->cash = $cache; + $this->em = $em; + $this->annotationReader = $annotationReader; } public function normalize($object, $format = null, array $context = []) { $docs = $this->decorated->normalize($object, $format, $context); + /* The we need to enrich al the entities and add the autoated routes */ + + // Lets get al the entities known to doctrine + $entities = $this->em->getConfiguration()->getMetadataDriverImpl()->getAllClassNames(); + + // Then we loop trough the entities to find the api platform entities + foreach($entities as $entity){ + $reflector = new \ReflectionClass($entity); + var_dump($this->annotationReader->getClassAnnotations($reflector)); + + // lest break for now + break; + + // If the entity is not a apiplatform entity lets continue + //if(){ + // continue + //} + } + + + + // This gets a resourceclass bassed on the route name, could + //$resourceMetadata = $resourceClass ? $this->metadataFactory->create($resourceClass) : null; + // Lest add an host if($this->params->get('common_ground.oas.host')){ $docs['host']= $this->params->get('common_ground.oas.host'); @@ -165,13 +209,44 @@ public function normalize($object, $format = null, array $context = []) 'schema'=>['type'=>'string', 'format' => 'date-time'], 'in' => 'query', ]; - } - - } + } + } + } + + /* @todo dit afbouwen */ + + /* + if(config heltchecks is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); + } + + if(config audittrail is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); + } + + if(config notifications is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); } + + if(config authorization is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); + } + */ return $docs; } From 2ca9569ddc4dcd73e97c0c9925794bf8374f388b Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sun, 17 Nov 2019 23:29:10 +0100 Subject: [PATCH 019/182] Added tag descriptions from entities --- api/composer.json | 1 + api/composer.lock | 2 +- api/helm/values.yaml | 1 - api/src/Entity/ExampleEntity.php | 14 ++- api/src/Swagger/SwaggerDecorator.php | 155 +++++++++++++++++++++++---- 5 files changed, 152 insertions(+), 21 deletions(-) diff --git a/api/composer.json b/api/composer.json index 08220e05..5f2cf5aa 100644 --- a/api/composer.json +++ b/api/composer.json @@ -10,6 +10,7 @@ "doctrine/doctrine-fixtures-bundle": "^3.2", "guzzlehttp/guzzle": "^6.3", "lexik/jwt-authentication-bundle": "^2.6", + "phpdocumentor/reflection-docblock": "^4.3", "ramsey/uuid": "^3.8", "ramsey/uuid-doctrine": "^1.5", "sensiolabs/security-checker": "^6.0", diff --git a/api/composer.lock b/api/composer.lock index 1fbe45a6..cdf70a77 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": "f3b8b4fa5bc19705f8f77ba64ce249e5", + "content-hash": "38df876b57237e6be24848f1f8f637da", "packages": [ { "name": "api-platform/api-pack", diff --git a/api/helm/values.yaml b/api/helm/values.yaml index fd5426c0..b53a056a 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -5,7 +5,6 @@ settings: registryBase: docker.io/conduction projectName: pc - version: dev env: dev debug: 1 replicaCount: 1 diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php index 6fde0bc3..1ff29279 100644 --- a/api/src/Entity/ExampleEntity.php +++ b/api/src/Entity/ExampleEntity.php @@ -16,9 +16,21 @@ use App\Filter\LikeFilter; /** + * This is an example entity + * + * With an adtional description, all in all its pritty nice [url](www.google.nl) + * * @ApiResource( * normalizationContext={"groups"={"read"}, "enable_max_depth"=true}, - * denormalizationContext={"groups"={"write"}, "enable_max_depth"=true} + * denormalizationContext={"groups"={"write"}, "enable_max_depth"=true}, + * itemOperations={ + * "get","put","delete", + * "audittrail"={ + * "method"="GET", + * "name"="Provides an auditrail for this entity", + * "description"="Provides an auditrail for this entity" + * } + * } * ) * @ORM\Entity(repositoryClass="App\Repository\ExampleEntityRepository") * @Gedmo\Loggable diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index be6ac767..27754379 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -3,13 +3,12 @@ namespace App\Swagger; -use ApiPlatform\Core\Swagger\Serializer\DocumentationNormalizer; -use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Cache\Adapter\AdapterInterface as CacheInterface; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\Common\Annotations\AnnotationReader ; +use Doctrine\Common\Annotations\Reader as AnnotationReader; +use ApiPlatform\Core\PathResolver\OperationPathResolverInterface; final class SwaggerDecorator implements NormalizerInterface { @@ -22,8 +21,6 @@ final class SwaggerDecorator implements NormalizerInterface private $annotationReader; public function __construct( - ResourceMetadataFactoryInterface $metadataFactory, - DocumentationNormalizer $documentationNormalizer, NormalizerInterface $decorated, ParameterBagInterface $params, CacheInterface $cache, @@ -31,8 +28,6 @@ public function __construct( AnnotationReader $annotationReader ) { - $this->metadataFactory = $metadataFactory; - $this->documentationNormalizer = $documentationNormalizer; $this->decorated = $decorated; $this->params = $params; $this->cash = $cache; @@ -46,21 +41,46 @@ public function normalize($object, $format = null, array $context = []) /* The we need to enrich al the entities and add the autoated routes */ + + // Lets make sure that we have tags + if(!array_key_exists ('tags',$docs)){$docs['tags']=[];} + // Lets get al the entities known to doctrine $entities = $this->em->getConfiguration()->getMetadataDriverImpl()->getAllClassNames(); // Then we loop trough the entities to find the api platform entities foreach($entities as $entity){ - $reflector = new \ReflectionClass($entity); - var_dump($this->annotationReader->getClassAnnotations($reflector)); - - // lest break for now - break; + //$reflector = new \ReflectionClass($entity); + $metadata = $this->em->getClassMetadata($entity); + $reflector = $metadata->getReflectionClass(); + + $properties = $metadata->getReflectionProperties(); + $annotations = $this->annotationReader->getClassAnnotations($reflector); - // If the entity is not a apiplatform entity lets continue - //if(){ - // continue - //} + foreach($annotations as $annotation){ + $annotationReflector = new \ReflectionClass($annotation); + if($annotationReflector->name == "ApiPlatform\Core\Annotation\ApiResource"){ + + // Lets add the class info to the tag + $shortName = $reflector->getShortName (); + + $factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); + $docblock = $factory->create($reflector->getDocComment()); + $summary = $docblock->getSummary(); + $description = $docblock->getDescription()->render(); + $description = $summary."\n\n".$description; + + $tag = []; + $tag['name'] = $shortName; + $tag['description'] = $description; + + $docs['tags'][] = $tag; + + // And lets add the aditional docs + $this->getAdditionalEntityDocs($entity); + break; + } + } } @@ -164,13 +184,25 @@ public function normalize($object, $format = null, array $context = []) ]; // NLX loging headers $call['parameters'][] = [ - 'name' => 'X-Audit-Clarification', + 'name' => 'X-NLX-Audit-Clarification', 'description' => 'A clarification as to why a request has been made (doelbinding)', 'in' => 'header', ]; if($method == "get"){ + + + // Health JSON + $call['produces'][] = 'application/health+json'; + + // WEBSUB header + $call['parameters'][] = [ + 'name' => 'Link', + 'description' => 'A [websub](https://www.w3.org/TR/websub/#discovery) header like ; rel="hub"', + 'in' => 'header', + ]; + // Lets add the extend functionality $call['parameters'][] = [ 'name' => 'extend[]', @@ -208,7 +240,7 @@ public function normalize($object, $format = null, array $context = []) 'description' => 'Returns objects valid until a given date time', 'schema'=>['type'=>'string', 'format' => 'date-time'], 'in' => 'query', - ]; + ]; } } } @@ -247,6 +279,52 @@ public function normalize($object, $format = null, array $context = []) array_unshift($fruits_list, $tag); } */ + //var_dump($docs); + + + // Aditional tags + + + // Security tag + $tag = []; + $tag['name'] = 'Health Checks'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + + // Security tag + $tag = []; + $tag['name'] = 'Notifications'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + + + // Security tag + $tag = []; + $tag['name'] = 'Audit trail'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + + // Security tag + $tag = []; + $tag['name'] = 'Authorization'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + + // Security tag + + // Security tag + + //$docs['tags']['name'] + + var_dump($docs); return $docs; } @@ -254,4 +332,45 @@ public function supportsNormalization($data, $format = null) { return $this->decorated->supportsNormalization($data, $format); } + + private function getAdditionalEntityDocs($entity){ + + $metadata = $this->em->getClassMetadata($entity); + $reflector = $metadata->getReflectionClass(); + $properties = $metadata->getReflectionProperties(); + $annotations = $this->annotationReader->getClassAnnotations($reflector); + + // Add audittrail + // Add healthcheck + + //var_dump($propertyAnnotation); + + // Lets take a look at the properties an annotions, + foreach($properties as $property){ + + // The annotations for this propertu + $propertyAnnotations = $this->annotationReader->getPropertyAnnotations($property); + + // Check the annotations for symfony vallidations + foreach($propertyAnnotations as $propertyAnnotation){ + + // Lentgh + if(get_class($propertyAnnotation) == "Symfony\Component\Validator\Constraints\NotNull"){ + + } + + // Lentgh + if(get_class($propertyAnnotation) == "Symfony\Component\Validator\Constraints\Length"){ + + } + } + + } + + + + $additionalDocs = []; + + return $additionalDocs; + } } \ No newline at end of file From 7d8d29f4229e5d1252b58a7cd610dd5c35e0c631 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 19 Nov 2019 08:47:11 +0100 Subject: [PATCH 020/182] Added auth, notification, audittrail and healthchecks to config --- .env | 34 +++++++++++---- api/config/packages/api_platform.yaml | 7 +-- api/config/packages/twig.yaml | 15 +++++-- api/helm/templates/configmap.yaml | 13 +++++- api/helm/templates/php-deployment.yaml | 35 ++++++++++++++- api/src/Swagger/SwaggerDecorator.php | 59 ++++++++++++++------------ api/templates/helm/values.yaml.twig | 10 ++++- docker-compose.yml | 12 +++--- 8 files changed, 135 insertions(+), 50 deletions(-) diff --git a/.env b/.env index a6cbce66..9c0e599a 100644 --- a/.env +++ b/.env @@ -8,9 +8,13 @@ # Enviroment settings ################################################## -# Depracticed, now set as CONTAINER_PROJECT_NAME +# The shortcode for this component, should be a small set of letters reprecentint the application APP_NAME=pc -# Do you want to dsiplay the symfony debug toolbar? +# The Full title of the application +APP_TITLE=Proto Component +# The current version of the application +APP_VERSION=V.0.1 +# Do you want to display the symfony debug toolbar? APP_DEBUG=1 # What is the enviroment type you want to use for local production? (choose between dec,stag,prod, acce or test) APP_ENV=dev @@ -19,32 +23,44 @@ APP_ENV=dev # Documentation settings ################################################## -APP_DEMO=dev -APP_REPRO=dev +APP_DEMO=pc.zaakonline.nl +APP_REPRO=https://github.com/ConductionNL/Proto-component-commonground ################################################## # Docker settings ################################################## CONTAINER_REGISTRY_BASE=docker.io/conduction -CONTAINER_PROJECT_TITLE=Proto Component CONTAINER_PROJECT_NAME=pc -CONTAINER_PROJECT_VERSION=V.0.1 ################################################## -# Websub settings +# Notifcation settings ################################################## -WEBSUB_PROVIDER=sasd -WEBSUB_AUTHORIZATION=sasd +NOTIFICATION_ENABLED=false +NOTIFICATION_PROVIDER=sasd +NOTIFICATION_ENABLED_AUTHORIZATION=sasd ################################################## # Authorization settings ################################################## +AUTH_ENABLED=false AUTH_PROVIDER=sasd AUTH_AUTHORIZATION=sasd +################################################## +# Auditrail settings +################################################## + +AUDITTRAIL_ENABLED=false + +################################################## +# Healthcheck settings +################################################## + +HEALTH_ENABLED=false + ################################################## # NLX Setup, read more at https://docs.nlx.io/get-started/# ################################################## diff --git a/api/config/packages/api_platform.yaml b/api/config/packages/api_platform.yaml index de2b19c8..9c8fa787 100644 --- a/api/config/packages/api_platform.yaml +++ b/api/config/packages/api_platform.yaml @@ -23,11 +23,12 @@ api_platform: title: '%env(APP_TITLE)%' description: | API Details - - Component: %env(CONTAINER_PROJECT_TITLE)% - - Reference: %env(CONTAINER_PROJECT_NAME)% + - Component: %env(APP_TITLE)% + - Reference: %env(APP_NAME)% - Enviroment: %env(APP_ENV)% - - Version: %env(CONTAINER_PROJECT_VERSION)% + - Version: %env(APP_VERSION)% - Repository: [%env(APP_REPRO)%](%env(APP_REPRO)%) / [zip](%env(APP_REPRO)%/archive/master.zip) + - Docker Image: [%env(APP_REPRO)%](%env(APP_REPRO)%) - Datamodel: [postman](/schema/openapi.postman_collection) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) %env(APP_DESCRIPTION)% diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml index d58f0a2d..1a687ce2 100644 --- a/api/config/packages/twig.yaml +++ b/api/config/packages/twig.yaml @@ -5,15 +5,24 @@ twig: globals: google_tag_manager_id: '%env(GOOGLE_TAG_MANAGER_ID)%' hubspot_embed_code: '%env(HUBSPOT_EMBED_CODE)%' - container_registry_base: '%env(CONTAINER_REGISTRY_BASE)%' - container_project_title: '%env(CONTAINER_PROJECT_TITLE)%' + + container_registry_base: '%env(CONTAINER_REGISTRY_BASE)%' container_project_name: '%env(CONTAINER_PROJECT_NAME)%' - container_project_version: '%env(CONTAINER_PROJECT_VERSION)%' + + app_name: '%env(APP_NAME)%' + app_title: '%env(APP_TITLE)%' + app_version: '%env(APP_VERSION)%' app_env: '%env(APP_ENV)%' app_debug: '%env(APP_DEBUG)%' app_demo: '%env(APP_DEMO)%' app_repro: '%env(APP_REPRO)%' app_description: '%env(APP_DESCRIPTION)%' + + app_auth: '%env(AUTH_ENABLED)%' + app_audittrail: '%env(AUDITTRAIL_ENABLED)%' + app_notification: '%env(NOTIFICATION_ENABLED)%' + app_health: '%env(HEALTH_ENABLED)%' + nlx_outway: '%env(NLX_OUTWAY)%' nlx_inway: '%env(NLX_INWAY)%' form_themes: diff --git a/api/helm/templates/configmap.yaml b/api/helm/templates/configmap.yaml index 462fedb6..744744e6 100644 --- a/api/helm/templates/configmap.yaml +++ b/api/helm/templates/configmap.yaml @@ -11,12 +11,23 @@ metadata: app.kubernetes.io/managed-by: {{ .Release.Service }} data: project_name: {{ .Values.settings.projectName | quote }} + app-name: {{ .Values.settings.name | quote }} + app-title: {{ .Values.settings.title | quote }} + app-version: {{ .Values.settings.version | quote }} + app-repro: {{ .Values.settings.repro | quote }} + app-demo: {{ .Values.settings.demo | quote }} + + #config + app-auth: {{ .Values.settings.demo | quote }} + app-audittrail: {{ .Values.settings.app_audittrail | quote }} + app-notification: {{ .Values.settings.app_notification | quote }} + app-health: {{ .Values.settings.demo | quote }} + env: {{ .Values.settings.env | quote }} debug: {{ .Values.settings.debug | quote }} cors-allow-origin: {{ .Values.settings.corsAllowOrigin | quote }} trusted-proxies: {{ join "," .Values.settings.trustedProxies }} trusted-hosts: {{ .Values.settings.trustedHosts | quote }} - project-name: {{ .Values.settings.projectName | quote }} php-service: {{ include "name" . }}-{{ .Values.settings.env }}-php varnish-url: {{ if .Values.varnish.enabled }}http://varnish{{ else }}{{ .Values.varnish.url | quote }}{{ end }} diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index bd471b70..7f4e1b31 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -46,7 +46,17 @@ spec: valueFrom: configMapKeyRef: name: {{ template "fullname" . }} - key: project-name + key: app-name + - name: APP_TITLE + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-title + - name: APP_VERSION + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-version - name: APP_ENV valueFrom: configMapKeyRef: @@ -57,6 +67,29 @@ spec: configMapKeyRef: name: {{ template "fullname" . }} key: debug + # config + - name: AUTH_ENABLED + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-auth + - name: AUDITTRAIL_ENABLED + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-audittrail + - name: NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-notification + - name: HEALTH_ENABLED + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-health + + # bla bla - name: CORS_ALLOW_ORIGIN valueFrom: configMapKeyRef: diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 27754379..8bed5f8b 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -286,41 +286,46 @@ public function normalize($object, $format = null, array $context = []) // Security tag - $tag = []; - $tag['name'] = 'Health Checks'; - $tag['description'] = 'Authorization'; - $tag['externalDocs'] = []; - $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; - array_unshift($docs['tags'], $tag); + if(getenv('HEALTH_ENABLED')){ + $tag = []; + $tag['name'] = 'Health Checks'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } // Security tag - $tag = []; - $tag['name'] = 'Notifications'; - $tag['description'] = 'Authorization'; - $tag['externalDocs'] = []; - $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; - array_unshift($docs['tags'], $tag); - + if(getenv('NOTIFICATION_ENABLED')){ + $tag = []; + $tag['name'] = 'Notifications'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } - // Security tag - $tag = []; - $tag['name'] = 'Audit trail'; - $tag['description'] = 'Authorization'; - $tag['externalDocs'] = []; - $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; - array_unshift($docs['tags'], $tag); // Security tag - $tag = []; - $tag['name'] = 'Authorization'; - $tag['description'] = 'Authorization'; - $tag['externalDocs'] = []; - $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; - array_unshift($docs['tags'], $tag); + if(getenv('AUDITTRAIL_ENABLED')){ + $tag = []; + $tag['name'] = 'Audit trail'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } // Security tag + if(getenv('AUTH_ENABLED')){ + $tag = []; + $tag['name'] = 'Authorization'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } - // Security tag //$docs['tags']['name'] diff --git a/api/templates/helm/values.yaml.twig b/api/templates/helm/values.yaml.twig index 1d024ae9..9a2e6d2a 100644 --- a/api/templates/helm/values.yaml.twig +++ b/api/templates/helm/values.yaml.twig @@ -5,6 +5,11 @@ settings: registryBase: {{ container_registry_base }} projectName: {{ container_project_name }} + name: {{ app_name }} + title: {{ app_title }} + version: {{ app_version }} + repro: {{ app_repro }} + demo: {{ app_demo }} env: {{ app_env }} debug: {{ app_debug }} replicaCount: 1 @@ -20,7 +25,10 @@ settings: loadbalancerEnabled: false # If you want to enable NLX you are requered to add the appropreate certificates to you nlx-settings folder (located in the /api folder) nlxInwayEnabled: {{ nlx_inway }} - nlxOutwayEnabled: {{ nlx_outway }} + # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer + notificationEnabled: false + audittrailEnabled: false + authorisationEnabled: false php: diff --git a/docker-compose.yml b/docker-compose.yml index 1506d754..afd238d8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,15 +29,17 @@ services: environment: - APP_ENV=${APP_ENV} - APP_DEBUG=${APP_DEBUG} - - APP_VERSION=${CONTAINER_PROJECT_VERSION} - - APP_TITLE=${CONTAINER_PROJECT_TITLE} - - APP_NAME=${CONTAINER_PROJECT_NAME} + - APP_VERSION=${APP_VERSION} + - APP_NAME=${APP_NAME} + - APP_TITLE=${APP_TITLE} + - AUTH_ENABLED=${AUTH_ENABLED} + - AUDITTRAIL_ENABLED=${AUDITTRAIL_ENABLED} + - NOTIFICATION_ENABLED=${NOTIFICATION_ENABLED} + - HEALTH_ENABLED=${HEALTH_ENABLED} - NLX_OUTWAY=${NLX_OUTWAY} - NLX_INWAY=${NLX_INWAY} - CONTAINER_REGISTRY_BASE=${CONTAINER_REGISTRY_BASE} - - CONTAINER_PROJECT_TITLE=${CONTAINER_PROJECT_TITLE} - CONTAINER_PROJECT_NAME=${CONTAINER_PROJECT_NAME} - - CONTAINER_PROJECT_VERSION=${CONTAINER_PROJECT_VERSION} - DATABASE_URL=postgres://api-platform:!ChangeMe!@db/api?serverVersion=10.1 ports: - "8082:80" From a5add0a8736440d8166ee00203b81dac04d4c301 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 19 Nov 2019 08:53:01 +0100 Subject: [PATCH 021/182] Added Archive configuration --- .env | 6 ++++++ api/helm/templates/configmap.yaml | 9 +++++---- api/helm/templates/php-deployment.yaml | 5 +++++ api/templates/helm/values.yaml.twig | 2 ++ docker-compose.yml | 1 + 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.env b/.env index 9c0e599a..bd3a2c4b 100644 --- a/.env +++ b/.env @@ -61,6 +61,12 @@ AUDITTRAIL_ENABLED=false HEALTH_ENABLED=false +################################################## +# Archive settings +################################################## + +ARCHIVE_ENABLED=false + ################################################## # NLX Setup, read more at https://docs.nlx.io/get-started/# ################################################## diff --git a/api/helm/templates/configmap.yaml b/api/helm/templates/configmap.yaml index 744744e6..fb7093d7 100644 --- a/api/helm/templates/configmap.yaml +++ b/api/helm/templates/configmap.yaml @@ -18,10 +18,11 @@ data: app-demo: {{ .Values.settings.demo | quote }} #config - app-auth: {{ .Values.settings.demo | quote }} - app-audittrail: {{ .Values.settings.app_audittrail | quote }} - app-notification: {{ .Values.settings.app_notification | quote }} - app-health: {{ .Values.settings.demo | quote }} + app-auth: {{ .Values.settings.authorisationEnabled | quote }} + app-audittrail: {{ .Values.settings.audittrailEnabled | quote }} + app-notification: {{ .Values.settings.notificationEnabled | quote }} + app-health: {{ .Values.settings.healthEnabled | quote }} + app-archive: {{ .Values.settings.archiveEnabled | quote }} env: {{ .Values.settings.env | quote }} debug: {{ .Values.settings.debug | quote }} diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index 7f4e1b31..21884a08 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -88,6 +88,11 @@ spec: configMapKeyRef: name: {{ template "fullname" . }} key: app-health + - name: ARCHIVE_ENABLED + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-archive # bla bla - name: CORS_ALLOW_ORIGIN diff --git a/api/templates/helm/values.yaml.twig b/api/templates/helm/values.yaml.twig index 9a2e6d2a..059cb8fb 100644 --- a/api/templates/helm/values.yaml.twig +++ b/api/templates/helm/values.yaml.twig @@ -29,6 +29,8 @@ settings: notificationEnabled: false audittrailEnabled: false authorisationEnabled: false + healthEnabled: false + archiveEnabled: false php: diff --git a/docker-compose.yml b/docker-compose.yml index afd238d8..8c89927d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -36,6 +36,7 @@ services: - AUDITTRAIL_ENABLED=${AUDITTRAIL_ENABLED} - NOTIFICATION_ENABLED=${NOTIFICATION_ENABLED} - HEALTH_ENABLED=${HEALTH_ENABLED} + - ARCHIVE_ENABLED=${ARCHIVE_ENABLED} - NLX_OUTWAY=${NLX_OUTWAY} - NLX_INWAY=${NLX_INWAY} - CONTAINER_REGISTRY_BASE=${CONTAINER_REGISTRY_BASE} From 5f7dbcf10c589882d7a8a8ec46c8fafb3a82cb6e Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 19 Nov 2019 11:03:04 +0100 Subject: [PATCH 022/182] Notification, Audittrail, Archive, Timetravel & expand functionality --- .env | 1 + api/config/packages/api_platform.yaml | 17 +-- api/helm/Chart.yaml | 2 +- api/helm/templates/php-deployment.yaml | 10 ++ api/helm/values.yaml | 12 +- api/public/schema/openapi.yaml | 158 ++++++------------------- api/src/Swagger/SwaggerDecorator.php | 12 +- api/templates/helm/Chart.yaml.twig | 4 +- docker-compose.yml | 3 + 9 files changed, 76 insertions(+), 143 deletions(-) diff --git a/.env b/.env index bd3a2c4b..85eed307 100644 --- a/.env +++ b/.env @@ -32,6 +32,7 @@ APP_REPRO=https://github.com/ConductionNL/Proto-component-commonground CONTAINER_REGISTRY_BASE=docker.io/conduction CONTAINER_PROJECT_NAME=pc +CONTAINER_REPRO=https://hub.docker.com/repository/docker/conduction/pc-php ################################################## # Notifcation settings diff --git a/api/config/packages/api_platform.yaml b/api/config/packages/api_platform.yaml index 9c8fa787..4f35c06b 100644 --- a/api/config/packages/api_platform.yaml +++ b/api/config/packages/api_platform.yaml @@ -4,16 +4,16 @@ parameters: # environment variables are not available yet. # You should not need to change this value. env(VARNISH_URL): '' - env(APP_VERSION): '' + env(APP_VERSION): ' + env(APP_NAME): ''' env(APP_TITLE): '' env(APP_DESCRIPTION): '' env(APP_REPRO): '' env(APP_DEMO): '' env(APP_ENV): '' env(CONTAINER_REGISTRY_BASE): '' - env(CONTAINER_PROJECT_TITLE): '' env(CONTAINER_PROJECT_NAME): '' - env(CONTAINER_PROJECT_VERSION): '' + env(CONTAINER_REPRO): '' api_platform: mapping: @@ -27,16 +27,11 @@ api_platform: - Reference: %env(APP_NAME)% - Enviroment: %env(APP_ENV)% - Version: %env(APP_VERSION)% - - Repository: [%env(APP_REPRO)%](%env(APP_REPRO)%) / [zip](%env(APP_REPRO)%/archive/master.zip) - - Docker Image: [%env(APP_REPRO)%](%env(APP_REPRO)%) + - Repository: [online](%env(APP_REPRO)%) / [zip](%env(APP_REPRO)%/archive/master.zip) + - Docker Image: [online](%env(CONTAINER_REPRO)%) - Datamodel: [postman](/schema/openapi.postman_collection) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) - %env(APP_DESCRIPTION)% - - Voor het gebruik van deze applicatie is een JWT Token nodig, deze hangt altijd vast aan een applicatie, ofwel user. Geldige JWT Tokens worden aangemaakt bij het registreren van een applicatie en kennen een beperkte houdbaarheid. - JWT Tokens kunnen zowel worden verlengd, als opnieuw worden aangevraagd, dit aan de hand van de applicatie id en sleutel. - Let er bij het meegeven van JWT tokens op dat deze moet worden voorafgegaan door een Bearer en een spatie, onder de header Authorization. De volledig naam wordt daarmee: 'Authorization: Bearer [TOKEN]'. - + %env(APP_DESCRIPTION)% version: '%env(APP_VERSION)%' diff --git a/api/helm/Chart.yaml b/api/helm/Chart.yaml index 858796cb..31ac8664 100644 --- a/api/helm/Chart.yaml +++ b/api/helm/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 appVersion: V.0.1 description: Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar. -name: protocomponent +name: pc version: 0.1.0 home: https://common-ground.dev icon: https://common-ground.dev/logo-250x250.png \ No newline at end of file diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index 21884a08..bca6a7fc 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -67,6 +67,16 @@ spec: configMapKeyRef: name: {{ template "fullname" . }} key: debug + - name: APP_DEMO + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-demo + - name: APP_REPRO + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-repro # config - name: AUTH_ENABLED valueFrom: diff --git a/api/helm/values.yaml b/api/helm/values.yaml index b53a056a..b79502c2 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -5,6 +5,11 @@ settings: registryBase: docker.io/conduction projectName: pc + name: pc + title: Proto Component + version: V.0.1 + repro: https://github.com/ConductionNL/Proto-component-commonground + demo: pc.zaakonline.nl env: dev debug: 1 replicaCount: 1 @@ -20,7 +25,12 @@ settings: loadbalancerEnabled: false # If you want to enable NLX you are requered to add the appropreate certificates to you nlx-settings folder (located in the /api folder) nlxInwayEnabled: false - nlxOutwayEnabled: true + # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer + notificationEnabled: false + audittrailEnabled: false + authorisationEnabled: false + healthEnabled: false + archiveEnabled: false php: diff --git a/api/public/schema/openapi.yaml b/api/public/schema/openapi.yaml index cb1cc166..549b9016 100644 --- a/api/public/schema/openapi.yaml +++ b/api/public/schema/openapi.yaml @@ -8,14 +8,11 @@ info: - Reference: pc - Enviroment: dev - Version: V.0.1 - - Repository: []() / [zip](/archive/master.zip) + - Repository: [online](https://github.com/ConductionNL/Proto-component-commonground) / [zip](https://github.com/ConductionNL/Proto-component-commonground/archive/master.zip) + - Docker Image: [online](https://hub.docker.com/repository/docker/conduction/pc-php) - Datamodel: [postman](/schema/openapi.postman_collection) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar. - - Voor het gebruik van deze applicatie is een JWT Token nodig, deze hangt altijd vast aan een applicatie, ofwel user. Geldige JWT Tokens worden aangemaakt bij het registreren van een applicatie en kennen een beperkte houdbaarheid. - JWT Tokens kunnen zowel worden verlengd, als opnieuw worden aangevraagd, dit aan de hand van de applicatie id en sleutel. - Let er bij het meegeven van JWT tokens op dat deze moet worden voorafgegaan door een Bearer en een spatie, onder de header Authorization. De volledig naam wordt daarmee: 'Authorization: Bearer [TOKEN]'. paths: /example_entities: @@ -114,9 +111,13 @@ paths: description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' in: header - - name: X-Audit-Clarification + name: X-NLX-Audit-Clarification description: 'A clarification as to why a request has been made (doelbinding)' in: header + - + name: Link + description: 'A [websub](https://www.w3.org/TR/websub/#discovery) header like ; rel="hub"' + in: header - name: 'extend[]' required: false @@ -155,6 +156,8 @@ paths: type: string format: date-time in: query + produces: + - application/health+json post: tags: - ExampleEntity @@ -252,14 +255,14 @@ paths: description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' in: header - - name: X-Audit-Clarification + name: X-NLX-Audit-Clarification description: 'A clarification as to why a request has been made (doelbinding)' in: header '/example_entities/{id}': get: tags: - ExampleEntity - operationId: getExampleEntityItem + operationId: audittrailExampleEntityItem summary: 'Retrieves a ExampleEntity resource.' parameters: - @@ -294,9 +297,13 @@ paths: description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' in: header - - name: X-Audit-Clarification + name: X-NLX-Audit-Clarification description: 'A clarification as to why a request has been made (doelbinding)' in: header + - + name: Link + description: 'A [websub](https://www.w3.org/TR/websub/#discovery) header like ; rel="hub"' + in: header - name: 'extend[]' required: false @@ -365,52 +372,8 @@ paths: $ref: '#/components/schemas/ExampleEntity-read' 404: description: 'Resource not found' - delete: - tags: - - ExampleEntity - operationId: deleteExampleEntityItem - summary: 'Removes the ExampleEntity resource.' - responses: - 204: - description: 'ExampleEntity resource deleted' - 404: - description: 'Resource not found' - parameters: - - - name: id - in: path - required: true - schema: - type: string - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header + produces: + - application/health+json put: tags: - ExampleEntity @@ -449,7 +412,7 @@ paths: description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' in: header - - name: X-Audit-Clarification + name: X-NLX-Audit-Clarification description: 'A clarification as to why a request has been made (doelbinding)' in: header responses: @@ -511,11 +474,16 @@ paths: schema: $ref: '#/components/schemas/ExampleEntity-write' description: 'The updated ExampleEntity resource' - patch: + delete: tags: - ExampleEntity - operationId: patchExampleEntityItem - summary: 'Updates the ExampleEntity resource.' + operationId: deleteExampleEntityItem + summary: 'Removes the ExampleEntity resource.' + responses: + 204: + description: 'ExampleEntity resource deleted' + 404: + description: 'Resource not found' parameters: - name: id @@ -549,73 +517,14 @@ paths: description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' in: header - - name: X-Audit-Clarification + name: X-NLX-Audit-Clarification description: 'A clarification as to why a request has been made (doelbinding)' in: header - responses: - 200: - description: 'ExampleEntity resource updated' - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - 400: - description: 'Invalid input' - 404: - description: 'Resource not found' - requestBody: - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - description: 'The updated ExampleEntity resource' components: schemas: ExampleEntity-read: type: object - description: '' + description: 'This is an example entity' properties: id: readOnly: true @@ -630,7 +539,7 @@ components: - name ExampleEntity-write: type: object - description: '' + description: 'This is an example entity' required: - name properties: @@ -640,6 +549,13 @@ components: description: description: 'The description of this example property' type: string +tags: + - + name: ExampleEntity + description: | + This is an example entity + + With an adtional description, all in all its pritty nice [url](www.google.nl) host: irc.zaakonline.nl servers: - diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 8bed5f8b..d7f0d214 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -286,7 +286,7 @@ public function normalize($object, $format = null, array $context = []) // Security tag - if(getenv('HEALTH_ENABLED')){ + if(getenv('HEALTH_ENABLED')=="true"){ $tag = []; $tag['name'] = 'Health Checks'; $tag['description'] = 'Authorization'; @@ -296,7 +296,7 @@ public function normalize($object, $format = null, array $context = []) } // Security tag - if(getenv('NOTIFICATION_ENABLED')){ + if(getenv('NOTIFICATION_ENABLED')=="true"){ $tag = []; $tag['name'] = 'Notifications'; $tag['description'] = 'Authorization'; @@ -307,7 +307,7 @@ public function normalize($object, $format = null, array $context = []) // Security tag - if(getenv('AUDITTRAIL_ENABLED')){ + if(getenv('AUDITTRAIL_ENABLED')=="true"){ $tag = []; $tag['name'] = 'Audit trail'; $tag['description'] = 'Authorization'; @@ -317,7 +317,7 @@ public function normalize($object, $format = null, array $context = []) } // Security tag - if(getenv('AUTH_ENABLED')){ + if(getenv('AUTH_ENABLED')=="true"){ $tag = []; $tag['name'] = 'Authorization'; $tag['description'] = 'Authorization'; @@ -327,9 +327,7 @@ public function normalize($object, $format = null, array $context = []) } - //$docs['tags']['name'] - - var_dump($docs); + //var_dump($docs); return $docs; } diff --git a/api/templates/helm/Chart.yaml.twig b/api/templates/helm/Chart.yaml.twig index 7795e920..6da2f97a 100644 --- a/api/templates/helm/Chart.yaml.twig +++ b/api/templates/helm/Chart.yaml.twig @@ -1,7 +1,7 @@ apiVersion: v1 -appVersion: {{ container_project_version }} +appVersion: {{ app_version }} description: {{ app_description }} -name: {{ container_project_title|replace({' ': ''})|lower }} +name: {{ app_name|replace({' ': ''})|lower }} version: 0.1.0 home: https://common-ground.dev icon: https://common-ground.dev/logo-250x250.png \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 8c89927d..1e2f587f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,6 +32,8 @@ services: - APP_VERSION=${APP_VERSION} - APP_NAME=${APP_NAME} - APP_TITLE=${APP_TITLE} + - APP_DEMO=${APP_DEMO} + - APP_REPRO=${APP_REPRO} - AUTH_ENABLED=${AUTH_ENABLED} - AUDITTRAIL_ENABLED=${AUDITTRAIL_ENABLED} - NOTIFICATION_ENABLED=${NOTIFICATION_ENABLED} @@ -41,6 +43,7 @@ services: - NLX_INWAY=${NLX_INWAY} - CONTAINER_REGISTRY_BASE=${CONTAINER_REGISTRY_BASE} - CONTAINER_PROJECT_NAME=${CONTAINER_PROJECT_NAME} + - CONTAINER_REPRO=${CONTAINER_REPRO} - DATABASE_URL=postgres://api-platform:!ChangeMe!@db/api?serverVersion=10.1 ports: - "8082:80" From 03ceb43aacce2391f0da15f32f8006c7f1f69e8b Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 19 Nov 2019 12:17:05 +0100 Subject: [PATCH 023/182] Update on helm files --- .env | 2 ++ INSTALLATION.md | 12 ++++++------ api/config/packages/api_platform.yaml | 2 +- api/helm/Chart.yaml | 2 +- api/helm/templates/configmap.yaml | 7 ++----- api/helm/templates/php-deployment.yaml | 5 +++++ api/helm/values.yaml | 3 ++- api/public/schema/openapi.yaml | 2 +- api/src/Entity/ExampleEntity.php | 25 +++++++++++++++++++++++++ api/templates/helm/Chart.yaml.twig | 2 +- api/templates/helm/values.yaml.twig | 3 ++- docker-compose.yml | 1 + 12 files changed, 49 insertions(+), 17 deletions(-) diff --git a/.env b/.env index 85eed307..0380f3ac 100644 --- a/.env +++ b/.env @@ -18,6 +18,8 @@ APP_VERSION=V.0.1 APP_DEBUG=1 # What is the enviroment type you want to use for local production? (choose between dec,stag,prod, acce or test) APP_ENV=dev +# The description for this api +APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' ################################################## # Documentation settings diff --git a/INSTALLATION.md b/INSTALLATION.md index 63989676..05bad3ed 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -65,16 +65,16 @@ $ helm dependency update ./api/helm ``` If you want to create a new instance ```CLI -$ helm install --name pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1 -$ helm install --name pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0 -$ helm install --name pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0 +$ helm install --name pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1,settings.loadbalancerEnabled=true +$ helm install --name pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0,settings.loadbalancerEnabled=true +$ helm install --name pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0,settings.loadbalancerEnabled=true ``` Or update if you want to update an existing one ```CLI -$ helm upgrade pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1 -$ helm upgrade pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0 -$ helm upgrade pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0 +$ helm upgrade pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1,settings.loadbalancerEnabled=true +$ helm upgrade pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0,settings.loadbalancerEnabled=true +$ helm upgrade pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0,settings.loadbalancerEnabled=true ``` Or del if you want to delete an existing one diff --git a/api/config/packages/api_platform.yaml b/api/config/packages/api_platform.yaml index 4f35c06b..81c20da1 100644 --- a/api/config/packages/api_platform.yaml +++ b/api/config/packages/api_platform.yaml @@ -41,7 +41,7 @@ api_platform: enable_re_doc: true # In the NL api strategie we use snake case for naming - name_converter: 'Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter' + # name_converter: 'Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter' # Lets confirm to JSON-HA: first, as per common ground. But allow other serializers formats: diff --git a/api/helm/Chart.yaml b/api/helm/Chart.yaml index 31ac8664..7c3c8a6a 100644 --- a/api/helm/Chart.yaml +++ b/api/helm/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 appVersion: V.0.1 -description: Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar. +description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' name: pc version: 0.1.0 home: https://common-ground.dev diff --git a/api/helm/templates/configmap.yaml b/api/helm/templates/configmap.yaml index fb7093d7..61797a1f 100644 --- a/api/helm/templates/configmap.yaml +++ b/api/helm/templates/configmap.yaml @@ -16,21 +16,18 @@ data: app-version: {{ .Values.settings.version | quote }} app-repro: {{ .Values.settings.repro | quote }} app-demo: {{ .Values.settings.demo | quote }} - - #config + app-description: {{ .Values.settings.description | quote }} app-auth: {{ .Values.settings.authorisationEnabled | quote }} app-audittrail: {{ .Values.settings.audittrailEnabled | quote }} app-notification: {{ .Values.settings.notificationEnabled | quote }} app-health: {{ .Values.settings.healthEnabled | quote }} app-archive: {{ .Values.settings.archiveEnabled | quote }} - env: {{ .Values.settings.env | quote }} debug: {{ .Values.settings.debug | quote }} cors-allow-origin: {{ .Values.settings.corsAllowOrigin | quote }} trusted-proxies: {{ join "," .Values.settings.trustedProxies }} trusted-hosts: {{ .Values.settings.trustedHosts | quote }} - php-service: {{ include "name" . }}-{{ .Values.settings.env }}-php - + php-service: {{ include "name" . }}-{{ .Values.settings.env }}-php varnish-url: {{ if .Values.varnish.enabled }}http://varnish{{ else }}{{ .Values.varnish.url | quote }}{{ end }} mercure-publish-url: {{ .Values.mercure.publishUrl | quote }} mercure-subscribe-url: {{ .Values.mercure.subscribeUrl | quote }} diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index bca6a7fc..1b03232e 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -52,6 +52,11 @@ spec: configMapKeyRef: name: {{ template "fullname" . }} key: app-title + - name: APP_DESCRIPTION + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-description - name: APP_VERSION valueFrom: configMapKeyRef: diff --git a/api/helm/values.yaml b/api/helm/values.yaml index b79502c2..6bf6d3b2 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -8,7 +8,8 @@ settings: name: pc title: Proto Component version: V.0.1 - repro: https://github.com/ConductionNL/Proto-component-commonground + description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' + repro: https://github.com/ConductionNL/Proto-component-commonground' demo: pc.zaakonline.nl env: dev debug: 1 diff --git a/api/public/schema/openapi.yaml b/api/public/schema/openapi.yaml index 549b9016..d3c1e631 100644 --- a/api/public/schema/openapi.yaml +++ b/api/public/schema/openapi.yaml @@ -12,7 +12,7 @@ info: - Docker Image: [online](https://hub.docker.com/repository/docker/conduction/pc-php) - Datamodel: [postman](/schema/openapi.postman_collection) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) - Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar. + 'Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' paths: /example_entities: diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php index 1ff29279..f41fad32 100644 --- a/api/src/Entity/ExampleEntity.php +++ b/api/src/Entity/ExampleEntity.php @@ -89,6 +89,19 @@ class ExampleEntity */ private $description; + /** + * @var string $camelCase Proof that we camel case our api + * @example Is the best group ever + * + * @Assert\Length( + * max = 2555 + * ) + * @Gedmo\Versioned + * @Groups({"read","write"}) + * @ORM\Column(type="string", length=255, nullable=true) + */ + private $camelCase; + public function getId(): ?int { return $this->id; @@ -118,4 +131,16 @@ public function setDescription(?string $description): self return $this; } + public function getCamelCase(): ?string + { + return $this->camelCase; + } + + public function setCamelCase(?string $camelCase): self + { + $this->camelCase = $camelCase; + + return $this; + } + } diff --git a/api/templates/helm/Chart.yaml.twig b/api/templates/helm/Chart.yaml.twig index 6da2f97a..821c26b2 100644 --- a/api/templates/helm/Chart.yaml.twig +++ b/api/templates/helm/Chart.yaml.twig @@ -1,6 +1,6 @@ apiVersion: v1 appVersion: {{ app_version }} -description: {{ app_description }} +description: '{{ app_description }}' name: {{ app_name|replace({' ': ''})|lower }} version: 0.1.0 home: https://common-ground.dev diff --git a/api/templates/helm/values.yaml.twig b/api/templates/helm/values.yaml.twig index 059cb8fb..33aebbd8 100644 --- a/api/templates/helm/values.yaml.twig +++ b/api/templates/helm/values.yaml.twig @@ -8,7 +8,8 @@ settings: name: {{ app_name }} title: {{ app_title }} version: {{ app_version }} - repro: {{ app_repro }} + description: '{{ app_description }}' + repro: {{ app_repro }}' demo: {{ app_demo }} env: {{ app_env }} debug: {{ app_debug }} diff --git a/docker-compose.yml b/docker-compose.yml index 1e2f587f..56e9368b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,6 +34,7 @@ services: - APP_TITLE=${APP_TITLE} - APP_DEMO=${APP_DEMO} - APP_REPRO=${APP_REPRO} + - APP_DESCRIPTION=${APP_DESCRIPTION} - AUTH_ENABLED=${AUTH_ENABLED} - AUDITTRAIL_ENABLED=${AUDITTRAIL_ENABLED} - NOTIFICATION_ENABLED=${NOTIFICATION_ENABLED} From 3801e401ba1abf90bcd3810565f5ee849a8d5425 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 19 Nov 2019 15:33:25 +0100 Subject: [PATCH 024/182] Fix on env variables --- api/config/packages/api_platform.yaml | 5 +++++ api/helm/templates/configmap.yaml | 2 ++ api/src/Entity/ExampleEntity.php | 2 +- docker-compose.yml | 8 ++++---- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/api/config/packages/api_platform.yaml b/api/config/packages/api_platform.yaml index 81c20da1..11f8555f 100644 --- a/api/config/packages/api_platform.yaml +++ b/api/config/packages/api_platform.yaml @@ -11,6 +11,11 @@ parameters: env(APP_REPRO): '' env(APP_DEMO): '' env(APP_ENV): '' + env(AUTH_ENABLED): '' + env(AUDITTRAIL_ENABLED): '' + env(NOTIFICATION_ENABLED): '' + env(HEALTH_ENABLED): '' + env(ARCHIVE_ENABLED): '' env(CONTAINER_REGISTRY_BASE): '' env(CONTAINER_PROJECT_NAME): '' env(CONTAINER_REPRO): '' diff --git a/api/helm/templates/configmap.yaml b/api/helm/templates/configmap.yaml index 61797a1f..55279410 100644 --- a/api/helm/templates/configmap.yaml +++ b/api/helm/templates/configmap.yaml @@ -17,11 +17,13 @@ data: app-repro: {{ .Values.settings.repro | quote }} app-demo: {{ .Values.settings.demo | quote }} app-description: {{ .Values.settings.description | quote }} + app-auth: {{ .Values.settings.authorisationEnabled | quote }} app-audittrail: {{ .Values.settings.audittrailEnabled | quote }} app-notification: {{ .Values.settings.notificationEnabled | quote }} app-health: {{ .Values.settings.healthEnabled | quote }} app-archive: {{ .Values.settings.archiveEnabled | quote }} + env: {{ .Values.settings.env | quote }} debug: {{ .Values.settings.debug | quote }} cors-allow-origin: {{ .Values.settings.corsAllowOrigin | quote }} diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php index f41fad32..389740cf 100644 --- a/api/src/Entity/ExampleEntity.php +++ b/api/src/Entity/ExampleEntity.php @@ -91,7 +91,7 @@ class ExampleEntity /** * @var string $camelCase Proof that we camel case our api - * @example Is the best group ever + * @example Best api ever * * @Assert\Length( * max = 2555 diff --git a/docker-compose.yml b/docker-compose.yml index 56e9368b..43498f17 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,6 +27,10 @@ services: # If you develop on Linux, uncomment the following line to use a bind-mounted host directory instead # - ./api/var:/srv/api/var:rw environment: + - CONTAINER_REGISTRY_BASE=${CONTAINER_REGISTRY_BASE} + - CONTAINER_PROJECT_NAME=${CONTAINER_PROJECT_NAME} + - CONTAINER_REPRO=${CONTAINER_REPRO} + - DATABASE_URL=postgres://api-platform:!ChangeMe!@db/api?serverVersion=10.1 - APP_ENV=${APP_ENV} - APP_DEBUG=${APP_DEBUG} - APP_VERSION=${APP_VERSION} @@ -42,10 +46,6 @@ services: - ARCHIVE_ENABLED=${ARCHIVE_ENABLED} - NLX_OUTWAY=${NLX_OUTWAY} - NLX_INWAY=${NLX_INWAY} - - CONTAINER_REGISTRY_BASE=${CONTAINER_REGISTRY_BASE} - - CONTAINER_PROJECT_NAME=${CONTAINER_PROJECT_NAME} - - CONTAINER_REPRO=${CONTAINER_REPRO} - - DATABASE_URL=postgres://api-platform:!ChangeMe!@db/api?serverVersion=10.1 ports: - "8082:80" From 78127b20a09ad222f311cbea46d63cc66c406502 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 25 Nov 2019 10:25:04 +0100 Subject: [PATCH 025/182] Fixes on design.md --- DESIGN.md | 211 ++++++++++++++++++++++------ api/docker/php/docker-entrypoint.sh | 9 +- api/src/Entity/ExampleEntity.php | 2 + 3 files changed, 173 insertions(+), 49 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index ac705c08..1f5104e0 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -1,16 +1,124 @@ -# Design Considerations +# Design Considerations as Proposal + +Welcome, you are currently viewing the design decisions for the proto component. The proto component aims to provide a framework for the quick development of production apis for the commonground project. + +*index* +- [The European factor](#the-european-factor) +- [On standards and standardisation](#on-standards-and-standardization) +- [NL API Strategie](#nl-api-strategie) + +*Design Choices* +- [NLX](#nlx) +- [English](#english) +- [Fields](#fields) +- [Search](#search) +- [Queries](#queries) +- [Extending](#extending) +- [Timetravel](#timetravel) +- [Archivation](#archivation) +- [Audittrail](#audittrail) +- [Healthchecks](#healthchecks) +- [Notifications](#notifications) +- [Authentication](#authentication) +- [Authorization](#authorization) +- [Ordering](#ordering) +- [Translations](#translations) +- [Errors](#errors) +- [Arrays](#arrays) +- [Filtering](#filtering) + +*Implementation choices* +- [Api Versioning](#api-versioning) +- [Environments and namespacing](#environments-and-namespacing) +- [Domain Build-up and routing](#domain-build-up-and-routing) +- Container Setup](#container-setup) -This component was designed in line with the [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index), [commonground principles](https://vng.nl/onderwerpenindex/bestuur/samen-organiseren-2019/common-ground) and international standards. - -The specific goal of this component is to provide a common architecture for common ground components as such the common ground principles are leading in design choices, and within those principles technological invocation and international compliancy is deemed most important. **We do not want to mace consessions to the current infrastructure.** As such the component might differ on [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index) and other standards if they are deemed incompatible or out of line with international standards. The European factor ------- -The proto-component isn't just a Dutch Component, it is in essence a dutch translation of european components, nowhere is this more obvious than in the core code. Our component is based on [API Platform](https://api-platform.com/) an API specific version of the symfony framework. This framework is build by the lovely people of []() and is build with support of the European Commission trough the [EU-FOSSA Hackathon](https://ec.europa.eu/info/news/first-eu-fossa-hackathon-it-happened-2019-may-03_en) and Digital Ocean trough [Hacktoberfest](https://hacktoberfest.digitalocean.com/). +The proto-component isn't just a Dutch Component, it is in essence a Dutch translation of European components, nowhere is this more obvious than in the core code. Our component is based on [API Platform](https://api-platform.com/) an API specific version of the symfony framework. This framework is build by the lovely people of []() and is build with support of the European Commission trough the [EU-FOSSA Hackathon](https://ec.europa.eu/info/news/first-eu-fossa-hackathon-it-happened-2019-may-03_en) and Digital Ocean trough [Hacktoberfest](https://hacktoberfest.digitalocean.com/). + +But it doesn't just end there. The [varnish container](https://hub.docker.com/r/eeacms/varnish/) that we use to speed up the API response is build and maintained by [EEA]() (The European Environment Agency) and the development team at conduction itself is attached to the [Odyssey program](https://www.odyssey.org/) and originated from the [startupinresidence](https://startupinresidence.com/) program. + +So you could say that both change and a European perspective is in our blood. + +On standards and standardization +------- +The specific goal of the proto component (which this current code base is a version of) is to provide a common architecture for common ground components. As such the common ground principles are leading in design choices, and within those principles international compliancy and technological invocation is deemed most important. **We do not want to make concessions to the current infrastructure.** As such the component might differ on [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index) and or other standards if they are deemed incompatible or out of line with (inter)national standards and or good practices. + +Unfortunatly (inter)national standards standards can be conflicting. We therefore prioritize standards on two grounds + +- International standards are put before local standards +- Standards caried by a standard organisation (like ISO, W3C etc) at put before floating standards (like RFC's) wichs are put before industraty standards, good practices and so on. + +### Commonground specific standards + +This component was designed in line with the [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index), [commonground principles](https://vng.nl/onderwerpenindex/bestuur/samen-organiseren-2019/common-ground). + +## NL API Strategie + +The [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie) takes a special place in this component, it is designed as a set of guidelines for API's for the dutch landscape. As such we follow it as close as posible. It dos however contains inconsistenies with both international standards and good practices. On those items we do not follow the norm but consider it our duty to try to change the norm. + +** We implement ** + +api-01, api-02, api-03, api-05, api-06, api-10, api-11, api-12, api-13,api-14, api-16, api-18, api-19, api-20, api-21, api-22, api-23, api-24, api-25, api-26, api-27, api-28, api-29, api-30, api-33, api-34, api-35, api-42 + +** We want to implement ** +- [api-14](https://docs.geostandaarden.nl/api/API-Strategie/#api-14) Use OAuth 2.0 for authorisation + +** We do not implement ** + +- [api-04](https://docs.geostandaarden.nl/api/API-Strategie/#api-04) Define interfaces in Dutch unless there is an official English glossary (see [english](#english)) +- [api-09](https://docs.geostandaarden.nl/api/API-Strategie/#api-09) Implement custom representation if supported see [fields](#fields)) +- [api-17](https://docs.geostandaarden.nl/api/API-Strategie/#api-17) Publish documentation in Dutch unless there is existing documentation in English or there is an official English glossary (see [english](#english)) +- [api-31](https://docs.geostandaarden.nl/api/API-Strategie/#api-31) Use the query parameter sorteer to sort (see [ordering](#ordering)) +- [api-32](https://docs.geostandaarden.nl/api/API-Strategie/#api-32) Use the query parameter zoek for full-text search (see [search](#search)) +- [api-36](https://docs.geostandaarden.nl/api/API-Strategie/#api-36) Provide a POST endpoint for GEO queries (see [queries](#queries)) +- [api-37](https://docs.geostandaarden.nl/api/API-Strategie/#api-37) Support mixed queries at POST endpoints available (see [queries](#queries)) +*[api-38](https://docs.geostandaarden.nl/api/API-Strategie/#api-38) Put results of a global spatial query in the relevant geometric context (see [queries](#queries)) +- + +** We doubt or havn't made a choice yet about** + +- [api-15](https://docs.geostandaarden.nl/api/API-Strategie/#api-15) Use PKIoverheid certificates for access-restricted or purpose-limited API authentication +- [api-39](https://docs.geostandaarden.nl/api/API-Strategie/#api-39) Use ETRS89 as the preferred coordinate reference system (CRS) +- [api-40](https://docs.geostandaarden.nl/api/API-Strategie/#api-40) Pass the coordinate reference system (CRS) of the request and the response in the headers +- [api-41](https://docs.geostandaarden.nl/api/API-Strategie/#api-41) Use content negotiation to serve different CRS + +NLX +------- +We implement the [NLX system](https://docs.nlx.io/understanding-the-basics/introduction/) as part of the basic commonground infrastructure, as such nlx headers are used in the internal logging. +The following X-NLX headers have been implemented for that reason `X-NLX-Logrecord-ID`,`X-NLX-Request-Process-Id`,`X-NLX-Request-Data-Elements` and `X-NLX-Request-Data-Subject`, these are tied to the internal audit trail (see audit trail for more information), and `X-Audit-Toelichting` (from the ZGW APIs) is implemented as `X-Audit-Clarification` -But it doesn't just end there. The [varnish container](https://hub.docker.com/r/eeacms/varnish/) that we use to speed up the API responce it build and maintained by [EEA]() (The European Environment Agency) and the development team at conduction itself is attached to the [Odyssey program](https://www.odyssey.org/) and originated from the [startupinresidence](https://startupinresidence.com/) program. +We do not use other NLX headers since they (conform to the [NLX schema](https://docs.nlx.io/further-reading/transaction-logs/))wil not reach the provider. Please note that the use of nlx is optional. The component can be used without NLX. In that case the `X-NLX` header should be set to false, the `X-NLX-Logrecord-ID` should be provided with an log record designd by the client application to be retracable to a unique user and action. Other headers still aplly. -So you could say that both change and a european perspective is in our blood. +We strongly discourage the use of the `X-NLX-Request-Data-Subject` header as it might allow private data (such as BSNs) to show up in logging. + +English +------- +The [NL API Standard](https://geonovum.github.io/KP-APIs/#api-04-define-interfaces-in-dutch-unless-there-is-an-official-english-glossary) describes that there is a preference for Dutch in API documentation. + +> Define resources and the underlying entities, fields and so on (the information model ad the external interface) in Dutch. English is allowed in case there is an official English glossary. + +We view this as a breach with good coding practice and international coding standards, all documentation and code is therefore supplied in English. We do however provide transaltion (or i18n) support. + +Fields +------- +A part of the [haal centraal](https://raw.githubusercontent.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/master/api-specificatie/Bevraging-Ingeschreven-Persoon/openapi.yaml) the concept of field limitations has been introduced its general purpose being to allow an application to limit the returned fields to prevent the unnecessary transportation of (private) data. In the [NL API Strategie](https://github.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/blob/master/features/fields.feature) this has been implemented as a parameter consisting of comma separated values. However the normal web standard for optional lists (conform w3c form standards) is an array. + +Search +------- +As part of [api-32](https://docs.geostandaarden.nl/api/API-Strategie/#api-32) a `zoeken` query has been itroduced that can handle wildcards. This breaks best practice, first of allest practice is a `search` query parameter (see also the nodes on [English](#english)). Secondly wildcards are a sql concept, not a webconcept, they are also a rather old concept severly limiting the search options provided. Instead the [regeular expresion standard](https://en.wikipedia.org/wiki/Regular_expression) should be used. + +__solution__ +We implement a `search` query parameter on resource collections, that filters with regex. + +Queries +------- +In several examples of the nl apistrategie we see query parameters being atached to post requests. This is unusual in the sence that sending query strings allong with a post is ocnsiderd bad practice (becouse query parameters end up as part of an url and are therfore logged by servers). But is is technically posile folowing RFC 3986. The real pain is that in the NL api-stratgie the POST requests seems to be used to search, ot in other words GET data. This is where compliance with HTTP (1.1) breaks. + +__solution__ +We do not implement a query endpoint on post requests. Domain Build-up and routing @@ -36,25 +144,13 @@ Besides the API environments the component also ships with additional tools/envi On the local development docker deploy the client environment is used as default instead of the production version of the api. -Logging Headers (NLX Audit trail) -------- -@todo update, a reaction about this has been given by the NLX team. - -We inherit a couple of headers from the transaction logging within the [NLX schema](https://docs.nlx.io/further-reading/transaction-logs/), we strongly discourage the use of the `X-NLX-Request-Data-Subject` header as it might allow private data (such as BSNs) to show up in logging. - -__solution__ -The following X-NLX headers have been implemented `X-NLX-Logrecord-ID`,`X-NLX-Request-Process-Id`,`X-NLX-Request-Data-Elements` and `X-NLX-Request-Data-Subject`, these are tied to the internal audit trail (see audit trail for more information), and `X-Audit-Toelichting` (from the ZGW APIs) is implemented as `X-Audit-Clarification` - -Api versioning +Api Versioning ------- As per [landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning) major versions in endpoint minor versions in header, for this the `API-Version` is used (instead of the `api-version` header used in haal centraal) -Fields -------- -A part of the [haal centraal](https://raw.githubusercontent.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/master/api-specificatie/Bevraging-Ingeschreven-Persoon/openapi.yaml) the concept of field limitations has been introduced its general purpose being to allow an application to limit the returned fields to prevent the unnecessary transportation of (private) data. In the [NL API Strategie](https://github.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/blob/master/features/fields.feature) this has been implemented as a parameter consisting of comma separated values. However the normal web standard for optional lists (conform w3c form standards) is an array. __solution__ -The fields parameter and functionality has been implemented as an array +The fields parameter and functionality has been implemented as an array, and should be used that way. We do howver support an comma separted value list. Extending ------- @@ -65,60 +161,86 @@ The extend parameter has been implemented as an array Archivation ------- -In line with the extending and fields principle whereby we only want resources that we need it was deemed, nice to make a sub resource of the archivation properties. This also results in a bid cleaner code. +There is a need (by law) for archivation, meaning that we should only keep resources for a fixed amount of time and delete them there afther. In line with the extending and fields principle whereby we only want resource properties that we need when we needid, it is deemded good practice make a sub resource of the archivation properties. For the archivation proterties the [zgw](https://zaken-api.vng.cloud/api/v1/schema/#operation/zaak_list) is followed and translated to englisch. + + +```json +{ + "id": "e2984465-190a-4562-829e-a8cca81aa35d", + "nomination": "destroy", + "action_date": "2019-11-25T07:26:54Z", + "status": "to_be_archived", +} +``` + +This gives us an intresting thought, acording to [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie/#api-10-implement-operations-that-do-not-fit-the-crud-model-as-sub-resources) subresources should have there own endpoint. Therefore we could use a archive sub of a difrend object for archivation rules e.g. /zaken/{uuid}/archivation for a verzoek. This in itself leads credence to the thought that archivation should have its own central crud api. Audittrail ------- -@todo this needs to be implemented -For notifications we use the base mechanism as provided by [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail) but we differ on insight into the data that should be returned and feel that the international standard [RFC 3881](https://tools.ietf.org/html/rfc3881) should have been followed here. +For audittrail we use the base mechanism as provided by [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail), we do however diver on some key point, +- Personal data schould never be part of a log, therefore only the user id with the client should be logged (insted of the name) +- Besides an endpoint per resource there should be a general enpoint to search all audit trials of a component +- [Timetravel](#timetravel) in combinaition with objects versioning makes the return of complete objects unnecesary. But an auditrail endpoint should support the [extend](#extending) functionalitiy to provide the option of obtaining complete objects. + __solution__ -In compliance with [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail) each individual object should support an /audittrail endpoint. You can look into the [tutorial](TUTORIAL.md) for specifications on how to activate an audit trail for a given object. However, instead of the values mention in the vng.cloud design we follow [RFC 3881](https://tools.ietf.org/html/rfc3881) for the return values. And we give NLX values precedence if provided. +In compliance with [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail) each individual object should support an /audittrail endpoint. You can look into the [tutorial](TUTORIAL.md) for specifications on how to activate an audit trail for a given object. + +Healthchecks +------- +From [issue 154](https://github.com/VNG-Realisatie/huwelijksplanner/issues/154) + +For healthc + +__solution__ + Notifications ------- -@todo this needs to be implemented -For notifications we do not use the current [ZGW standard](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/notificaties) since we deem it insecure to send properties or data objects along with a notification. This is a potential security breach explained [here](https://github.com/VNG-Realisatie/gemma-zaken/issues/1427#issuecomment-549272696). It also doesn�t follow the [web standard](https://www.w3.org/TR/websub/). Instead we are developing our own subscriber service that is tailored for the NLX / VNG environment and based on current web standards [here](). +For notifications we do not YET use the current [ZGW standard](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/notificaties) since there is an [dicusion](https://github.com/VNG-Realisatie/gemma-zaken/issues/1427#issuecomment-549272696) about the posible insecurity of sending properties or data objects along with a notification. It also dosn't follow the [web standard](https://www.w3.org/TR/websub/). We wait for the conclusion of that discusion before making an implementation. + +__solution__ +In compliance with [w3.org](https://www.w3.org/TR/websub/) each endpoint returns an header containing an subscribtion url. That can be used in acordanse with the application to subscribe to both individual objects as collections. whereby collections serve as 'kanalen'. We aim to implement the ZGW notificatie component, but feel that further features on that component would be required to make to be fully suported. We will suply feature requests per issue to support this effort. + +Authentication +------- __solution__ -In compliance with [w3.org](https://www.w3.org/TR/websub/) each endpoint returns an header containing an subscribtion url. That can be used in acordanse with the application to subscribe to both individual objects as collections. whereby collections serve as 'kanalen'. -Scopes, Authentication and Authorization +Authorization ------- -@todo this needs to be implemented -We implement user scopes as per [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/autorisatie-scopes) standard. But see problems with how the scopes are defined and named, and consider the general setup to be to focused on ZGW (including Dutch naming, zgw specific fields like maxVertrouwlijkheid and a lack of CRUD thinking). There is a further document concerning [Authentication and Authorization](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/authenticatie-autorisatie) that details how we should authenticate users and give them scopes. We agree with the principles of the document on application based authorization and the use of JWT tokens. But disagree on some key technical aspect. Most important being that the architecture doesn't take into consideration the use of one component by several organizations +We implement user scopes as per [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/autorisatie-scopes) standard. But see problems with how the scopes are defined and named, and consider the general setup to be to focused on ZGW (including Dutch naming, zgw specific fields like maxVertrouwlijkheid and a lack of CRUD thinking). There is a further document concerning [Authentication and Authorization](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/authenticatie-autorisatie) that details how we should authenticate users and give them scopes. We agree with the principles of the document on application based authorization and the use of JWT tokens. But disagree on some key technical aspect. Most important being that the architecture doesn't take into consideration the use of one component by several organizations at once. Or scopese per property. __solution__ -No solution as of yet, so there is no implementation of Authorization or Scopes. We might build a new Authorization Component in the long run. +No solution as of yet, so there is no implementation of Authorization or Scopes. We aim to implement the ZGW authorisatie component, but feel that further features on that component would be required to make to be fully suported. We will suply feature requests per issue to support this effort. Timetravel ------- A part of the [haal centraal](https://raw.githubusercontent.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/master/api-specificatie/Bevraging-Ingeschreven-Persoon/openapi.yaml) the concept of timetravel has been introduced, as in getting the version of an object as it was on a given date. For this the `geldigop` [see the docs](file:///C:/Users/ruben/Desktop/doc_gba_historie.html#operation/getBewoningen) header is used. In addition the `geldigvan` and `geldigtot` are introduced as collection filters. -The commonground proto componant natively supports time traveling on all entities that are annotaded with the @Gedmo\Loggable, this is done by adding the ?validOn=[date] query to a request, date can either be a datetime or datedatime string. Any value supported by php's [strtotime()](https://www.php.net/manual/en/function.strtotime.php) is supported. Keep in mind that this returns the entity a as it was valid on that time or better put, the last changed version BEFORE that moment. To get a complete list of all changes on a item the ?showLogs=true quarry can be used. +The commonground proto componant natively supports time traveling on all entities that are annotaded with the @Gedmo\Loggable, this is done by adding the ?validOn=[date] query to a request, date can either be a datetime or datedatime string. Any value supported by php's [strtotime()](https://www.php.net/manual/en/function.strtotime.php) is supported. Keep in mind that this returns the entity a as it was valid on that time or better put, the last changed version BEFORE that moment. To get a complete list of all changes on a item the /audittrail endpoint can be used. __solution__ -In compliance with [schema.org](https://schema.org/validFrom) `geldigop`,`geldigvan` and `geldigtot` are implemented as `validOn`,`validFrom` and `validUntil`. And can be used a query parameters on colelction operations. +In compliance with [schema.org](https://schema.org/validFrom) `geldigop`,`geldigvan` and `geldigtot` are implemented as `validOn`,`validFrom` and `validUntil`. And can be used a query parameters on collection operations/ -Additionally `validOn` can be used on a single object get request to get the version of that object on a given date, a 404 is returned if no version of that object can be given for that date +Additionally `validOn` can be used on a single object get request to get the version of that object on a given date, a 404 is returned if no version of that object can be given for the given date -Ordering results +Ordering ------- In the [zaak-api](https://zaken-api.vng.cloud/api/v1/schema/#operation/zaak_list) ordering is done in a single field parameter, we however prefer to be able to order on multiple fields in combination of ascending and descending orders. We therefore implement an order parameter as array where they key is the property on wish should be ordered and the value the type of ordering e.g. `?order[name]=desc&order[status]=asc`. The order in which the keys are added to the order array determines the order in which they are applied. -Dutch versus English -------- -The [NL API Standard](https://geonovum.github.io/KP-APIs/#api-04-define-interfaces-in-dutch-unless-there-is-an-official-english-glossary) describes that there is a preference for Dutch in API documentation. - -> Define resources and the underlying entities, fields and so on (the information model ad the external interface) in Dutch. English is allowed in case there is an official English glossary. - -We view this as a breach with good coding practice and international coding standards, all documentation is therefore supplied in English +Translations +------- +We support translations trough the `Accept-Language` header (read the [docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language)), the fallback langouge for all messages is englisch +Errors +------- +See [jsonapi](https://jsonapi.org/examples/#error-objects) and the [rfc](https://tools.ietf.org/html/rfc7807). -Comma Notation versus Bracket Notation on arrays's +Arrays ------- The NL API standard uses comma notation on array's in http requests. E.g. fields=id,name,description however common browsers(based on chromium e.g. chrome and edge) use bracket notation for query style array's e.g. fields[]=id&fields[]=name,&fields[]=description. The difference of course is obvious since comma notation doesn't allow you to index arrays. [Interestingly enough there isn't actually a rfc spec for this](https://stackoverflow.com/questions/15854017/what-rfc-defines-arrays-transmitted-over-http). @@ -202,3 +324,4 @@ A component is (speaking in kubernetes terms) a service that is available at | string | bsn | | | | | | string | iban | | | | | | | | | | | | + diff --git a/api/docker/php/docker-entrypoint.sh b/api/docker/php/docker-entrypoint.sh index 459dee21..2f39d520 100755 --- a/api/docker/php/docker-entrypoint.sh +++ b/api/docker/php/docker-entrypoint.sh @@ -62,14 +62,13 @@ if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then echo "Loading fixtures" bin/console doctrine:fixtures:load --no-interaction - # echo "Creating OAS documentation" # Lets update the docs to show the latest chages - # bin/console api:openapi:export --output=/srv/api/public/schema/openapi.yaml --yaml --spec-version=3 + echo "Creating OAS documentation" + bin/console api:openapi:export --output=/srv/api/public/schema/openapi.yaml --yaml --spec-version=3 # this should only be done in an build - # echo "Updating Helm charts" - # Lets update the docs to show the latest chages - # bin/console app:helm:update --location=/srv/api/helm --spec-version=3 + echo "Updating Helm charts" + bin/console app:helm:update --location=/srv/api/helm --spec-version=3 fi fi diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php index 389740cf..8eee3dac 100644 --- a/api/src/Entity/ExampleEntity.php +++ b/api/src/Entity/ExampleEntity.php @@ -1,5 +1,7 @@ Date: Mon, 25 Nov 2019 16:24:16 +0100 Subject: [PATCH 026/182] Fixed issue with case sensitivity --- api/templates/helm/{values.yaml.twig => Values.yaml.twig} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename api/templates/helm/{values.yaml.twig => Values.yaml.twig} (100%) diff --git a/api/templates/helm/values.yaml.twig b/api/templates/helm/Values.yaml.twig similarity index 100% rename from api/templates/helm/values.yaml.twig rename to api/templates/helm/Values.yaml.twig From 221e83abea455040d4337103bb953bb4a06677ff Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 26 Nov 2019 11:07:56 +0100 Subject: [PATCH 027/182] Added automatic oas for @example and @assert annotations --- DESIGN.md | 4 +- api/src/Entity/ExampleEntity.php | 19 +--- api/src/Swagger/SwaggerDecorator.php | 143 ++++++++++++++++++++++----- 3 files changed, 125 insertions(+), 41 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 1f5104e0..34ff5696 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -2,7 +2,7 @@ Welcome, you are currently viewing the design decisions for the proto component. The proto component aims to provide a framework for the quick development of production apis for the commonground project. -*index* +*Index* - [The European factor](#the-european-factor) - [On standards and standardisation](#on-standards-and-standardization) - [NL API Strategie](#nl-api-strategie) @@ -31,7 +31,7 @@ Welcome, you are currently viewing the design decisions for the proto component. - [Api Versioning](#api-versioning) - [Environments and namespacing](#environments-and-namespacing) - [Domain Build-up and routing](#domain-build-up-and-routing) -- Container Setup](#container-setup) +- [Container Setup](#container-setup) The European factor diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php index 8eee3dac..94f81e03 100644 --- a/api/src/Entity/ExampleEntity.php +++ b/api/src/Entity/ExampleEntity.php @@ -42,19 +42,8 @@ class ExampleEntity { /** * @var \Ramsey\Uuid\UuidInterface - * - * @ApiProperty( - * identifier=true, - * attributes={ - * "swagger_context"={ - * "description" = "The UUID identifier of this object", - * "type"="string", - * "format"="uuid", - * "example"="e2984465-190a-4562-829e-a8cca81aa35d" - * } - * } - * ) - * + * @example e2984465-190a-4562-829e-a8cca81aa35d + * * @Assert\Uuid * @Groups({"read"}) * @ORM\Id @@ -93,10 +82,10 @@ class ExampleEntity /** * @var string $camelCase Proof that we camel case our api - * @example Best api ever + * @example Best api ever * * @Assert\Length( - * max = 2555 + * max = 255 * ) * @Gedmo\Versioned * @Groups({"read","write"}) diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index d7f0d214..597d7fae 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -4,11 +4,12 @@ namespace App\Swagger; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; +use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Cache\Adapter\AdapterInterface as CacheInterface; use Doctrine\ORM\EntityManagerInterface; use Doctrine\Common\Annotations\Reader as AnnotationReader; -use ApiPlatform\Core\PathResolver\OperationPathResolverInterface; + final class SwaggerDecorator implements NormalizerInterface { @@ -19,13 +20,15 @@ final class SwaggerDecorator implements NormalizerInterface private $cash; private $em; private $annotationReader; + private $camelCaseToSnakeCaseNameConverter; public function __construct( NormalizerInterface $decorated, ParameterBagInterface $params, CacheInterface $cache, EntityManagerInterface $em, - AnnotationReader $annotationReader + AnnotationReader $annotationReader, + CamelCaseToSnakeCaseNameConverter $camelCaseToSnakeCaseNameConverter ) { $this->decorated = $decorated; @@ -33,6 +36,7 @@ public function __construct( $this->cash = $cache; $this->em = $em; $this->annotationReader = $annotationReader; + $this->camelCaseToSnakeCaseNameConverter= $camelCaseToSnakeCaseNameConverter; } public function normalize($object, $format = null, array $context = []) @@ -41,13 +45,35 @@ public function normalize($object, $format = null, array $context = []) /* The we need to enrich al the entities and add the autoated routes */ + //var_dump($docs); // Lets make sure that we have tags if(!array_key_exists ('tags',$docs)){$docs['tags']=[];} + // Lets make sure that we have security and JWT-Claims + if(!array_key_exists ('securityDefinitions',$docs)){$docs['securityDefinitions']=[];} + + // Lets add JWT-Oauth + $docs['securityDefinitions']['JWT-Oauth'] = [ + "type"=>"oauth2", + "authorizationUrl"=>"http://petstore.swagger.io/api/oauth/dialog", + "flow"=>"implicit", + "scopes"=>[] #scopes will be filled later autmaticly + ]; + + $docs['securityDefinitions']['JWT-Token'] = [ + "type"=>"apiKey", + "in"=> "header", # can be "header", "query" or "cookie" + "name"=> "Authorization", # name of the header, query parameter or cookie + "scopes"=>[] #scopes will be filled later autmaticly + ]; + + // Lets get al the entities known to doctrine $entities = $this->em->getConfiguration()->getMetadataDriverImpl()->getAllClassNames(); + $additionalDocs = []; + // Then we loop trough the entities to find the api platform entities foreach($entities as $entity){ //$reflector = new \ReflectionClass($entity); @@ -74,19 +100,33 @@ public function normalize($object, $format = null, array $context = []) $tag['name'] = $shortName; $tag['description'] = $description; - $docs['tags'][] = $tag; + $docs['tags'][] = $tag; // And lets add the aditional docs - $this->getAdditionalEntityDocs($entity); + + //$additionalEntityDocs = $this->getAdditionalEntityDocs($entity); + $entityDocs = $this->getAdditionalEntityDocs($entity); + $additionalDocs= array_merge($additionalDocs,$entityDocs['properties']); + + // Security + $docs['securityDefinitions']['JWT-Oauth']['scopes']= array_merge($docs['securityDefinitions']['JWT-Oauth']['scopes'],$entityDocs['security']); + $docs['securityDefinitions']['JWT-Token']['scopes']= array_merge($docs['securityDefinitions']['JWT-Token']['scopes'],$entityDocs['security']); + break; } } } - - - - // This gets a resourceclass bassed on the route name, could - //$resourceMetadata = $resourceClass ? $this->metadataFactory->create($resourceClass) : null; + + // Oke dit is echt but lelijk + $schemas = (array) $docs['definitions']; + foreach($schemas as $schemaName => $schema){ + $additionalDocs[$schemaName] = array_merge( (array) $schema, $additionalDocs[$schemaName]); + $properties = (array) $schema['properties']; + foreach($properties as $propertyName => $property){ + $additionalDocs[$schemaName]['properties'][$propertyName] = array_merge( (array) $property, $additionalDocs[$schemaName]['properties'][$propertyName] ); + } + } + $docs['definitions'] = $additionalDocs; // Lest add an host if($this->params->get('common_ground.oas.host')){ @@ -342,37 +382,92 @@ private function getAdditionalEntityDocs($entity){ $reflector = $metadata->getReflectionClass(); $properties = $metadata->getReflectionProperties(); $annotations = $this->annotationReader->getClassAnnotations($reflector); + $additionalDocs = ['properties','security'=>[]]; + $required = []; // Add audittrail // Add healthcheck - //var_dump($propertyAnnotation); + $class = $reflector->getShortName(); + $path = '/'.$this->camelCaseToSnakeCaseNameConverter->normalize($class); + // Lets take a look at the properties an annotions, - foreach($properties as $property){ + foreach($properties as $property){ - // The annotations for this propertu - $propertyAnnotations = $this->annotationReader->getPropertyAnnotations($property); + // The dockBlocks for thie property + $factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); + $docblock = $factory->create($property->getDocComment()); + $tags = $docblock->getTags(); + $atributes = []; - // Check the annotations for symfony vallidations - foreach($propertyAnnotations as $propertyAnnotation){ + foreach($tags as $tag){ + $name = $tag->getName(); + $description = $tag->getDescription(); + // + //$description = (string) $description; - // Lentgh - if(get_class($propertyAnnotation) == "Symfony\Component\Validator\Constraints\NotNull"){ + switch ($name) { + // Docblocks + case "example": + $atributes['example'] = (string) $description; + break; - } - - // Lentgh - if(get_class($propertyAnnotation) == "Symfony\Component\Validator\Constraints\Length"){ - - } + // Groups + case "Groups": + $propertyAnnotation = $this->annotationReader->getPropertyAnnotation($property, "Symfony\Component\Serializer\Annotation\Groups"); + $groups = $propertyAnnotation->getGroups(); + break; + + // Constrainds (Validation) + case "Assert\Uuid": + $atributes['format'] = 'uuid'; + break; + case "Assert\Email": + $atributes['format'] = 'email'; + break; + case "Assert\Url": + $atributes['format'] = 'url'; + break; + case "Assert\Regex": + $atributes['format'] = 'regex'; + break; + case "Assert\Ip": + $atributes['format'] = 'ip'; + break; + case "Assert\Json": + $atributes['format'] = 'json'; + break; + case "Assert\Choice": + //@todo + //$atributes['format'] = 'json'; + break; + + case "Assert\NotNull": + $required[] = $property->name; + break; + case "Assert\Length": + $propertyAnnotation = $this->annotationReader->getPropertyAnnotation($property, "Symfony\Component\Validator\Constraints\Length"); + if($propertyAnnotation->max){$atributes['maxLength'] = $propertyAnnotation->max;} + if($propertyAnnotation->min){$atributes['minLength'] = $propertyAnnotation->min;} + break; + } + } + // Lets write everything to the docs + foreach($groups as $group){ + //$additionalDocs["components"]['schemas'][$class."-".$group] = $atributes; + $additionalDocs['properties'][$class."-".$group]["properties"][$property->name]= $atributes; + $additionalDocs['properties'][$class."-".$group]["required"] = $required; + + + if(!array_key_exists ($class.".".$group,$additionalDocs['security'])){$additionalDocs['security'][$class.".".$group] = $group.' right to the '.$class.' resource'; } + } } - $additionalDocs = []; return $additionalDocs; } From 4304a6ec467da29b4f0907cdaf2c629ba35e2438 Mon Sep 17 00:00:00 2001 From: rjzondervan Date: Tue, 26 Nov 2019 11:30:30 +0100 Subject: [PATCH 028/182] creating a GitHub action to build, run and push components --- .github/workflows/dockerimage.yml | 53 +++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 .github/workflows/dockerimage.yml diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml new file mode 100644 index 00000000..e299708b --- /dev/null +++ b/.github/workflows/dockerimage.yml @@ -0,0 +1,53 @@ +name: Docker Image CI + +on: + pull_request: + branches: + - master + - staging + - development + push: + branches: + - master + - staging + - development + +jobs: + + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Pulling old images, if any + run: docker-compose pull --ignore-pull-failures + - name: Setting APP_ENV + env: + APP_ENV: dev + run: echo "set APP_ENV to $APP_ENV" + - if: contains( github.ref, 'master' ) || contains( github.base_ref, 'master' ) + env: + APP_ENV: prod + run: echo "set APP_ENV to $APP_ENV" + - if: contains( github.ref, 'staging' ) || contains( github.base_ref, 'staging' ) + env: + APP_ENV: stag + run: echo "set APP_ENV to $APP_ENV" + - name: Build the Docker image + run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV + - name: Run the docker image + run: docker-compose up -d + - name: Taking some sleep + run: sleep 100 + - name: Check if all containers are running + run: docker ps + #docker-compose logs + - name: Security Checks + run: docker-compose exec -T php composer req sensiolabs/security-checker + - name: Chores + run: docker-compose down + - name: Login to DockerHub Registry + run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin + - name: Push to docker hub + run: docker-compose push From c9cf334a03123fd9ca273403a56eb89c289349e7 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Tue, 26 Nov 2019 13:20:55 +0100 Subject: [PATCH 029/182] adding logs for debugging --- .github/workflows/dockerimage.yml | 3 +- .idea/workspace.xml | 100 ++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 .idea/workspace.xml diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index e299708b..2d11e911 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -42,7 +42,8 @@ jobs: run: sleep 100 - name: Check if all containers are running run: docker ps - #docker-compose logs + - name: Dumping the logs + run: docker-compose logs - name: Security Checks run: docker-compose exec -T php composer req sensiolabs/security-checker - name: Chores diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 00000000..8e8ff17f --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,100 @@ + + + + + + + $PROJECT_DIR$/api/composer.json + + + + + + + + + + + + + + + + + + + + + + + + 1573726460744 + + + 1573726496674 + + + 1573733386819 + + + 1573735733551 + + + + + + + + + + + + + \ No newline at end of file From 0660750d569ccd2ad485d212fc01b0719a53905c Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 26 Nov 2019 14:05:36 +0100 Subject: [PATCH 030/182] fix on missing array index --- api/src/Swagger/SwaggerDecorator.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 597d7fae..3f84954e 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -47,6 +47,9 @@ public function normalize($object, $format = null, array $context = []) //var_dump($docs); + // Lets make sure that we have definitions + if(!array_key_exists ('definitions',$docs)){$docs['definitions']=[];} + // Lets make sure that we have tags if(!array_key_exists ('tags',$docs)){$docs['tags']=[];} @@ -461,7 +464,7 @@ private function getAdditionalEntityDocs($entity){ $additionalDocs['properties'][$class."-".$group]["required"] = $required; - if(!array_key_exists ($class.".".$group,$additionalDocs['security'])){$additionalDocs['security'][$class.".".$group] = $group.' right to the '.$class.' resource'; } + if(!array_key_exists ($group,$additionalDocs['security'])){$additionalDocs['security'][$group] = $group.' right to the '.$class.' resource'; } } } From 8f177cd4c4c63718997b5a1ece19320317d33ae8 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 26 Nov 2019 15:31:46 +0100 Subject: [PATCH 031/182] Fixes on delete error in postman --- api/src/Subscriber/LogSubscriber.php | 84 ------------------------ api/src/Subscriber/ValidOnSubscriber.php | 13 ++-- 2 files changed, 7 insertions(+), 90 deletions(-) delete mode 100644 api/src/Subscriber/LogSubscriber.php diff --git a/api/src/Subscriber/LogSubscriber.php b/api/src/Subscriber/LogSubscriber.php deleted file mode 100644 index c58d7d1c..00000000 --- a/api/src/Subscriber/LogSubscriber.php +++ /dev/null @@ -1,84 +0,0 @@ -params = $params; - $this->em= $em; - $this->serializer= $serializer; - $this->annotationReader = $annotationReader; - } - - public static function getSubscribedEvents() - { - return [ - KernelEvents::VIEW => ['Log', EventPriorities::PRE_SERIALIZE], - ]; - - } - - public function Log(GetResponseForControllerResultEvent $event) - { - $result = $event->getControllerResult(); - $showLogs= $event->getRequest()->query->get('showLogs'); - - // Lets see if this class has a Loggableannotation - $loggable = false; - $reflClass = new \ReflectionClass($result); - $annotations = $this->annotationReader->getClassAnnotations($reflClass); - - foreach($annotations as $annotation ){ - if(get_class($annotation) == "Gedmo\Mapping\Annotation\Loggable"){ - $loggable = true; - } - } - - // Only do somthing if we are on te log route and the entity is logable - /* @todo we should trhow errors here foruser feedback */ - if (!$showLogs || !$loggable) { - return $result; - } - - $repo = $this->em->getRepository('Gedmo\Loggable\Entity\LogEntry'); // we use default log entry class - $logs = $repo->getLogEntries($result); - - // now we need to overide the normal subscriber - $json = $this->serializer->serialize( - $logs, - 'jsonhal',['enable_max_depth' => true] - ); - - $response = new Response( - $json, - Response::HTTP_OK, - ['content-type' => 'application/json+hal'] - ); - - $event->setResponse($response); - - return; - } -} diff --git a/api/src/Subscriber/ValidOnSubscriber.php b/api/src/Subscriber/ValidOnSubscriber.php index 220b5288..616d66ef 100644 --- a/api/src/Subscriber/ValidOnSubscriber.php +++ b/api/src/Subscriber/ValidOnSubscriber.php @@ -48,6 +48,13 @@ public function validOn(GetResponseForControllerResultEvent $event) $geldigOp = $event->getRequest()->query->get('geldigOp', false); $validOn = $event->getRequest()->query->get('validOn', $geldigOp); + + // Only do somthing if fields is query supplied + if (!$validOn) { + return $result; + } + + // Lets see if this class has a Loggableannotation $loggable = false; $reflClass = new \ReflectionClass($result); @@ -58,12 +65,6 @@ public function validOn(GetResponseForControllerResultEvent $event) $loggable = true; } } - - // Only do somthing if fields is query supplied - if (!$validOn) { - return $result; - } - /* @todo propper error handling */ if(!$loggable){ throw new \Exception('This enity is not loggable therefore no previus versions can be obtained'); From ed11b2e6097b857dd79518a38bd145d80cf88197 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Tue, 26 Nov 2019 15:58:08 +0100 Subject: [PATCH 032/182] First attempt to deploy to kubernetes --- .github/workflows/dockerimage.yml | 4 + .idea/workspace.xml | 141 ++++++++++++++++++++++++++++-- 2 files changed, 140 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 2d11e911..698ec235 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -52,3 +52,7 @@ jobs: run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin - name: Push to docker hub run: docker-compose push + - name: Deploy through helm + env: + KUBECONFIG: ${{ secrets.KUBECONFIG }} + run: helm install --name pc-dev ./api/helm --kubeconfig=$KUBECONFIG --namespace=dev --set settings.env=dev,settings.debug=1 diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 8e8ff17f..63cda310 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,14 +1,17 @@ - + + + + - + $PROJECT_DIR$/api/composer.json @@ -24,6 +27,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -52,6 +172,7 @@ @@ -85,7 +213,9 @@ - + + @@ -95,6 +225,7 @@ - \ No newline at end of file From c676dc58cb92ccbc2b087979238476e2dc424d96 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Tue, 26 Nov 2019 16:17:29 +0100 Subject: [PATCH 033/182] No deployment from pull requests --- .github/workflows/dockerimage.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 698ec235..4ae9ced0 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -53,6 +53,7 @@ jobs: - name: Push to docker hub run: docker-compose push - name: Deploy through helm + if: contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' ) env: KUBECONFIG: ${{ secrets.KUBECONFIG }} run: helm install --name pc-dev ./api/helm --kubeconfig=$KUBECONFIG --namespace=dev --set settings.env=dev,settings.debug=1 From 347c8d9d3eb3fa9d8a2bb1005d501e728984800e Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 06:37:17 +0100 Subject: [PATCH 034/182] Setup helm deploy with enviroment --- .github/workflows/dockerimage.yml | 2 +- api/src/Swagger/SwaggerDecorator.php | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 4ae9ced0..5f3d8a18 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -56,4 +56,4 @@ jobs: if: contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' ) env: KUBECONFIG: ${{ secrets.KUBECONFIG }} - run: helm install --name pc-dev ./api/helm --kubeconfig=$KUBECONFIG --namespace=dev --set settings.env=dev,settings.debug=1 + run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig=$KUBECONFIG --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 3f84954e..8a6edbd6 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -122,8 +122,10 @@ public function normalize($object, $format = null, array $context = []) // Oke dit is echt but lelijk $schemas = (array) $docs['definitions']; - foreach($schemas as $schemaName => $schema){ + foreach($schemas as $schemaName => $schema){ + $additionalDocs[$schemaName] = array_merge( (array) $schema, $additionalDocs[$schemaName]); + $properties = (array) $schema['properties']; foreach($properties as $propertyName => $property){ $additionalDocs[$schemaName]['properties'][$propertyName] = array_merge( (array) $property, $additionalDocs[$schemaName]['properties'][$propertyName] ); From a5171fb7c5cb77f459d00c1437906976e0d7bc41 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 06:53:23 +0100 Subject: [PATCH 035/182] Setting up deploy file --- .github/deploy.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/deploy.yml diff --git a/.github/deploy.yml b/.github/deploy.yml new file mode 100644 index 00000000..3bd4c3c9 --- /dev/null +++ b/.github/deploy.yml @@ -0,0 +1,4 @@ +# View examples and documentation at https://deliverybot.dev/docs/ +production: + environment: production + production_environment: true From 17c5f5dad9051150821a5aa81b4fb2cfdfebd91c Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 07:19:25 +0100 Subject: [PATCH 036/182] tried to fix it --- .github/workflows/dockerimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 5f3d8a18..45b88c29 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -56,4 +56,4 @@ jobs: if: contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' ) env: KUBECONFIG: ${{ secrets.KUBECONFIG }} - run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig=$KUBECONFIG --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 + run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig="$KUBECONFIG" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 From d1bf3136973f7aadf07b20190d6ed43f9ded7c2e Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 08:39:22 +0100 Subject: [PATCH 037/182] Create kubeconfig file --- .github/workflows/dockerimage.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 45b88c29..6144200f 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -20,6 +20,16 @@ jobs: steps: - uses: actions/checkout@v1 + - name: Create kube config + uses: finnp/create-file-action@master + env: + FILE_NAME: "kubeconfig.yaml" + FILE_DATA: ${{ secrets.KUBECONFIG }} + - name: Deploy through helm + if: contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' ) + env: + KUBECONFIG: ${{ secrets.KUBECONFIG }} + run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Pulling old images, if any run: docker-compose pull --ignore-pull-failures - name: Setting APP_ENV @@ -52,8 +62,3 @@ jobs: run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin - name: Push to docker hub run: docker-compose push - - name: Deploy through helm - if: contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' ) - env: - KUBECONFIG: ${{ secrets.KUBECONFIG }} - run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig="$KUBECONFIG" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 From 36ffcaab5e4a9d02248781f6f0d990aea9e8edb7 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 08:39:22 +0100 Subject: [PATCH 038/182] Create kubeconfig file --- .github/workflows/dockerimage.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 45b88c29..6144200f 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -20,6 +20,16 @@ jobs: steps: - uses: actions/checkout@v1 + - name: Create kube config + uses: finnp/create-file-action@master + env: + FILE_NAME: "kubeconfig.yaml" + FILE_DATA: ${{ secrets.KUBECONFIG }} + - name: Deploy through helm + if: contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' ) + env: + KUBECONFIG: ${{ secrets.KUBECONFIG }} + run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Pulling old images, if any run: docker-compose pull --ignore-pull-failures - name: Setting APP_ENV @@ -52,8 +62,3 @@ jobs: run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin - name: Push to docker hub run: docker-compose push - - name: Deploy through helm - if: contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' ) - env: - KUBECONFIG: ${{ secrets.KUBECONFIG }} - run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig="$KUBECONFIG" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 From 0d9568b732cf763d97ebfb5daed2c3e77d4e30dc Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 09:18:16 +0100 Subject: [PATCH 039/182] Some experimenting with APP_ENV --- .github/workflows/dockerimage.yml | 3 +- .idea/workspace.xml | 132 +----------------------------- 2 files changed, 5 insertions(+), 130 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 957efdb2..b74d6067 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -33,7 +33,8 @@ jobs: - if: contains( github.ref, 'staging' ) || contains( github.base_ref, 'staging' ) env: APP_ENV: stag - run: echo "set APP_ENV to $APP_ENV" + run: echo "set APP_ENV to $APP_ENV" + - run: echo "APP_ENV is now $APP_ENV" - name: Build the Docker image run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV - name: Run the docker image diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 63cda310..bf2a5276 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -11,7 +11,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -172,7 +55,6 @@ @@ -225,7 +100,6 @@ - - \ No newline at end of file From d37b48475009ea6aa490b714a70a1311ef3b4a3a Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 09:18:16 +0100 Subject: [PATCH 040/182] Revert "Some experimenting with APP_ENV" This reverts commit 0d9568b732cf763d97ebfb5daed2c3e77d4e30dc. --- .github/workflows/dockerimage.yml | 3 +- .idea/workspace.xml | 132 +++++++++++++++++++++++++++++- 2 files changed, 130 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index b74d6067..957efdb2 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -33,8 +33,7 @@ jobs: - if: contains( github.ref, 'staging' ) || contains( github.base_ref, 'staging' ) env: APP_ENV: stag - run: echo "set APP_ENV to $APP_ENV" - - run: echo "APP_ENV is now $APP_ENV" + run: echo "set APP_ENV to $APP_ENV" - name: Build the Docker image run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV - name: Run the docker image diff --git a/.idea/workspace.xml b/.idea/workspace.xml index bf2a5276..63cda310 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -11,7 +11,7 @@ - + $PROJECT_DIR$/api/composer.json @@ -27,6 +27,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -55,6 +172,7 @@ @@ -100,6 +225,7 @@ - \ No newline at end of file From 63f5d80bf5cd9222ec766f2aae54b581e8a57f21 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 09:19:17 +0100 Subject: [PATCH 041/182] Adding a debugging step --- .github/workflows/dockerimage.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 957efdb2..343bdeca 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -34,6 +34,7 @@ jobs: env: APP_ENV: stag run: echo "set APP_ENV to $APP_ENV" + - run: echo "APP_ENV is now $APP_ENV" - name: Build the Docker image run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV - name: Run the docker image From ec0c8cb9f6c618555a416ec1cf6718d5622d5980 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 09:26:20 +0100 Subject: [PATCH 042/182] Fear was confirmed, attempt to solve. --- .github/workflows/dockerimage.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 343bdeca..88ba3799 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -17,7 +17,8 @@ jobs: build: runs-on: ubuntu-latest - + env: + APP_ENV: dev steps: - uses: actions/checkout@v1 - name: Pulling old images, if any From 64a207e92abe045960af9abf9315b44056260a96 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 09:28:44 +0100 Subject: [PATCH 043/182] Some testing with my solution --- .github/workflows/dockerimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 88ba3799..88b98f39 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest env: - APP_ENV: dev + APP_ENV: test steps: - uses: actions/checkout@v1 - name: Pulling old images, if any From dff45cf090f4c1f622d0de286ee6393a0970d49b Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 09:38:09 +0100 Subject: [PATCH 044/182] Trying suggested solution --- .github/workflows/dockerimage.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 88b98f39..f6d8fc66 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -24,9 +24,9 @@ jobs: - name: Pulling old images, if any run: docker-compose pull --ignore-pull-failures - name: Setting APP_ENV - env: - APP_ENV: dev - run: echo "set APP_ENV to $APP_ENV" + run: | + echo ::set-env name=APP_ENV::dev + echo "set APP_ENV to $APP_ENV" - if: contains( github.ref, 'master' ) || contains( github.base_ref, 'master' ) env: APP_ENV: prod From fd2a6bcd6e531d2a293c02a18bfbf1c16adc68d1 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 09:50:50 +0100 Subject: [PATCH 045/182] New attempt --- .github/workflows/dockerimage.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index f6d8fc66..adbef710 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -17,8 +17,6 @@ jobs: build: runs-on: ubuntu-latest - env: - APP_ENV: test steps: - uses: actions/checkout@v1 - name: Pulling old images, if any From ab87947a489c58f5ac80e2e81865ec0c3a5b1948 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 09:53:49 +0100 Subject: [PATCH 046/182] Applying confirmed solution throughout. --- .github/workflows/dockerimage.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index adbef710..182d9ea9 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -26,13 +26,13 @@ jobs: echo ::set-env name=APP_ENV::dev echo "set APP_ENV to $APP_ENV" - if: contains( github.ref, 'master' ) || contains( github.base_ref, 'master' ) - env: - APP_ENV: prod - run: echo "set APP_ENV to $APP_ENV" + run: | + echo ::set-env name=APP_ENV::prod + echo "set APP_ENV to $APP_ENV" - if: contains( github.ref, 'staging' ) || contains( github.base_ref, 'staging' ) - env: - APP_ENV: stag - run: echo "set APP_ENV to $APP_ENV" + run: | + echo ::set-env name=APP_ENV::stag + echo "set APP_ENV to $APP_ENV" - run: echo "APP_ENV is now $APP_ENV" - name: Build the Docker image run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV From ca5a30bb0c41056f232c25a2bec57a6854293740 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 12:05:20 +0100 Subject: [PATCH 047/182] Making the process a little bit more neat, skipping deployment steps when secrets not set --- .github/workflows/dockerimage.yml | 34 +++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 182d9ea9..e73dbdf9 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -21,19 +21,22 @@ jobs: - uses: actions/checkout@v1 - name: Pulling old images, if any run: docker-compose pull --ignore-pull-failures - - name: Setting APP_ENV + - name: Setting APP_ENV to dev run: | echo ::set-env name=APP_ENV::dev echo "set APP_ENV to $APP_ENV" - - if: contains( github.ref, 'master' ) || contains( github.base_ref, 'master' ) + - name: Setting APP_ENV to prod + if: contains( github.ref, 'master' ) || contains( github.base_ref, 'master' ) run: | echo ::set-env name=APP_ENV::prod echo "set APP_ENV to $APP_ENV" - - if: contains( github.ref, 'staging' ) || contains( github.base_ref, 'staging' ) + - name: Setting APP_ENV to stag + if: contains( github.ref, 'staging' ) || contains( github.base_ref, 'staging' ) run: | echo ::set-env name=APP_ENV::stag echo "set APP_ENV to $APP_ENV" - - run: echo "APP_ENV is now $APP_ENV" + - name: Print definitive APP_ENV + run: echo "APP_ENV is now $APP_ENV" - name: Build the Docker image run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV - name: Run the docker image @@ -49,12 +52,27 @@ jobs: - name: Chores run: docker-compose down - name: Login to DockerHub Registry - run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin - - name: Push to docker hub + id: dockerhub-login + run: | + if [ "${{ secrets.DOCKERHUB_PASSWORD }}" != "" ] && [ "${{ secrets.DOCKERHUB_USERNAME }}" != "" ]; then + echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin + echo "##[set-output name=success;]true" + else + echo "##[set-output name=success;]false" + fi + - if: steps.dockerhub-login.outputs.success == 'true' + name: Push to docker hub run: docker-compose push - name: Create kube config + id: kubeconfig if: contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' ) - run: printf "${{ secrets.KUBECONFIG }}" > kubeconfig.yaml + run: | + if [ "${{ secrets.KUBECONFIG }}" != "" ]; then + printf "${{ secrets.KUBECONFIG }}" > kubeconfig.yaml + echo "##[set-output name=success]true" + else + echo "##[set-output name=success]false" + fi - name: Deploy through helm - if: contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' ) + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true From 2210828e0374527a2e2f4c72d12eef386745f812 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 12:11:41 +0000 Subject: [PATCH 048/182] Apply fixes from StyleCI --- api/config/bundles.php | 30 +- api/src/Command/ApiHelmCommand.php | 118 +-- api/src/Entity/ExampleEntity.php | 88 +- api/src/Entity/NLXRequestLog.php | 4 +- api/src/Filter/LikeFilter.php | 81 +- api/src/Filter/RegexpFilter.php | 81 +- .../Repository/NLXRequestLogRepository.php | 21 +- api/src/Service/NLXLogService.php | 18 +- api/src/Subscriber/FieldsSubscriber.php | 114 +-- api/src/Subscriber/NLXSubscriber.php | 199 ++-- api/src/Subscriber/ValidOnSubscriber.php | 178 ++-- api/src/Swagger/SwaggerDecorator.php | 942 +++++++++--------- api/src/Types/IncompleteDateType.php | 98 +- api/src/Types/UnderInvestigationType.php | 121 +-- api/src/ValueObject/IncompleteDate.php | 118 ++- api/src/ValueObject/UnderInvestigation.php | 55 +- 16 files changed, 1126 insertions(+), 1140 deletions(-) diff --git a/api/config/bundles.php b/api/config/bundles.php index 426c3ab7..fa4a09fd 100644 --- a/api/config/bundles.php +++ b/api/config/bundles.php @@ -1,19 +1,19 @@ ['all' => true], - Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], - Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true], - Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], - Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true], - Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], - 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], - Conduction\CommonGroundBundle\CommonGroundBundle::class => ['all' => true], - Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], - Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], - Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], - Tbbc\MoneyBundle\TbbcMoneyBundle::class => ['all' => true], + Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], + Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], + Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true], + Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], + Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true], + Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + 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], + Conduction\CommonGroundBundle\CommonGroundBundle::class => ['all' => true], + Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], + Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], + Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], + Tbbc\MoneyBundle\TbbcMoneyBundle::class => ['all' => true], ]; diff --git a/api/src/Command/ApiHelmCommand.php b/api/src/Command/ApiHelmCommand.php index 6bac5366..0caa16f6 100644 --- a/api/src/Command/ApiHelmCommand.php +++ b/api/src/Command/ApiHelmCommand.php @@ -1,5 +1,7 @@ twig= $twig; - - parent::__construct(); - } - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('app:helm:update') - // the short description shown while running "php bin/console list" - ->setDescription('Creates a new helm chart.') - - // the full command description shown when running the command with - // the "--help" option - ->setHelp('This command allows you to create a new hel chart from the helm template') - ->setAliases(['app:helm:export']) - ->setDescription('Dump the OpenAPI documentation') - ->addOption('location', null, InputOption::VALUE_OPTIONAL, 'Write output to files in the given location','/srv/api/helm') - ->addOption('spec-version', null, InputOption::VALUE_OPTIONAL, 'Helm version to use ("0.1.0")', '0.1.0') - ; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $io = new SymfonyStyle($input, $output); - /** @var string $version */ - $version = $input->getOption('spec-version'); - - //if (!\in_array($version, ['0.1.0'], true)) { - // throw new InvalidOptionException(sprintf('This tool only supports version 2 and 3 of the OpenAPI specification ("%s" given).', $version)); - //} - - $values = $this->twig->render('helm/Values.yaml.twig'); - $chart = $this->twig->render('helm/Chart.yaml.twig'); - - - if (!empty($location= $input->getOption('location')) && \is_string($location)) { - file_put_contents($location.'/values.yaml', $values); - file_put_contents($location.'/Chart.yaml', $chart); - $io->success(sprintf('Data written to %s (specification version %s).', $location, $version)); - } else { - // outputs multiple lines to the console (adding "\n" at the end of each line) - $output->writeln([ - 'Helm Chart Creator', - '============', - $chart, - ]); - } - } + private $twig; + + public function __construct(Environment $twig) + { + $this->twig = $twig; + + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('app:helm:update') + // the short description shown while running "php bin/console list" + ->setDescription('Creates a new helm chart.') + + // the full command description shown when running the command with + // the "--help" option + ->setHelp('This command allows you to create a new hel chart from the helm template') + ->setAliases(['app:helm:export']) + ->setDescription('Dump the OpenAPI documentation') + ->addOption('location', null, InputOption::VALUE_OPTIONAL, 'Write output to files in the given location', '/srv/api/helm') + ->addOption('spec-version', null, InputOption::VALUE_OPTIONAL, 'Helm version to use ("0.1.0")', '0.1.0'); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + /** @var string $version */ + $version = $input->getOption('spec-version'); + + //if (!\in_array($version, ['0.1.0'], true)) { + // throw new InvalidOptionException(sprintf('This tool only supports version 2 and 3 of the OpenAPI specification ("%s" given).', $version)); + //} + + $values = $this->twig->render('helm/Values.yaml.twig'); + $chart = $this->twig->render('helm/Chart.yaml.twig'); + + if (!empty($location = $input->getOption('location')) && \is_string($location)) { + file_put_contents($location.'/values.yaml', $values); + file_put_contents($location.'/Chart.yaml', $chart); + $io->success(sprintf('Data written to %s (specification version %s).', $location, $version)); + } else { + // outputs multiple lines to the console (adding "\n" at the end of each line) + $output->writeln([ + 'Helm Chart Creator', + '============', + $chart, + ]); + } + } } diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php index 94f81e03..47705b5c 100644 --- a/api/src/Entity/ExampleEntity.php +++ b/api/src/Entity/ExampleEntity.php @@ -5,23 +5,18 @@ namespace App\Entity; use ApiPlatform\Core\Annotation\ApiFilter; -use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter; use ApiPlatform\Core\Annotation\ApiResource; -use ApiPlatform\Core\Annotation\ApiProperty; +use App\Filter\LikeFilter; use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; -use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Serializer\Annotation\Groups; -use Symfony\Component\Serializer\Annotation\MaxDepth; - - -use App\Filter\LikeFilter; +use Symfony\Component\Validator\Constraints as Assert; /** - * This is an example entity - * + * This is an example entity. + * * With an adtional description, all in all its pritty nice [url](www.google.nl) - * + * * @ApiResource( * normalizationContext={"groups"={"read"}, "enable_max_depth"=true}, * denormalizationContext={"groups"={"write"}, "enable_max_depth"=true}, @@ -40,55 +35,59 @@ */ class ExampleEntity { - /** - * @var \Ramsey\Uuid\UuidInterface - * @example e2984465-190a-4562-829e-a8cca81aa35d - * - * @Assert\Uuid - * @Groups({"read"}) - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator") - */ - private $id; + /** + * @var \Ramsey\Uuid\UuidInterface + * + * @example e2984465-190a-4562-829e-a8cca81aa35d + * + * @Assert\Uuid + * @Groups({"read"}) + * @ORM\Id + * @ORM\Column(type="uuid", unique=true) + * @ORM\GeneratedValue(strategy="CUSTOM") + * @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator") + */ + private $id; /** - * @var string $name The name of this example property - * @example My Group - * - * @Assert\NotNull - * @Assert\Length( - * max = 255 - * ) + * @var string The name of this example property + * + * @example My Group + * + * @Assert\NotNull + * @Assert\Length( + * max = 255 + * ) * @Gedmo\Versioned - * @Groups({"read","write"}) + * @Groups({"read","write"}) * @ORM\Column(type="string", length=255) */ private $name; /** - * @var string $description The description of this example property - * @example Is the best group ever - * - * @Assert\Length( - * max = 2555 - * ) + * @var string The description of this example property + * + * @example Is the best group ever + * + * @Assert\Length( + * max = 2555 + * ) * @Gedmo\Versioned - * @Groups({"read","write"}) + * @Groups({"read","write"}) * @ORM\Column(type="text", nullable=true) */ private $description; /** - * @var string $camelCase Proof that we camel case our api - * @example Best api ever - * - * @Assert\Length( - * max = 255 - * ) + * @var string Proof that we camel case our api + * + * @example Best api ever + * + * @Assert\Length( + * max = 255 + * ) * @Gedmo\Versioned - * @Groups({"read","write"}) + * @Groups({"read","write"}) * @ORM\Column(type="string", length=255, nullable=true) */ private $camelCase; @@ -133,5 +132,4 @@ public function setCamelCase(?string $camelCase): self return $this; } - } diff --git a/api/src/Entity/NLXRequestLog.php b/api/src/Entity/NLXRequestLog.php index c3c3a1c4..1d886b85 100644 --- a/api/src/Entity/NLXRequestLog.php +++ b/api/src/Entity/NLXRequestLog.php @@ -235,12 +235,12 @@ public function setEndpoint(string $endpoint): self public function getMethod(): ?string { - return $this->method; + return $this->method; } public function setMethod(string $method): self { - $this->method = $method; + $this->method = $method; return $this; } diff --git a/api/src/Filter/LikeFilter.php b/api/src/Filter/LikeFilter.php index 1496dd18..029c73e9 100644 --- a/api/src/Filter/LikeFilter.php +++ b/api/src/Filter/LikeFilter.php @@ -1,4 +1,5 @@ isPropertyEnabled($property, $resourceClass) || - !$this->isPropertyMapped($property, $resourceClass) - ) { - return; - } - - $parameterName = $queryNameGenerator->generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters - $queryBuilder - ->andWhere(sprintf('o.%s LIKE :%s', $property, $parameterName)) - ->setParameter($parameterName, $value); - } - - // This function is only used to hook in documentation generators (supported by Swagger and Hydra) - public function getDescription(string $resourceClass): array - { - if (!$this->properties) { - return []; - } - - $description = []; - foreach ($this->properties as $property => $strategy) { - $description["like_$property"] = [ - 'property' => $property, - 'type' => 'string', - 'required' => false, - 'swagger' => [ - 'description' => 'This filter narows your result using the * and _ wildcards, where * is assumed to be one or more characters and _ is assumed to be a single character', - 'name' => $property, - 'type' => 'string', - ], - ]; - } - - return $description; - } -} \ No newline at end of file + protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null) + { + // otherwise filter is applied to order and page as well + if ( + !$this->isPropertyEnabled($property, $resourceClass) || + !$this->isPropertyMapped($property, $resourceClass) + ) { + return; + } + + $parameterName = $queryNameGenerator->generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters + $queryBuilder + ->andWhere(sprintf('o.%s LIKE :%s', $property, $parameterName)) + ->setParameter($parameterName, $value); + } + + // This function is only used to hook in documentation generators (supported by Swagger and Hydra) + public function getDescription(string $resourceClass): array + { + if (!$this->properties) { + return []; + } + + $description = []; + foreach ($this->properties as $property => $strategy) { + $description["like_$property"] = [ + 'property' => $property, + 'type' => 'string', + 'required' => false, + 'swagger' => [ + 'description' => 'This filter narows your result using the * and _ wildcards, where * is assumed to be one or more characters and _ is assumed to be a single character', + 'name' => $property, + 'type' => 'string', + ], + ]; + } + + return $description; + } +} diff --git a/api/src/Filter/RegexpFilter.php b/api/src/Filter/RegexpFilter.php index ffda6ff7..da1f747e 100644 --- a/api/src/Filter/RegexpFilter.php +++ b/api/src/Filter/RegexpFilter.php @@ -1,4 +1,5 @@ isPropertyEnabled($property, $resourceClass) || - !$this->isPropertyMapped($property, $resourceClass) - ) { - return; - } - - $parameterName = $queryNameGenerator->generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters - $queryBuilder - ->andWhere(sprintf('REGEXP(o.%s, :%s) = 1', $property, $parameterName)) - ->setParameter($parameterName, $value); - } - - // This function is only used to hook in documentation generators (supported by Swagger and Hydra) - public function getDescription(string $resourceClass): array - { - if (!$this->properties) { - return []; - } - - $description = []; - foreach ($this->properties as $property => $strategy) { - $description["regexp_$property"] = [ - 'property' => $property, - 'type' => 'string', - 'required' => false, - 'swagger' => [ - 'description' => 'Filter for an exact match using a [Regular expression](https://en.wikipedia.org/wiki/Regular_expression).', - 'name' => $property, - 'type' => 'string', - ], - ]; - } - - return $description; - } -} \ No newline at end of file + protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null) + { + // otherwise filter is applied to order and page as well + if ( + !$this->isPropertyEnabled($property, $resourceClass) || + !$this->isPropertyMapped($property, $resourceClass) + ) { + return; + } + + $parameterName = $queryNameGenerator->generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters + $queryBuilder + ->andWhere(sprintf('REGEXP(o.%s, :%s) = 1', $property, $parameterName)) + ->setParameter($parameterName, $value); + } + + // This function is only used to hook in documentation generators (supported by Swagger and Hydra) + public function getDescription(string $resourceClass): array + { + if (!$this->properties) { + return []; + } + + $description = []; + foreach ($this->properties as $property => $strategy) { + $description["regexp_$property"] = [ + 'property' => $property, + 'type' => 'string', + 'required' => false, + 'swagger' => [ + 'description' => 'Filter for an exact match using a [Regular expression](https://en.wikipedia.org/wiki/Regular_expression).', + 'name' => $property, + 'type' => 'string', + ], + ]; + } + + return $description; + } +} diff --git a/api/src/Repository/NLXRequestLogRepository.php b/api/src/Repository/NLXRequestLogRepository.php index ed8d0a95..bc1dad3c 100644 --- a/api/src/Repository/NLXRequestLogRepository.php +++ b/api/src/Repository/NLXRequestLogRepository.php @@ -20,19 +20,18 @@ public function __construct(RegistryInterface $registry) } /** - * @return NLXRequestLog[] Returns an array of NLXRequestLog objects - */ + * @return NLXRequestLog[] Returns an array of NLXRequestLog objects + */ public function getLogEntries($entity) { - return $this->createQueryBuilder('l') - ->where('l.objectClass = :objectClass') - ->setParameter('objectClass', $this->getEntityManager()->getMetadataFactory()->getMetadataFor(get_class($entity))->getName()) - ->andWhere('l.objectId = :objectId') - ->setParameter('objectId', $entity->getId()) - ->orderBy('l.loggedAt', 'DESC') - ->getQuery() - ->getResult(); - + return $this->createQueryBuilder('l') + ->where('l.objectClass = :objectClass') + ->setParameter('objectClass', $this->getEntityManager()->getMetadataFactory()->getMetadataFor(get_class($entity))->getName()) + ->andWhere('l.objectId = :objectId') + ->setParameter('objectId', $entity->getId()) + ->orderBy('l.loggedAt', 'DESC') + ->getQuery() + ->getResult(); } /* diff --git a/api/src/Service/NLXLogService.php b/api/src/Service/NLXLogService.php index 24c5cff1..3f2d2e3c 100644 --- a/api/src/Service/NLXLogService.php +++ b/api/src/Service/NLXLogService.php @@ -1,4 +1,5 @@ em = $em; - } - + private $em; + + public function __construct(EntityManagerInterface $em) + { + $this->em = $em; + } } diff --git a/api/src/Subscriber/FieldsSubscriber.php b/api/src/Subscriber/FieldsSubscriber.php index 1372fd99..f842a8e2 100644 --- a/api/src/Subscriber/FieldsSubscriber.php +++ b/api/src/Subscriber/FieldsSubscriber.php @@ -2,73 +2,67 @@ namespace App\Subscriber; -use ApiPlatform\Core\Exception\InvalidArgumentException; use ApiPlatform\Core\EventListener\EventPriorities; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Serializer\SerializerInterface; -use Doctrine\ORM\EntityManagerInterface; -use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; - -use App\Service\RequestTypeService; class FieldsSubscriber implements EventSubscriberInterface { - private $params; - private $serializer; - - public function __construct(ParameterBagInterface $params, SerializerInterface $serializer) - { - $this->params = $params; - $this->serializer= $serializer; - } - - public static function getSubscribedEvents() - { - return [ - KernelEvents::VIEW => ['FilterFields', EventPriorities::PRE_SERIALIZE], - ]; - - } - - public function FilterFields(GetResponseForControllerResultEvent $event) - { - $result = $event->getControllerResult(); - $fields = $event->getRequest()->query->get('fields'); - - // Only do somthing if fields is query supplied - if (!$fields) { - return $result; - } - - // let turn fields into an array if it isn't one already - if(!is_array($fields)){ - $fields = explode(",", $fields); - } - - - // we always need to return an id and links (in order not to break stuff) - if(!in_array("id",$fields)){$fields[]='id';} - if(!in_array("_links",$fields)){$fields[]='_links';} - - // now we need to overide the normal subscriber - $json = $this->serializer->serialize( - $result, - 'jsonhal',['enable_max_depth' => true,'attributes'=> $fields] - ); - - $response = new Response( - $json, - Response::HTTP_OK, - ['content-type' => 'application/json+hal'] - ); - - $event->setResponse($response); - - return; - } + private $params; + private $serializer; + + public function __construct(ParameterBagInterface $params, SerializerInterface $serializer) + { + $this->params = $params; + $this->serializer = $serializer; + } + + public static function getSubscribedEvents() + { + return [ + KernelEvents::VIEW => ['FilterFields', EventPriorities::PRE_SERIALIZE], + ]; + } + + public function FilterFields(GetResponseForControllerResultEvent $event) + { + $result = $event->getControllerResult(); + $fields = $event->getRequest()->query->get('fields'); + + // Only do somthing if fields is query supplied + if (!$fields) { + return $result; + } + + // let turn fields into an array if it isn't one already + if (!is_array($fields)) { + $fields = explode(',', $fields); + } + + // we always need to return an id and links (in order not to break stuff) + if (!in_array('id', $fields)) { + $fields[] = 'id'; + } + if (!in_array('_links', $fields)) { + $fields[] = '_links'; + } + + // now we need to overide the normal subscriber + $json = $this->serializer->serialize( + $result, + 'jsonhal', ['enable_max_depth' => true, 'attributes'=> $fields] + ); + + $response = new Response( + $json, + Response::HTTP_OK, + ['content-type' => 'application/json+hal'] + ); + + $event->setResponse($response); + } } diff --git a/api/src/Subscriber/NLXSubscriber.php b/api/src/Subscriber/NLXSubscriber.php index d846884b..5411001e 100644 --- a/api/src/Subscriber/NLXSubscriber.php +++ b/api/src/Subscriber/NLXSubscriber.php @@ -2,118 +2,109 @@ namespace App\Subscriber; -use ApiPlatform\Core\Exception\InvalidArgumentException; use ApiPlatform\Core\EventListener\EventPriorities; +use App\Entity\NLXRequestLog; +use App\Service\NLXLogService; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Serializer\SerializerInterface; -use Doctrine\ORM\EntityManagerInterface; -use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; -use Symfony\Component\HttpFoundation\Session\Session; - - -use App\Service\NLXLogService; -use App\Entity\NLXRequestLog; class NLXSubscriber implements EventSubscriberInterface { - private $params; - private $em; - private $serializer; - private $nlxLogService; - - public function __construct(ParameterBagInterface $params, EntityManagerInterface $em, SerializerInterface $serializer,NLXLogService $nlxLogService) - { - $this->params = $params; - $this->em = $em; - $this->serializer = $serializer; - $this->nlxLogService = $nlxLogService; - } - - public static function getSubscribedEvents() - { - return [ - KernelEvents::VIEW => ['NLXLog', EventPriorities::PRE_VALIDATE], - KernelEvents::VIEW => ['NLXAudit', EventPriorities::PRE_SERIALIZE], - ]; - - } - - public function NLXAudit(GetResponseForControllerResultEvent $event){ - - $result = $event->getControllerResult(); - $auditTrail= $event->getRequest()->query->get('auditTrail'); - - // Only do somthing if we are on te log route and the entity is logable - /* @todo we should trhow errors here foruser feedback */ - if (!$auditTrail ) { - return $result; - } - - $repo = $this->em->getRepository('App\Entity\NLXRequestLog'); - $logs = $repo->getLogEntries($result); - - - // now we need to overide the normal subscriber - $json = $this->serializer->serialize( - $logs, - 'jsonhal',['enable_max_depth' => true] - ); - - $response = new Response( - $json, - Response::HTTP_OK, - ['content-type' => 'application/json+hal'] - ); - - $event->setResponse($response); - - return; - } - - - public function NLXLog(GetResponseForControllerResultEvent $event) - { - $result = $event->getControllerResult(); - - $session = new Session(); - $session->start(); - // See: https://docs.nlx.io/further-reading/transaction-logs/ - - $log = New NLXRequestLog; - $log->setApplicationId ($event->getRequest()->headers->get('X-NLX-Application-Id')); - $log->setRequestId ($event->getRequest()->headers->get('X-NLX-Request-Id')); - $log->setUserId ($event->getRequest()->headers->get('X-NLX-Request-User-Id')); - $log->setSubjectId ($event->getRequest()->headers->get('X-NLX-Request-Subject-Identifier')); - $log->setProcessId ($event->getRequest()->headers->get('X-NLX-Request-Process-Id')); - $log->setDataElements ($event->getRequest()->headers->get('X-NLX-Request-Data-Elements')); - $log->setDataSubjects ($event->getRequest()->headers->get('X-NLX-Request-Data-Subject')); - $log->setObjectId ($result->getid()); - $log->setObjectClass ($this->em->getMetadataFactory()->getMetadataFor(get_class($result))->getName()); - $log->setRoute ($event->getRequest()->attributes->get('_route')); - $log->setEndpoint ($event->getRequest()->getPathInfo()); - $log->setMethod ($event->getRequest()->getMethod()); - $log->setContentType ($event->getRequest()->headers->get('Content-Type')); - $log->setContent ($event->getRequest()->getContent()); - $log->setSession ($session->getId()); - $log->setLoggedAt (new \DateTime() ); - - $this->em->persist($log); - $this->em->flush($log); - - // $authorization = $this->params->get('nlx.components.authorization.'); - // We need to do serveral things for nlx - - // First of all we need to log this request to our audit trial, where at minimal level we need to log who (application) asked what (data) for wich reasons (goal). We also need to consider that the requestee might have used the field query parmeter. So we need to log what fields of the object where actually returned. - - // Then we need to authenticate the request against a common ground authentication component - - // In the current common ground we dont bother with authorization (every one may do anything as long as we know who it is) - - return $result; - } + private $params; + private $em; + private $serializer; + private $nlxLogService; + + public function __construct(ParameterBagInterface $params, EntityManagerInterface $em, SerializerInterface $serializer, NLXLogService $nlxLogService) + { + $this->params = $params; + $this->em = $em; + $this->serializer = $serializer; + $this->nlxLogService = $nlxLogService; + } + + public static function getSubscribedEvents() + { + return [ + KernelEvents::VIEW => ['NLXLog', EventPriorities::PRE_VALIDATE], + KernelEvents::VIEW => ['NLXAudit', EventPriorities::PRE_SERIALIZE], + ]; + } + + public function NLXAudit(GetResponseForControllerResultEvent $event) + { + $result = $event->getControllerResult(); + $auditTrail = $event->getRequest()->query->get('auditTrail'); + + // Only do somthing if we are on te log route and the entity is logable + /* @todo we should trhow errors here foruser feedback */ + if (!$auditTrail) { + return $result; + } + + $repo = $this->em->getRepository('App\Entity\NLXRequestLog'); + $logs = $repo->getLogEntries($result); + + // now we need to overide the normal subscriber + $json = $this->serializer->serialize( + $logs, + 'jsonhal', ['enable_max_depth' => true] + ); + + $response = new Response( + $json, + Response::HTTP_OK, + ['content-type' => 'application/json+hal'] + ); + + $event->setResponse($response); + } + + public function NLXLog(GetResponseForControllerResultEvent $event) + { + $result = $event->getControllerResult(); + + $session = new Session(); + $session->start(); + // See: https://docs.nlx.io/further-reading/transaction-logs/ + + $log = new NLXRequestLog(); + $log->setApplicationId($event->getRequest()->headers->get('X-NLX-Application-Id')); + $log->setRequestId($event->getRequest()->headers->get('X-NLX-Request-Id')); + $log->setUserId($event->getRequest()->headers->get('X-NLX-Request-User-Id')); + $log->setSubjectId($event->getRequest()->headers->get('X-NLX-Request-Subject-Identifier')); + $log->setProcessId($event->getRequest()->headers->get('X-NLX-Request-Process-Id')); + $log->setDataElements($event->getRequest()->headers->get('X-NLX-Request-Data-Elements')); + $log->setDataSubjects($event->getRequest()->headers->get('X-NLX-Request-Data-Subject')); + $log->setObjectId($result->getid()); + $log->setObjectClass($this->em->getMetadataFactory()->getMetadataFor(get_class($result))->getName()); + $log->setRoute($event->getRequest()->attributes->get('_route')); + $log->setEndpoint($event->getRequest()->getPathInfo()); + $log->setMethod($event->getRequest()->getMethod()); + $log->setContentType($event->getRequest()->headers->get('Content-Type')); + $log->setContent($event->getRequest()->getContent()); + $log->setSession($session->getId()); + $log->setLoggedAt(new \DateTime()); + + $this->em->persist($log); + $this->em->flush($log); + + // $authorization = $this->params->get('nlx.components.authorization.'); + // We need to do serveral things for nlx + + // First of all we need to log this request to our audit trial, where at minimal level we need to log who (application) asked what (data) for wich reasons (goal). We also need to consider that the requestee might have used the field query parmeter. So we need to log what fields of the object where actually returned. + + // Then we need to authenticate the request against a common ground authentication component + + // In the current common ground we dont bother with authorization (every one may do anything as long as we know who it is) + + return $result; + } } diff --git a/api/src/Subscriber/ValidOnSubscriber.php b/api/src/Subscriber/ValidOnSubscriber.php index 616d66ef..4aac9f15 100644 --- a/api/src/Subscriber/ValidOnSubscriber.php +++ b/api/src/Subscriber/ValidOnSubscriber.php @@ -2,106 +2,96 @@ namespace App\Subscriber; -use ApiPlatform\Core\Exception\InvalidArgumentException; use ApiPlatform\Core\EventListener\EventPriorities; +use Doctrine\Common\Annotations\Reader; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Serializer\SerializerInterface; -use Doctrine\ORM\EntityManagerInterface; -use Doctrine\Common\Annotations\Reader; -use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; - -use App\Service\RequestService; class ValidOnSubscriber implements EventSubscriberInterface { - private $params; - private $em; - private $serializer; - private $annotationReader; - - public function __construct(ParameterBagInterface $params, EntityManagerInterface $em, SerializerInterface $serializer, Reader $annotationReader) - { - $this->params = $params; - $this->em= $em; - $this->serializer= $serializer; - $this->annotationReader = $annotationReader; - } - - public static function getSubscribedEvents() - { - return [ - KernelEvents::VIEW => ['validOn', EventPriorities::PRE_SERIALIZE], - ]; - - } - - public function validOn(GetResponseForControllerResultEvent $event) - { - $result = $event->getControllerResult(); - - // Lets get validOn from the query but deafult back to geldig op (for backward compatibality with api standaard) - $geldigOp = $event->getRequest()->query->get('geldigOp', false); - $validOn = $event->getRequest()->query->get('validOn', $geldigOp); - - - // Only do somthing if fields is query supplied - if (!$validOn) { - return $result; - } - - - // Lets see if this class has a Loggableannotation - $loggable = false; - $reflClass = new \ReflectionClass($result); - $annotations = $this->annotationReader->getClassAnnotations($reflClass); - - foreach($annotations as $annotation ){ - if(get_class($annotation) == "Gedmo\Mapping\Annotation\Loggable"){ - $loggable = true; - } - } - /* @todo propper error handling */ - if(!$loggable){ - throw new \Exception('This enity is not loggable therefore no previus versions can be obtained'); - } - - // Lets turn valid on into a date - try{ - $date = strtotime($validOn); - $date = date("Y-m-d H:i:s", $date); - - } catch (Exception $e) { - /* @todo thow propper exeption */ - throw new \Exception('Caught exception: ', $e->getMessage(), "\n"); - } - - // Lets try to get an version valid on that date - $queryBuilder= $this->em->getRepository('Gedmo\Loggable\Entity\LogEntry')->createQueryBuilder('l') - ->where('l.objectClass = :objectClass') - ->setParameter('objectClass', $this->em->getMetadataFactory()->getMetadataFor(get_class($result))->getName()) - ->andWhere('l.objectId = :objectId') - ->setParameter('objectId', $result->getId()) - ->andWhere('l.loggedAt <= :loggedAt') - ->setParameter('loggedAt', $date) - ->setMaxResults(1) - ->orderBy('l.loggedAt', 'DESC'); - - $version = $queryBuilder->getQuery()->getOneOrNullResult(); - - /* @todo propper error handling */ - if(!$version){ - throw new \Exception('Could not find a valid version for date: '.$date); - } - - // Lets use the found version to rewind the object and return is - $repo = $this->em->getRepository('\Gedmo\Loggable\Entity\LogEntry'); // we use default log entry class - $repo->revert($result, $version->getVersion()); - - return $result; - } + private $params; + private $em; + private $serializer; + private $annotationReader; + + public function __construct(ParameterBagInterface $params, EntityManagerInterface $em, SerializerInterface $serializer, Reader $annotationReader) + { + $this->params = $params; + $this->em = $em; + $this->serializer = $serializer; + $this->annotationReader = $annotationReader; + } + + public static function getSubscribedEvents() + { + return [ + KernelEvents::VIEW => ['validOn', EventPriorities::PRE_SERIALIZE], + ]; + } + + public function validOn(GetResponseForControllerResultEvent $event) + { + $result = $event->getControllerResult(); + + // Lets get validOn from the query but deafult back to geldig op (for backward compatibality with api standaard) + $geldigOp = $event->getRequest()->query->get('geldigOp', false); + $validOn = $event->getRequest()->query->get('validOn', $geldigOp); + + // Only do somthing if fields is query supplied + if (!$validOn) { + return $result; + } + + // Lets see if this class has a Loggableannotation + $loggable = false; + $reflClass = new \ReflectionClass($result); + $annotations = $this->annotationReader->getClassAnnotations($reflClass); + + foreach ($annotations as $annotation) { + if (get_class($annotation) == "Gedmo\Mapping\Annotation\Loggable") { + $loggable = true; + } + } + /* @todo propper error handling */ + if (!$loggable) { + throw new \Exception('This enity is not loggable therefore no previus versions can be obtained'); + } + + // Lets turn valid on into a date + try { + $date = strtotime($validOn); + $date = date('Y-m-d H:i:s', $date); + } catch (Exception $e) { + /* @todo thow propper exeption */ + throw new \Exception('Caught exception: ', $e->getMessage(), "\n"); + } + + // Lets try to get an version valid on that date + $queryBuilder = $this->em->getRepository('Gedmo\Loggable\Entity\LogEntry')->createQueryBuilder('l') + ->where('l.objectClass = :objectClass') + ->setParameter('objectClass', $this->em->getMetadataFactory()->getMetadataFor(get_class($result))->getName()) + ->andWhere('l.objectId = :objectId') + ->setParameter('objectId', $result->getId()) + ->andWhere('l.loggedAt <= :loggedAt') + ->setParameter('loggedAt', $date) + ->setMaxResults(1) + ->orderBy('l.loggedAt', 'DESC'); + + $version = $queryBuilder->getQuery()->getOneOrNullResult(); + + /* @todo propper error handling */ + if (!$version) { + throw new \Exception('Could not find a valid version for date: '.$date); + } + + // Lets use the found version to rewind the object and return is + $repo = $this->em->getRepository('\Gedmo\Loggable\Entity\LogEntry'); // we use default log entry class + $repo->revert($result, $version->getVersion()); + + return $result; + } } diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 8a6edbd6..045ef50c 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -1,479 +1,481 @@ decorated = $decorated; - $this->params = $params; - $this->cash = $cache; - $this->em = $em; - $this->annotationReader = $annotationReader; - $this->camelCaseToSnakeCaseNameConverter= $camelCaseToSnakeCaseNameConverter; - } - - public function normalize($object, $format = null, array $context = []) - { - $docs = $this->decorated->normalize($object, $format, $context); - - /* The we need to enrich al the entities and add the autoated routes */ - - //var_dump($docs); - - // Lets make sure that we have definitions - if(!array_key_exists ('definitions',$docs)){$docs['definitions']=[];} - - // Lets make sure that we have tags - if(!array_key_exists ('tags',$docs)){$docs['tags']=[];} - - // Lets make sure that we have security and JWT-Claims - if(!array_key_exists ('securityDefinitions',$docs)){$docs['securityDefinitions']=[];} - - // Lets add JWT-Oauth - $docs['securityDefinitions']['JWT-Oauth'] = [ - "type"=>"oauth2", - "authorizationUrl"=>"http://petstore.swagger.io/api/oauth/dialog", - "flow"=>"implicit", - "scopes"=>[] #scopes will be filled later autmaticly - ]; - - $docs['securityDefinitions']['JWT-Token'] = [ - "type"=>"apiKey", - "in"=> "header", # can be "header", "query" or "cookie" - "name"=> "Authorization", # name of the header, query parameter or cookie - "scopes"=>[] #scopes will be filled later autmaticly - ]; - - - // Lets get al the entities known to doctrine - $entities = $this->em->getConfiguration()->getMetadataDriverImpl()->getAllClassNames(); - - $additionalDocs = []; - - // Then we loop trough the entities to find the api platform entities - foreach($entities as $entity){ - //$reflector = new \ReflectionClass($entity); - $metadata = $this->em->getClassMetadata($entity); - $reflector = $metadata->getReflectionClass(); - - $properties = $metadata->getReflectionProperties(); - $annotations = $this->annotationReader->getClassAnnotations($reflector); - - foreach($annotations as $annotation){ - $annotationReflector = new \ReflectionClass($annotation); - if($annotationReflector->name == "ApiPlatform\Core\Annotation\ApiResource"){ - - // Lets add the class info to the tag - $shortName = $reflector->getShortName (); - - $factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); - $docblock = $factory->create($reflector->getDocComment()); - $summary = $docblock->getSummary(); - $description = $docblock->getDescription()->render(); - $description = $summary."\n\n".$description; - - $tag = []; - $tag['name'] = $shortName; - $tag['description'] = $description; - - $docs['tags'][] = $tag; - - // And lets add the aditional docs - - //$additionalEntityDocs = $this->getAdditionalEntityDocs($entity); - $entityDocs = $this->getAdditionalEntityDocs($entity); - $additionalDocs= array_merge($additionalDocs,$entityDocs['properties']); - - // Security - $docs['securityDefinitions']['JWT-Oauth']['scopes']= array_merge($docs['securityDefinitions']['JWT-Oauth']['scopes'],$entityDocs['security']); - $docs['securityDefinitions']['JWT-Token']['scopes']= array_merge($docs['securityDefinitions']['JWT-Token']['scopes'],$entityDocs['security']); - - break; - } - } - } - - // Oke dit is echt but lelijk - $schemas = (array) $docs['definitions']; - foreach($schemas as $schemaName => $schema){ - - $additionalDocs[$schemaName] = array_merge( (array) $schema, $additionalDocs[$schemaName]); - - $properties = (array) $schema['properties']; - foreach($properties as $propertyName => $property){ - $additionalDocs[$schemaName]['properties'][$propertyName] = array_merge( (array) $property, $additionalDocs[$schemaName]['properties'][$propertyName] ); - } - } - $docs['definitions'] = $additionalDocs; - - // Lest add an host - if($this->params->get('common_ground.oas.host')){ - $docs['host']= $this->params->get('common_ground.oas.host'); - } - - // Lets set the servers - if(array_key_exists ('servers',$docs)){$docs['servers']=[];} - foreach($this->params->get('common_ground.oas.servers') as $key => $value){ - $docs['servers'][$key] = $value; - - } - - // Lets set the external documentation - if(array_key_exists ('externalDocs',$docs)){$docs['externalDocs']=[];} - foreach($this->params->get('common_ground.oas.externalDocs') as $key => $value){ - $docs['externalDocs'][$key] = $value; - - } - - // Lets add the commonground codes - if(array_key_exists ('x-commonground',$docs)){$docs['x-commonground']=[];} - - // Lets set the component type - $docs['x-commonground']['type'] = $this->params->get('common_ground.oas.type'); - - // Lets set the devolopers - if(array_key_exists ('developers',$docs['x-commonground'])){$docs['developers']=[];} - foreach($this->params->get('common_ground.oas.developers') as $key => $value){ - $docs['x-commonground']['developers'][$key] = $value; - - } - - // Lets set the build checks - if(array_key_exists ('builds',$docs['x-commonground'])){$docs['builds']=[];} - foreach($this->params->get('common_ground.oas.builds') as $key => $value){ - $docs['x-commonground']['builds'][$key] = $value; - } - - /*todo a loop within a lopo is butt ugly */ - foreach($docs['paths'] as $path => $calls){ - - foreach($calls as $method => $call){ - - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'Authorization', - 'description' => 'The JWT of the entity performing the request', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'API-Version', - 'description' => 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)', - 'example'=>'1.0.1', - 'in' => 'header', - ]; - /* - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Request-Application-Id', - 'description' => 'The id of the application performing the request', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Request-Subject-Identifier', - 'description' => 'An subject identifier for purpose registration (doelbinding)', - 'in' => 'header', - ]; - */ - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Logrecord-ID', - 'description' => 'A globally unique id of the request, which makes a request traceable throughout the network.', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Request-Process-Id', - 'description' => 'A process id for purpose registration (doelbinding)', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Request-Data-Elements', - 'description' => 'A list of requested data elements', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Request-Data-Subject', - 'description' => 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Audit-Clarification', - 'description' => 'A clarification as to why a request has been made (doelbinding)', - 'in' => 'header', - ]; - - - if($method == "get"){ - - - // Health JSON - $call['produces'][] = 'application/health+json'; - - // WEBSUB header - $call['parameters'][] = [ - 'name' => 'Link', - 'description' => 'A [websub](https://www.w3.org/TR/websub/#discovery) header like ; rel="hub"', - 'in' => 'header', - ]; - - // Lets add the extend functionality - $call['parameters'][] = [ - 'name' => 'extend[]', - 'required' => false, - 'description' => 'An array of nested objects to include in the return object', - 'in' => 'query', - 'schema'=>['type'=>'array'] - ]; - // Lets add the fields functionality - $call['parameters'][] = [ - 'name' => 'fields[]', - 'required' => false, - 'description' => 'An array of fields to return in output, wil return all fields is not supplied', - 'in' => 'query', - 'schema'=>['type'=>'array'] - ]; - // Lets add some time travel - $call['parameters'][] = [ - 'name' => 'validOn', - 'required' => false, - 'description' => 'Returns object as valid on a given date time', - 'schema'=>['type'=>'string', 'format' => 'date-time'], - 'in' => 'query', - ]; - $call['parameters'][] = [ - 'name' => 'validFrom', - 'required' => false, - 'description' => 'Returns objects valid from a given date time', - 'schema'=>['type'=>'string', 'format' => 'date-time'], - 'in' => 'query', - ]; - $call['parameters'][] = [ - 'name' => 'validUntil', - 'required' => false, - 'description' => 'Returns objects valid until a given date time', - 'schema'=>['type'=>'string', 'format' => 'date-time'], - 'in' => 'query', - ]; - } - } - } - - /* @todo dit afbouwen */ - - /* - if(config heltchecks is true){ - $tag=[]; - $tag['name']=''; - $tag['description']=''; - array_unshift($fruits_list, $tag); - - } - - if(config audittrail is true){ - $tag=[]; - $tag['name']=''; - $tag['description']=''; - array_unshift($fruits_list, $tag); - - } - - if(config notifications is true){ - $tag=[]; - $tag['name']=''; - $tag['description']=''; - array_unshift($fruits_list, $tag); - - } - - if(config authorization is true){ - $tag=[]; - $tag['name']=''; - $tag['description']=''; - array_unshift($fruits_list, $tag); - } - */ - //var_dump($docs); - - - // Aditional tags - - - // Security tag - if(getenv('HEALTH_ENABLED')=="true"){ - $tag = []; - $tag['name'] = 'Health Checks'; - $tag['description'] = 'Authorization'; - $tag['externalDocs'] = []; - $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; - array_unshift($docs['tags'], $tag); - } - - // Security tag - if(getenv('NOTIFICATION_ENABLED')=="true"){ - $tag = []; - $tag['name'] = 'Notifications'; - $tag['description'] = 'Authorization'; - $tag['externalDocs'] = []; - $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; - array_unshift($docs['tags'], $tag); - } - - - // Security tag - if(getenv('AUDITTRAIL_ENABLED')=="true"){ - $tag = []; - $tag['name'] = 'Audit trail'; - $tag['description'] = 'Authorization'; - $tag['externalDocs'] = []; - $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; - array_unshift($docs['tags'], $tag); - } - - // Security tag - if(getenv('AUTH_ENABLED')=="true"){ - $tag = []; - $tag['name'] = 'Authorization'; - $tag['description'] = 'Authorization'; - $tag['externalDocs'] = []; - $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; - array_unshift($docs['tags'], $tag); - } - - - //var_dump($docs); - return $docs; - } - - public function supportsNormalization($data, $format = null) - { - return $this->decorated->supportsNormalization($data, $format); - } - - private function getAdditionalEntityDocs($entity){ - - $metadata = $this->em->getClassMetadata($entity); - $reflector = $metadata->getReflectionClass(); - $properties = $metadata->getReflectionProperties(); - $annotations = $this->annotationReader->getClassAnnotations($reflector); - $additionalDocs = ['properties','security'=>[]]; - $required = []; - - // Add audittrail - // Add healthcheck - - $class = $reflector->getShortName(); - $path = '/'.$this->camelCaseToSnakeCaseNameConverter->normalize($class); - - - // Lets take a look at the properties an annotions, - foreach($properties as $property){ - - // The dockBlocks for thie property - $factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); - $docblock = $factory->create($property->getDocComment()); - $tags = $docblock->getTags(); - $atributes = []; - - foreach($tags as $tag){ - $name = $tag->getName(); - $description = $tag->getDescription(); - // - //$description = (string) $description; - - switch ($name) { - // Docblocks - case "example": - $atributes['example'] = (string) $description; - break; - - // Groups - case "Groups": - $propertyAnnotation = $this->annotationReader->getPropertyAnnotation($property, "Symfony\Component\Serializer\Annotation\Groups"); - $groups = $propertyAnnotation->getGroups(); - break; - - // Constrainds (Validation) - case "Assert\Uuid": - $atributes['format'] = 'uuid'; - break; - case "Assert\Email": - $atributes['format'] = 'email'; - break; - case "Assert\Url": - $atributes['format'] = 'url'; - break; - case "Assert\Regex": - $atributes['format'] = 'regex'; - break; - case "Assert\Ip": - $atributes['format'] = 'ip'; - break; - case "Assert\Json": - $atributes['format'] = 'json'; - break; - case "Assert\Choice": - //@todo - //$atributes['format'] = 'json'; - break; - - case "Assert\NotNull": - $required[] = $property->name; - break; - case "Assert\Length": - $propertyAnnotation = $this->annotationReader->getPropertyAnnotation($property, "Symfony\Component\Validator\Constraints\Length"); - if($propertyAnnotation->max){$atributes['maxLength'] = $propertyAnnotation->max;} - if($propertyAnnotation->min){$atributes['minLength'] = $propertyAnnotation->min;} - break; - } - - } - // Lets write everything to the docs - foreach($groups as $group){ - //$additionalDocs["components"]['schemas'][$class."-".$group] = $atributes; - $additionalDocs['properties'][$class."-".$group]["properties"][$property->name]= $atributes; - $additionalDocs['properties'][$class."-".$group]["required"] = $required; - - - if(!array_key_exists ($group,$additionalDocs['security'])){$additionalDocs['security'][$group] = $group.' right to the '.$class.' resource'; } - } - - } - - - - - return $additionalDocs; - } -} \ No newline at end of file + private $metadataFactory; + private $documentationNormalizer; + private $decorated; + private $params; + private $cash; + private $em; + private $annotationReader; + private $camelCaseToSnakeCaseNameConverter; + + public function __construct( + NormalizerInterface $decorated, + ParameterBagInterface $params, + CacheInterface $cache, + EntityManagerInterface $em, + AnnotationReader $annotationReader, + CamelCaseToSnakeCaseNameConverter $camelCaseToSnakeCaseNameConverter + ) { + $this->decorated = $decorated; + $this->params = $params; + $this->cash = $cache; + $this->em = $em; + $this->annotationReader = $annotationReader; + $this->camelCaseToSnakeCaseNameConverter = $camelCaseToSnakeCaseNameConverter; + } + + public function normalize($object, $format = null, array $context = []) + { + $docs = $this->decorated->normalize($object, $format, $context); + + /* The we need to enrich al the entities and add the autoated routes */ + + //var_dump($docs); + + // Lets make sure that we have definitions + if (!array_key_exists('definitions', $docs)) { + $docs['definitions'] = []; + } + + // Lets make sure that we have tags + if (!array_key_exists('tags', $docs)) { + $docs['tags'] = []; + } + + // Lets make sure that we have security and JWT-Claims + if (!array_key_exists('securityDefinitions', $docs)) { + $docs['securityDefinitions'] = []; + } + + // Lets add JWT-Oauth + $docs['securityDefinitions']['JWT-Oauth'] = [ + 'type' => 'oauth2', + 'authorizationUrl'=> 'http://petstore.swagger.io/api/oauth/dialog', + 'flow' => 'implicit', + 'scopes' => [], //scopes will be filled later autmaticly + ]; + + $docs['securityDefinitions']['JWT-Token'] = [ + 'type' => 'apiKey', + 'in' => 'header', // can be "header", "query" or "cookie" + 'name' => 'Authorization', // name of the header, query parameter or cookie + 'scopes'=> [], //scopes will be filled later autmaticly + ]; + + // Lets get al the entities known to doctrine + $entities = $this->em->getConfiguration()->getMetadataDriverImpl()->getAllClassNames(); + + $additionalDocs = []; + + // Then we loop trough the entities to find the api platform entities + foreach ($entities as $entity) { + //$reflector = new \ReflectionClass($entity); + $metadata = $this->em->getClassMetadata($entity); + $reflector = $metadata->getReflectionClass(); + + $properties = $metadata->getReflectionProperties(); + $annotations = $this->annotationReader->getClassAnnotations($reflector); + + foreach ($annotations as $annotation) { + $annotationReflector = new \ReflectionClass($annotation); + if ($annotationReflector->name == "ApiPlatform\Core\Annotation\ApiResource") { + + // Lets add the class info to the tag + $shortName = $reflector->getShortName(); + + $factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); + $docblock = $factory->create($reflector->getDocComment()); + $summary = $docblock->getSummary(); + $description = $docblock->getDescription()->render(); + $description = $summary."\n\n".$description; + + $tag = []; + $tag['name'] = $shortName; + $tag['description'] = $description; + + $docs['tags'][] = $tag; + + // And lets add the aditional docs + + //$additionalEntityDocs = $this->getAdditionalEntityDocs($entity); + $entityDocs = $this->getAdditionalEntityDocs($entity); + $additionalDocs = array_merge($additionalDocs, $entityDocs['properties']); + + // Security + $docs['securityDefinitions']['JWT-Oauth']['scopes'] = array_merge($docs['securityDefinitions']['JWT-Oauth']['scopes'], $entityDocs['security']); + $docs['securityDefinitions']['JWT-Token']['scopes'] = array_merge($docs['securityDefinitions']['JWT-Token']['scopes'], $entityDocs['security']); + + break; + } + } + } + + // Oke dit is echt but lelijk + $schemas = (array) $docs['definitions']; + foreach ($schemas as $schemaName => $schema) { + $additionalDocs[$schemaName] = array_merge((array) $schema, $additionalDocs[$schemaName]); + + $properties = (array) $schema['properties']; + foreach ($properties as $propertyName => $property) { + $additionalDocs[$schemaName]['properties'][$propertyName] = array_merge((array) $property, $additionalDocs[$schemaName]['properties'][$propertyName]); + } + } + $docs['definitions'] = $additionalDocs; + + // Lest add an host + if ($this->params->get('common_ground.oas.host')) { + $docs['host'] = $this->params->get('common_ground.oas.host'); + } + + // Lets set the servers + if (array_key_exists('servers', $docs)) { + $docs['servers'] = []; + } + foreach ($this->params->get('common_ground.oas.servers') as $key => $value) { + $docs['servers'][$key] = $value; + } + + // Lets set the external documentation + if (array_key_exists('externalDocs', $docs)) { + $docs['externalDocs'] = []; + } + foreach ($this->params->get('common_ground.oas.externalDocs') as $key => $value) { + $docs['externalDocs'][$key] = $value; + } + + // Lets add the commonground codes + if (array_key_exists('x-commonground', $docs)) { + $docs['x-commonground'] = []; + } + + // Lets set the component type + $docs['x-commonground']['type'] = $this->params->get('common_ground.oas.type'); + + // Lets set the devolopers + if (array_key_exists('developers', $docs['x-commonground'])) { + $docs['developers'] = []; + } + foreach ($this->params->get('common_ground.oas.developers') as $key => $value) { + $docs['x-commonground']['developers'][$key] = $value; + } + + // Lets set the build checks + if (array_key_exists('builds', $docs['x-commonground'])) { + $docs['builds'] = []; + } + foreach ($this->params->get('common_ground.oas.builds') as $key => $value) { + $docs['x-commonground']['builds'][$key] = $value; + } + + /*todo a loop within a lopo is butt ugly */ + foreach ($docs['paths'] as $path => $calls) { + foreach ($calls as $method => $call) { + + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'Authorization', + 'description' => 'The JWT of the entity performing the request', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'API-Version', + 'description' => 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)', + 'example' => '1.0.1', + 'in' => 'header', + ]; + /* + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Request-Application-Id', + 'description' => 'The id of the application performing the request', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Request-Subject-Identifier', + 'description' => 'An subject identifier for purpose registration (doelbinding)', + 'in' => 'header', + ]; + */ + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Logrecord-ID', + 'description' => 'A globally unique id of the request, which makes a request traceable throughout the network.', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Request-Process-Id', + 'description' => 'A process id for purpose registration (doelbinding)', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Request-Data-Elements', + 'description' => 'A list of requested data elements', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Request-Data-Subject', + 'description' => 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Audit-Clarification', + 'description' => 'A clarification as to why a request has been made (doelbinding)', + 'in' => 'header', + ]; + + if ($method == 'get') { + + // Health JSON + $call['produces'][] = 'application/health+json'; + + // WEBSUB header + $call['parameters'][] = [ + 'name' => 'Link', + 'description' => 'A [websub](https://www.w3.org/TR/websub/#discovery) header like ; rel="hub"', + 'in' => 'header', + ]; + + // Lets add the extend functionality + $call['parameters'][] = [ + 'name' => 'extend[]', + 'required' => false, + 'description' => 'An array of nested objects to include in the return object', + 'in' => 'query', + 'schema' => ['type'=>'array'], + ]; + // Lets add the fields functionality + $call['parameters'][] = [ + 'name' => 'fields[]', + 'required' => false, + 'description' => 'An array of fields to return in output, wil return all fields is not supplied', + 'in' => 'query', + 'schema' => ['type'=>'array'], + ]; + // Lets add some time travel + $call['parameters'][] = [ + 'name' => 'validOn', + 'required' => false, + 'description' => 'Returns object as valid on a given date time', + 'schema' => ['type'=>'string', 'format' => 'date-time'], + 'in' => 'query', + ]; + $call['parameters'][] = [ + 'name' => 'validFrom', + 'required' => false, + 'description' => 'Returns objects valid from a given date time', + 'schema' => ['type'=>'string', 'format' => 'date-time'], + 'in' => 'query', + ]; + $call['parameters'][] = [ + 'name' => 'validUntil', + 'required' => false, + 'description' => 'Returns objects valid until a given date time', + 'schema' => ['type'=>'string', 'format' => 'date-time'], + 'in' => 'query', + ]; + } + } + } + + /* @todo dit afbouwen */ + + /* + if(config heltchecks is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); + + } + + if(config audittrail is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); + + } + + if(config notifications is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); + + } + + if(config authorization is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); + } + */ + //var_dump($docs); + + // Aditional tags + + // Security tag + if (getenv('HEALTH_ENABLED') == 'true') { + $tag = []; + $tag['name'] = 'Health Checks'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } + + // Security tag + if (getenv('NOTIFICATION_ENABLED') == 'true') { + $tag = []; + $tag['name'] = 'Notifications'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } + + // Security tag + if (getenv('AUDITTRAIL_ENABLED') == 'true') { + $tag = []; + $tag['name'] = 'Audit trail'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } + + // Security tag + if (getenv('AUTH_ENABLED') == 'true') { + $tag = []; + $tag['name'] = 'Authorization'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } + + //var_dump($docs); + return $docs; + } + + public function supportsNormalization($data, $format = null) + { + return $this->decorated->supportsNormalization($data, $format); + } + + private function getAdditionalEntityDocs($entity) + { + $metadata = $this->em->getClassMetadata($entity); + $reflector = $metadata->getReflectionClass(); + $properties = $metadata->getReflectionProperties(); + $annotations = $this->annotationReader->getClassAnnotations($reflector); + $additionalDocs = ['properties', 'security'=>[]]; + $required = []; + + // Add audittrail + // Add healthcheck + + $class = $reflector->getShortName(); + $path = '/'.$this->camelCaseToSnakeCaseNameConverter->normalize($class); + + // Lets take a look at the properties an annotions, + foreach ($properties as $property) { + + // The dockBlocks for thie property + $factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); + $docblock = $factory->create($property->getDocComment()); + $tags = $docblock->getTags(); + $atributes = []; + + foreach ($tags as $tag) { + $name = $tag->getName(); + $description = $tag->getDescription(); + // + //$description = (string) $description; + + switch ($name) { + // Docblocks + case 'example': + $atributes['example'] = (string) $description; + break; + + // Groups + case 'Groups': + $propertyAnnotation = $this->annotationReader->getPropertyAnnotation($property, "Symfony\Component\Serializer\Annotation\Groups"); + $groups = $propertyAnnotation->getGroups(); + break; + + // Constrainds (Validation) + case "Assert\Uuid": + $atributes['format'] = 'uuid'; + break; + case "Assert\Email": + $atributes['format'] = 'email'; + break; + case "Assert\Url": + $atributes['format'] = 'url'; + break; + case "Assert\Regex": + $atributes['format'] = 'regex'; + break; + case "Assert\Ip": + $atributes['format'] = 'ip'; + break; + case "Assert\Json": + $atributes['format'] = 'json'; + break; + case "Assert\Choice": + //@todo + //$atributes['format'] = 'json'; + break; + + case "Assert\NotNull": + $required[] = $property->name; + break; + case "Assert\Length": + $propertyAnnotation = $this->annotationReader->getPropertyAnnotation($property, "Symfony\Component\Validator\Constraints\Length"); + if ($propertyAnnotation->max) { + $atributes['maxLength'] = $propertyAnnotation->max; + } + if ($propertyAnnotation->min) { + $atributes['minLength'] = $propertyAnnotation->min; + } + break; + } + } + // Lets write everything to the docs + foreach ($groups as $group) { + //$additionalDocs["components"]['schemas'][$class."-".$group] = $atributes; + $additionalDocs['properties'][$class.'-'.$group]['properties'][$property->name] = $atributes; + $additionalDocs['properties'][$class.'-'.$group]['required'] = $required; + + if (!array_key_exists($group, $additionalDocs['security'])) { + $additionalDocs['security'][$group] = $group.' right to the '.$class.' resource'; + } + } + } + + return $additionalDocs; + } +} diff --git a/api/src/Types/IncompleteDateType.php b/api/src/Types/IncompleteDateType.php index 8badbc8e..88f66c3c 100644 --- a/api/src/Types/IncompleteDateType.php +++ b/api/src/Types/IncompleteDateType.php @@ -2,54 +2,58 @@ namespace App\Types; -use Doctrine\DBAL\Types\Type; -use Doctrine\DBAL\Platforms\AbstractPlatform; - use App\ValueObject\IncompleteDate; +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Types\Type; class IncompleteDateType extends Type { - const INCOMPLETEDATE = 'incompleteDate'; - - public function getName() - { - return self::INCOMPLETEDATE; - } - - public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) - { - return 'INTEGER'; - } - - public function convertToPHPValue($value, AbstractPlatform $platform) - { - // Lets make this nullable - if(!$value){ - return null; - } - // We save incomplete date's as YYYYMMDD integer values so that we can easily index and order on them - list($year, $month, $day) = sscanf($value, '%04u%02u%02u'); - - return new IncompleteDate($year, $month, $day); - } - - public function convertToDatabaseValue($value, AbstractPlatform $platform) - { - // Lets make this nullable - if(!$value){ - return null; - } - // We save incomplete date's as YYYYMMDD integer values so that we can easily index and order on them - if ($value instanceof IncompleteDate) { - $value = sprintf('%04u%02u%02u', $value->getYear(), $value->getMonth(), $value->getDay()); - } - else{ - if(!array_key_exists("year",$value)){ $value['year']=0;} - if(!array_key_exists("month",$value)){ $value['month']=0;} - if(!array_key_exists("day",$value)){ $value['day']=0;} - $value = sprintf('%04u%02u%02u', (int) $value['year'], (int) $value['month'], (int) $value['day']); - } - - return $value; - } -} \ No newline at end of file + const INCOMPLETEDATE = 'incompleteDate'; + + public function getName() + { + return self::INCOMPLETEDATE; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return 'INTEGER'; + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + // Lets make this nullable + if (!$value) { + return; + } + // We save incomplete date's as YYYYMMDD integer values so that we can easily index and order on them + list($year, $month, $day) = sscanf($value, '%04u%02u%02u'); + + return new IncompleteDate($year, $month, $day); + } + + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + // Lets make this nullable + if (!$value) { + return; + } + // We save incomplete date's as YYYYMMDD integer values so that we can easily index and order on them + if ($value instanceof IncompleteDate) { + $value = sprintf('%04u%02u%02u', $value->getYear(), $value->getMonth(), $value->getDay()); + } else { + if (!array_key_exists('year', $value)) { + $value['year'] = 0; + } + if (!array_key_exists('month', $value)) { + $value['month'] = 0; + } + if (!array_key_exists('day', $value)) { + $value['day'] = 0; + } + $value = sprintf('%04u%02u%02u', (int) $value['year'], (int) $value['month'], (int) $value['day']); + } + + return $value; + } +} diff --git a/api/src/Types/UnderInvestigationType.php b/api/src/Types/UnderInvestigationType.php index e66e7e7c..4717bf51 100644 --- a/api/src/Types/UnderInvestigationType.php +++ b/api/src/Types/UnderInvestigationType.php @@ -2,66 +2,69 @@ namespace App\Types; -use Doctrine\DBAL\Types\Type; -use Doctrine\DBAL\Platforms\AbstractPlatform; - use App\ValueObject\UnderInvestigation; +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Types\Type; class UnderInvestigationType extends Type { - const UNDERINVESTIGATION = 'underInvestigation'; - - public function getName() - { - return self::UNDERINVESTIGATION; - } - - public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) - { - return 'JSON'; - } - - public function convertToPHPValue($value, AbstractPlatform $platform) - { - // Lets make this nullable - if(!$value){ - return null; - } - //list($longitude, $latitude) = sscanf($value, 'JSON(%s)'); - $value= json_decode ($value, true); - //var_dump($data); - $date = $value['date']; - $properties = $value['properties']; - return new UnderInvestigation($properties, $date); - } - - public function convertToDatabaseValue($value, AbstractPlatform $platform) - { - // Lets make this nullable - if(!$value){ - return null; - } - if ($value instanceof UnderInvestigation) { - /* @todo throw an error ir the property isn't a boolean*/ - $value= ["properties"=> $value->getProperties(),"date"=> $value->getDate()]; - $value = json_encode($value); - } - else{ - // lets make sure we have a properties array - if(!array_key_exists("properties",$value)){ $value['properties']=[];} - // Lets analyse this dataset - foreach ($value as $key => $property){ - // lets skip the date and propertieskeys - if($key=='date' || $key=='properties'){continue;} - /* @todo throw an error ir the property isn't a boolean*/ - - // lets add the property to the stack - $value['properties'][$key] = $property; - unset($value[$key]); - } - $value = json_encode($value); - } - - return $value; - } -} \ No newline at end of file + const UNDERINVESTIGATION = 'underInvestigation'; + + public function getName() + { + return self::UNDERINVESTIGATION; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return 'JSON'; + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + // Lets make this nullable + if (!$value) { + return; + } + //list($longitude, $latitude) = sscanf($value, 'JSON(%s)'); + $value = json_decode($value, true); + //var_dump($data); + $date = $value['date']; + $properties = $value['properties']; + + return new UnderInvestigation($properties, $date); + } + + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + // Lets make this nullable + if (!$value) { + return; + } + if ($value instanceof UnderInvestigation) { + /* @todo throw an error ir the property isn't a boolean*/ + $value = ['properties'=> $value->getProperties(), 'date'=> $value->getDate()]; + $value = json_encode($value); + } else { + // lets make sure we have a properties array + if (!array_key_exists('properties', $value)) { + $value['properties'] = []; + } + // Lets analyse this dataset + foreach ($value as $key => $property) { + // lets skip the date and propertieskeys + if ($key == 'date' || $key == 'properties') { + continue; + } + /* @todo throw an error ir the property isn't a boolean*/ + + // lets add the property to the stack + $value['properties'][$key] = $property; + unset($value[$key]); + } + $value = json_encode($value); + } + + return $value; + } +} diff --git a/api/src/ValueObject/IncompleteDate.php b/api/src/ValueObject/IncompleteDate.php index 97149fc6..c9fbb072 100644 --- a/api/src/ValueObject/IncompleteDate.php +++ b/api/src/ValueObject/IncompleteDate.php @@ -2,64 +2,72 @@ namespace App\ValueObject; - /* * Incomplomplete data class - * + * * This doctrine value object is designd to work in tendem with the incompleteData mapping type to provide doctrine support for the working with incomplete date objects - * - * + * + * */ -class IncompleteDate +class IncompleteDate { - /** - * @param integer $day - * @param integer $month - * @param integer $year - */ - public function __construct($year, $month, $day) - { - $this->day = $day; - $this->month= $month; - $this->year = $year; - } - - /** - * @return integer - */ - public function getDay() - { - // If the day is missing we return zero - if(!$this->day){return 0;} - return $this->day; - } - - /** - * @return integer - */ - public function getMonth() - { - // If the month is missing we return zero - if(!$this->month){return 0;} - return $this->month; - } - - /** - * @return integer - */ - public function getYear() - { - // If the year is missing we return zero - if(!$this->year){return 0;} - return $this->year; - } - - /** - * @return string - */ - public function getDate() - { - return sprintf('%04u-%02u-%02u', $this->getYear(), $this->getMonth(), $this->getDay()); - } -} \ No newline at end of file + /** + * @param int $day + * @param int $month + * @param int $year + */ + public function __construct($year, $month, $day) + { + $this->day = $day; + $this->month = $month; + $this->year = $year; + } + + /** + * @return int + */ + public function getDay() + { + // If the day is missing we return zero + if (!$this->day) { + return 0; + } + + return $this->day; + } + + /** + * @return int + */ + public function getMonth() + { + // If the month is missing we return zero + if (!$this->month) { + return 0; + } + + return $this->month; + } + + /** + * @return int + */ + public function getYear() + { + // If the year is missing we return zero + if (!$this->year) { + return 0; + } + + return $this->year; + } + + /** + * @return string + */ + public function getDate() + { + return sprintf('%04u-%02u-%02u', $this->getYear(), $this->getMonth(), $this->getDay()); + } +} diff --git a/api/src/ValueObject/UnderInvestigation.php b/api/src/ValueObject/UnderInvestigation.php index 63912361..bbbb98f1 100644 --- a/api/src/ValueObject/UnderInvestigation.php +++ b/api/src/ValueObject/UnderInvestigation.php @@ -2,32 +2,31 @@ namespace App\ValueObject; - -class UnderInvestigation +class UnderInvestigation { - /** - * @param array $properties - * @param string $date - */ - public function __construct($properties, $date) - { - $this->properties= $properties; - $this->date= $date; - } - - /** - * @return array - */ - public function getProperties() - { - return $this->properties; - } - - /** - * @return string - */ - public function getDate() - { - return $this->date; - } -} \ No newline at end of file + /** + * @param array $properties + * @param string $date + */ + public function __construct($properties, $date) + { + $this->properties = $properties; + $this->date = $date; + } + + /** + * @return array + */ + public function getProperties() + { + return $this->properties; + } + + /** + * @return string + */ + public function getDate() + { + return $this->date; + } +} From 8c49648e3effd79880d6709915b92bcf3a03ea31 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 13:27:44 +0100 Subject: [PATCH 049/182] Test voor helm version --- .github/workflows/dockerimage.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index e73dbdf9..81cf4025 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -72,7 +72,13 @@ jobs: echo "##[set-output name=success]true" else echo "##[set-output name=success]false" - fi + fi + - name: Set correct helm version + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' + run: | + brew unlink kubernetes-helm + brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/78d64252f30a12b6f4b3ce29686ab5e262eea812/Formula/kubernetes-helm.rb + brew switch kubernetes-helm 2.12.3 - name: Deploy through helm if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true From 909269ffae6d7dd2a7d200f166bd0d41b5727fe0 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 13:27:44 +0100 Subject: [PATCH 050/182] Test voor helm version --- .github/workflows/dockerimage.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index e73dbdf9..11736f5e 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -19,6 +19,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 + - name: Set correct helm version + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' + run: ./get_helm.sh -v v2.12.3 - name: Pulling old images, if any run: docker-compose pull --ignore-pull-failures - name: Setting APP_ENV to dev @@ -72,7 +75,7 @@ jobs: echo "##[set-output name=success]true" else echo "##[set-output name=success]false" - fi + fi - name: Deploy through helm if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true From 5dfe8ea64203e4da57f8ef0d457a91df03a3c403 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 14:01:44 +0100 Subject: [PATCH 051/182] Removing problematic condition from code --- .github/workflows/dockerimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 11736f5e..f5087182 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -20,7 +20,7 @@ jobs: steps: - uses: actions/checkout@v1 - name: Set correct helm version - if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) run: ./get_helm.sh -v v2.12.3 - name: Pulling old images, if any run: docker-compose pull --ignore-pull-failures From aedb339c2cf2f7f67096ff2e518f4437cffa3e8f Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 15:10:45 +0100 Subject: [PATCH 052/182] Adding conditional upgrade instead of install --- .github/workflows/dockerimage.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 66b6eb8c..f1521ee7 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -77,5 +77,13 @@ jobs: if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: helm init --upgrade --kubeconfig="kubeconfig.yaml" - name: Deploy through helm + - name: Deploy through helm + id: helm-install if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' + run: | + helm install pc-$APP_ENV ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true + echo "##[set-output name=status-code]$?" + continue-on-error: true + - name: Deploy through helm upgrade + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' && steps.helm-install.ouputs.status-code!=0 run: helm upgrade pc-$APP_ENV ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true From 93143d94af4fd2dacde15ce1ffec09d3c39bfb2d Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 27 Nov 2019 15:14:47 +0100 Subject: [PATCH 053/182] Some fixes --- .github/workflows/dockerimage.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index f1521ee7..a39144e6 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -76,14 +76,13 @@ jobs: - name: Set correct helm version if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: helm init --upgrade --kubeconfig="kubeconfig.yaml" - - name: Deploy through helm - name: Deploy through helm id: helm-install if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: | - helm install pc-$APP_ENV ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true + helm install pc-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true echo "##[set-output name=status-code]$?" continue-on-error: true - name: Deploy through helm upgrade if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' && steps.helm-install.ouputs.status-code!=0 - run: helm upgrade pc-$APP_ENV ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true + run: helm upgrade pc-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true From d9d1e2fecfc8b33dbc8967468baa6212340f704b Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 20:20:27 +0100 Subject: [PATCH 054/182] Test for helm install backup --- .github/workflows/dockerimage.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 529514cf..254b6999 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -79,3 +79,6 @@ jobs: - name: Deploy through helm if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: helm upgrade pc-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true + - name: Install through helm + if: failure() + run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 From 0ef9cce5577c7391761061f8a4959dee60fa7112 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 20:32:46 +0100 Subject: [PATCH 055/182] Fix on APP_NAME --- .github/workflows/dockerimage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 254b6999..4adbce8d 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -78,7 +78,7 @@ jobs: run: helm init --upgrade --kubeconfig="kubeconfig.yaml" - name: Deploy through helm if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' - run: helm upgrade pc-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true + run: helm upgrade ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true - name: Install through helm if: failure() - run: helm install --name pc-$APP_ENV ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 + run: helm install --name ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=APP_ENV,settings.debug=1 From 97905f565e2f344044e7b83c58dbb412941dd083 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 20:39:40 +0100 Subject: [PATCH 056/182] Added rolling restart --- .github/workflows/dockerimage.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 4adbce8d..d5ff70ad 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -82,3 +82,6 @@ jobs: - name: Install through helm if: failure() run: helm install --name ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=APP_ENV,settings.debug=1 + - name: Rollout new containers + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' + run: kubectl rollout restart --kubeconfig="kubeconfig.yaml" From 97c28bbd8c84b98ad3944e648d124a8cc57fdf20 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 20:40:26 +0100 Subject: [PATCH 057/182] bugfix --- .github/workflows/dockerimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index d5ff70ad..17c833da 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -81,7 +81,7 @@ jobs: run: helm upgrade ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true - name: Install through helm if: failure() - run: helm install --name ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=APP_ENV,settings.debug=1 + run: helm install --name ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=APP_ENV,settings.debug=1 - name: Rollout new containers if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: kubectl rollout restart --kubeconfig="kubeconfig.yaml" From 2b01afe1f0a0820a482ad84fcd6dba0d50ae2815 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 Nov 2019 20:40:26 +0100 Subject: [PATCH 058/182] bugfix --- .github/workflows/dockerimage.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index d5ff70ad..d2c5a329 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -81,7 +81,7 @@ jobs: run: helm upgrade ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true - name: Install through helm if: failure() - run: helm install --name ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=APP_ENV,settings.debug=1 - - name: Rollout new containers - if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' - run: kubectl rollout restart --kubeconfig="kubeconfig.yaml" + run: helm install --name ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=APP_ENV,settings.debug=1 + # - name: Rollout new containers + # if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' + # run: kubectl rollout restart --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV From 8ebae01e6e962201d95735f88d52fd84e4f3b5ab Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 28 Nov 2019 07:08:16 +0100 Subject: [PATCH 059/182] Removed default load balancer --- .github/workflows/dockerimage.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 4818c59c..ffb94a4e 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -79,10 +79,10 @@ jobs: - name: Deploy through helm id: helm-install if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' - run: helm upgrade ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1,settings.loadbalancerEnabled=true + run: helm upgrade ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Install through helm if: failure() run: helm install --name ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=APP_ENV,settings.debug=1 - # - name: Rollout new containers - # if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' - # run: kubectl rollout restart --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + - name: Rollout new containers + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' + run: kubectl rollout restart --kubeconfig="kubeconfig.yaml" From b2e78533efb43804b0fbcac8dc4c860f49496975 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 28 Nov 2019 15:37:09 +0100 Subject: [PATCH 060/182] Added rollout --- .github/workflows/dockerimage.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index ffb94a4e..4ee3a2c6 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -85,4 +85,7 @@ jobs: run: helm install --name ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=APP_ENV,settings.debug=1 - name: Rollout new containers if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' - run: kubectl rollout restart --kubeconfig="kubeconfig.yaml" + run: | + kubectl rollout restart deployment/${{ secrets.APP_NAME }}-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + kubectl rollout restart deployment/${{ secrets.APP_NAME }}-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + kubectl rollout restart deployment/${{ secrets.APP_NAME }}-varnish --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV From eedca34c3769bfe31eb6c1bf17ec494dde078f11 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 28 Nov 2019 15:41:33 +0100 Subject: [PATCH 061/182] bug fix --- .github/workflows/dockerimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 4ee3a2c6..ded88c92 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -82,7 +82,7 @@ jobs: run: helm upgrade ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Install through helm if: failure() - run: helm install --name ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=APP_ENV,settings.debug=1 + run: helm install --name ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Rollout new containers if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: | From 2c133d71ef99ce81045c6c4b6690367c7a2cc2e3 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 28 Nov 2019 16:53:44 +0100 Subject: [PATCH 062/182] Bug fix for when a property has no groups --- api/src/Swagger/SwaggerDecorator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 045ef50c..02e872d2 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -407,6 +407,7 @@ private function getAdditionalEntityDocs($entity) $docblock = $factory->create($property->getDocComment()); $tags = $docblock->getTags(); $atributes = []; + $groups = []; foreach ($tags as $tag) { $name = $tag->getName(); From e9feaa3e15dd283a5c2523bba4016c0c10d71f43 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 10:41:02 +0100 Subject: [PATCH 063/182] Testing with setting environment variable from .env --- .github/workflows/test.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..0455bf49 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,21 @@ +name: Test + +on: + pull_request: + branches: + - dev-robert + push: + branches: + - dev-robert + +jobs: + + build: + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - run: | + echo ::set-env name APP_BUILD::$(grep APP_VERSION= .env | cut -d '=' -f2) + echo echo "set APP_BUILD to $APP_BUILD" + From dc47c2731175eaa37a9338e1c5ef844c35d7b2ae Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 10:42:28 +0100 Subject: [PATCH 064/182] Fix on syntax --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0455bf49..5456956d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,6 +16,6 @@ jobs: steps: - uses: actions/checkout@v1 - run: | - echo ::set-env name APP_BUILD::$(grep APP_VERSION= .env | cut -d '=' -f2) + echo ::set-env name=APP_BUILD::$(grep APP_VERSION= .env | cut -d '=' -f2) echo echo "set APP_BUILD to $APP_BUILD" From 1e7f393e1ccf9fe11ebc3dd8ffc8f7e35b65ee15 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 10:47:47 +0100 Subject: [PATCH 065/182] More testing with GREP --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5456956d..8ffbed08 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,6 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 + - run: grep APP_VERSION= .env - run: | echo ::set-env name=APP_BUILD::$(grep APP_VERSION= .env | cut -d '=' -f2) echo echo "set APP_BUILD to $APP_BUILD" From d7c4b61ddab17e2a9b834661d38f8fafaa3f10e8 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 10:49:41 +0100 Subject: [PATCH 066/182] Even more testing --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8ffbed08..1416c067 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - - run: grep APP_VERSION= .env + - run: grep APP_VERSION= .env | cut -d '=' -f2 - run: | echo ::set-env name=APP_BUILD::$(grep APP_VERSION= .env | cut -d '=' -f2) echo echo "set APP_BUILD to $APP_BUILD" From f22b4064a6db25bdc10c47fdef72478661e43d56 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 10:53:05 +0100 Subject: [PATCH 067/182] Export instead of set:: --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1416c067..37b67f81 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,6 @@ jobs: - uses: actions/checkout@v1 - run: grep APP_VERSION= .env | cut -d '=' -f2 - run: | - echo ::set-env name=APP_BUILD::$(grep APP_VERSION= .env | cut -d '=' -f2) + export APP_BUILD=$(grep APP_VERSION= .env | cut -d '=' -f2) echo echo "set APP_BUILD to $APP_BUILD" From e73549da0a70acd4a4f6cd9531a99f023a429238 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 10:54:25 +0100 Subject: [PATCH 068/182] Passing between steps? --- .github/workflows/dockerimage.yml | 2 +- .github/workflows/test.yml | 1 + .idea/workspace.xml | 39 ++++++++++++++++++++++++++++--- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index ded88c92..77feb89b 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -38,7 +38,7 @@ jobs: - name: Print definitive APP_ENV run: echo "APP_ENV is now $APP_ENV" - name: Build the Docker image - run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV + run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV APP_BUILD=$APP_BUILD - name: Run the docker image run: docker-compose up -d - name: Taking some sleep diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 37b67f81..8736609f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,4 +19,5 @@ jobs: - run: | export APP_BUILD=$(grep APP_VERSION= .env | cut -d '=' -f2) echo echo "set APP_BUILD to $APP_BUILD" + - run: echo "APP_BUILD is now $APP_BUILD" diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 63cda310..8f27ec44 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,8 +1,9 @@ - + + @@ -226,6 +255,10 @@ - \ No newline at end of file From 8a0bb6983e88b8d51c19679343bd83dbbdc1b45d Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 11:05:41 +0100 Subject: [PATCH 069/182] export to set-env --- .github/workflows/test.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8736609f..73e2c532 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,8 @@ jobs: - uses: actions/checkout@v1 - run: grep APP_VERSION= .env | cut -d '=' -f2 - run: | - export APP_BUILD=$(grep APP_VERSION= .env | cut -d '=' -f2) - echo echo "set APP_BUILD to $APP_BUILD" + export VERSION=$(grep APP_VERSION= .env | cut -d '=' -f2) + echo ::set-env name=APP_BUILD::$VERSION + echo "set APP_BUILD to $APP_BUILD" - run: echo "APP_BUILD is now $APP_BUILD" From 8066e7afb597da94d2b8fc3a95fe56d46ee69d28 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 2 Dec 2019 11:22:16 +0100 Subject: [PATCH 070/182] Updates on the design desicions --- DESIGN.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 34ff5696..01221282 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -36,7 +36,7 @@ Welcome, you are currently viewing the design decisions for the proto component. The European factor ------- -The proto-component isn't just a Dutch Component, it is in essence a Dutch translation of European components, nowhere is this more obvious than in the core code. Our component is based on [API Platform](https://api-platform.com/) an API specific version of the symfony framework. This framework is build by the lovely people of []() and is build with support of the European Commission trough the [EU-FOSSA Hackathon](https://ec.europa.eu/info/news/first-eu-fossa-hackathon-it-happened-2019-may-03_en) and Digital Ocean trough [Hacktoberfest](https://hacktoberfest.digitalocean.com/). +The proto-component isn't just a Dutch Component, it is in essence a Dutch translation of European components, nowhere is this more obvious than in the core code. Our component is based on [API Platform](https://api-platform.com/) an API specific version of the symfony framework. This framework is build by the lovely people of [Les Tilleuls](https://les-tilleuls.coop/en) and is build with support of the European Commission trough the [EU-FOSSA Hackathon](https://ec.europa.eu/info/news/first-eu-fossa-hackathon-it-happened-2019-may-03_en) and Digital Ocean trough [Hacktoberfest](https://hacktoberfest.digitalocean.com/). But it doesn't just end there. The [varnish container](https://hub.docker.com/r/eeacms/varnish/) that we use to speed up the API response is build and maintained by [EEA]() (The European Environment Agency) and the development team at conduction itself is attached to the [Odyssey program](https://www.odyssey.org/) and originated from the [startupinresidence](https://startupinresidence.com/) program. @@ -46,11 +46,13 @@ On standards and standardization ------- The specific goal of the proto component (which this current code base is a version of) is to provide a common architecture for common ground components. As such the common ground principles are leading in design choices, and within those principles international compliancy and technological invocation is deemed most important. **We do not want to make concessions to the current infrastructure.** As such the component might differ on [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index) and or other standards if they are deemed incompatible or out of line with (inter)national standards and or good practices. -Unfortunatly (inter)national standards standards can be conflicting. We therefore prioritize standards on two grounds +Unfortunatly (inter)national standards standards can be conflicting. We therefore prioritize standards on sevarl grounds -- International standards are put before local standards +- International is put before local - Standards caried by a standard organisation (like ISO, W3C etc) at put before floating standards (like RFC's) wichs are put before industraty standards, good practices and so on. +So if for instance a **local** standard is out of line with an **internation** good practice we follow the international good practice. + ### Commonground specific standards This component was designed in line with the [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index), [commonground principles](https://vng.nl/onderwerpenindex/bestuur/samen-organiseren-2019/common-ground). From 30f752eb1358d80056a98eb4919dcde550219887 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 11:23:54 +0100 Subject: [PATCH 071/182] Set APP_BUILD --- .github/workflows/dockerimage.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 77feb89b..df6a1ae8 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -24,16 +24,24 @@ jobs: - name: Setting APP_ENV to dev run: | echo ::set-env name=APP_ENV::dev + echo ::set-env name=APP_BUILD::dev echo "set APP_ENV to $APP_ENV" - name: Setting APP_ENV to prod if: contains( github.ref, 'master' ) || contains( github.base_ref, 'master' ) run: | echo ::set-env name=APP_ENV::prod echo "set APP_ENV to $APP_ENV" + - name: Set APP_BUILD to APP_VERSION + if: contains( github.ref, 'master' ) + run: | + export VERSION=$(grep APP_VERSION= .env | cut -d '=' -f2) + echo ::set-env name=APP_BUILD::$VERSION + echo "set APP_BUILD to $APP_BUILD" - name: Setting APP_ENV to stag if: contains( github.ref, 'staging' ) || contains( github.base_ref, 'staging' ) run: | echo ::set-env name=APP_ENV::stag + echo ::set-env name=APP_BUILD::stag echo "set APP_ENV to $APP_ENV" - name: Print definitive APP_ENV run: echo "APP_ENV is now $APP_ENV" From 764b61a0a0d073cbec16d9725256955f7dc144fa Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 11:25:56 +0100 Subject: [PATCH 072/182] APP NAME testen --- .github/workflows/dockerimage.yml | 5 +++++ .github/workflows/test.yml | 4 ++++ .idea/workspace.xml | 15 +++++++++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index df6a1ae8..35a1ff59 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -21,6 +21,11 @@ jobs: - uses: actions/checkout@v1 - name: Pulling old images, if any run: docker-compose pull --ignore-pull-failures + - name: Setting APP_NAME + run: | + export NAME=$(grep APP_NAME= .env | cut -d '=' -f2) + echo ::set-env name=APP_NAME::$NAME + echo "set APP_NAME to $APP_NAME" - name: Setting APP_ENV to dev run: | echo ::set-env name=APP_ENV::dev diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 73e2c532..f7f59574 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,4 +21,8 @@ jobs: echo ::set-env name=APP_BUILD::$VERSION echo "set APP_BUILD to $APP_BUILD" - run: echo "APP_BUILD is now $APP_BUILD" + - run: | + export NAME=$(grep APP_NAME= .env | cut -d '=' -f2) + echo ::set-env name=APP_NAME::$NAME + echo "set APP_NAME to $APP_NAME" diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 8f27ec44..1797973c 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,9 +1,8 @@ - + - @@ -259,6 +265,7 @@ - \ No newline at end of file From 435a44df66fe03e354d0107ea73726cda6d06efd Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 11:26:26 +0100 Subject: [PATCH 073/182] Passing to next? --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f7f59574..23273fc5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,4 +25,4 @@ jobs: export NAME=$(grep APP_NAME= .env | cut -d '=' -f2) echo ::set-env name=APP_NAME::$NAME echo "set APP_NAME to $APP_NAME" - + - run: echo "APP_NAME is now $APP_NAME" From e375777dde08c3ade0e0a43b42d542e067a43ac0 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 2 Dec 2019 11:27:33 +0100 Subject: [PATCH 074/182] Docker compose update --- .env | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.env b/.env index 0380f3ac..66007731 100644 --- a/.env +++ b/.env @@ -18,6 +18,8 @@ APP_VERSION=V.0.1 APP_DEBUG=1 # What is the enviroment type you want to use for local production? (choose between dec,stag,prod, acce or test) APP_ENV=dev +# We use a build to tag images, this is swithced to the version on master and to env on other branches +APP_BUILD=dev # The description for this api APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' From 402e180413964b24ac0cab03a935e015d5b42245 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 11:36:37 +0100 Subject: [PATCH 075/182] removing test workflow --- .github/workflows/test.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 23273fc5..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Test - -on: - pull_request: - branches: - - dev-robert - push: - branches: - - dev-robert - -jobs: - - build: - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - run: grep APP_VERSION= .env | cut -d '=' -f2 - - run: | - export VERSION=$(grep APP_VERSION= .env | cut -d '=' -f2) - echo ::set-env name=APP_BUILD::$VERSION - echo "set APP_BUILD to $APP_BUILD" - - run: echo "APP_BUILD is now $APP_BUILD" - - run: | - export NAME=$(grep APP_NAME= .env | cut -d '=' -f2) - echo ::set-env name=APP_NAME::$NAME - echo "set APP_NAME to $APP_NAME" - - run: echo "APP_NAME is now $APP_NAME" From ada871a5c173fd45042339b1aa0681617a68c16a Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 2 Dec 2019 11:37:46 +0100 Subject: [PATCH 076/182] Added automatic release creation --- .github/workflows/dockerimage.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 35a1ff59..9bda97aa 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -102,3 +102,14 @@ jobs: kubectl rollout restart deployment/${{ secrets.APP_NAME }}-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/${{ secrets.APP_NAME }}-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/${{ secrets.APP_NAME }}-varnish --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + - name: Create Release + if: contains( github.ref, 'master' ) + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + with: + tag_name: $APP_BUILD + release_name: $APP_BUILD + draft: false + prerelease: false From 8ed7e764c604862c0340fb66ed4a31f3fa1ae002 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 11:46:02 +0100 Subject: [PATCH 077/182] fix on build args --- .github/workflows/dockerimage.yml | 2 +- .idea/workspace.xml | 36 +++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 35a1ff59..f4111e45 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -51,7 +51,7 @@ jobs: - name: Print definitive APP_ENV run: echo "APP_ENV is now $APP_ENV" - name: Build the Docker image - run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV APP_BUILD=$APP_BUILD + run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV --build-arg APP_BUILD=$APP_BUILD - name: Run the docker image run: docker-compose up -d - name: Taking some sleep diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 1797973c..86564d40 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -237,7 +237,35 @@ @@ -266,6 +294,10 @@ - \ No newline at end of file From fa9f508a376a432efd6ff0c1659589b029c6c564 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 11:49:07 +0100 Subject: [PATCH 078/182] Removed APP_NAME from secrets, added continue-on-error --- .github/workflows/dockerimage.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index f4111e45..1ef45dfa 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -92,10 +92,11 @@ jobs: - name: Deploy through helm id: helm-install if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' - run: helm upgrade ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 + run: helm upgrade $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 + continue-on-error: true - name: Install through helm if: failure() - run: helm install --name ${{ secrets.APP_NAME }}-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 + run: helm install --name $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Rollout new containers if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: | From 227514cbdc8a5d70be4fe5f244a55b563df4ee68 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 11:51:58 +0100 Subject: [PATCH 079/182] Issue with APP_NAME --- .github/workflows/dockerimage.yml | 1 + .idea/workspace.xml | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 1ef45dfa..379a3255 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -26,6 +26,7 @@ jobs: export NAME=$(grep APP_NAME= .env | cut -d '=' -f2) echo ::set-env name=APP_NAME::$NAME echo "set APP_NAME to $APP_NAME" + - run: echo "APP_NAME = $APP_NAME" - name: Setting APP_ENV to dev run: | echo ::set-env name=APP_ENV::dev diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 86564d40..ffac64a7 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,7 +3,6 @@ - @@ -298,6 +311,8 @@ - \ No newline at end of file From d6d0a1f50dc5be9b8029edbc8b36e1cd201af296 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 2 Dec 2019 11:56:23 +0100 Subject: [PATCH 080/182] Error fix --- DESIGN.md | 12 ++++++------ api/src/Swagger/SwaggerDecorator.php | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 01221282..7cc0df69 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -71,14 +71,14 @@ api-01, api-02, api-03, api-05, api-06, api-10, api-11, api-12, api-13,api-14, a ** We do not implement ** - [api-04](https://docs.geostandaarden.nl/api/API-Strategie/#api-04) Define interfaces in Dutch unless there is an official English glossary (see [english](#english)) -- [api-09](https://docs.geostandaarden.nl/api/API-Strategie/#api-09) Implement custom representation if supported see [fields](#fields)) +- [api-09](https://docs.geostandaarden.nl/api/API-Strategie/#api-09) Implement custom representation if supported (see [fields](#fields)) - [api-17](https://docs.geostandaarden.nl/api/API-Strategie/#api-17) Publish documentation in Dutch unless there is existing documentation in English or there is an official English glossary (see [english](#english)) - [api-31](https://docs.geostandaarden.nl/api/API-Strategie/#api-31) Use the query parameter sorteer to sort (see [ordering](#ordering)) - [api-32](https://docs.geostandaarden.nl/api/API-Strategie/#api-32) Use the query parameter zoek for full-text search (see [search](#search)) - [api-36](https://docs.geostandaarden.nl/api/API-Strategie/#api-36) Provide a POST endpoint for GEO queries (see [queries](#queries)) - [api-37](https://docs.geostandaarden.nl/api/API-Strategie/#api-37) Support mixed queries at POST endpoints available (see [queries](#queries)) -*[api-38](https://docs.geostandaarden.nl/api/API-Strategie/#api-38) Put results of a global spatial query in the relevant geometric context (see [queries](#queries)) -- +- [api-38](https://docs.geostandaarden.nl/api/API-Strategie/#api-38) Put results of a global spatial query in the relevant geometric context (see [queries](#queries)) + ** We doubt or havn't made a choice yet about** @@ -90,12 +90,12 @@ api-01, api-02, api-03, api-05, api-06, api-10, api-11, api-12, api-13,api-14, a NLX ------- We implement the [NLX system](https://docs.nlx.io/understanding-the-basics/introduction/) as part of the basic commonground infrastructure, as such nlx headers are used in the internal logging. -The following X-NLX headers have been implemented for that reason `X-NLX-Logrecord-ID`,`X-NLX-Request-Process-Id`,`X-NLX-Request-Data-Elements` and `X-NLX-Request-Data-Subject`, these are tied to the internal audit trail (see audit trail for more information), and `X-Audit-Toelichting` (from the ZGW APIs) is implemented as `X-Audit-Clarification` - -We do not use other NLX headers since they (conform to the [NLX schema](https://docs.nlx.io/further-reading/transaction-logs/))wil not reach the provider. Please note that the use of nlx is optional. The component can be used without NLX. In that case the `X-NLX` header should be set to false, the `X-NLX-Logrecord-ID` should be provided with an log record designd by the client application to be retracable to a unique user and action. Other headers still aplly. +The following X-NLX headers have been implemented for that reason `X-NLX-Logrecord-ID`,`X-NLX-Request-Process-Id`,`X-NLX-Request-Data-Elements` and `X-NLX-Request-Data-Subject`, these are tied to the internal audit trail (see audit trail for more information), and `X-Audit-Toelichting` (from the ZGW APIs) is implemented as `X-Audit-Clarification`. We do not use other NLX headers since they (conform to the [NLX schema](https://docs.nlx.io/reference-information/transaction-log-headers/)) wil not reach the provider. We strongly discourage the use of the `X-NLX-Request-Data-Subject` header as it might allow private data (such as BSNs) to show up in logging. +Please note that the use of nlx is optional. The component can be used without NLX. In that case do not provide an `X-NLX-Logrecord-ID` but instead do + English ------- The [NL API Standard](https://geonovum.github.io/KP-APIs/#api-04-define-interfaces-in-dutch-unless-there-is-an-official-english-glossary) describes that there is a preference for Dutch in API documentation. diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 02e872d2..3287c7eb 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -127,6 +127,12 @@ public function normalize($object, $format = null, array $context = []) // Oke dit is echt but lelijk $schemas = (array) $docs['definitions']; foreach ($schemas as $schemaName => $schema) { + + // We can only merge if we actually have content + if(!in_array ($schemaName, $additionalDocs)){ + continue; + } + $additionalDocs[$schemaName] = array_merge((array) $schema, $additionalDocs[$schemaName]); $properties = (array) $schema['properties']; From aecf399b8951abe1864e6b20a4ea922ce9932bcf Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 12:00:21 +0100 Subject: [PATCH 081/182] Housekeeping --- .github/workflows/dockerimage.yml | 4 ++-- .idea/workspace.xml | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 379a3255..89ac99eb 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -25,8 +25,8 @@ jobs: run: | export NAME=$(grep APP_NAME= .env | cut -d '=' -f2) echo ::set-env name=APP_NAME::$NAME - echo "set APP_NAME to $APP_NAME" - - run: echo "APP_NAME = $APP_NAME" + - name: Print app name + run: echo "APP_NAME = $APP_NAME" - name: Setting APP_ENV to dev run: | echo ::set-env name=APP_ENV::dev diff --git a/.idea/workspace.xml b/.idea/workspace.xml index ffac64a7..980cc0cb 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -278,7 +278,14 @@ @@ -313,6 +320,7 @@ - \ No newline at end of file From aa3457430956a394e40bca9a388f9c88ec49baa4 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 2 Dec 2019 13:02:25 +0100 Subject: [PATCH 082/182] Changes and spelling fixes --- DESIGN.md | 115 +++++++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 57 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 7cc0df69..cffb8595 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -14,10 +14,10 @@ Welcome, you are currently viewing the design decisions for the proto component. - [Search](#search) - [Queries](#queries) - [Extending](#extending) -- [Timetravel](#timetravel) +- [Time travel](#timetravel) - [Archivation](#archivation) -- [Audittrail](#audittrail) -- [Healthchecks](#healthchecks) +- [Audit trail](#audittrail) +- [Health checks](#healthchecks) - [Notifications](#notifications) - [Authentication](#authentication) - [Authorization](#authorization) @@ -29,7 +29,7 @@ Welcome, you are currently viewing the design decisions for the proto component. *Implementation choices* - [Api Versioning](#api-versioning) -- [Environments and namespacing](#environments-and-namespacing) +- [Environments and name spacing](#environments-and-namespacing) - [Domain Build-up and routing](#domain-build-up-and-routing) - [Container Setup](#container-setup) @@ -46,12 +46,12 @@ On standards and standardization ------- The specific goal of the proto component (which this current code base is a version of) is to provide a common architecture for common ground components. As such the common ground principles are leading in design choices, and within those principles international compliancy and technological invocation is deemed most important. **We do not want to make concessions to the current infrastructure.** As such the component might differ on [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index) and or other standards if they are deemed incompatible or out of line with (inter)national standards and or good practices. -Unfortunatly (inter)national standards standards can be conflicting. We therefore prioritize standards on sevarl grounds +Unfortunately (inter)national standards can be conflicting. We therefore prioritize standards on several grounds - International is put before local -- Standards caried by a standard organisation (like ISO, W3C etc) at put before floating standards (like RFC's) wichs are put before industraty standards, good practices and so on. +- Standards carried by a standard organization (like ISO, W3C etc) at put before floating standards (like RFC's) wichs are put before industry standards, good practices and so on. -So if for instance a **local** standard is out of line with an **internation** good practice we follow the international good practice. +So if for instance a **local** standard is out of line with an **international** good practice we follow the international good practice. ### Commonground specific standards @@ -59,14 +59,14 @@ This component was designed in line with the [NL API Strategie](https://docs.geo ## NL API Strategie -The [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie) takes a special place in this component, it is designed as a set of guidelines for API's for the dutch landscape. As such we follow it as close as posible. It dos however contains inconsistenies with both international standards and good practices. On those items we do not follow the norm but consider it our duty to try to change the norm. +The [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie) takes a special place in this component, it is designed as a set of guidelines for API's for the Dutch landscape. As such we follow it as close as possible. It dos however contains inconsistencies with both international standards and good practices. On those items we do not follow the norm but consider it our duty to try to change the norm. ** We implement ** api-01, api-02, api-03, api-05, api-06, api-10, api-11, api-12, api-13,api-14, api-16, api-18, api-19, api-20, api-21, api-22, api-23, api-24, api-25, api-26, api-27, api-28, api-29, api-30, api-33, api-34, api-35, api-42 ** We want to implement ** -- [api-14](https://docs.geostandaarden.nl/api/API-Strategie/#api-14) Use OAuth 2.0 for authorisation +- [api-14](https://docs.geostandaarden.nl/api/API-Strategie/#api-14) Use OAuth 2.0 for authorization ** We do not implement ** @@ -80,9 +80,9 @@ api-01, api-02, api-03, api-05, api-06, api-10, api-11, api-12, api-13,api-14, a - [api-38](https://docs.geostandaarden.nl/api/API-Strategie/#api-38) Put results of a global spatial query in the relevant geometric context (see [queries](#queries)) -** We doubt or havn't made a choice yet about** +** We doubt or haven’t made a choice yet about** -- [api-15](https://docs.geostandaarden.nl/api/API-Strategie/#api-15) Use PKIoverheid certificates for access-restricted or purpose-limited API authentication +- [api-15](https://docs.geostandaarden.nl/api/API-Strategie/#api-15) Use PKI overheid certificates for access-restricted or purpose-limited API authentication - [api-39](https://docs.geostandaarden.nl/api/API-Strategie/#api-39) Use ETRS89 as the preferred coordinate reference system (CRS) - [api-40](https://docs.geostandaarden.nl/api/API-Strategie/#api-40) Pass the coordinate reference system (CRS) of the request and the response in the headers - [api-41](https://docs.geostandaarden.nl/api/API-Strategie/#api-41) Use content negotiation to serve different CRS @@ -94,7 +94,7 @@ The following X-NLX headers have been implemented for that reason `X-NLX-Logreco We strongly discourage the use of the `X-NLX-Request-Data-Subject` header as it might allow private data (such as BSNs) to show up in logging. -Please note that the use of nlx is optional. The component can be used without NLX. In that case do not provide an `X-NLX-Logrecord-ID` but instead do +Please note that the use of nlx is optional. The component can be used without NLX. In that case set `X-NLX-Logrecord-ID` to false and provide (the normaly ignored) fields `X-NLX-Requester-User-Id`, `X-NLX-Request-Application-Id`, `X-NLX-Request-Subject-Identifier`, `X-NLX-Requester-Claims` and `X-NLX-Request-User` as if you are making an NLX call. This provides the API with enough credentials to make an complete audit trail. It also provides an easy implementation route to NLX since the only thing that would need to be changed at a later time is making you call to an nlx outway instead of the API directly. English ------- @@ -102,7 +102,7 @@ The [NL API Standard](https://geonovum.github.io/KP-APIs/#api-04-define-interfac > Define resources and the underlying entities, fields and so on (the information model ad the external interface) in Dutch. English is allowed in case there is an official English glossary. -We view this as a breach with good coding practice and international coding standards, all documentation and code is therefore supplied in English. We do however provide transaltion (or i18n) support. +We view this as a breach with good coding practice and international coding standards, all documentation and code is therefore supplied in English. We do however provide translation (or i18n) support. Fields ------- @@ -110,49 +110,24 @@ A part of the [haal centraal](https://raw.githubusercontent.com/VNG-Realisatie/H Search ------- -As part of [api-32](https://docs.geostandaarden.nl/api/API-Strategie/#api-32) a `zoeken` query has been itroduced that can handle wildcards. This breaks best practice, first of allest practice is a `search` query parameter (see also the nodes on [English](#english)). Secondly wildcards are a sql concept, not a webconcept, they are also a rather old concept severly limiting the search options provided. Instead the [regeular expresion standard](https://en.wikipedia.org/wiki/Regular_expression) should be used. +As part of [api-32](https://docs.geostandaarden.nl/api/API-Strategie/#api-32) a `zoeken` query has been introduced that can handle wildcards. This breaks best practice, first of allest practice is a `search` query parameter (see also the nodes on [English](#english)). Secondly wildcards are a sql concept, not a webconcept, they are also a rather old concept severely limiting the search options provided. Instead the [regular expression standard](https://en.wikipedia.org/wiki/Regular_expression) should be used. __solution__ We implement a `search` query parameter on resource collections, that filters with regex. Queries ------- -In several examples of the nl apistrategie we see query parameters being atached to post requests. This is unusual in the sence that sending query strings allong with a post is ocnsiderd bad practice (becouse query parameters end up as part of an url and are therfore logged by servers). But is is technically posile folowing RFC 3986. The real pain is that in the NL api-stratgie the POST requests seems to be used to search, ot in other words GET data. This is where compliance with HTTP (1.1) breaks. +In several examples of the nl api strategie we see query parameters being attached to post requests. This is unusual in the sence that sending query strings along with a post is considered bad practice (because query parameters end up as part of an url and are therefore logged by servers). But it is technically possible folowing RFC 3986. The real pain is that in the NL api-stratgie the POST requests seems to be used to search, ot in other words GET data. This is where compliance with HTTP (1.1) breaks. __solution__ We do not implement a query endpoint on post requests. - -Domain Build-up and routing -------- -By convention the component assumes that you follow the common ground domain name build up, meaning {environment}.{component}.{rest of domain}. That means that only the first two url parts are used for routing. It is also assumed that when no environment is supplied the production environment should be offered E.g. a proper domain for the production API of the verzoeken registratie component would be prod.vrc.zaakonline.nl but it should also be reachable under vrc.zaakonline.nl. The proper location for the development environment should always be dev.vrc.zaakonlin.nl - -Environments and namespacing -------- -We assume that for that you want to run several environments for development purposes. We identify the following namespaces for support. -- prod (Production) -- acce (Acceptation) -- stag (Staging) -- test (Testing) -- dev (Development) - -Because we base the common ground infrastructure on kubernetes, and we want to keep a hard separation between environment we also assume that you are using your environment as a namespace - -Symfony library management gives us the option to define the libraries on a per environment base, you can find that definition in the [bundle config](api/config/bundles.php) - -Besides the API environments the component also ships with additional tools/environments but those are not meant to be deployed -- client (An react client frontend) -- admin (An read admin interface) - -On the local development docker deploy the client environment is used as default instead of the production version of the api. - Api Versioning ------- -As per [landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning) major versions in endpoint minor versions in header, for this the `API-Version` is used (instead of the `api-version` header used in haal centraal) - +As per [landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning) we provide/ask major versions in the endpoint and minor versions in header, for this the `API-Version` is used (instead of the `api-version` header used in haal centraal) __solution__ -The fields parameter and functionality has been implemented as an array, and should be used that way. We do howver support an comma separted value list. +We implement both endpoint and header versioning Extending ------- @@ -163,7 +138,7 @@ The extend parameter has been implemented as an array Archivation ------- -There is a need (by law) for archivation, meaning that we should only keep resources for a fixed amount of time and delete them there afther. In line with the extending and fields principle whereby we only want resource properties that we need when we needid, it is deemded good practice make a sub resource of the archivation properties. For the archivation proterties the [zgw](https://zaken-api.vng.cloud/api/v1/schema/#operation/zaak_list) is followed and translated to englisch. +There is a need (by law) for archivation, meaning that we should only keep resources for a fixed amount of time and delete them thereafter. In line with the extending and fields principle whereby we only want resource properties that we need when we needed, it is deemed good practice make a sub resource of the archivation properties. For the archivation properties the [zgw](https://zaken-api.vng.cloud/api/v1/schema/#operation/zaak_list) is followed and translated to englisch. ```json @@ -175,15 +150,15 @@ There is a need (by law) for archivation, meaning that we should only keep resou } ``` -This gives us an intresting thought, acording to [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie/#api-10-implement-operations-that-do-not-fit-the-crud-model-as-sub-resources) subresources should have there own endpoint. Therefore we could use a archive sub of a difrend object for archivation rules e.g. /zaken/{uuid}/archivation for a verzoek. This in itself leads credence to the thought that archivation should have its own central crud api. +This gives us an interesting thought, according to [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie/#api-10-implement-operations-that-do-not-fit-the-crud-model-as-sub-resources) sub resources should have their own endpoint. Therefore we could use a archive sub of a different resource for archivation rules e.g. /zaken/{uuid}/archivation for a verzoek. This in itself leads credence to the thought that archivation should have its own central crud api. Audittrail ------- For audittrail we use the base mechanism as provided by [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail), we do however diver on some key point, -- Personal data schould never be part of a log, therefore only the user id with the client should be logged (insted of the name) +- Personal data should never be part of a log, therefore only the user id with the client should be logged (instead of the name) - Besides an endpoint per resource there should be a general enpoint to search all audit trials of a component -- [Timetravel](#timetravel) in combinaition with objects versioning makes the return of complete objects unnecesary. But an auditrail endpoint should support the [extend](#extending) functionalitiy to provide the option of obtaining complete objects. +- [Time travel](#timetravel) in combination with objects versioning makes the return of complete objects unnecessary. But an audit rail endpoint should support the [extend](#extending) functionality to provide the option of obtaining complete objects. __solution__ @@ -193,17 +168,18 @@ Healthchecks ------- From [issue 154](https://github.com/VNG-Realisatie/huwelijksplanner/issues/154) -For healthc +For healthchecks we use the health-json principle (or json-health to stay in line with json-ld and json-hal). This means the any endpoint `should` be capable of providing health information concerning that endpoint and services behind it. __solution__ +The use of a `Content-Type: application/health+json` header returns an health json schema. Notifications ------- -For notifications we do not YET use the current [ZGW standard](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/notificaties) since there is an [dicusion](https://github.com/VNG-Realisatie/gemma-zaken/issues/1427#issuecomment-549272696) about the posible insecurity of sending properties or data objects along with a notification. It also dosn't follow the [web standard](https://www.w3.org/TR/websub/). We wait for the conclusion of that discusion before making an implementation. +For notifications we do not YET use the current [ZGW standard](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/notificaties) since there is an [dicusion](https://github.com/VNG-Realisatie/gemma-zaken/issues/1427#issuecomment-549272696) about the possible insecurity of sending properties or data objects along with a notification. It also doesn’t follow the [web standard](https://www.w3.org/TR/websub/). We wait for the conclusion of that discussion before making an implementation. __solution__ -In compliance with [w3.org](https://www.w3.org/TR/websub/) each endpoint returns an header containing an subscribtion url. That can be used in acordanse with the application to subscribe to both individual objects as collections. whereby collections serve as 'kanalen'. We aim to implement the ZGW notificatie component, but feel that further features on that component would be required to make to be fully suported. We will suply feature requests per issue to support this effort. +In compliance with [w3.org](https://www.w3.org/TR/websub/) each endpoint `should` returns an header containing an subscription url. That can be used in accordance with the application to subscribe to both individual objects as collections whereby collections serve as 'kanalen'. We aim to implement the ZGW notificatie component, but feel that further features on that component would be required to make to be fully supported. We will supply feature requests per issue to support this effort. Authentication ------- @@ -212,17 +188,18 @@ __solution__ Authorization ------- -We implement user scopes as per [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/autorisatie-scopes) standard. But see problems with how the scopes are defined and named, and consider the general setup to be to focused on ZGW (including Dutch naming, zgw specific fields like maxVertrouwlijkheid and a lack of CRUD thinking). There is a further document concerning [Authentication and Authorization](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/authenticatie-autorisatie) that details how we should authenticate users and give them scopes. We agree with the principles of the document on application based authorization and the use of JWT tokens. But disagree on some key technical aspect. Most important being that the architecture doesn't take into consideration the use of one component by several organizations at once. Or scopese per property. +We implement user scopes as per [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/autorisatie-scopes) standard. But see problems with how the scopes are defined and named, and consider the general setup to be to focused on ZGW (including Dutch naming, zgw specific fields like maxVertrouwlijkheid and a lack of CRUD thinking). There is a further document concerning [Authentication and Authorization](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/authenticatie-autorisatie) that details how we should authenticate users and give them scopes. We agree with the principles of the document on application based authorization and the use of JWT tokens. But disagree on some key technical aspect. Most important being that the architecture doesn't take into consideration the use of one component by several organizations at once. Or scopes per property. __solution__ -No solution as of yet, so there is no implementation of Authorization or Scopes. We aim to implement the ZGW authorisatie component, but feel that further features on that component would be required to make to be fully suported. We will suply feature requests per issue to support this effort. +No solution as of yet, so there is no implementation of Authorization or Scopes. We aim to implement the ZGW authorisatie component, but feel that further features on that component would be required to make to be fully supported. We will supply feature requests per issue to support this effort. Timetravel ------- A part of the [haal centraal](https://raw.githubusercontent.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/master/api-specificatie/Bevraging-Ingeschreven-Persoon/openapi.yaml) the concept of timetravel has been introduced, as in getting the version of an object as it was on a given date. For this the `geldigop` [see the docs](file:///C:/Users/ruben/Desktop/doc_gba_historie.html#operation/getBewoningen) header is used. In addition the `geldigvan` and `geldigtot` are introduced as collection filters. -The commonground proto componant natively supports time traveling on all entities that are annotaded with the @Gedmo\Loggable, this is done by adding the ?validOn=[date] query to a request, date can either be a datetime or datedatime string. Any value supported by php's [strtotime()](https://www.php.net/manual/en/function.strtotime.php) is supported. Keep in mind that this returns the entity a as it was valid on that time or better put, the last changed version BEFORE that moment. To get a complete list of all changes on a item the /audittrail endpoint can be used. +The commonground proto componant natively supports time traveling on all resources that are annotaded with the @Gedmo\Loggable, this is done by adding the ?validOn=[date] query to a request, date can either be a datetime or datedatime string. Any value supported by php's [strtotime()](https://www.php.net/manual/en/function.strtotime.php) is supported. Keep in mind that this returns the entity a as it was valid on that time or better put, the last changed version BEFORE that moment. To get a complete list of all changes on an item the [/audittrail](#Audittrail +) endpoint can be used. __solution__ In compliance with [schema.org](https://schema.org/validFrom) `geldigop`,`geldigvan` and `geldigtot` are implemented as `validOn`,`validFrom` and `validUntil`. And can be used a query parameters on collection operations/ @@ -236,7 +213,7 @@ In the [zaak-api](https://zaken-api.vng.cloud/api/v1/schema/#operation/zaak_list Translations ------- -We support translations trough the `Accept-Language` header (read the [docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language)), the fallback langouge for all messages is englisch +We support translations trough the `Accept-Language` header (read the [docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language)), the fallback language for all messages is English Errors ------- @@ -258,7 +235,7 @@ We support both comma and bracket notation on array's, but only document bracket Container Setup ------- - https://medium.com/shiphp/building-a-custom-nginx-docker-image-with-environment-variables-in-the-config-4a0c36c4a617 +https://medium.com/shiphp/building-a-custom-nginx-docker-image-with-environment-variables-in-the-config-4a0c36c4a617 Filtering @@ -270,7 +247,7 @@ __Regex Exact__ __Regex Contains__ __Like___ -The like filters is used to search for enities with the traditional sql LIKE operator. If pattern does not contain percent signs or underscores, then the pattern only represents the string itself; in that case LIKE acts like the equals operator. An underscore (_) in pattern stands for (matches) any single character; a percent sign (%) matches any sequence of zero or more characters. +The like filters is used to search for resources with the traditional sql LIKE operator. If pattern does not contain percent signs or underscores, then the pattern only represents the string itself; in that case LIKE acts like the equals operator. An underscore (_) in pattern stands for (matches) any single character; a percent sign (%) matches any sequence of zero or more characters. Some examples: @@ -278,6 +255,7 @@ Some examples: 'abc' LIKE 'a%' true 'abc' LIKE '_b_' true 'abc' LIKE 'c' false + LIKE pattern matching always covers the entire string. Therefore, if it's desired to match a sequence anywhere within a string, the pattern must start and end with a percent sign. To match a literal underscore or percent sign without matching other characters, the respective character in pattern must be preceded by a backlash. @@ -285,10 +263,32 @@ To match a literal underscore or percent sign without matching other characters, ## Kubernetes ### Loadbalancers -We no longer provide a load balancer per component, since this would require a ip per component. Draining ip's on mult component kubernetes clusters. In stead we make componentes available as an interner service +We no longer provide a load balancer per component, since this would require a IP address per component (and ipv 4 addresses are in short supply). Instead we make components available as an internal service. A central load balancer could then be used to provide several api’s in one ### server naming -A component is (speaking in kubernetes terms) a service that is available at +A component is (speaking in kubernetes terms) a service that is available at a name corresponding to its designation + +### Domain Build-up and routing +By convention the component assumes that you follow the common ground domain name build up, meaning {environment}.{component}.{rest of domain}. That means that only the first two url parts are used for routing. It is also assumed that when no environment is supplied the production environment should be offered E.g. a proper domain for the production API of the verzoeken registratie component would be prod.vrc.zaakonline.nl but it should also be reachable under vrc.zaakonline.nl. The proper location for the development environment should always be dev.vrc.zaakonlin.nl + +### Environments and namespacing +We assume that for that you want to run several environments for development purposes. We identify the following namespaces for support. +- prod (Production) +- acce (Acceptation) +- stag (Staging) +- test (Testing) +- dev (Development) + +Because we base the common ground infrastructure on kubernetes, and we want to keep a hard separation between environment we also assume that you are using your environment as a namespace + +Symfony library management gives us the option to define the libraries on a per environment base, you can find that definition in the [bundle config](api/config/bundles.php) + +Besides the API environments the component also ships with additional tools/environments but those are not meant to be deployed +- client (An react client frontend) +- admin (An read admin interface) + +On the local development docker deploy the client environment is used as default instead of the production version of the api. + ## Data types @@ -327,3 +327,4 @@ A component is (speaking in kubernetes terms) a service that is available at | string | iban | | | | | | | | | | | | + From a42c9db7f1486b6de7ba7eb87b06a4e9faa7dfb8 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 13:21:50 +0100 Subject: [PATCH 083/182] Fix on container rollout --- .github/workflows/dockerimage.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 89ac99eb..0bacadc6 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -101,6 +101,6 @@ jobs: - name: Rollout new containers if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: | - kubectl rollout restart deployment/${{ secrets.APP_NAME }}-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV - kubectl rollout restart deployment/${{ secrets.APP_NAME }}-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV - kubectl rollout restart deployment/${{ secrets.APP_NAME }}-varnish --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + kubectl rollout restart deployment/$APP_NAME-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + kubectl rollout restart deployment/$APP_NAME-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + kubectl rollout restart deployment/$APP_NAME-varnish --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV From 986f549c7ac38371e5ba706842be76d785020b30 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 13:31:24 +0100 Subject: [PATCH 084/182] Style fix on swaggerdecorator --- api/src/Swagger/SwaggerDecorator.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 3287c7eb..28b4d3e5 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -127,12 +127,12 @@ public function normalize($object, $format = null, array $context = []) // Oke dit is echt but lelijk $schemas = (array) $docs['definitions']; foreach ($schemas as $schemaName => $schema) { - - // We can only merge if we actually have content - if(!in_array ($schemaName, $additionalDocs)){ - continue; - } - + + // We can only merge if we actually have content + if (!in_array($schemaName, $additionalDocs)) { + continue; + } + $additionalDocs[$schemaName] = array_merge((array) $schema, $additionalDocs[$schemaName]); $properties = (array) $schema['properties']; From 0f151ff22111dd986bdac02c7a7cfaaedfeaece7 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 2 Dec 2019 13:59:21 +0100 Subject: [PATCH 085/182] Tsja --- api/src/Swagger/SwaggerDecorator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 3287c7eb..51b2169c 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -127,12 +127,12 @@ public function normalize($object, $format = null, array $context = []) // Oke dit is echt but lelijk $schemas = (array) $docs['definitions']; foreach ($schemas as $schemaName => $schema) { - + // We can only merge if we actually have content if(!in_array ($schemaName, $additionalDocs)){ continue; } - + $additionalDocs[$schemaName] = array_merge((array) $schema, $additionalDocs[$schemaName]); $properties = (array) $schema['properties']; From 353ad00515ebd5b76e2eb9a903d50760fee13b02 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 15:10:32 +0100 Subject: [PATCH 086/182] Trying to fix issue caused by continue-on-error --- .github/workflows/dockerimage.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 01f711b8..610fe32c 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -93,11 +93,14 @@ jobs: - name: Deploy through helm id: helm-install if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' - run: helm upgrade $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 + run: | + echo "##[set-output name=success]false" + helm upgrade $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 + echo "##[set-output name=success]true" continue-on-error: true - name: Install through helm if: failure() - run: helm install --name $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 + run: helm install --name $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Rollout new containers if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: | From bbd8b61ca6926e231232872a9d6ee3c00e88bf6c Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 15:27:00 +0100 Subject: [PATCH 087/182] Adding conition for helm install and rollout --- .github/workflows/dockerimage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 610fe32c..cf7dbbdf 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -99,10 +99,10 @@ jobs: echo "##[set-output name=success]true" continue-on-error: true - name: Install through helm - if: failure() + if: steps.helm-install.success == 'false' run: helm install --name $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Rollout new containers - if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' && steps.helm-install.success == 'true' run: | kubectl rollout restart deployment/$APP_NAME-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV From f394cee1fc974e1af641c7e8d704e60bd48db79d Mon Sep 17 00:00:00 2001 From: bbrands02 <57346398+bbrands02@users.noreply.github.com> Date: Mon, 2 Dec 2019 16:17:03 +0100 Subject: [PATCH 088/182] APIProperty removed --- TUTORIAL.md | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/TUTORIAL.md b/TUTORIAL.md index 74aad7ba..4107e573 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -224,18 +224,7 @@ with //... /** * @var \Ramsey\Uuid\UuidInterface - * - * @ApiProperty( - * identifier=true, - * attributes={ - * "openapi_context"={ - * "description" = "The UUID identifier of this object", - * "type"="string", - * "format"="uuid", - * "example"="e2984465-190a-4562-829e-a8cca81aa35d" - * } - * } - * ) + * @example e2984465-190a-4562-829e-a8cca81aa35d * * @Groups({"read"}) * @ORM\Id From ecb9c64c37ab2a3f3b3d1f9c24e74692e61448a5 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 2 Dec 2019 16:26:37 +0100 Subject: [PATCH 089/182] Tekstuele aanpassingen --- TUTORIAL.md | 49 ++++++++++++++++--------------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/TUTORIAL.md b/TUTORIAL.md index 74aad7ba..e736be4d 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -350,36 +350,33 @@ When using Github. To set up a webhook, go to the settings page of your reposito Now every time you update your repository the commonground dev page will alerted, rescan your repository and do al the appropriate platform actions. It just as easy as that. -Automated Testing and Deployment (continues integration) +Continues integration ------- -The following bit of the tutorial requires two additional accounts -- [https://hub.docker.com/](https://hub.docker.com/) (You might already have this for docker for desktop) -- [https://travis-ci.org](https://travis-ci.org) (You can use you github account) +> The following bit of the tutorial requires an additional accounts +> - [https://hub.docker.com/](https://hub.docker.com/) (You might already have this for docker for desktop) -The proto component ships with a pre-fab continues integration script based on travis. What does this mean you ask? Continuous integration (or CI for short) is an optimized and automated way for your code to become part of your projects. In the case of your commonground component that means that we will automatically validate new code commits or pushes and (if everything checks out) build that code and deploy the containers thereof to docker hub. Making is possible to update al the environments that use those components. +The proto component ships with a pre-fab continues integration script based on github action (there is also a travis script in here if you want it). What does this mean you ask? Continuous integration (or CI for short) is an optimized and automated way for your code to become part of your projects. In the case of your commonground component that means that we will automatically validate new code commits or pushes and (if everything checks out) build that code and deploy the containers thereof to docker hub. Making is possible to update al the environments that use those components. Whats even better is that we check your code for known security issues, so whenever a dependency or libary has a security issue you will be notified to take action. -Okay, that's nice, but how do we do that? Actually it is very simple. First of all make sure you have a docker account, log into [docker hub](https://hub.docker.com/) and have a look around. We don't need to create anything just yet, but it is nice to get a feeling of the place. As you can see docker hub also uses repositories etc. So that recognizable. +Okay, that's nice, but how do we do that? Actually it is very simple. You do nothing. The scripts are already enabled by default. Just go to the actions tab of your github repository to see the results whenever you push code. -Next we need to prepare our github repository that holds our code. For the travis script to work as intended we need to create a couple of branches(if we don't have those already) open up your git interface and create a branch called 'development' and a branch called 'staging'. Don't forget to push the branches so that they are present on github (and not just on your local machine). - -Oke just one more place to go and that is travis, head over to [https://travis-ci.org](https://travis-ci.org) and login with your github account. If everything is alright you should see your repository there. Activate it by pressing 'activate repository' and then go to 'More options' -> 'Settings' and scroll down to environment variables. Here we can present travis wit the variables that it need to execute our build script. Lets first set the common variables that we need for all our branches: `DOCKER_PASSWORD` your docker password,`DOCKER_REGISTRY` docker.io/[your username] ,`DOCKER_USERNAME` your docker user name. This will be used by travis to push the completed containers into docker hub. Next we need to specify a couple of variables that are branch specific. Or to be more exact, set the same variable `APP_ENV` with different values for different branches. It needs to be 'staging'->stag,'master'->prod,'development'->dev. - -And all done! Head over back to the code on your computer and make a small change. Then commit push that change into github. Travis should automatically pick op your change and start a build. +There is however a bit of extra here that you can do and that is to insert your docker hub credentials into the repository. You can do that under the settings->secrets tab of yout repoistory by setting a `DOCKERHUB_USERNAME` and `DOCKERHUB_PASSWORD` secret containing (you might have guesed it) your dockerhub username and secret. And all done! Head over back to the code on your computer and make a small change. Then commit push that change into github. Wait for the action to complete and head over to your docker hub repository page. You should find your build containers ready for you. +Continues deployment +------- +> The following bit of the tutorial requires an additional accounts +> - [https://www.digitalocean.com/](https://www.digitalocean.com/) -### Unit / Behat +Actually the repository goes a bit further then just getting your containers ready to deploy, it can acctually deploy them for you! Again all the code is already there. The only thing that you need to do is add a kubeconfig file. You can get a kubeconfig file from a running kubernetes clusters, it provides your repositorie with both the credentials and endpoints it needs to deploy the application. How you get a Kubeconfig file difers a bit from provider to provider. But you can get more inforamtion on that here -TODO +- [Digitalocean](https://www.digitalocean.com/docs/kubernetes/how-to/connect-to-cluster/) +- [Google Cloud](https://cloud.google.com/sdk/gcloud/reference/container/clusters/get-credentials) +- [Amazone AWS](https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html) -### Postman -TODO - -### Trouble shooting -Please make sure that your github repository is set to public, and keep in mind that a complex travis build (and certainly one that includes a pushing of containers can take up to 20 minutes). +Afther you have abtained a kuneconfig you need to save it to your repository as a secret (NEVER COMMIT A KUBECONFIG FILE), use the secret `KUBECONFIG` to save your cubeconfig file. Now simply commit and push your code to your repository and presto! You have a working common-ground component online. Documentation and dockblocks ------- -TODO +You want both your redoc documentation and your code to be readable and reausable to other developers. To this effect we use docblok annotation. You can read more about that [here](https://docs.phpdoc.org/references/phpdoc/basic-syntax.html) but the basic is this, we supply each class and propery with a docblock contained within /\* \* / characters. At the very least we want to describe our properties, the expected results and example data (see the example under [audittrail](#audittrail) Audittrail ------- @@ -440,17 +437,3 @@ class ExampleEntity ``` And now we have a fully nl api strategy integrated audit trail! - - -Setting up automated deployment (continues delivery) -------- -TODO - -## Commonground specific data types -TODO - -### incompleteDate - - -### underInvestigation - From c77e5086586462db1990d616589e7ee9751438c1 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 2 Dec 2019 15:27:41 +0000 Subject: [PATCH 090/182] Apply fixes from StyleCI --- api/src/Swagger/SwaggerDecorator.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 51b2169c..28b4d3e5 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -128,10 +128,10 @@ public function normalize($object, $format = null, array $context = []) $schemas = (array) $docs['definitions']; foreach ($schemas as $schemaName => $schema) { - // We can only merge if we actually have content - if(!in_array ($schemaName, $additionalDocs)){ - continue; - } + // We can only merge if we actually have content + if (!in_array($schemaName, $additionalDocs)) { + continue; + } $additionalDocs[$schemaName] = array_merge((array) $schema, $additionalDocs[$schemaName]); From 89c072333612034560868b7a15eb896db25dfded Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 2 Dec 2019 16:45:57 +0100 Subject: [PATCH 091/182] Removed entity en object descriptions for resources --- TUTORIAL.md | 67 ++++++++++++++++++----------------------------------- 1 file changed, 22 insertions(+), 45 deletions(-) diff --git a/TUTORIAL.md b/TUTORIAL.md index e736be4d..ed149d7b 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -8,7 +8,7 @@ What do you need for this tutorial? * Docker for desktop ## Before you begin -For the steps considering the generation of entities an example entity a availale, feel free to [take a look](https://github.com/ConductionNL/Proto-component-commonground/blob/master/api/src/Entity/ExampleEntity.php) at it if you have trouble figuring out the code. +For the steps considering the generation of resources (or entities as symfony calls them) an example resource a availale, feel free to [take a look](https://github.com/ConductionNL/Proto-component-commonground/blob/master/api/src/Entity/ExampleEntity.php) at it if you have trouble figuring out the code. ## Setting up your enviroment @@ -57,10 +57,10 @@ $ docker volume prune **What are we looking at?** The Common Ground base component provides a bit more than just a development interface, it also includes an example application and a backend that automatically hooks into your api. For now we're just going to focus on our api, but is good to read up on all the features of the Common Ground base component here. -## Adding your own objects -You can now access your api at http://localhost:8080/, as you can see it's pre-loaded with some example objects. Let's replace them with your own objects! +## Adding your own resources +You can now access your api at http://localhost:8080/, as you can see it's pre-loaded with some example resources. Let's replace them with your own resources! -First let's remove the objects currently in the api, we can do that by just removing the entities form our code base, navigate to the folder where you stored your code and open the folder api/src/Entity , you can find the example entities (our name for objects) there. Just delete all the php files in that folder. +First let's remove the resources currently in the api, we can do that by just removing the resources form our code base, navigate to the folder where you stored your code and open the folder api/src/Entity , you can find the example entities (the symfony name for resources) there. Just delete all the php files in that folder. Next let's add our own entities, we can do this in two ways, we can do old fashioned coding, but we can also use the build in maker bundle of the proto component, to quickly generate our entities for us (without the fuss of actual coding). @@ -69,7 +69,7 @@ Let's open a new command line window and navigate to our root folder, exactly li ```CLI $ docker-compose exec php bin/console make:entity ``` -We should now see a wizard that allows us to either make new entities, or add parameters to existing entities (by supplying the name of an existing entity). +We should now see a wizard that allows us to either make new entities, or add parameters to existing entities (by supplying the name of an existing resource). ## Keeping your repository up to date with the Conduction Common Ground component @@ -107,7 +107,7 @@ git merge upstream --allow-unrelated-histories Keep in mind that you wil need to make sure to stay up to date about changes on the Common Ground component repository. ## Renaming your component -Right now the name of your component is 'commonground' that's that's fine while running it locally or in its own kubernetes cluster but wil get you in when running it with other components when it without using a name space. So its good practice to name your component distinctly. But besides al of these practical reasons its of course also just cool to name your child before you unleash it on the unsuspecting common ground community. +Right now the name of your component is `commonground component` and its unique id `cg` that's that's fine while running it locally or in its own kubernetes cluster but wil get you in when running it with other components when it without using a name space. So its good practice to name your component distinctly. But besides al of these practical reasons its of course also just cool to name your child before you unleash it on the unsuspecting common ground community. Oke, so before we can nae the component we need to come up with a name. There are a couple of conventions here. First of the name should tell us what the component does, or is supposed to do with one or two words. So we would normally call an component about dogs the DogComponent and one about cats te CatComponent. The second convention is that we don't usually actually name our component 'component' but indicate its position in de common ground architecture. For that we have the following options: * Catalogus @@ -116,34 +116,11 @@ Oke, so before we can nae the component we need to come up with a name. There ar * Application * Tool -The we need to touch te following files +The actual name change is rather simple doh, just head over to the .env that contains all our config and change the apropriate variables * .env -* dockercompose.yaml -* api/.env -* api/helm/values.yaml -* api/docker/nginx/ -## Adding more openapi documantation - -```php -//... - /** - * @ApiProperty( - * attributes={ - * "openapi_context"={ - * "description" = "The name of a organisation", - * "type"="string", - * "format"="string", - * "example"="My Organisation" - * } - * } - * ) - */ - private $name; -//... -``` - -## Setting up security and access (also helps with serialization) +## Setting up security and access +We want to secure our resources in such a way that only users or applications with propper right can acces and update properties. ```PHP // src/Entity/Organisation.php @@ -169,7 +146,7 @@ class Organisation ``` ## Using validation -Right now we are just accepting data and passing them on to the database, and in a mock or poc context this is fine. Most of the calls will end up being get requests anyway. But in case that we actually want our clients to make post to the api it would be wise to add some validation to the fields we are recieving. Luckely for us the component comes pre packed with a valdiation tool that we can configure from our entity through annotion. If we for example want to make a field required we could do so as follows: +Right now we are just accepting data and passing them on to the database, and in a mock or poc context this is fine. Most of the calls will end up being get requests anyway. But in case that we actually want our clients to make post to the api it would be wise to add some validation to the fields we are recieving. Luckely for us the component comes pre packed with a valdiation tool that we can configure from our resources through annotion. If we for example want to make a field required we could do so as follows: ```PHP // src/Entity/Organisation.php @@ -196,7 +173,7 @@ Keep in mind that we need to add the assert annotation to our class dependencies More inforation on using validation can be found at the [symfony website](https://symfony.com/doc/current/validation.html), but it is als worth nothing that tis component comes pre packed with some typical NL validators like BSN. You can find those [here](). ## Using UUID -As default doctrine uses auto increment integers as identifiers (1,2, etc). For modern web applications we however prefer the use of UUID's. (e.g. e2984465-190a-4562-829e-a8cca81aa35d). Why? Wel for one it is more secure integer id's are easily guessable and make it possible to "ask" endpoint about objects that you should not know about. But UUID's also have a benefit in future proofing the application. If we in the future want to merge a table with another table (for example because two organisations using a component perform a merger) then we would have to reassign al id's and relations if we where using int based id's (both tables would have a row 1,2 etc) with UUID's however the change of doubles range somewhere in the billions. Meaning that it is likely that we only need to either reidentify only a handful of rows or more likely none at al! Turning our entire migration into a copy paste action. +As default doctrine uses auto increment integers as identifiers (1,2, etc). For modern web applications we however prefer the use of UUID's. (e.g. e2984465-190a-4562-829e-a8cca81aa35d). Why? Wel for one it is more secure integer id's are easily guessable and make it possible to "ask" endpoint about resources that you should not know about. But UUID's also have a benefit in future proofing the application. If we in the future want to merge a table with another table (for example because two organisations using a component perform a merger) then we would have to reassign al id's and relations if we where using int based id's (both tables would have a row 1,2 etc) with UUID's however the change of doubles range somewhere in the billions. Meaning that it is likely that we only need to either reidentify only a handful of rows or more likely none at al! Turning our entire migration into a copy paste action. The proto component supports Ramsey's uuid objects strategy out of the box, so to use UUID's as identifier simply we need to add the ApiProperty as a dependency @@ -229,7 +206,7 @@ with * identifier=true, * attributes={ * "openapi_context"={ - * "description" = "The UUID identifier of this object", + * "description" = "The UUID identifier of this resource", * "type"="string", * "format"="uuid", * "example"="e2984465-190a-4562-829e-a8cca81aa35d" @@ -247,7 +224,7 @@ with //.. ``` -and remove the integer on the getter turning this: +and remove the : ?integer on the getter turning this: ```PHP //... @@ -272,7 +249,7 @@ into this and you're all done ### Trouble shooting -If you have already spun your component including your new entity your going to run into some trouble because doctrine is going to try changing your primary key column (id) from an integer to string (tables tend not to like that). In that case its best to just drop your database and reinstall it using the following commands: +If you have already spun your component including your new resource your going to run into some trouble because doctrine is going to try changing your primary key column (id) from an integer to string (tables tend not to like that). In that case its best to just drop your database and reinstall it using the following commands: ```CLI $ bin/console doctrine:schema:drop @@ -281,9 +258,9 @@ $ bin/console doctrine:schema:update --force ## Advanced data sets -Oke lets make it complex, until now we have just added some simple entities to our component, but what if we want to attaches one entity to another? Fortunately our build in database engine support rather complex scenarios called associations. So let [take a look](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html) at that. +Oke lets make it complex, until now we have just added some simple entities to our component, but what if we want to attaches one resource to another? Fortunately our build in database engine support rather complex scenarios called associations. So let [take a look](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html) at that. -Baffled? Wel its rather complex. But remember that Make:entity command that we used earlier? That actually accepts relations as a data type. Or to but it simply instead of using the default 'string' we could just type "ManyToOne" and it will just fire up some questions that will help it determine how you want your relations to be. +Baffled? Wel its rather complex. But remember that make:entity command that we used earlier? That actually accepts relations as a data type. Or to but it simply instead of using the default 'string' we could just type "ManyToOne" and it will just fire up some questions that will help it determine how you want your relations to be. ### Trouble shooting @@ -315,7 +292,7 @@ We can now prevent circular references by setting a max depth on the properties ```PHP //... /** - * @var ArrayCollection $stuffs Some stuff that is attached to this example object + * @var ArrayCollection $stuffs Some stuff that is attached to this example resource * * @MaxDepth(1) * @Groups({"read","write"}) @@ -326,7 +303,7 @@ We can now prevent circular references by setting a max depth on the properties ``` ## Data fixtures -For testing cases it can be useful to use data fixtures a predefined set of data that fills the database of your component at startup. Since we use php classes to describe our objects creating fixtures is easy (you can find an example in your project folder at api/src/DataFixtures). We simply go trough some classes assign values and persist them to the database. Once we have written our fixtures we can use a single command to load them +For testing cases it can be useful to use data fixtures a predefined set of data that fills the database of your component at startup. Since we use php classes to describe our resources creating fixtures is easy (you can find an example in your project folder at api/src/DataFixtures). We simply go trough some classes assign values and persist them to the database. Once we have written our fixtures we can use a single command to load them ```CLI $ bin/console doctrine:fixtures:load --env=dev @@ -352,7 +329,7 @@ Now every time you update your repository the commonground dev page will alerted Continues integration ------- -> The following bit of the tutorial requires an additional accounts +> The following bit of the tutorial requires an additional account > - [https://hub.docker.com/](https://hub.docker.com/) (You might already have this for docker for desktop) The proto component ships with a pre-fab continues integration script based on github action (there is also a travis script in here if you want it). What does this mean you ask? Continuous integration (or CI for short) is an optimized and automated way for your code to become part of your projects. In the case of your commonground component that means that we will automatically validate new code commits or pushes and (if everything checks out) build that code and deploy the containers thereof to docker hub. Making is possible to update al the environments that use those components. Whats even better is that we check your code for known security issues, so whenever a dependency or libary has a security issue you will be notified to take action. @@ -363,10 +340,10 @@ There is however a bit of extra here that you can do and that is to insert your Continues deployment ------- -> The following bit of the tutorial requires an additional accounts +> The following bit of the tutorial requires an additional account > - [https://www.digitalocean.com/](https://www.digitalocean.com/) -Actually the repository goes a bit further then just getting your containers ready to deploy, it can acctually deploy them for you! Again all the code is already there. The only thing that you need to do is add a kubeconfig file. You can get a kubeconfig file from a running kubernetes clusters, it provides your repositorie with both the credentials and endpoints it needs to deploy the application. How you get a Kubeconfig file difers a bit from provider to provider. But you can get more inforamtion on that here +Actually the repository goes a bit further then just getting your containers ready to deploy, it can acctually deploy them for you! Again all the code is already there. The only thing that you need to do is add a kubeconfig file. You can get a kubeconfig file from a running kubernetes clusters, it provides your repository with both the credentials and endpoints it needs to deploy the application. How you get a Kubeconfig file difers a bit from provider to provider. But you can get more information on that here - [Digitalocean](https://www.digitalocean.com/docs/kubernetes/how-to/connect-to-cluster/) - [Google Cloud](https://cloud.google.com/sdk/gcloud/reference/container/clusters/get-credentials) @@ -382,7 +359,7 @@ Audittrail ------- As you might expect the proto-component ships with a neat function for generating audit trails, that basically exist of three parts. -First we need to activate logging on the entities that we want logged (for obvious security reasons we don't log entity changes by default) to do that by adding the `@Gedmo\Loggable` annotation to our php class, which should then look something like: +First we need to activate logging on the entities that we want logged (for obvious security reasons we don't log resource changes by default) to do that by adding the `@Gedmo\Loggable` annotation to our php class, which should then look something like: ```PHP //... From e263f398274dbf608c0fd89674e33cc4a0c6ce73 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Mon, 2 Dec 2019 16:51:27 +0100 Subject: [PATCH 092/182] Rollback of continue on error --- .github/workflows/dockerimage.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index cf7dbbdf..9e8658ca 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -93,13 +93,9 @@ jobs: - name: Deploy through helm id: helm-install if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' - run: | - echo "##[set-output name=success]false" - helm upgrade $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - echo "##[set-output name=success]true" - continue-on-error: true + run: helm upgrade $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Install through helm - if: steps.helm-install.success == 'false' + if: failure() run: helm install --name $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Rollout new containers if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' && steps.helm-install.success == 'true' From 78057468b516a073c345049c943f066a4b535686 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2019 18:59:10 +0000 Subject: [PATCH 093/182] Bump symfony/cache from 4.3.4 to 4.3.9 in /api Bumps [symfony/cache](https://github.com/symfony/cache) from 4.3.4 to 4.3.9. - [Release notes](https://github.com/symfony/cache/releases) - [Changelog](https://github.com/symfony/cache/blob/master/CHANGELOG.md) - [Commits](https://github.com/symfony/cache/compare/v4.3.4...v4.3.9) Signed-off-by: dependabot[bot] --- api/composer.lock | 60 +++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/api/composer.lock b/api/composer.lock index cdf70a77..8f53d27f 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -2229,8 +2229,8 @@ "authors": [ { "name": "Luís Otávio Cobucci Oblonczyk", - "role": "Developer", - "email": "lcobucci@gmail.com" + "email": "lcobucci@gmail.com", + "role": "Developer" } ], "description": "A simple library to work with JSON Web Token and JSON Web Signature", @@ -3025,16 +3025,16 @@ }, { "name": "psr/log", - "version": "1.1.0", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", - "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801", + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801", "shasum": "" }, "require": { @@ -3043,7 +3043,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -3068,7 +3068,7 @@ "psr", "psr-3" ], - "time": "2018-11-20T15:27:04+00:00" + "time": "2019-11-01T11:05:21+00:00" }, { "name": "ralouphie/getallheaders", @@ -3420,16 +3420,16 @@ }, { "name": "symfony/cache", - "version": "v4.3.4", + "version": "v4.3.9", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "1d8f7fee990c586f275cde1a9fc883d6b1e2d43e" + "reference": "2a7bcc592adcaab9efc165bbced5a91fe905fad4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/1d8f7fee990c586f275cde1a9fc883d6b1e2d43e", - "reference": "1d8f7fee990c586f275cde1a9fc883d6b1e2d43e", + "url": "https://api.github.com/repos/symfony/cache/zipball/2a7bcc592adcaab9efc165bbced5a91fe905fad4", + "reference": "2a7bcc592adcaab9efc165bbced5a91fe905fad4", "shasum": "" }, "require": { @@ -3494,20 +3494,20 @@ "caching", "psr6" ], - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-12-01T10:50:31+00:00" }, { "name": "symfony/cache-contracts", - "version": "v1.1.5", + "version": "v1.1.7", "source": { "type": "git", "url": "https://github.com/symfony/cache-contracts.git", - "reference": "ec5524b669744b5f1dc9c66d3c2b091eb7e7f0db" + "reference": "af50d14ada9e4e82cfabfabdc502d144f89be0a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/ec5524b669744b5f1dc9c66d3c2b091eb7e7f0db", - "reference": "ec5524b669744b5f1dc9c66d3c2b091eb7e7f0db", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/af50d14ada9e4e82cfabfabdc502d144f89be0a1", + "reference": "af50d14ada9e4e82cfabfabdc502d144f89be0a1", "shasum": "" }, "require": { @@ -3552,7 +3552,7 @@ "interoperability", "standards" ], - "time": "2019-06-13T11:15:36+00:00" + "time": "2019-10-04T21:43:27+00:00" }, { "name": "symfony/config", @@ -6313,16 +6313,16 @@ }, { "name": "symfony/service-contracts", - "version": "v1.1.6", + "version": "v1.1.8", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3" + "reference": "ffc7f5692092df31515df2a5ecf3b7302b3ddacf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ea7263d6b6d5f798b56a45a5b8d686725f2719a3", - "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ffc7f5692092df31515df2a5ecf3b7302b3ddacf", + "reference": "ffc7f5692092df31515df2a5ecf3b7302b3ddacf", "shasum": "" }, "require": { @@ -6367,7 +6367,7 @@ "interoperability", "standards" ], - "time": "2019-08-20T14:44:19+00:00" + "time": "2019-10-14T12:27:06+00:00" }, { "name": "symfony/stopwatch", @@ -6749,28 +6749,28 @@ }, { "name": "symfony/var-exporter", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "d5b4e2d334c1d80e42876c7d489896cfd37562f2" + "reference": "e566070effe60b8d16b99e958cdbd92aa2e470cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/d5b4e2d334c1d80e42876c7d489896cfd37562f2", - "reference": "d5b4e2d334c1d80e42876c7d489896cfd37562f2", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/e566070effe60b8d16b99e958cdbd92aa2e470cb", + "reference": "e566070effe60b8d16b99e958cdbd92aa2e470cb", "shasum": "" }, "require": { "php": "^7.1.3" }, "require-dev": { - "symfony/var-dumper": "^4.1.1" + "symfony/var-dumper": "^4.1.1|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6805,7 +6805,7 @@ "instantiate", "serialize" ], - "time": "2019-08-22T07:33:08+00:00" + "time": "2019-12-01T08:39:58+00:00" }, { "name": "symfony/web-link", From 17d2e31d35d09ef9672eb3aca08d5ab9abbe7873 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2019 20:09:32 +0000 Subject: [PATCH 094/182] Bump symfony/security-http from 4.3.4 to 4.3.9 in /api Bumps [symfony/security-http](https://github.com/symfony/security-http) from 4.3.4 to 4.3.9. - [Release notes](https://github.com/symfony/security-http/releases) - [Commits](https://github.com/symfony/security-http/compare/v4.3.4...v4.3.9) Signed-off-by: dependabot[bot] --- api/composer.lock | 230 +++++++++++++++++++++++----------------------- 1 file changed, 117 insertions(+), 113 deletions(-) diff --git a/api/composer.lock b/api/composer.lock index cdf70a77..71601ac8 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -2229,8 +2229,8 @@ "authors": [ { "name": "Luís Otávio Cobucci Oblonczyk", - "role": "Developer", - "email": "lcobucci@gmail.com" + "email": "lcobucci@gmail.com", + "role": "Developer" } ], "description": "A simple library to work with JSON Web Token and JSON Web Signature", @@ -3025,16 +3025,16 @@ }, { "name": "psr/log", - "version": "1.1.0", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", - "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801", + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801", "shasum": "" }, "require": { @@ -3043,7 +3043,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -3068,7 +3068,7 @@ "psr", "psr-3" ], - "time": "2018-11-20T15:27:04+00:00" + "time": "2019-11-01T11:05:21+00:00" }, { "name": "ralouphie/getallheaders", @@ -3766,16 +3766,16 @@ }, { "name": "symfony/debug", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "afcdea44a2e399c1e4b52246ec8d54c715393ced" + "reference": "b8600a1d7d20b0e80906398bb1f50612fa074a8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/afcdea44a2e399c1e4b52246ec8d54c715393ced", - "reference": "afcdea44a2e399c1e4b52246ec8d54c715393ced", + "url": "https://api.github.com/repos/symfony/debug/zipball/b8600a1d7d20b0e80906398bb1f50612fa074a8e", + "reference": "b8600a1d7d20b0e80906398bb1f50612fa074a8e", "shasum": "" }, "require": { @@ -3786,12 +3786,12 @@ "symfony/http-kernel": "<3.4" }, "require-dev": { - "symfony/http-kernel": "~3.4|~4.0" + "symfony/http-kernel": "^3.4|^4.0|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -3818,7 +3818,7 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2019-08-20T14:27:59+00:00" + "time": "2019-11-28T13:33:56+00:00" }, { "name": "symfony/dependency-injection", @@ -4103,16 +4103,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2" + "reference": "b3c3068a72623287550fe20b84a2b01dcba2686f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/429d0a1451d4c9c4abe1959b2986b88794b9b7d2", - "reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b3c3068a72623287550fe20b84a2b01dcba2686f", + "reference": "b3c3068a72623287550fe20b84a2b01dcba2686f", "shasum": "" }, "require": { @@ -4128,12 +4128,12 @@ }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/http-foundation": "^3.4|^4.0", - "symfony/service-contracts": "^1.1", - "symfony/stopwatch": "~3.4|~4.0" + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/stopwatch": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/dependency-injection": "", @@ -4142,7 +4142,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4169,20 +4169,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:55:16+00:00" + "time": "2019-11-28T13:33:56+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v1.1.5", + "version": "v1.1.7", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "c61766f4440ca687de1084a5c00b08e167a2575c" + "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c61766f4440ca687de1084a5c00b08e167a2575c", - "reference": "c61766f4440ca687de1084a5c00b08e167a2575c", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c43ab685673fb6c8d84220c77897b1d6cdbe1d18", + "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18", "shasum": "" }, "require": { @@ -4227,7 +4227,7 @@ "interoperability", "standards" ], - "time": "2019-06-20T06:46:26+00:00" + "time": "2019-09-17T09:54:03+00:00" }, { "name": "symfony/expression-language", @@ -4756,31 +4756,31 @@ }, { "name": "symfony/http-foundation", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "d804bea118ff340a12e22a79f9c7e7eb56b35adc" + "reference": "8bccc59e61b41963d14c3dbdb23181e5c932a1d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d804bea118ff340a12e22a79f9c7e7eb56b35adc", - "reference": "d804bea118ff340a12e22a79f9c7e7eb56b35adc", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8bccc59e61b41963d14c3dbdb23181e5c932a1d5", + "reference": "8bccc59e61b41963d14c3dbdb23181e5c932a1d5", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/mime": "^4.3", + "symfony/mime": "^4.3|^5.0", "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { "predis/predis": "~1.0", - "symfony/expression-language": "~3.4|~4.0" + "symfony/expression-language": "^3.4|^4.0|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4807,20 +4807,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:55:16+00:00" + "time": "2019-11-28T13:33:56+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.3.4", + "version": "v4.3.9", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "5e0fc71be03d52cd00c423061cfd300bd6f92a52" + "reference": "3feb99b01560f94173d8fbc5a203ea497d01d499" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/5e0fc71be03d52cd00c423061cfd300bd6f92a52", - "reference": "5e0fc71be03d52cd00c423061cfd300bd6f92a52", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3feb99b01560f94173d8fbc5a203ea497d01d499", + "reference": "3feb99b01560f94173d8fbc5a203ea497d01d499", "shasum": "" }, "require": { @@ -4899,20 +4899,20 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2019-08-26T16:47:42+00:00" + "time": "2019-12-01T14:00:23+00:00" }, { "name": "symfony/inflector", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/inflector.git", - "reference": "b25a8dc15fada858432efa083c1ecd2cef5991a7" + "reference": "98581481d9ddabe4db3a66e10202fe1fa08d791b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/inflector/zipball/b25a8dc15fada858432efa083c1ecd2cef5991a7", - "reference": "b25a8dc15fada858432efa083c1ecd2cef5991a7", + "url": "https://api.github.com/repos/symfony/inflector/zipball/98581481d9ddabe4db3a66e10202fe1fa08d791b", + "reference": "98581481d9ddabe4db3a66e10202fe1fa08d791b", "shasum": "" }, "require": { @@ -4922,7 +4922,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4957,7 +4957,7 @@ "symfony", "words" ], - "time": "2019-08-06T18:44:23+00:00" + "time": "2019-11-06T12:02:32+00:00" }, { "name": "symfony/intl", @@ -5226,16 +5226,16 @@ }, { "name": "symfony/mime", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "987a05df1c6ac259b34008b932551353f4f408df" + "reference": "010cc488e56cafe5f7494dea70aea93100c234df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/987a05df1c6ac259b34008b932551353f4f408df", - "reference": "987a05df1c6ac259b34008b932551353f4f408df", + "url": "https://api.github.com/repos/symfony/mime/zipball/010cc488e56cafe5f7494dea70aea93100c234df", + "reference": "010cc488e56cafe5f7494dea70aea93100c234df", "shasum": "" }, "require": { @@ -5243,14 +5243,17 @@ "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, + "conflict": { + "symfony/mailer": "<4.4" + }, "require-dev": { "egulias/email-validator": "^2.1.10", - "symfony/dependency-injection": "~3.4|^4.1" + "symfony/dependency-injection": "^3.4|^4.1|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5281,7 +5284,7 @@ "mime", "mime-type" ], - "time": "2019-08-22T08:16:11+00:00" + "time": "2019-11-30T08:27:26+00:00" }, { "name": "symfony/options-resolver", @@ -5397,16 +5400,16 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "6af626ae6fa37d396dc90a399c0ff08e5cfc45b2" + "reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6af626ae6fa37d396dc90a399c0ff08e5cfc45b2", - "reference": "6af626ae6fa37d396dc90a399c0ff08e5cfc45b2", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6f9c239e61e1b0c9229a28ff89a812dc449c3d46", + "reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46", "shasum": "" }, "require": { @@ -5420,7 +5423,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5455,20 +5458,20 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17" + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17", - "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f", + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f", "shasum": "" }, "require": { @@ -5480,7 +5483,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5514,20 +5517,20 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T14:18:11+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "04ce3335667451138df4307d6a9b61565560199e" + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/04ce3335667451138df4307d6a9b61565560199e", - "reference": "04ce3335667451138df4307d6a9b61565560199e", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/66fea50f6cb37a35eea048d75a7d99a45b586038", + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038", "shasum": "" }, "require": { @@ -5536,7 +5539,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5569,20 +5572,20 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188" + "reference": "4b0e2222c55a25b4541305a053013d5647d3a25f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/2ceb49eaccb9352bff54d22570276bb75ba4a188", - "reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/4b0e2222c55a25b4541305a053013d5647d3a25f", + "reference": "4b0e2222c55a25b4541305a053013d5647d3a25f", "shasum": "" }, "require": { @@ -5591,7 +5594,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5627,7 +5630,7 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T16:25:15+00:00" }, { "name": "symfony/process", @@ -5680,24 +5683,24 @@ }, { "name": "symfony/property-access", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "bb0c302375ffeef60c31e72a4539611b7f787565" + "reference": "bafdc8c3a9d2671af4a81baec0fcc4687c0c17bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/bb0c302375ffeef60c31e72a4539611b7f787565", - "reference": "bb0c302375ffeef60c31e72a4539611b7f787565", + "url": "https://api.github.com/repos/symfony/property-access/zipball/bafdc8c3a9d2671af4a81baec0fcc4687c0c17bc", + "reference": "bafdc8c3a9d2671af4a81baec0fcc4687c0c17bc", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/inflector": "~3.4|~4.0" + "symfony/inflector": "^3.4|^4.0|^5.0" }, "require-dev": { - "symfony/cache": "~3.4|~4.0" + "symfony/cache": "^3.4|^4.0|^5.0" }, "suggest": { "psr/cache-implementation": "To cache access methods." @@ -5705,7 +5708,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5743,7 +5746,7 @@ "property path", "reflection" ], - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-12-01T10:50:45+00:00" }, { "name": "symfony/property-info", @@ -5983,35 +5986,36 @@ }, { "name": "symfony/security-core", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "a8c67a8bc6bd8012c5d6b70cb030ca3422476caa" + "reference": "312c91f90786fd7add89e8542cfc98543f0e60db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/a8c67a8bc6bd8012c5d6b70cb030ca3422476caa", - "reference": "a8c67a8bc6bd8012c5d6b70cb030ca3422476caa", + "url": "https://api.github.com/repos/symfony/security-core/zipball/312c91f90786fd7add89e8542cfc98543f0e60db", + "reference": "312c91f90786fd7add89e8542cfc98543f0e60db", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/event-dispatcher-contracts": "^1.1", - "symfony/service-contracts": "^1.1" + "symfony/event-dispatcher-contracts": "^1.1|^2", + "symfony/service-contracts": "^1.1.6|^2" }, "conflict": { - "symfony/event-dispatcher": "<4.3", + "symfony/event-dispatcher": "<4.3|>=5", + "symfony/ldap": "<4.4", "symfony/security-guard": "<4.3" }, "require-dev": { "psr/container": "^1.0", "psr/log": "~1.0", "symfony/event-dispatcher": "^4.3", - "symfony/expression-language": "~3.4|~4.0", - "symfony/http-foundation": "~3.4|~4.0", - "symfony/ldap": "~3.4|~4.0", - "symfony/validator": "^3.4.31|^4.3.4" + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/ldap": "^4.4|^5.0", + "symfony/validator": "^3.4.31|^4.3.4|^5.0" }, "suggest": { "psr/container-implementation": "To instantiate the Security class", @@ -6024,7 +6028,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6051,7 +6055,7 @@ ], "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", - "time": "2019-08-26T08:55:16+00:00" + "time": "2019-11-20T10:44:55+00:00" }, { "name": "symfony/security-csrf", @@ -6168,16 +6172,16 @@ }, { "name": "symfony/security-http", - "version": "v4.3.4", + "version": "v4.3.9", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "65281f9b7c7a77cccaa5b89026ef2a02940dc2cc" + "reference": "75e96df3a1b9b38c67e2fa208894f72dae5e1147" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/65281f9b7c7a77cccaa5b89026ef2a02940dc2cc", - "reference": "65281f9b7c7a77cccaa5b89026ef2a02940dc2cc", + "url": "https://api.github.com/repos/symfony/security-http/zipball/75e96df3a1b9b38c67e2fa208894f72dae5e1147", + "reference": "75e96df3a1b9b38c67e2fa208894f72dae5e1147", "shasum": "" }, "require": { @@ -6229,7 +6233,7 @@ ], "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-11-30T13:16:45+00:00" }, { "name": "symfony/serializer", @@ -6313,16 +6317,16 @@ }, { "name": "symfony/service-contracts", - "version": "v1.1.6", + "version": "v1.1.8", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3" + "reference": "ffc7f5692092df31515df2a5ecf3b7302b3ddacf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ea7263d6b6d5f798b56a45a5b8d686725f2719a3", - "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ffc7f5692092df31515df2a5ecf3b7302b3ddacf", + "reference": "ffc7f5692092df31515df2a5ecf3b7302b3ddacf", "shasum": "" }, "require": { @@ -6367,7 +6371,7 @@ "interoperability", "standards" ], - "time": "2019-08-20T14:44:19+00:00" + "time": "2019-10-14T12:27:06+00:00" }, { "name": "symfony/stopwatch", From 5cf3c7029807a3c0fb443b726f58d62aa81162e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2019 23:27:35 +0000 Subject: [PATCH 095/182] Bump symfony/http-foundation from 4.3.4 to 4.4.1 in /api Bumps [symfony/http-foundation](https://github.com/symfony/http-foundation) from 4.3.4 to 4.4.1. - [Release notes](https://github.com/symfony/http-foundation/releases) - [Changelog](https://github.com/symfony/http-foundation/blob/master/CHANGELOG.md) - [Commits](https://github.com/symfony/http-foundation/compare/v4.3.4...v4.4.1) Signed-off-by: dependabot[bot] --- api/composer.lock | 73 ++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/api/composer.lock b/api/composer.lock index cdf70a77..ad43758d 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -2229,8 +2229,8 @@ "authors": [ { "name": "Luís Otávio Cobucci Oblonczyk", - "role": "Developer", - "email": "lcobucci@gmail.com" + "email": "lcobucci@gmail.com", + "role": "Developer" } ], "description": "A simple library to work with JSON Web Token and JSON Web Signature", @@ -4756,31 +4756,31 @@ }, { "name": "symfony/http-foundation", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "d804bea118ff340a12e22a79f9c7e7eb56b35adc" + "reference": "8bccc59e61b41963d14c3dbdb23181e5c932a1d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d804bea118ff340a12e22a79f9c7e7eb56b35adc", - "reference": "d804bea118ff340a12e22a79f9c7e7eb56b35adc", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8bccc59e61b41963d14c3dbdb23181e5c932a1d5", + "reference": "8bccc59e61b41963d14c3dbdb23181e5c932a1d5", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/mime": "^4.3", + "symfony/mime": "^4.3|^5.0", "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { "predis/predis": "~1.0", - "symfony/expression-language": "~3.4|~4.0" + "symfony/expression-language": "^3.4|^4.0|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4807,7 +4807,7 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:55:16+00:00" + "time": "2019-11-28T13:33:56+00:00" }, { "name": "symfony/http-kernel", @@ -5226,16 +5226,16 @@ }, { "name": "symfony/mime", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "987a05df1c6ac259b34008b932551353f4f408df" + "reference": "010cc488e56cafe5f7494dea70aea93100c234df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/987a05df1c6ac259b34008b932551353f4f408df", - "reference": "987a05df1c6ac259b34008b932551353f4f408df", + "url": "https://api.github.com/repos/symfony/mime/zipball/010cc488e56cafe5f7494dea70aea93100c234df", + "reference": "010cc488e56cafe5f7494dea70aea93100c234df", "shasum": "" }, "require": { @@ -5243,14 +5243,17 @@ "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, + "conflict": { + "symfony/mailer": "<4.4" + }, "require-dev": { "egulias/email-validator": "^2.1.10", - "symfony/dependency-injection": "~3.4|^4.1" + "symfony/dependency-injection": "^3.4|^4.1|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5281,7 +5284,7 @@ "mime", "mime-type" ], - "time": "2019-08-22T08:16:11+00:00" + "time": "2019-11-30T08:27:26+00:00" }, { "name": "symfony/options-resolver", @@ -5397,16 +5400,16 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "6af626ae6fa37d396dc90a399c0ff08e5cfc45b2" + "reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6af626ae6fa37d396dc90a399c0ff08e5cfc45b2", - "reference": "6af626ae6fa37d396dc90a399c0ff08e5cfc45b2", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6f9c239e61e1b0c9229a28ff89a812dc449c3d46", + "reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46", "shasum": "" }, "require": { @@ -5420,7 +5423,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5455,20 +5458,20 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17" + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17", - "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f", + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f", "shasum": "" }, "require": { @@ -5480,7 +5483,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5514,20 +5517,20 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T14:18:11+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "04ce3335667451138df4307d6a9b61565560199e" + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/04ce3335667451138df4307d6a9b61565560199e", - "reference": "04ce3335667451138df4307d6a9b61565560199e", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/66fea50f6cb37a35eea048d75a7d99a45b586038", + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038", "shasum": "" }, "require": { @@ -5536,7 +5539,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5569,7 +5572,7 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/polyfill-php73", From ff2e87ed5cfef34ab16ebc85b7d63e5912bad9e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2019 23:28:00 +0000 Subject: [PATCH 096/182] Bump symfony/mime from 4.3.4 to 4.4.1 in /api Bumps [symfony/mime](https://github.com/symfony/mime) from 4.3.4 to 4.4.1. - [Release notes](https://github.com/symfony/mime/releases) - [Changelog](https://github.com/symfony/mime/blob/master/CHANGELOG.md) - [Commits](https://github.com/symfony/mime/compare/v4.3.4...v4.4.1) Signed-off-by: dependabot[bot] --- api/composer.lock | 57 +++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/api/composer.lock b/api/composer.lock index cdf70a77..de842e26 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -2229,8 +2229,8 @@ "authors": [ { "name": "Luís Otávio Cobucci Oblonczyk", - "role": "Developer", - "email": "lcobucci@gmail.com" + "email": "lcobucci@gmail.com", + "role": "Developer" } ], "description": "A simple library to work with JSON Web Token and JSON Web Signature", @@ -5226,16 +5226,16 @@ }, { "name": "symfony/mime", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "987a05df1c6ac259b34008b932551353f4f408df" + "reference": "010cc488e56cafe5f7494dea70aea93100c234df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/987a05df1c6ac259b34008b932551353f4f408df", - "reference": "987a05df1c6ac259b34008b932551353f4f408df", + "url": "https://api.github.com/repos/symfony/mime/zipball/010cc488e56cafe5f7494dea70aea93100c234df", + "reference": "010cc488e56cafe5f7494dea70aea93100c234df", "shasum": "" }, "require": { @@ -5243,14 +5243,17 @@ "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, + "conflict": { + "symfony/mailer": "<4.4" + }, "require-dev": { "egulias/email-validator": "^2.1.10", - "symfony/dependency-injection": "~3.4|^4.1" + "symfony/dependency-injection": "^3.4|^4.1|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5281,7 +5284,7 @@ "mime", "mime-type" ], - "time": "2019-08-22T08:16:11+00:00" + "time": "2019-11-30T08:27:26+00:00" }, { "name": "symfony/options-resolver", @@ -5397,16 +5400,16 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "6af626ae6fa37d396dc90a399c0ff08e5cfc45b2" + "reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6af626ae6fa37d396dc90a399c0ff08e5cfc45b2", - "reference": "6af626ae6fa37d396dc90a399c0ff08e5cfc45b2", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6f9c239e61e1b0c9229a28ff89a812dc449c3d46", + "reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46", "shasum": "" }, "require": { @@ -5420,7 +5423,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5455,20 +5458,20 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17" + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17", - "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f", + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f", "shasum": "" }, "require": { @@ -5480,7 +5483,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5514,20 +5517,20 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T14:18:11+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "04ce3335667451138df4307d6a9b61565560199e" + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/04ce3335667451138df4307d6a9b61565560199e", - "reference": "04ce3335667451138df4307d6a9b61565560199e", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/66fea50f6cb37a35eea048d75a7d99a45b586038", + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038", "shasum": "" }, "require": { @@ -5536,7 +5539,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5569,7 +5572,7 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/polyfill-php73", From d8677202a6e9fbe1da58538c86a44050ee5dcfab Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Tue, 3 Dec 2019 14:17:36 +0100 Subject: [PATCH 097/182] Free 'Create Release' from install/upgrade lock. --- .github/workflows/dockerimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 9e8658ca..33e5189a 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -104,7 +104,7 @@ jobs: kubectl rollout restart deployment/$APP_NAME-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-varnish --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV - name: Create Release - if: contains( github.ref, 'master' ) + if: contains( github.ref, 'master' ) && steps.kubeconfig.outputs.success == 'true' && ( success() || failure() ) id: create_release uses: actions/create-release@v1 env: From b5b7c8a5fb618b650e028b462cc49e3d39935026 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Tue, 3 Dec 2019 15:37:27 +0100 Subject: [PATCH 098/182] Fix issue with rollout --- .github/workflows/dockerimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 33e5189a..5907d2d5 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -98,7 +98,7 @@ jobs: if: failure() run: helm install --name $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Rollout new containers - if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' && steps.helm-install.success == 'true' + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' && steps.helm-install.success == 'true' && success() run: | kubectl rollout restart deployment/$APP_NAME-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV From f7a9729c53050508cd0035f6087d151359b93f55 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Tue, 3 Dec 2019 16:18:57 +0100 Subject: [PATCH 099/182] (semi) definitive fix for rollout issue --- .github/workflows/dockerimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 5907d2d5..cfdb0166 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -98,7 +98,7 @@ jobs: if: failure() run: helm install --name $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Rollout new containers - if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' && steps.helm-install.success == 'true' && success() + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' && success() run: | kubectl rollout restart deployment/$APP_NAME-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV From dde1ed2bf348b02e7371862ce83034ddf41cee02 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Tue, 3 Dec 2019 16:51:28 +0100 Subject: [PATCH 100/182] Allow create release to fail --- .github/workflows/dockerimage.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index cfdb0166..176b4b14 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -107,6 +107,7 @@ jobs: if: contains( github.ref, 'master' ) && steps.kubeconfig.outputs.success == 'true' && ( success() || failure() ) id: create_release uses: actions/create-release@v1 + continue-on-error: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token with: From d937a5be2137591c3ed2ecf3505bffd0c669647b Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 4 Dec 2019 06:32:09 +0100 Subject: [PATCH 101/182] Tutorial updates --- .github/workflows/dockerimage.yml | 4 ++-- TUTORIAL.md | 30 ++++++++++-------------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 9aa6baf6..9fd5d8a7 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -111,7 +111,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token with: - tag_name: $APP_BUILD - release_name: $APP_BUILD + tag_name: $APP_BUILD-${{ secrets.GITHUB_TOKEN }} + release_name: $APP_BUILD-${{ secrets.GITHUB_TOKEN }} draft: false prerelease: false diff --git a/TUTORIAL.md b/TUTORIAL.md index ed149d7b..356121e3 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -12,7 +12,7 @@ For the steps considering the generation of resources (or entities as symfony ca ## Setting up your enviroment -You can install docker-desktop from [the docker website](). +You can install docker-desktop from [the docker website](https://hub.docker.com/editions/community/docker-ce-desktop-windows). ## Generating your component (repository/codebase) @@ -26,7 +26,7 @@ After that you should be redirected to your own brand new repository. We ran a fork of the base Common Ground component, that means that we copied the code of the original project into a new repository. By doing so we made sure we have all the necessities for our component, including security and compliance with international standards. ## Spinning up your component -Before we can spin up our component we must first get a local copy from our repository, we can either do this through the command line (example here) or use a Git client. +Before we can spin up our component we must first get a local copy from our repository, we can either do this through the command line or use a Git client. For this example we're going to use GitKraken but you can use any tool you like, feel free to skip this part if you are already familiar with setting up a local clone of your repository. @@ -35,7 +35,7 @@ Open gitkraken press "clone a repo" and fill in the form (select where on your l You can now navigate to the folder where you just installed your code, it should contain some folders and files and generally look like this. We will get into the files later, lets first spin up our component! Open a command window (example) and browse to the folder where you just stuffed your code, navigating in a command window is done by cd, so for our example we could type -cd c:\repos\common-ground\my-component (if you installed your code on a different disk then where the cmd window opens first type : for example D: and hit enter to go to that disk, D in this case). We are now in our folder, so let's go! Type docker-compose up and hit enter. From now on whenever we describe a command line command we will document it as follows: +cd c:\repos\common-ground\my-component (if you installed your code on a different disk then where the cmd window opens first type : for example D: and hit enter to go to that disk, D in this case). We are now in our folder, so let's go! Type docker-compose up and hit enter. From now on whenever we describe a command line command we will document it as follows (the $ isn't actually typed but represents your folder structure): ```CLI $ docker-compose up @@ -45,8 +45,9 @@ Your computer should now start up your local development environment. Don't worr Open your browser type http://localhost/ as address and hit enter, you should now see your common ground component up and running. -### trouble shooting +### Trouble shooting When spinning up components we make extensive use of the cashing of docker, and use volumes to represent server disks. When running in to unexpected trouble always remember to clear your local docker vm with the -a command (removing image cash) + ```CLI $ docker system prune -a ``` @@ -62,7 +63,7 @@ You can now access your api at http://localhost:8080/, as you can see it's pre-l First let's remove the resources currently in the api, we can do that by just removing the resources form our code base, navigate to the folder where you stored your code and open the folder api/src/Entity , you can find the example entities (the symfony name for resources) there. Just delete all the php files in that folder. -Next let's add our own entities, we can do this in two ways, we can do old fashioned coding, but we can also use the build in maker bundle of the proto component, to quickly generate our entities for us (without the fuss of actual coding). +Next let's add our own resources, we can do this in two ways, we can do old fashioned coding, but we can also use the build in maker bundle of the proto component, to quickly generate our entities for us (without the fuss of actual coding). Let's open a new command line window and navigate to our root folder, exactly like we did under "spinning up your component". And then lets fire up maker bundle (make sure that your component is still running in your other command window). We can do so by the following command: @@ -170,7 +171,7 @@ class Organisation Keep in mind that we need to add the assert annotation to our class dependencies under 'use'. -More inforation on using validation can be found at the [symfony website](https://symfony.com/doc/current/validation.html), but it is als worth nothing that tis component comes pre packed with some typical NL validators like BSN. You can find those [here](). +More information on using validation can be found at the [symfony website](https://symfony.com/doc/current/validation.html), but it is als worth nothing that tis component comes pre packed with some typical NL validators like BSN. You can find those [here](). ## Using UUID As default doctrine uses auto increment integers as identifiers (1,2, etc). For modern web applications we however prefer the use of UUID's. (e.g. e2984465-190a-4562-829e-a8cca81aa35d). Why? Wel for one it is more secure integer id's are easily guessable and make it possible to "ask" endpoint about resources that you should not know about. But UUID's also have a benefit in future proofing the application. If we in the future want to merge a table with another table (for example because two organisations using a component perform a merger) then we would have to reassign al id's and relations if we where using int based id's (both tables would have a row 1,2 etc) with UUID's however the change of doubles range somewhere in the billions. Meaning that it is likely that we only need to either reidentify only a handful of rows or more likely none at al! Turning our entire migration into a copy paste action. @@ -199,20 +200,9 @@ with ```PHP //... - /** - * @var \Ramsey\Uuid\UuidInterface - * - * @ApiProperty( - * identifier=true, - * attributes={ - * "openapi_context"={ - * "description" = "The UUID identifier of this resource", - * "type"="string", - * "format"="uuid", - * "example"="e2984465-190a-4562-829e-a8cca81aa35d" - * } - * } - * ) + /** + * @var \Ramsey\Uuid\UuidInterface The UUID identifier of this resource + * @example e2984465-190a-4562-829e-a8cca81aa35d * * @Groups({"read"}) * @ORM\Id From e08f378acd27f9e58107b9a98165fc97b5094fc0 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 4 Dec 2019 06:49:47 +0100 Subject: [PATCH 102/182] Fix on releases --- .github/workflows/dockerimage.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 9e8658ca..4f170956 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -103,14 +103,17 @@ jobs: kubectl rollout restart deployment/$APP_NAME-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-varnish --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + - name: Create Release - if: contains( github.ref, 'master' ) + if: contains( github.ref, 'master' ) && steps.kubeconfig.outputs.success == 'true' && ( success() || failure() ) id: create_release uses: actions/create-release@v1 + continue-on-error: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token with: - tag_name: $APP_BUILD - release_name: $APP_BUILD + tag_name: $APP_BUILD-${{ secrets.GITHUB_TOKEN }} + release_name: $APP_BUILD-${{ secrets.GITHUB_TOKEN }} draft: false prerelease: false + From 90ef003a10e6b790f7bd58ed6d6ab11b417b5307 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 07:18:52 +0100 Subject: [PATCH 103/182] Changed from token to commit id --- .github/workflows/dockerimage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 4f170956..38ea29e8 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -112,8 +112,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token with: - tag_name: $APP_BUILD-${{ secrets.GITHUB_TOKEN }} - release_name: $APP_BUILD-${{ secrets.GITHUB_TOKEN }} + tag_name: $APP_BUILD-$(git rev-parse --short "$GITHUB_SHA") + release_name: $APP_BUILD-$(git rev-parse --short "$GITHUB_SHA") draft: false prerelease: false From 07ca03b4b7d5465820803f8db9e20c146af8dd63 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 08:16:49 +0100 Subject: [PATCH 104/182] Test with release name --- .github/workflows/test.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..01c84352 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,28 @@ +name: Test + +on: + pull_request: + branches: + - master + - staging + - development + push: + branches: + - master + - staging + - development + +jobs: + + build: + + runs-on: ubuntu-latest + steps: + - name: Export release code + id: export + if: (success() || failure()) + run: | + echo "##[set-output name=releasename]$APP_BUILD-$(git rev-parse --short HEAD)" + - run: echo "$RELEASE" + with: + RELEASE: ${{ steps.export.outputs.releasename }} From 41d0d72f11cd06e6dd6cb3fefc465f7340791177 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 08:17:07 +0100 Subject: [PATCH 105/182] (semi) definitive fix for rollout issue --- .github/workflows/test.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 01c84352..719f756a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,16 +1,9 @@ name: Test on: - pull_request: - branches: - - master - - staging - - development push: branches: - - master - - staging - - development + - dev-robert jobs: From ed2817f07652e6305bf93294f2155b868c666ae4 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 08:17:55 +0100 Subject: [PATCH 106/182] changed with to env --- .github/workflows/test.yml | 2 +- .idea/workspace.xml | 57 +++++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 719f756a..5e00928f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,5 +17,5 @@ jobs: run: | echo "##[set-output name=releasename]$APP_BUILD-$(git rev-parse --short HEAD)" - run: echo "$RELEASE" - with: + env: RELEASE: ${{ steps.export.outputs.releasename }} diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 980cc0cb..ced0c1eb 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,8 +1,9 @@ - - + + + @@ -321,6 +365,11 @@ - \ No newline at end of file From 510426659a1a4a25039beb003545eff5051c2858 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 08:19:11 +0100 Subject: [PATCH 107/182] HEAD to GITHUB SHA --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5e00928f..8541c591 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: id: export if: (success() || failure()) run: | - echo "##[set-output name=releasename]$APP_BUILD-$(git rev-parse --short HEAD)" + echo "##[set-output name=releasename]$APP_BUILD-$(git rev-parse --short '$GITHUB_SHA')" - run: echo "$RELEASE" env: RELEASE: ${{ steps.export.outputs.releasename }} From fb928b7d699fb6040185d9a7f337ebfa82754a93 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 08:20:11 +0100 Subject: [PATCH 108/182] Short GITHUB_SHA --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8541c591..7736035e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: id: export if: (success() || failure()) run: | - echo "##[set-output name=releasename]$APP_BUILD-$(git rev-parse --short '$GITHUB_SHA')" + echo "##[set-output name=releasename]$APP_BUILD-$GITHUB_SHA" - run: echo "$RELEASE" env: RELEASE: ${{ steps.export.outputs.releasename }} From 50fb9c7d50308c12179475c518698a3f256b59d6 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 11:12:14 +0100 Subject: [PATCH 109/182] Removal of test script, adding release number/code --- .github/workflows/dockerimage.yml | 16 +++++++++++----- .github/workflows/test.yml | 21 --------------------- 2 files changed, 11 insertions(+), 26 deletions(-) delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 176b4b14..786009b4 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -103,15 +103,21 @@ jobs: kubectl rollout restart deployment/$APP_NAME-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-varnish --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + - name: Export release code + if: (success() || failure()) + id: releasecode + run: | + echo "##[set-output name=releasename]$APP_BUILD-$GITHUB_SHA" + - name: Create Release if: contains( github.ref, 'master' ) && steps.kubeconfig.outputs.success == 'true' && ( success() || failure() ) id: create_release uses: actions/create-release@v1 continue-on-error: true env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token with: - tag_name: $APP_BUILD - release_name: $APP_BUILD - draft: false - prerelease: false + tag_name: ${{ steps.releasecode.outputs.releasename }} + release_name: ${{ steps.releasecode.outputs.releasename }} + draft: false + prerelease: false diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 7736035e..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Test - -on: - push: - branches: - - dev-robert - -jobs: - - build: - - runs-on: ubuntu-latest - steps: - - name: Export release code - id: export - if: (success() || failure()) - run: | - echo "##[set-output name=releasename]$APP_BUILD-$GITHUB_SHA" - - run: echo "$RELEASE" - env: - RELEASE: ${{ steps.export.outputs.releasename }} From 6a09adb1a7e4b512bc4a57ee8575e9893d8ebffc Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 13:28:05 +0100 Subject: [PATCH 110/182] Github shortcode instead of full SHA (under test) --- .github/workflows/dockerimage.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 786009b4..c809fda7 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -107,7 +107,8 @@ jobs: if: (success() || failure()) id: releasecode run: | - echo "##[set-output name=releasename]$APP_BUILD-$GITHUB_SHA" + export RELEASE=$APP_BUILD-$(git rev-parse --short "$GITHUB_SHA") + echo "##[set-output name=releasename]$RELEASE" - name: Create Release if: contains( github.ref, 'master' ) && steps.kubeconfig.outputs.success == 'true' && ( success() || failure() ) From 9ddbb43cf6de1c5c066877a7db6f64e75fd1d969 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 13:46:13 +0100 Subject: [PATCH 111/182] Printing the release name, just to be sure --- .github/workflows/dockerimage.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index c809fda7..e4bffcf2 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -109,7 +109,10 @@ jobs: run: | export RELEASE=$APP_BUILD-$(git rev-parse --short "$GITHUB_SHA") echo "##[set-output name=releasename]$RELEASE" - + - name: Print release name + run: echo $RELEASENAME + env: + RELEASENAME: ${{ steps.releasecode.outputs.releasename }} - name: Create Release if: contains( github.ref, 'master' ) && steps.kubeconfig.outputs.success == 'true' && ( success() || failure() ) id: create_release From dbac038e026a74edfc2174f9f0c0b229921ac64c Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 13:46:47 +0100 Subject: [PATCH 112/182] Made print unconditional --- .github/workflows/dockerimage.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index e4bffcf2..070e4ee0 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -110,6 +110,7 @@ jobs: export RELEASE=$APP_BUILD-$(git rev-parse --short "$GITHUB_SHA") echo "##[set-output name=releasename]$RELEASE" - name: Print release name + if: (success() || failure()) run: echo $RELEASENAME env: RELEASENAME: ${{ steps.releasecode.outputs.releasename }} From 40ab8f5b418cdf479708c5a7174c1777d81eb469 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 14:07:40 +0100 Subject: [PATCH 113/182] Quotes be gone --- .github/workflows/dockerimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 070e4ee0..4f8b430e 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -107,7 +107,7 @@ jobs: if: (success() || failure()) id: releasecode run: | - export RELEASE=$APP_BUILD-$(git rev-parse --short "$GITHUB_SHA") + export RELEASE=$APP_BUILD-$(git rev-parse --short $GITHUB_SHA) echo "##[set-output name=releasename]$RELEASE" - name: Print release name if: (success() || failure()) From 8768eea03c27e7cce631618af42af422555f0f06 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 14:33:28 +0100 Subject: [PATCH 114/182] Moved creation of release name to prevent out-of-sync GITHUB_SHA --- .github/workflows/dockerimage.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 4f8b430e..3697caa5 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -19,6 +19,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 + - name: Export release code + if: (success() || failure()) + id: releasecode + run: | + export RELEASE=$APP_BUILD-$(git rev-parse --short $GITHUB_SHA) + echo "##[set-output name=releasename]$RELEASE" - name: Pulling old images, if any run: docker-compose pull --ignore-pull-failures - name: Setting APP_NAME @@ -103,12 +109,7 @@ jobs: kubectl rollout restart deployment/$APP_NAME-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-varnish --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV - - name: Export release code - if: (success() || failure()) - id: releasecode - run: | - export RELEASE=$APP_BUILD-$(git rev-parse --short $GITHUB_SHA) - echo "##[set-output name=releasename]$RELEASE" + - name: Print release name if: (success() || failure()) run: echo $RELEASENAME From 4f8839c3de558a346f8ed7e684639b25ec29a3eb Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 14:34:29 +0100 Subject: [PATCH 115/182] Also move print location of release name --- .github/workflows/dockerimage.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 3697caa5..7910c9cb 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -25,6 +25,11 @@ jobs: run: | export RELEASE=$APP_BUILD-$(git rev-parse --short $GITHUB_SHA) echo "##[set-output name=releasename]$RELEASE" + - name: Print release name + if: (success() || failure()) + run: echo $RELEASENAME + env: + RELEASENAME: ${{ steps.releasecode.outputs.releasename }} - name: Pulling old images, if any run: docker-compose pull --ignore-pull-failures - name: Setting APP_NAME @@ -110,11 +115,7 @@ jobs: kubectl rollout restart deployment/$APP_NAME-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-varnish --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV - - name: Print release name - if: (success() || failure()) - run: echo $RELEASENAME - env: - RELEASENAME: ${{ steps.releasecode.outputs.releasename }} + - name: Create Release if: contains( github.ref, 'master' ) && steps.kubeconfig.outputs.success == 'true' && ( success() || failure() ) id: create_release From 2e6167dc6df47cc427ccd02b5da5de95567c321b Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 4 Dec 2019 14:36:11 +0100 Subject: [PATCH 116/182] Moving does not make a difference and probably breaks stuff again --- .github/workflows/dockerimage.yml | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 7910c9cb..4f8b430e 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -19,17 +19,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - - name: Export release code - if: (success() || failure()) - id: releasecode - run: | - export RELEASE=$APP_BUILD-$(git rev-parse --short $GITHUB_SHA) - echo "##[set-output name=releasename]$RELEASE" - - name: Print release name - if: (success() || failure()) - run: echo $RELEASENAME - env: - RELEASENAME: ${{ steps.releasecode.outputs.releasename }} - name: Pulling old images, if any run: docker-compose pull --ignore-pull-failures - name: Setting APP_NAME @@ -114,8 +103,17 @@ jobs: kubectl rollout restart deployment/$APP_NAME-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV kubectl rollout restart deployment/$APP_NAME-varnish --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV - - + - name: Export release code + if: (success() || failure()) + id: releasecode + run: | + export RELEASE=$APP_BUILD-$(git rev-parse --short $GITHUB_SHA) + echo "##[set-output name=releasename]$RELEASE" + - name: Print release name + if: (success() || failure()) + run: echo $RELEASENAME + env: + RELEASENAME: ${{ steps.releasecode.outputs.releasename }} - name: Create Release if: contains( github.ref, 'master' ) && steps.kubeconfig.outputs.success == 'true' && ( success() || failure() ) id: create_release From af5d9540c53c66b3bcb6e47a2bf3930fa921ba89 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 4 Dec 2019 20:50:42 +0100 Subject: [PATCH 117/182] Updates to the ingress resource Should make the entire thing available on the ingres ip --- .env | 1 + api/config/packages/twig.yaml | 1 + api/helm/templates/configmap.yaml | 1 + api/helm/templates/ingress.yaml | 10 ++++------ api/helm/templates/php-deployment.yaml | 5 +++++ api/helm/values.yaml | 10 ++-------- api/templates/helm/Values.yaml.twig | 1 + docker-compose.yml | 1 + 8 files changed, 16 insertions(+), 14 deletions(-) diff --git a/.env b/.env index 66007731..ce0fe0a0 100644 --- a/.env +++ b/.env @@ -27,6 +27,7 @@ APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) inte # Documentation settings ################################################## +APP_DOMAIN=conduction.nl APP_DEMO=pc.zaakonline.nl APP_REPRO=https://github.com/ConductionNL/Proto-component-commonground diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml index 1a687ce2..7d186ad6 100644 --- a/api/config/packages/twig.yaml +++ b/api/config/packages/twig.yaml @@ -14,6 +14,7 @@ twig: app_version: '%env(APP_VERSION)%' app_env: '%env(APP_ENV)%' app_debug: '%env(APP_DEBUG)%' + app_domain: '%env(APP_DOMAIN)%' app_demo: '%env(APP_DEMO)%' app_repro: '%env(APP_REPRO)%' app_description: '%env(APP_DESCRIPTION)%' diff --git a/api/helm/templates/configmap.yaml b/api/helm/templates/configmap.yaml index 55279410..d3b97459 100644 --- a/api/helm/templates/configmap.yaml +++ b/api/helm/templates/configmap.yaml @@ -16,6 +16,7 @@ data: app-version: {{ .Values.settings.version | quote }} app-repro: {{ .Values.settings.repro | quote }} app-demo: {{ .Values.settings.demo | quote }} + app-domain: {{ .Values.settings.domain | quote }} app-description: {{ .Values.settings.description | quote }} app-auth: {{ .Values.settings.authorisationEnabled | quote }} diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index 4437f785..6c924078 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -1,7 +1,7 @@ apiVersion: extensions/v1beta1 kind: Ingress metadata: - name: {{ template "fullname" . }} + name: {{ include "name" . }}-{{ .Values.settings.env }}-ingress labels: app.kubernetes.io/name: {{ include "name" . }}-ingress app.kubernetes.io/part-of: {{ include "name" . }} @@ -24,12 +24,10 @@ spec: {{- end }} {{- end }} rules: - {{- range .Values.ingress.hosts }} - - host: {{ .host | quote }} + - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} http: paths: - path: /* backend: - serviceName: {{ .serviceName }} - servicePort: {{ .servicePort | default 80 }} - {{- end }} + serviceName: {{ include "name" . }}-nginx + servicePort: 80 diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index 1b03232e..3f09ef5d 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -77,6 +77,11 @@ spec: configMapKeyRef: name: {{ template "fullname" . }} key: app-demo + - name: APP_DOMAIN + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-domain - name: APP_REPRO valueFrom: configMapKeyRef: diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 6bf6d3b2..3e671e4d 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -11,11 +11,12 @@ settings: description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' repro: https://github.com/ConductionNL/Proto-component-commonground' demo: pc.zaakonline.nl + domain: conduction.nl env: dev debug: 1 replicaCount: 1 corsAllowOrigin: ['*'] - trustedHosts: '^(.+\.)?common-ground\.dev$|^(.+\.)?zaakonline\.nl$|^(.+\.)?conduction\.nl$|^example\.com$|^(.+\.)?178.128.142.152$|178.128.142.152|localhost' + trustedHosts: '^(.+\.)?conduction\.nl$|localhost' pullPolicy: Always # You will need these proxies on kubernetes trustedProxies: @@ -94,13 +95,6 @@ ingress: # - hosts: # - example.com # - mercure.example.com - hosts: - api: - host: example.com - serviceName: varnish - mercure: - host: mercure.example.com - serviceName: mercure resources: {} # We usually recommend not to specify default resources and to leave this as a conscious diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 33aebbd8..40241105 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -10,6 +10,7 @@ settings: version: {{ app_version }} description: '{{ app_description }}' repro: {{ app_repro }}' + domain: {{ app_domain }} demo: {{ app_demo }} env: {{ app_env }} debug: {{ app_debug }} diff --git a/docker-compose.yml b/docker-compose.yml index 43498f17..68795b67 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -36,6 +36,7 @@ services: - APP_VERSION=${APP_VERSION} - APP_NAME=${APP_NAME} - APP_TITLE=${APP_TITLE} + - APP_DOMAIN=${APP_DOMAIN} - APP_DEMO=${APP_DEMO} - APP_REPRO=${APP_REPRO} - APP_DESCRIPTION=${APP_DESCRIPTION} From 086c40de8b0e331c409d83b2a95c4871c3bf516f Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 5 Dec 2019 06:47:14 +0100 Subject: [PATCH 118/182] Updated ingress for new domain routing --- .env | 4 ++++ INSTALLATION.md | 19 +++++++++++----- api/.env | 4 ++-- api/config/packages/twig.yaml | 5 ++++- api/helm/templates/ingress.yaml | 35 ++++++++++++++++++++++++++--- api/helm/values.yaml | 2 +- api/templates/helm/Values.yaml.twig | 2 +- docker-compose.yml | 2 ++ 8 files changed, 59 insertions(+), 14 deletions(-) diff --git a/.env b/.env index ce0fe0a0..71e479f4 100644 --- a/.env +++ b/.env @@ -23,6 +23,10 @@ APP_BUILD=dev # The description for this api APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' +# The urls on wich this api is available +TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 +TRUSTED_HOSTS='^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.nl$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' + ################################################## # Documentation settings ################################################## diff --git a/INSTALLATION.md b/INSTALLATION.md index 05bad3ed..96ea76d5 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -4,6 +4,7 @@ This document dives a little bit deeper into installing your component on a kube ## Setting up helm + ## Setting up tiller Create the tiller service account: @@ -18,39 +19,45 @@ $ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --service Now we can run helm init, which installs Tiller on our cluster, along with some local housekeeping tasks such as downloading the stable repo details: ```CLI -$ helm init --service-account tiller --kubeconfig="api/helm/kubeconfig.yaml" +$ helm init --service-account tiller --kubeconfig="kubeconfig.yaml" ``` To verify that Tiller is running, list the pods in the kube-system namespace: ```CLI -$ kubectl get pods --namespace kube-system --kubeconfig="api/helm/kubeconfig.yaml" +$ kubectl get pods --namespace kube-system --kubeconfig="kubeconfig.yaml" ``` The Tiller pod name begins with the prefix tiller-deploy-. Now that we've installed both Helm components, we're ready to use helm to install our first application. + +## Setting up ingress +We need at least one nginx controller per kubernetes kluster, doh optionally we could set on up on a per namebase basis + +helm install stable/nginx-ingress --name loadbalancer --kubeconfig="kubeconfig.yaml" + ## Setting up Kubernetes Dashboard After we installed helm and tiller we can easily use both to install kubernetes dashboard ```CLI -$ helm install stable/kubernetes-dashboard --name dashboard --kubeconfig="api/helm/kubeconfig.yaml" --namespace="kube-system" +$ helm install stable/kubernetes-dashboard --name dashboard --kubeconfig="kubeconfig.yaml" --namespace="kube-system" ``` But before we can login to tiller we need a token, we can get one of those trough the secrets. Get yourself a secret list by running the following command ```CLI -$ kubectl -n kube-system get secret --kubeconfig="api/helm/kubeconfig.yaml" +$ kubectl -n kube-system get secret --kubeconfig="kubeconfig.yaml" ``` Because we just bound tiller to our admin account and use tiller (trough helm) to manage our code deployment it makes sense to use the tiller token, lets look at the tiller secret (it should look something like "tiller-token-XXXXX" and ask for the corresponding token. ```CLI -$ kubectl -n kube-system describe secrets tiller-token-xxxxx --kubeconfig="api/helm/kubeconfig.yaml" +$ kubectl -n kube-system describe secrets tiller-token-xxxxx --kubeconfig="kubeconfig.yaml" ``` This should return the token, copy it to somewhere save (just the token not the other returned information) and start up a dashboard connection ```CLI -$kubectl proxy --kubeconfig="api/helm/kubeconfig.yaml" +$kubectl proxy --kubeconfig="kubeconfig.yaml" ``` This should proxy our dashboard to helm making it available trough our favorite browser and a simple link diff --git a/api/.env b/api/.env index a2472076..235c628f 100644 --- a/api/.env +++ b/api/.env @@ -27,8 +27,8 @@ CONDUCTION_COMMONGROUND_BAG_APIKEY=!ChangeMe! #APP_NAME='pc' APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' APP_SECRET=!ChangeMe! -TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 -TRUSTED_HOSTS='^(.+\.)?localhost|api$' +#TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 +#TRUSTED_HOSTS='^(.+\.)?localhost|api$' ###< symfony/framework-bundle ### ###> symfony/framework-bundle ### diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml index 7d186ad6..8284abd9 100644 --- a/api/config/packages/twig.yaml +++ b/api/config/packages/twig.yaml @@ -22,7 +22,10 @@ twig: app_auth: '%env(AUTH_ENABLED)%' app_audittrail: '%env(AUDITTRAIL_ENABLED)%' app_notification: '%env(NOTIFICATION_ENABLED)%' - app_health: '%env(HEALTH_ENABLED)%' + app_health: '%env(HEALTH_ENABLED)%' + + trusted_hosts: '%env(TRUSTED_HOSTS)%' + trusted_proxies: '%env(TRUSTED_PROXIES)%' nlx_outway: '%env(NLX_OUTWAY)%' nlx_inway: '%env(NLX_INWAY)%' diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index 6c924078..1c549535 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -24,10 +24,39 @@ spec: {{- end }} {{- end }} rules: + - #host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} + http: + paths: + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} http: paths: - - path: /* - backend: - serviceName: {{ include "name" . }}-nginx + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 + - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.huwelijksplanner.online + http: + paths: + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 + - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.trouwplanner.online + http: + paths: + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 + - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.common-ground.nl + http: + paths: + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 + - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.larping.eu + http: + paths: + - backend: + serviceName: {{ include "name" . }} servicePort: 80 diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 3e671e4d..3f474c4a 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -16,7 +16,7 @@ settings: debug: 1 replicaCount: 1 corsAllowOrigin: ['*'] - trustedHosts: '^(.+\.)?conduction\.nl$|localhost' + trustedHosts: '^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.nl$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' pullPolicy: Always # You will need these proxies on kubernetes trustedProxies: diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 40241105..8b6ef17f 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -16,7 +16,7 @@ settings: debug: {{ app_debug }} replicaCount: 1 corsAllowOrigin: ['*'] - trustedHosts: '^(.+\.)?common-ground\.dev$|^(.+\.)?zaakonline\.nl$|^(.+\.)?conduction\.nl$|^example\.com$|^(.+\.)?178.128.142.152$|178.128.142.152|localhost' + trustedHosts: {{ trusted_hosts }} pullPolicy: Always # You will need these proxies on kubernetes trustedProxies: diff --git a/docker-compose.yml b/docker-compose.yml index 68795b67..51c9655a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,6 +40,8 @@ services: - APP_DEMO=${APP_DEMO} - APP_REPRO=${APP_REPRO} - APP_DESCRIPTION=${APP_DESCRIPTION} + - TRUSTED_PROXIES=${TRUSTED_PROXIES} + - TRUSTED_HOSTS=${TRUSTED_HOSTS} - AUTH_ENABLED=${AUTH_ENABLED} - AUDITTRAIL_ENABLED=${AUDITTRAIL_ENABLED} - NOTIFICATION_ENABLED=${NOTIFICATION_ENABLED} From a170188ba5205b2b6880aba3062d6eef32bb0272 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 5 Dec 2019 08:26:36 +0100 Subject: [PATCH 119/182] test --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index 71e479f4..483e5053 100644 --- a/.env +++ b/.env @@ -47,7 +47,7 @@ CONTAINER_REPRO=https://hub.docker.com/repository/docker/conduction/pc-php # Notifcation settings ################################################## -NOTIFICATION_ENABLED=false +NOTIFICATION_ENABLED=falsedxfddxf NOTIFICATION_PROVIDER=sasd NOTIFICATION_ENABLED_AUTHORIZATION=sasd From 03fb95557b97814220cb2e5c5ba0f69d80e0f53c Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Thu, 5 Dec 2019 11:06:22 +0100 Subject: [PATCH 120/182] Set component.domain instead of component.environment.domain when in prod --- api/helm/templates/ingress.yaml | 45 ++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index 1c549535..9c651cc4 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -24,12 +24,44 @@ spec: {{- end }} {{- end }} rules: - - #host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} - http: - paths: - - backend: - serviceName: {{ include "name" . }} - servicePort: 80 +# - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} +# http: +# paths: +# - backend: +# serviceName: {{ include "name" . }} +# servicePort: 80 + {{- if .Values.settings.env == 'prod' -}} + - host: {{ .Values.settings.name }}.{{ .Values.settings.domain }} + http: + paths: + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 + - host: {{ .Values.settings.name }}.huwelijksplanner.online + http: + paths: + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 + - host: {{ .Values.settings.name }}.trouwplanner.online + http: + paths: + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 + - host: {{ .Values.settings.name }}.common-ground.nl + http: + paths: + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 + - host: {{ .Values.settings.name }}.larping.eu + http: + paths: + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 + {{- else -}} - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} http: paths: @@ -60,3 +92,4 @@ spec: - backend: serviceName: {{ include "name" . }} servicePort: 80 + {{- end }} From 366c4fe9131704ae4ef56f1adc1ba30c027b1b67 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 5 Dec 2019 11:37:15 +0100 Subject: [PATCH 121/182] If then fix for ingress on prod env --- INSTALLATION.md | 12 ++++++------ api/helm/templates/ingress.yaml | 18 +++++++++++++++--- api/helm/values.yaml | 7 +++++++ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/INSTALLATION.md b/INSTALLATION.md index 96ea76d5..2e8410d6 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -72,16 +72,16 @@ $ helm dependency update ./api/helm ``` If you want to create a new instance ```CLI -$ helm install --name pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1,settings.loadbalancerEnabled=true -$ helm install --name pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0,settings.loadbalancerEnabled=true -$ helm install --name pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0,settings.loadbalancerEnabled=true +$ helm install --name pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1 +$ helm install --name pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0 +$ helm install --name pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0 ``` Or update if you want to update an existing one ```CLI -$ helm upgrade pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1,settings.loadbalancerEnabled=true -$ helm upgrade pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0,settings.loadbalancerEnabled=true -$ helm upgrade pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0,settings.loadbalancerEnabled=true +$ helm upgrade pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1 +$ helm upgrade pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0 +$ helm upgrade pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0 ``` Or del if you want to delete an existing one diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index 9c651cc4..ad27ed07 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -30,7 +30,7 @@ spec: # - backend: # serviceName: {{ include "name" . }} # servicePort: 80 - {{- if .Values.settings.env == 'prod' -}} + {{- if eq .Values.settings.env "prod" }} - host: {{ .Values.settings.name }}.{{ .Values.settings.domain }} http: paths: @@ -60,8 +60,14 @@ spec: paths: - backend: serviceName: {{ include "name" . }} - servicePort: 80 - {{- else -}} + servicePort: 80 + - host: {{ .Values.settings.name }}.zaakonline.eu + http: + paths: + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 + {{- else }} - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} http: paths: @@ -92,4 +98,10 @@ spec: - backend: serviceName: {{ include "name" . }} servicePort: 80 + - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.zaakonline.nl + http: + paths: + - backend: + serviceName: {{ include "name" . }} + servicePort: 80 {{- end }} diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 3f474c4a..11e81898 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -12,6 +12,13 @@ settings: repro: https://github.com/ConductionNL/Proto-component-commonground' demo: pc.zaakonline.nl domain: conduction.nl + domains: + - conduction.nl + - larping.eu + - zaakonline.nl + - huwelijksplanner.online + - trouwplanner.online + - common-ground.dev env: dev debug: 1 replicaCount: 1 From b02a0104d8aaae1404c02940563c58032c9e33fe Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 5 Dec 2019 11:58:27 +0100 Subject: [PATCH 122/182] Fix in yaml template --- api/helm/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 11e81898..3aab74a4 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -9,7 +9,7 @@ settings: title: Proto Component version: V.0.1 description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' - repro: https://github.com/ConductionNL/Proto-component-commonground' + repro: 'https://github.com/ConductionNL/Proto-component-commonground' demo: pc.zaakonline.nl domain: conduction.nl domains: From 705da9c0d3b1b90faef9d3176837e16135edbec1 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 5 Dec 2019 13:11:01 +0100 Subject: [PATCH 123/182] Update Values.yaml.twig --- api/templates/helm/Values.yaml.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 8b6ef17f..26d3ab44 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -9,7 +9,7 @@ settings: title: {{ app_title }} version: {{ app_version }} description: '{{ app_description }}' - repro: {{ app_repro }}' + repro: '{{ app_repro }}' domain: {{ app_domain }} demo: {{ app_demo }} env: {{ app_env }} From d2b9965e79789fd7dd518ccddd12c1594ebb2d41 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Thu, 5 Dec 2019 13:34:37 +0100 Subject: [PATCH 124/182] Trying to fix weird errors --- api/templates/helm/Values.yaml.twig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 26d3ab44..28b8fe07 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -16,24 +16,24 @@ settings: debug: {{ app_debug }} replicaCount: 1 corsAllowOrigin: ['*'] - trustedHosts: {{ trusted_hosts }} + trustedHosts: '^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.nl$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' pullPolicy: Always # You will need these proxies on kubernetes trustedProxies: - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16 - # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer + # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer loadbalancerEnabled: false # If you want to enable NLX you are requered to add the appropreate certificates to you nlx-settings folder (located in the /api folder) nlxInwayEnabled: {{ nlx_inway }} - # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer + # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer notificationEnabled: false audittrailEnabled: false authorisationEnabled: false healthEnabled: false archiveEnabled: false - + php: repository: docker.io/conduction/protocomponent-php From c74e1e4780be16fcd98c0dd987a781f67c6e7dca Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Thu, 5 Dec 2019 14:59:29 +0100 Subject: [PATCH 125/182] Fix a bug with env vs values --- .env | 16 ++++---- api/helm/values.yaml | 22 +++++------ api/public/schema/openapi.yaml | 57 +++++++++++++++++++++++++++-- api/templates/helm/Values.yaml.twig | 2 +- 4 files changed, 74 insertions(+), 23 deletions(-) diff --git a/.env b/.env index 483e5053..4bfa0eec 100644 --- a/.env +++ b/.env @@ -1,6 +1,6 @@ ################################################## -# -# General settings for your component +# +# General settings for your component # ################################################## @@ -18,14 +18,14 @@ APP_VERSION=V.0.1 APP_DEBUG=1 # What is the enviroment type you want to use for local production? (choose between dec,stag,prod, acce or test) APP_ENV=dev -# We use a build to tag images, this is swithced to the version on master and to env on other branches +# We use a build to tag images, this is swithced to the version on master and to env on other branches APP_BUILD=dev # The description for this api APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' # The urls on wich this api is available TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 -TRUSTED_HOSTS='^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.nl$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' +TRUSTED_HOSTS=^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.nl$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost ################################################## # Documentation settings @@ -78,17 +78,17 @@ HEALTH_ENABLED=false ARCHIVE_ENABLED=false ################################################## -# NLX Setup, read more at https://docs.nlx.io/get-started/# +# NLX Setup, read more at https://docs.nlx.io/get-started/# ################################################## # Do you want to provide an nlx outway? (option for your component to reach nlx services) -NLX_OUTWAY=true +NLX_OUTWAY=true # Do you want to provice an nlx inway (option for nlx services to reach your api) -NLX_INWAY=false +NLX_INWAY=false # NLX Certification Details -NLX_COUNTRY_NAME=Netherlands +NLX_COUNTRY_NAME=Netherlands NLX_STATE=Noord-Holland NLX_LOCALITY=Amsterdam NLX_ORGANIZATION_NAME=Conduction diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 3aab74a4..7f4d3075 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -10,15 +10,8 @@ settings: version: V.0.1 description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' repro: 'https://github.com/ConductionNL/Proto-component-commonground' - demo: pc.zaakonline.nl domain: conduction.nl - domains: - - conduction.nl - - larping.eu - - zaakonline.nl - - huwelijksplanner.online - - trouwplanner.online - - common-ground.dev + demo: pc.zaakonline.nl env: dev debug: 1 replicaCount: 1 @@ -30,17 +23,17 @@ settings: - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16 - # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer + # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer loadbalancerEnabled: false # If you want to enable NLX you are requered to add the appropreate certificates to you nlx-settings folder (located in the /api folder) nlxInwayEnabled: false - # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer + # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer notificationEnabled: false audittrailEnabled: false authorisationEnabled: false healthEnabled: false archiveEnabled: false - + php: repository: docker.io/conduction/protocomponent-php @@ -102,6 +95,13 @@ ingress: # - hosts: # - example.com # - mercure.example.com + hosts: + api: + host: example.com + serviceName: varnish + mercure: + host: mercure.example.com + serviceName: mercure resources: {} # We usually recommend not to specify default resources and to leave this as a conscious diff --git a/api/public/schema/openapi.yaml b/api/public/schema/openapi.yaml index d3c1e631..3cd704c7 100644 --- a/api/public/schema/openapi.yaml +++ b/api/public/schema/openapi.yaml @@ -524,7 +524,7 @@ components: schemas: ExampleEntity-read: type: object - description: 'This is an example entity' + description: 'This is an example entity.' properties: id: readOnly: true @@ -535,11 +535,14 @@ components: description: description: 'The description of this example property' type: string + camelCase: + description: 'Proof that we camel case our api' + type: string required: - name ExampleEntity-write: type: object - description: 'This is an example entity' + description: 'This is an example entity.' required: - name properties: @@ -549,13 +552,61 @@ components: description: description: 'The description of this example property' type: string + camelCase: + description: 'Proof that we camel case our api' + type: string +definitions: + ExampleEntity-read: + properties: + id: + example: e2984465-190a-4562-829e-a8cca81aa35d + format: uuid + name: + example: 'My Group' + maxLength: 255 + description: + example: 'Is the best group ever' + maxLength: 2555 + camelCase: + example: 'Best api ever' + maxLength: 255 + required: + - name + ExampleEntity-write: + properties: + name: + example: 'My Group' + maxLength: 255 + description: + example: 'Is the best group ever' + maxLength: 2555 + camelCase: + example: 'Best api ever' + maxLength: 255 + required: + - name tags: - name: ExampleEntity description: | - This is an example entity + This is an example entity. With an adtional description, all in all its pritty nice [url](www.google.nl) +securityDefinitions: + JWT-Oauth: + type: oauth2 + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + flow: implicit + scopes: + read: 'read right to the ExampleEntity resource' + write: 'write right to the ExampleEntity resource' + JWT-Token: + type: apiKey + in: header + name: Authorization + scopes: + read: 'read right to the ExampleEntity resource' + write: 'write right to the ExampleEntity resource' host: irc.zaakonline.nl servers: - diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 28b8fe07..8a8e6ae7 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -16,7 +16,7 @@ settings: debug: {{ app_debug }} replicaCount: 1 corsAllowOrigin: ['*'] - trustedHosts: '^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.nl$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' + trustedHosts: '{{ trusted_hosts }}' pullPolicy: Always # You will need these proxies on kubernetes trustedProxies: From 642f10ce234106f04e4fc1367728e59bb82ad7e0 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Thu, 5 Dec 2019 15:55:05 +0100 Subject: [PATCH 126/182] trigger another build --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index 4bfa0eec..edfba234 100644 --- a/.env +++ b/.env @@ -48,7 +48,7 @@ CONTAINER_REPRO=https://hub.docker.com/repository/docker/conduction/pc-php ################################################## NOTIFICATION_ENABLED=falsedxfddxf -NOTIFICATION_PROVIDER=sasd +NOTIFICATION_PROVIDER=sasdasd NOTIFICATION_ENABLED_AUTHORIZATION=sasd ################################################## From d36e73b104d143b8812e8b3f255e244be0b5d31d Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 10 Dec 2019 07:19:08 +0100 Subject: [PATCH 127/182] Added sesnsio framework etxra bundle --- api/composer.json | 1 + api/composer.lock | 84 ++++++++++++++++++- api/config/bundles.php | 29 +++---- .../packages/sensio_framework_extra.yaml | 3 + api/symfony.lock | 12 +++ 5 files changed, 112 insertions(+), 17 deletions(-) create mode 100644 api/config/packages/sensio_framework_extra.yaml diff --git a/api/composer.json b/api/composer.json index 5f2cf5aa..bc7545a9 100644 --- a/api/composer.json +++ b/api/composer.json @@ -13,6 +13,7 @@ "phpdocumentor/reflection-docblock": "^4.3", "ramsey/uuid": "^3.8", "ramsey/uuid-doctrine": "^1.5", + "sensio/framework-extra-bundle": "^5.5", "sensiolabs/security-checker": "^6.0", "stof/doctrine-extensions-bundle": "^1.3", "symfony/console": "4.3.*", diff --git a/api/composer.lock b/api/composer.lock index 72f0df7f..3fc1d7d6 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": "38df876b57237e6be24848f1f8f637da", + "content-hash": "a5cf6c5b0e2fcb4b7558cd2635260c67", "packages": [ { "name": "api-platform/api-pack", @@ -2229,8 +2229,8 @@ "authors": [ { "name": "Luís Otávio Cobucci Oblonczyk", - "email": "lcobucci@gmail.com", - "role": "Developer" + "role": "Developer", + "email": "lcobucci@gmail.com" } ], "description": "A simple library to work with JSON Web Token and JSON Web Signature", @@ -3249,6 +3249,84 @@ ], "time": "2018-08-11T21:01:22+00:00" }, + { + "name": "sensio/framework-extra-bundle", + "version": "v5.5.1", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git", + "reference": "dfc2c4df9f7d465a65c770e9feb578fe071636f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/dfc2c4df9f7d465a65c770e9feb578fe071636f7", + "reference": "dfc2c4df9f7d465a65c770e9feb578fe071636f7", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.0", + "php": ">=7.1.3", + "symfony/config": "^4.3|^5.0", + "symfony/dependency-injection": "^4.3|^5.0", + "symfony/framework-bundle": "^4.3|^5.0", + "symfony/http-kernel": "^4.3|^5.0" + }, + "conflict": { + "doctrine/doctrine-cache-bundle": "<1.3.1" + }, + "require-dev": { + "doctrine/doctrine-bundle": "^1.11|^2.0", + "doctrine/orm": "^2.5", + "nyholm/psr7": "^1.1", + "symfony/browser-kit": "^4.3|^5.0", + "symfony/dom-crawler": "^4.3|^5.0", + "symfony/expression-language": "^4.3|^5.0", + "symfony/finder": "^4.3|^5.0", + "symfony/monolog-bridge": "^4.0|^5.0", + "symfony/monolog-bundle": "^3.2", + "symfony/phpunit-bridge": "^4.3.5|^5.0", + "symfony/psr-http-message-bridge": "^1.1", + "symfony/security-bundle": "^4.3|^5.0", + "symfony/twig-bundle": "^4.3|^5.0", + "symfony/yaml": "^4.3|^5.0", + "twig/twig": "^1.34|^2.4|^3.0" + }, + "suggest": { + "symfony/expression-language": "", + "symfony/psr-http-message-bridge": "To use the PSR-7 converters", + "symfony/security-bundle": "" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "5.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sensio\\Bundle\\FrameworkExtraBundle\\": "src/" + }, + "exclude-from-classmap": [ + "/tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "This bundle provides a way to configure your controllers with annotations", + "keywords": [ + "annotations", + "controllers" + ], + "time": "2019-10-16T18:54:45+00:00" + }, { "name": "sensiolabs/security-checker", "version": "v6.0.3", diff --git a/api/config/bundles.php b/api/config/bundles.php index fa4a09fd..32cd19d9 100644 --- a/api/config/bundles.php +++ b/api/config/bundles.php @@ -1,19 +1,20 @@ ['all' => true], - Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], - Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true], - Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], - Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true], - Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], - 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], - Conduction\CommonGroundBundle\CommonGroundBundle::class => ['all' => true], - Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], + Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], + Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], + Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], + Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true], + Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], + Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true], + Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + 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], + Conduction\CommonGroundBundle\CommonGroundBundle::class => ['all' => true], + Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], - Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], - Tbbc\MoneyBundle\TbbcMoneyBundle::class => ['all' => true], + Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], + Tbbc\MoneyBundle\TbbcMoneyBundle::class => ['all' => true], ]; diff --git a/api/config/packages/sensio_framework_extra.yaml b/api/config/packages/sensio_framework_extra.yaml new file mode 100644 index 00000000..1821ccc0 --- /dev/null +++ b/api/config/packages/sensio_framework_extra.yaml @@ -0,0 +1,3 @@ +sensio_framework_extra: + router: + annotations: false diff --git a/api/symfony.lock b/api/symfony.lock index be591f61..4942a3b5 100644 --- a/api/symfony.lock +++ b/api/symfony.lock @@ -226,6 +226,18 @@ "config/packages/ramsey_uuid_doctrine.yaml" ] }, + "sensio/framework-extra-bundle": { + "version": "5.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "5.2", + "ref": "fb7e19da7f013d0d422fa9bce16f5c510e27609b" + }, + "files": [ + "config/packages/sensio_framework_extra.yaml" + ] + }, "sensiolabs/security-checker": { "version": "4.0", "recipe": { From fd514c7d3209d73d3b756e88019cb8b5f55a08ab Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 10 Dec 2019 11:35:16 +0100 Subject: [PATCH 128/182] Test voor certbot --- .env | 13 +++ api/config/packages/twig.yaml | 7 ++ api/helm/templates/ingress.yaml | 100 +++++++++++++++---- api/helm/templates/lets-encrypt-job.yaml | 39 ++++++++ api/helm/templates/lets-encrypt-secret.yaml | 12 +++ api/helm/templates/lets-encrypt-service.yaml | 16 +++ api/templates/helm/Values.yaml.twig | 1 + 7 files changed, 167 insertions(+), 21 deletions(-) create mode 100644 api/helm/templates/lets-encrypt-job.yaml create mode 100644 api/helm/templates/lets-encrypt-secret.yaml create mode 100644 api/helm/templates/lets-encrypt-service.yaml diff --git a/.env b/.env index edfba234..d2f0c4c3 100644 --- a/.env +++ b/.env @@ -27,6 +27,19 @@ APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) inte TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 TRUSTED_HOSTS=^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.nl$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost +################################################## +# Orgization details +################################################## + +# The following details describe your organisations and are used for both certificate creation and common-ground.dev + +ORGANIZATION_NAME=Conduction +ORGANIZATION_EMAIL_ADDRESS=info@conduction.nl +ORGANIZATION_COUNTRY_NAME=Netherlands +ORGANIZATION_STATE=Noord-Holland +ORGANIZATION_LOCALITY=Amsterdam +ORGANIZATION_UNIT_NAME=Common-Ground + ################################################## # Documentation settings ################################################## diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml index 8284abd9..26f06175 100644 --- a/api/config/packages/twig.yaml +++ b/api/config/packages/twig.yaml @@ -8,6 +8,13 @@ twig: container_registry_base: '%env(CONTAINER_REGISTRY_BASE)%' container_project_name: '%env(CONTAINER_PROJECT_NAME)%' + + organization_name: '%env(ORGANIZATION_NAME)%' + organization_email: '%env(ORGANIZATION_EMAIL_ADDRESS)%' + organization_country: '%env(ORGANIZATION_COUNTRY_NAME)%' + organization_state: '%env(ORGANIZATION_STATE)%' + organization_locality: '%env(ORGANIZATION_LOCALITY)%' + organization_unit: '%env(ORGANIZATION_UNIT_NAME)%' app_name: '%env(APP_NAME)%' app_title: '%env(APP_TITLE)%' diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index ad27ed07..d7cd7d40 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -13,16 +13,14 @@ metadata: {{- toYaml . | nindent 4 }} {{- end }} spec: -{{- if .Values.ingress.tls }} tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ .host | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} -{{- end }} + - hosts: + {{- if eq .Values.settings.env "prod" }} + - {{ .Values.settings.domain }} + {{- else }} + - {{ .Values.settings.env }}.{{ .Values.settings.domain }} + {{- end }} + secretName: {{ include "name" . }}-certs rules: # - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} # http: @@ -34,74 +32,134 @@ spec: - host: {{ .Values.settings.name }}.{{ .Values.settings.domain }} http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.huwelijksplanner.online http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.trouwplanner.online http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.common-ground.nl http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.larping.eu http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.zaakonline.eu http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 {{- else }} - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.huwelijksplanner.online http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.trouwplanner.online http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.common-ground.nl http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.larping.eu http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.zaakonline.nl http: paths: - - backend: + - path: /.well-known/* + backend: + serviceName: {{ include "name" . }}-letsencrypt + servicePort: 80 + - path: /* + backend: serviceName: {{ include "name" . }} servicePort: 80 {{- end }} diff --git a/api/helm/templates/lets-encrypt-job.yaml b/api/helm/templates/lets-encrypt-job.yaml new file mode 100644 index 00000000..ee55da01 --- /dev/null +++ b/api/helm/templates/lets-encrypt-job.yaml @@ -0,0 +1,39 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "name" . }}-letsencrypt-job + labels: + app.kubernetes.io/name: {{ include "name" . }} + app.kubernetes.io/part-of: {{ include "name" . }} + helm.sh/chart: {{ include "chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + template: + metadata: + name: {{ include "name" . }}-letsencrypt + labels: + app: {{ include "name" . }}-letsencrypt + spec: + containers: + # Bash script that starts an http server and launches certbot + # Fork of github.com/sjenning/kube-nginx-letsencrypt + - image: quay.io/hiphipjorge/kube-nginx-letsencrypt:latest + name: letsencrypt + imagePullPolicy: Always + ports: + - name: letsencrypt + containerPort: 80 + env: + {{- if eq .Values.settings.env "prod" }} + - name: DOMAINS + value: { .Values.settings.domain }} + {{- else }} + - name: DOMAINS + value: {{ .Values.settings.env }}.{{ .Values.settings.domain }} + {{- end }} + - name: EMAIL + value: {{ .Values.settings.email }} + - name: SECRET + value: {{ include "name" . }}-letsencrypt-certs + restartPolicy: Never \ No newline at end of file diff --git a/api/helm/templates/lets-encrypt-secret.yaml b/api/helm/templates/lets-encrypt-secret.yaml new file mode 100644 index 00000000..4ea2960a --- /dev/null +++ b/api/helm/templates/lets-encrypt-secret.yaml @@ -0,0 +1,12 @@ +# An empty secret (with no data) in order for the update to work +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "fullname" . }}-letsencrypt-certs + labels: + app.kubernetes.io/name: {{ include "name" . }} + app.kubernetes.io/part-of: {{ include "name" . }} + helm.sh/chart: {{ include "chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +type: Opaque \ No newline at end of file diff --git a/api/helm/templates/lets-encrypt-service.yaml b/api/helm/templates/lets-encrypt-service.yaml new file mode 100644 index 00000000..48247ae1 --- /dev/null +++ b/api/helm/templates/lets-encrypt-service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "name" . }}-letsencrypt + labels: + app.kubernetes.io/name: {{ include "name" . }} + app.kubernetes.io/part-of: {{ include "name" . }} + helm.sh/chart: {{ include "chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + selector: + app: {{ include "name" . }}-letsencrypt + ports: + - protocol: "TCP" + port: 80 \ No newline at end of file diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 8a8e6ae7..e9b28795 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -11,6 +11,7 @@ settings: description: '{{ app_description }}' repro: '{{ app_repro }}' domain: {{ app_domain }} + email: {{ organization_email }} demo: {{ app_demo }} env: {{ app_env }} debug: {{ app_debug }} From f0681520ce5f9b3fb972391c7c3a34bab6ac97aa Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 10 Dec 2019 14:47:53 +0100 Subject: [PATCH 129/182] Fixed certbot --- INSTALLATION.md | 42 ++++++++- api/helm/templates/cert-issuer.yaml | 16 ++++ api/helm/templates/certificate.yaml | 22 +++++ api/helm/templates/ingress.yaml | 96 ++++---------------- api/helm/templates/lets-encrypt-job.yaml | 39 -------- api/helm/templates/lets-encrypt-secret.yaml | 12 --- api/helm/templates/lets-encrypt-service.yaml | 16 ---- 7 files changed, 93 insertions(+), 150 deletions(-) create mode 100644 api/helm/templates/cert-issuer.yaml create mode 100644 api/helm/templates/certificate.yaml delete mode 100644 api/helm/templates/lets-encrypt-job.yaml delete mode 100644 api/helm/templates/lets-encrypt-secret.yaml delete mode 100644 api/helm/templates/lets-encrypt-service.yaml diff --git a/INSTALLATION.md b/INSTALLATION.md index 2e8410d6..5ed0a969 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -35,10 +35,19 @@ Now that we've installed both Helm components, we're ready to use helm to instal ## Setting up ingress We need at least one nginx controller per kubernetes kluster, doh optionally we could set on up on a per namebase basis -helm install stable/nginx-ingress --name loadbalancer --kubeconfig="kubeconfig.yaml" +```CLI +$ helm install stable/nginx-ingress --name loadbalancer --kubeconfig="kubeconfig.yaml" +``` + +We can check that out with + +```CLI +$ kubectl describe ingress pc-dev-ingress -n=kube-system --kubeconfig="kubeconfig.yaml" +``` ## Setting up Kubernetes Dashboard After we installed helm and tiller we can easily use both to install kubernetes dashboard + ```CLI $ helm install stable/kubernetes-dashboard --name dashboard --kubeconfig="kubeconfig.yaml" --namespace="kube-system" ``` @@ -57,7 +66,7 @@ $ kubectl -n kube-system describe secrets tiller-token-xxxxx --kubeconfig="kube This should return the token, copy it to somewhere save (just the token not the other returned information) and start up a dashboard connection ```CLI -$kubectl proxy --kubeconfig="kubeconfig.yaml" +$ kubectl proxy --kubeconfig="kubeconfig.yaml" ``` This should proxy our dashboard to helm making it available trough our favorite browser and a simple link @@ -65,6 +74,29 @@ This should proxy our dashboard to helm making it available trough our favorite http://localhost:8001/api/v1/namespaces/kube-system/services/https:dashboard-kubernetes-dashboard:https/proxy/#!/login ``` + +## Cert Manager +https://cert-manager.io/docs/installation/kubernetes/ + +```CLI +$ kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml --kubeconfig="kubeconfig.yaml" +$ kubectl create namespace cert-manager --kubeconfig="kubeconfig.yaml" +``` + + The we need tp deploy the cert manager to our cluster + +```CLI +$ helm repo add jetstack https://charts.jetstack.io +$ helm install --name cert-manager --namespace cert-manager --version v0.12.0 \ jetstack/cert-manager --kubeconfig="kubeconfig.yaml" +``` + +lets check if everything is working + +```CLI +$ kubectl get pods --namespace cert-manager --kubeconfig="kubeconfig.yaml" +$ kubectl describe certificate -n dev --kubeconfig="kubeconfig.yaml" +``` + ## Deploying trough helm First we always need to update our dependencies ```CLI @@ -86,9 +118,9 @@ $ helm upgrade pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --name Or del if you want to delete an existing one ```CLI -$ helm del pc-dev --purge --kubeconfig="api/helm/kubeconfig.yaml --namespace=dev" -$ helm del pc-stag --purge --kubeconfig="api/helm/kubeconfig.yaml --namespace=stag" -$ helm del pp-prod --purge --kubeconfig="api/helm/kubeconfig.yaml --namespace=prod" +$ helm del pc-dev --purge --kubeconfig="api/helm/kubeconfig.yaml" +$ helm del pc-stag --purge --kubeconfig="api/helm/kubeconfig.yaml" +$ helm del pc-prod --purge --kubeconfig="api/helm/kubeconfig.yaml" ``` Note that you can replace common ground with the namespace that you want to use (normally the name of your component). diff --git a/api/helm/templates/cert-issuer.yaml b/api/helm/templates/cert-issuer.yaml new file mode 100644 index 00000000..804486a2 --- /dev/null +++ b/api/helm/templates/cert-issuer.yaml @@ -0,0 +1,16 @@ +apiVersion: cert-manager.io/v1alpha2 +kind: ClusterIssuer +metadata: + name: {{ include "name" . }}-{{ .Values.settings.env }}-letsencrypt +spec: + acme: + email: {{ .Values.settings.email }} + http01: {} + privateKeySecretRef: + name: letsencrypt-private-key + server: https://acme-v02.api.letsencrypt.org/directory + solvers: + - selector: {} + http01: + ingress: + class: nginx \ No newline at end of file diff --git a/api/helm/templates/certificate.yaml b/api/helm/templates/certificate.yaml new file mode 100644 index 00000000..43dacaf8 --- /dev/null +++ b/api/helm/templates/certificate.yaml @@ -0,0 +1,22 @@ +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: {{ include "name" . }}-acme-cert +spec: + secretName: {{ include "name" . }}-tls-cert + duration: 24h + renewBefore: 12h + {{- if eq .Values.settings.env "prod" }} + commonName: {{ .Values.settings.name }}.{{ .Values.settings.domain }} + {{- else }} + commonName: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} + {{- end }} + dnsNames: + {{- if eq .Values.settings.env "prod" }} + - {{ .Values.settings.name }}.{{ .Values.settings.domain }} + {{- else }} + - {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} + {{- end }} + issuerRef: + name: {{ include "name" . }}-{{ .Values.settings.env }}-letsencrypt + kind: ClusterIssuer \ No newline at end of file diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index d7cd7d40..5c76e036 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -1,6 +1,10 @@ apiVersion: extensions/v1beta1 kind: Ingress metadata: + annotations: + # add an annotation indicating the issuer to use. + cert-manager.io/acme-challenge-type: http01 + cert-manager.io/cluster-issuer: {{ include "name" . }}-{{ .Values.settings.env }}-letsencrypt name: {{ include "name" . }}-{{ .Values.settings.env }}-ingress labels: app.kubernetes.io/name: {{ include "name" . }}-ingress @@ -13,14 +17,10 @@ metadata: {{- toYaml . | nindent 4 }} {{- end }} spec: - tls: + tls: - hosts: - {{- if eq .Values.settings.env "prod" }} - {{ .Values.settings.domain }} - {{- else }} - - {{ .Values.settings.env }}.{{ .Values.settings.domain }} - {{- end }} - secretName: {{ include "name" . }}-certs + secretName: {{ include "name" . }}-tls-cert rules: # - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} # http: @@ -32,134 +32,74 @@ spec: - host: {{ .Values.settings.name }}.{{ .Values.settings.domain }} http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.huwelijksplanner.online http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.trouwplanner.online http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.common-ground.nl http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.larping.eu http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.zaakonline.eu http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 {{- else }} - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.huwelijksplanner.online http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.trouwplanner.online http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.common-ground.nl http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.larping.eu http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.zaakonline.nl http: paths: - - path: /.well-known/* - backend: - serviceName: {{ include "name" . }}-letsencrypt - servicePort: 80 - - path: /* - backend: + - backend: serviceName: {{ include "name" . }} servicePort: 80 {{- end }} diff --git a/api/helm/templates/lets-encrypt-job.yaml b/api/helm/templates/lets-encrypt-job.yaml deleted file mode 100644 index ee55da01..00000000 --- a/api/helm/templates/lets-encrypt-job.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ include "name" . }}-letsencrypt-job - labels: - app.kubernetes.io/name: {{ include "name" . }} - app.kubernetes.io/part-of: {{ include "name" . }} - helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} -spec: - template: - metadata: - name: {{ include "name" . }}-letsencrypt - labels: - app: {{ include "name" . }}-letsencrypt - spec: - containers: - # Bash script that starts an http server and launches certbot - # Fork of github.com/sjenning/kube-nginx-letsencrypt - - image: quay.io/hiphipjorge/kube-nginx-letsencrypt:latest - name: letsencrypt - imagePullPolicy: Always - ports: - - name: letsencrypt - containerPort: 80 - env: - {{- if eq .Values.settings.env "prod" }} - - name: DOMAINS - value: { .Values.settings.domain }} - {{- else }} - - name: DOMAINS - value: {{ .Values.settings.env }}.{{ .Values.settings.domain }} - {{- end }} - - name: EMAIL - value: {{ .Values.settings.email }} - - name: SECRET - value: {{ include "name" . }}-letsencrypt-certs - restartPolicy: Never \ No newline at end of file diff --git a/api/helm/templates/lets-encrypt-secret.yaml b/api/helm/templates/lets-encrypt-secret.yaml deleted file mode 100644 index 4ea2960a..00000000 --- a/api/helm/templates/lets-encrypt-secret.yaml +++ /dev/null @@ -1,12 +0,0 @@ -# An empty secret (with no data) in order for the update to work -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "fullname" . }}-letsencrypt-certs - labels: - app.kubernetes.io/name: {{ include "name" . }} - app.kubernetes.io/part-of: {{ include "name" . }} - helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} -type: Opaque \ No newline at end of file diff --git a/api/helm/templates/lets-encrypt-service.yaml b/api/helm/templates/lets-encrypt-service.yaml deleted file mode 100644 index 48247ae1..00000000 --- a/api/helm/templates/lets-encrypt-service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "name" . }}-letsencrypt - labels: - app.kubernetes.io/name: {{ include "name" . }} - app.kubernetes.io/part-of: {{ include "name" . }} - helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} -spec: - selector: - app: {{ include "name" . }}-letsencrypt - ports: - - protocol: "TCP" - port: 80 \ No newline at end of file From 75e28298b02939271a483a684fedf564b1b4b906 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Tue, 10 Dec 2019 14:51:37 +0100 Subject: [PATCH 130/182] Replaced deprecated interface --- api/src/Repository/ExampleEntityRepository.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/Repository/ExampleEntityRepository.php b/api/src/Repository/ExampleEntityRepository.php index 7baa698c..692bece7 100644 --- a/api/src/Repository/ExampleEntityRepository.php +++ b/api/src/Repository/ExampleEntityRepository.php @@ -4,7 +4,7 @@ use App\Entity\ExampleEntity; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; -use Symfony\Bridge\Doctrine\RegistryInterface; +use Doctrine\Common\Persistence\ManagerRegistry; /** * @method ExampleEntity|null find($id, $lockMode = null, $lockVersion = null) @@ -14,7 +14,7 @@ */ class ExampleEntityRepository extends ServiceEntityRepository { - public function __construct(RegistryInterface $registry) + public function __construct(ManagerRegistry $registry) { parent::__construct($registry, ExampleEntity::class); } From ae03943e0c16bac86d1cf2ae1f22161b21f62ab5 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 10 Dec 2019 13:56:48 +0000 Subject: [PATCH 131/182] Apply fixes from StyleCI --- api/config/bundles.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/api/config/bundles.php b/api/config/bundles.php index 32cd19d9..b3f9617a 100644 --- a/api/config/bundles.php +++ b/api/config/bundles.php @@ -1,20 +1,20 @@ ['all' => true], - Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], - Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], - Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true], - Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], - Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true], - Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], - 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], - Conduction\CommonGroundBundle\CommonGroundBundle::class => ['all' => true], - Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], + Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], + Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], + Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], + Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true], + Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], + Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true], + Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + 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], + Conduction\CommonGroundBundle\CommonGroundBundle::class => ['all' => true], + Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], - Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], - Tbbc\MoneyBundle\TbbcMoneyBundle::class => ['all' => true], + Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], + Tbbc\MoneyBundle\TbbcMoneyBundle::class => ['all' => true], ]; From 06bc6bc194b643c8a09d43f287ce8b98a3d3f00d Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 10 Dec 2019 15:47:56 +0100 Subject: [PATCH 132/182] Fix on .env variable and an increase of the php containers to 3 --- api/helm/templates/configmap.yaml | 7 ++++++ api/helm/templates/php-deployment.yaml | 32 +++++++++++++++++++++++--- api/templates/helm/Values.yaml.twig | 7 +++++- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/api/helm/templates/configmap.yaml b/api/helm/templates/configmap.yaml index d3b97459..39c5e996 100644 --- a/api/helm/templates/configmap.yaml +++ b/api/helm/templates/configmap.yaml @@ -25,6 +25,13 @@ data: app-health: {{ .Values.settings.healthEnabled | quote }} app-archive: {{ .Values.settings.archiveEnabled | quote }} + organization-name: {{ .Values.settings.organisationMame | quote }} + organization-email: {{ .Values.settings.email | quote }} + organization-country: {{ .Values.settings.country | quote }} + organization-state: {{ .Values.settings.state | quote }} + organization-locality: {{ .Values.settings.locality | quote }} + organization-unit: {{ .Values.settings.unit | quote }} + env: {{ .Values.settings.env | quote }} debug: {{ .Values.settings.debug | quote }} cors-allow-origin: {{ .Values.settings.corsAllowOrigin | quote }} diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index 3f09ef5d..611e5d39 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -9,7 +9,7 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: - replicas: {{ .Values.php.replicaCount }} + replicas: 3 template: metadata: labels: @@ -82,11 +82,37 @@ spec: configMapKeyRef: name: {{ template "fullname" . }} key: app-domain - - name: APP_REPRO + # organization + - name: ORGANIZATION_NAME valueFrom: configMapKeyRef: name: {{ template "fullname" . }} - key: app-repro + key: organization-name + - name: ORGANIZATION_EMAIL_ADDRESS + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: organization-email + - name: ORGANIZATION_COUNTRY_NAME + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: organization-country + - name: ORGANIZATION_STATE + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: organization-state + - name: ORGANIZATION_LOCALITY + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: organization-locality + - name: ORGANIZATION_UNIT_NAME + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: organization-unit # config - name: AUTH_ENABLED valueFrom: diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index e9b28795..616c3f77 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -10,8 +10,13 @@ settings: version: {{ app_version }} description: '{{ app_description }}' repro: '{{ app_repro }}' - domain: {{ app_domain }} + domain: {{ app_domain }} + organisationName: {{ organization_name }} email: {{ organization_email }} + country: {{ organization_country }} + state: {{ organization_state }} + locality: {{ organization_locality }} + unit: {{ unit }} demo: {{ app_demo }} env: {{ app_env }} debug: {{ app_debug }} From 0d1fe68c642413f8bfb9b105ab376c415658c76d Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 10 Dec 2019 15:57:22 +0100 Subject: [PATCH 133/182] Added missing .env variables --- docker-compose.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 51c9655a..4d7436b7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,6 +40,12 @@ services: - APP_DEMO=${APP_DEMO} - APP_REPRO=${APP_REPRO} - APP_DESCRIPTION=${APP_DESCRIPTION} + - ORGANIZATION_NAME=${ORGANIZATION_NAME} + - ORGANIZATION_EMAIL_ADDRESS=${ORGANIZATION_EMAIL_ADDRESS} + - ORGANIZATION_COUNTRY_NAME=${ORGANIZATION_COUNTRY_NAME} + - ORGANIZATION_STATE=${ORGANIZATION_STATE} + - ORGANIZATION_LOCALITY=${ORGANIZATION_LOCALITY} + - ORGANIZATION_UNIT_NAME=${ORGANIZATION_UNIT_NAME} - TRUSTED_PROXIES=${TRUSTED_PROXIES} - TRUSTED_HOSTS=${TRUSTED_HOSTS} - AUTH_ENABLED=${AUTH_ENABLED} From 43c9ea0bede798d6479df097991299ce0db00f83 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 10 Dec 2019 16:07:30 +0100 Subject: [PATCH 134/182] Fix on organisation unit --- api/templates/helm/Values.yaml.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 616c3f77..37ec6129 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -16,7 +16,7 @@ settings: country: {{ organization_country }} state: {{ organization_state }} locality: {{ organization_locality }} - unit: {{ unit }} + unit: {{ organization_unit }} demo: {{ app_demo }} env: {{ app_env }} debug: {{ app_debug }} From 4ef9753fbe70b5abec418ef99f2708aa75f22526 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 10 Dec 2019 17:04:04 +0100 Subject: [PATCH 135/182] Added doctrine shema check to ci/cd --- .github/workflows/dockerimage.yml | 2 ++ api/helm/values.yaml | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 4f8b430e..e5ca75c3 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -63,6 +63,8 @@ jobs: run: docker-compose logs - name: Security Checks run: docker-compose exec -T php composer req sensiolabs/security-checker + - name: Database Check + run: docker-compose exec -T php bin/console doctrine:schema:validate - name: Chores run: docker-compose down - name: Login to DockerHub Registry diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 7f4d3075..18c2d9e3 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -10,7 +10,13 @@ settings: version: V.0.1 description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' repro: 'https://github.com/ConductionNL/Proto-component-commonground' - domain: conduction.nl + domain: conduction.nl + organisationName: Conduction + email: info@conduction.nl + country: Netherlands + state: Noord-Holland + locality: Amsterdam + unit: Common-Ground demo: pc.zaakonline.nl env: dev debug: 1 From 3c801ea5aa06204a66d6268bf88c332d8fedd414 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 10 Dec 2019 17:38:58 +0100 Subject: [PATCH 136/182] Add database update to ci/cd --- .github/workflows/dockerimage.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index e5ca75c3..3be28c02 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -63,6 +63,8 @@ jobs: run: docker-compose logs - name: Security Checks run: docker-compose exec -T php composer req sensiolabs/security-checker + - name: Database Update + run: docker-compose exec -T php bin/console doctrine:schema:update --force - name: Database Check run: docker-compose exec -T php bin/console doctrine:schema:validate - name: Chores From 06075d0a201dbcd6879092ad7d9609173f22f5d5 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 10 Dec 2019 22:20:19 +0100 Subject: [PATCH 137/182] Domain to domains An array should make it possible to obtain several security certificates --- .env | 1 + api/config/packages/twig.yaml | 11 +++++++++++ api/helm/values.yaml | 7 +++++++ api/templates/helm/Values.yaml.twig | 4 ++++ docker-compose.yml | 1 + 5 files changed, 24 insertions(+) diff --git a/.env b/.env index d2f0c4c3..dc31d8a8 100644 --- a/.env +++ b/.env @@ -45,6 +45,7 @@ ORGANIZATION_UNIT_NAME=Common-Ground ################################################## APP_DOMAIN=conduction.nl +APP_DOMAINS=["conduction.nl","zaakonline.nl","larping.eu","common-ground.dev","trouwplanner.online","huwelijksplanner.online"] APP_DEMO=pc.zaakonline.nl APP_REPRO=https://github.com/ConductionNL/Proto-component-commonground diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml index 26f06175..ee6c1853 100644 --- a/api/config/packages/twig.yaml +++ b/api/config/packages/twig.yaml @@ -1,3 +1,13 @@ +parameters: + env(APP_DOMAINS): '[]' + # Organisation stuff + env(ORGANIZATION_NAME): '' + env(ORGANIZATION_EMAIL_ADDRESS): '' + env(ORGANIZATION_COUNTRY_NAME): '' + env(ORGANIZATION_STATE): '' + env(ORGANIZATION_LOCALITY): '' + env(ORGANIZATION_UNIT_NAME): '' + twig: default_path: '%kernel.project_dir%/templates' debug: '%kernel.debug%' @@ -22,6 +32,7 @@ twig: app_env: '%env(APP_ENV)%' app_debug: '%env(APP_DEBUG)%' app_domain: '%env(APP_DOMAIN)%' + app_domains: '%env(json:APP_DOMAINS)%' app_demo: '%env(APP_DEMO)%' app_repro: '%env(APP_REPRO)%' app_description: '%env(APP_DESCRIPTION)%' diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 18c2d9e3..93067cb8 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -11,6 +11,13 @@ settings: description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' repro: 'https://github.com/ConductionNL/Proto-component-commonground' domain: conduction.nl + domains: + - conduction.nl + - zaakonline.nl + - larping.eu + - common-ground.dev + - trouwplanner.online + - huwelijksplanner.online organisationName: Conduction email: info@conduction.nl country: Netherlands diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 37ec6129..aade15ab 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -11,6 +11,10 @@ settings: description: '{{ app_description }}' repro: '{{ app_repro }}' domain: {{ app_domain }} + domains: +{% for domain in app_domains %} + - {{ domain }} +{% endfor %} organisationName: {{ organization_name }} email: {{ organization_email }} country: {{ organization_country }} diff --git a/docker-compose.yml b/docker-compose.yml index 4d7436b7..3c8a82c8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -37,6 +37,7 @@ services: - APP_NAME=${APP_NAME} - APP_TITLE=${APP_TITLE} - APP_DOMAIN=${APP_DOMAIN} + - APP_DOMAINS=${APP_DOMAINS} - APP_DEMO=${APP_DEMO} - APP_REPRO=${APP_REPRO} - APP_DESCRIPTION=${APP_DESCRIPTION} From ed9f8a5e0df8eff18d522dfd6fe61f7d4eaa389a Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 11 Dec 2019 09:19:58 +0100 Subject: [PATCH 138/182] Fix on conflicting secrets --- api/helm/templates/certificate.yaml | 9 ++------- api/helm/templates/ingress.yaml | 5 ++++- api/templates/helm/Values.yaml.twig | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/api/helm/templates/certificate.yaml b/api/helm/templates/certificate.yaml index 43dacaf8..85095579 100644 --- a/api/helm/templates/certificate.yaml +++ b/api/helm/templates/certificate.yaml @@ -1,16 +1,11 @@ apiVersion: cert-manager.io/v1alpha2 kind: Certificate metadata: - name: {{ include "name" . }}-acme-cert + name: {{ include "name" . }}-{{ .Values.settings.env }}-cert spec: - secretName: {{ include "name" . }}-tls-cert + secretName: {{ include "name" . }}-{{ .Values.settings.env }}-cert duration: 24h renewBefore: 12h - {{- if eq .Values.settings.env "prod" }} - commonName: {{ .Values.settings.name }}.{{ .Values.settings.domain }} - {{- else }} - commonName: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} - {{- end }} dnsNames: {{- if eq .Values.settings.env "prod" }} - {{ .Values.settings.name }}.{{ .Values.settings.domain }} diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index 5c76e036..45380689 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -19,8 +19,11 @@ metadata: spec: tls: - hosts: + # {{- range .Values.settings.domains }} + # - {{ .domain | quote }} + # {{- end }} - {{ .Values.settings.domain }} - secretName: {{ include "name" . }}-tls-cert + secretName: {{ include "name" . }}-{{ .Values.settings.env }}-cert rules: # - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} # http: diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index aade15ab..c44953a6 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -13,7 +13,7 @@ settings: domain: {{ app_domain }} domains: {% for domain in app_domains %} - - {{ domain }} + - domain: {{ domain }} {% endfor %} organisationName: {{ organization_name }} email: {{ organization_email }} From 796c48dd4852434e87db85ed06314bfd339f9f93 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 11 Dec 2019 10:13:37 +0100 Subject: [PATCH 139/182] Add conditions to perform a helm install --- .github/workflows/dockerimage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 3be28c02..091c7edd 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -99,7 +99,7 @@ jobs: if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: helm upgrade $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Install through helm - if: failure() + if: failure() && (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' run: helm install --name $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 - name: Rollout new containers if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' && success() From d547dcf605e1cdf939ce90bcfaf8ffe8e86b1b2f Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 12 Dec 2019 09:07:50 +0100 Subject: [PATCH 140/182] Updates to config - fix op composer - multi domain certificates - swagger proterties fix --- .env | 9 ++++++++- api/Dockerfile | 3 +++ api/helm/templates/certificate.yaml | 8 +++++--- api/helm/templates/ingress.yaml | 6 ++++-- api/src/Swagger/SwaggerDecorator.php | 5 ++++- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/.env b/.env index dc31d8a8..db64850a 100644 --- a/.env +++ b/.env @@ -31,7 +31,7 @@ TRUSTED_HOSTS=^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)? # Orgization details ################################################## -# The following details describe your organisations and are used for both certificate creation and common-ground.dev +# The following details describe your organisations and are used for both certificate creation, nlx (if active) and common-ground.dev ORGANIZATION_NAME=Conduction ORGANIZATION_EMAIL_ADDRESS=info@conduction.nl @@ -44,9 +44,15 @@ ORGANIZATION_UNIT_NAME=Common-Ground # Documentation settings ################################################## +# The primary domain for this API @depracticed APP_DOMAIN=conduction.nl +# he domains on wich you want to provide this component, the first wil be used as primary (or common in cert-manger terms) APP_DOMAINS=["conduction.nl","zaakonline.nl","larping.eu","common-ground.dev","trouwplanner.online","huwelijksplanner.online"] +# If set to true wil provide the component on an {APP_NAME}.{APP_DOMAIN} basis for production enviroment, and {APP_NAME}.{APP_ENV}.{APP_DOMAIN} basis for other enviroments. Wil skipp the {APP_NAME}. on both if set to false +APP_USE_NAME_AS_SUBDOMAIN=true +# The demo enviroment for this component @depracticed APP_DEMO=pc.zaakonline.nl +# he Repository for this component APP_REPRO=https://github.com/ConductionNL/Proto-component-commonground ################################################## @@ -55,6 +61,7 @@ APP_REPRO=https://github.com/ConductionNL/Proto-component-commonground CONTAINER_REGISTRY_BASE=docker.io/conduction CONTAINER_PROJECT_NAME=pc +# The repository for the primary (php) container of this project CONTAINER_REPRO=https://hub.docker.com/repository/docker/conduction/pc-php ################################################## diff --git a/api/Dockerfile b/api/Dockerfile index 1b028ba9..aae76b53 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -104,6 +104,9 @@ RUN set -eux; \ chmod +x bin/console; sync VOLUME /srv/api/var +# Now that we have our own composer lets update +RUN composer update --no-interaction + COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint RUN chmod +x /usr/local/bin/docker-entrypoint diff --git a/api/helm/templates/certificate.yaml b/api/helm/templates/certificate.yaml index 85095579..e831c7af 100644 --- a/api/helm/templates/certificate.yaml +++ b/api/helm/templates/certificate.yaml @@ -7,10 +7,12 @@ spec: duration: 24h renewBefore: 12h dnsNames: - {{- if eq .Values.settings.env "prod" }} - - {{ .Values.settings.name }}.{{ .Values.settings.domain }} + {{- range .Values.settings.domains }} + {{- if eq $.Values.settings.env "prod" }} + - {{ $.Values.settings.name }}.{{ . }} {{- else }} - - {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} + - {{ $.Values.settings.name }}.{{ $.Values.settings.env }}.{{ . }} + {{- end }} {{- end }} issuerRef: name: {{ include "name" . }}-{{ .Values.settings.env }}-letsencrypt diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index 45380689..0ba65e6f 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -21,8 +21,10 @@ spec: - hosts: # {{- range .Values.settings.domains }} # - {{ .domain | quote }} - # {{- end }} - - {{ .Values.settings.domain }} + # {{- end }} + {{- with .Values.settings.domains }} + {{- toYaml . | nindent 4 }} + {{- end }} secretName: {{ include "name" . }}-{{ .Values.settings.env }}-cert rules: # - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 28b4d3e5..2c8b5eba 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -113,7 +113,10 @@ public function normalize($object, $format = null, array $context = []) //$additionalEntityDocs = $this->getAdditionalEntityDocs($entity); $entityDocs = $this->getAdditionalEntityDocs($entity); - $additionalDocs = array_merge($additionalDocs, $entityDocs['properties']); + // Only run if we have aditional docs + if(in_array('properties',$entityDocs)){ + $additionalDocs = array_merge($additionalDocs, $entityDocs['properties']); + } // Security $docs['securityDefinitions']['JWT-Oauth']['scopes'] = array_merge($docs['securityDefinitions']['JWT-Oauth']['scopes'], $entityDocs['security']); From afa5afdd76a2a582fcf640eacdee4b64de2da65e Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Thu, 12 Dec 2019 16:33:33 +0100 Subject: [PATCH 141/182] Small bugfix and the adding of gd --- api/helm/templates/ingress.yaml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index 0ba65e6f..c0a8d1fe 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -18,13 +18,11 @@ metadata: {{- end }} spec: tls: - - hosts: - # {{- range .Values.settings.domains }} - # - {{ .domain | quote }} - # {{- end }} - {{- with .Values.settings.domains }} - {{- toYaml . | nindent 4 }} - {{- end }} + - hosts: + #{{- with .Values.settings.domains }} + {{- toYaml .Values.settings.domains | nindent 4 }} + #{{- end }} + #- {{ .domain | quote }} secretName: {{ include "name" . }}-{{ .Values.settings.env }}-cert rules: # - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} From 527a8e784c432315377c57552c2953ab15f504d7 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Fri, 13 Dec 2019 07:17:30 +0100 Subject: [PATCH 142/182] Multi domain ssl --- .env | 2 +- api/Dockerfile | 1 + api/helm/templates/certificate.yaml | 6 +- api/helm/templates/configmap.yaml | 2 +- api/helm/templates/ingress.yaml | 91 ++++------------------------ api/src/Swagger/SwaggerDecorator.php | 2 +- 6 files changed, 18 insertions(+), 86 deletions(-) diff --git a/.env b/.env index db64850a..1f2db881 100644 --- a/.env +++ b/.env @@ -25,7 +25,7 @@ APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) inte # The urls on wich this api is available TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 -TRUSTED_HOSTS=^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.nl$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost +TRUSTED_HOSTS=^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost ################################################## # Orgization details diff --git a/api/Dockerfile b/api/Dockerfile index aae76b53..cccb535c 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -40,6 +40,7 @@ RUN set -eux; \ zip \ mysqli \ pdo_mysql \ + gd \ ; \ pecl install \ apcu-${APCU_VERSION} \ diff --git a/api/helm/templates/certificate.yaml b/api/helm/templates/certificate.yaml index e831c7af..6d7d47d5 100644 --- a/api/helm/templates/certificate.yaml +++ b/api/helm/templates/certificate.yaml @@ -7,13 +7,13 @@ spec: duration: 24h renewBefore: 12h dnsNames: - {{- range .Values.settings.domains }} +{{- range .Values.settings.domains }} {{- if eq $.Values.settings.env "prod" }} - - {{ $.Values.settings.name }}.{{ . }} + - {{ $.Values.settings.name }}.{{ . }} {{- else }} - {{ $.Values.settings.name }}.{{ $.Values.settings.env }}.{{ . }} {{- end }} - {{- end }} +{{- end }} issuerRef: name: {{ include "name" . }}-{{ .Values.settings.env }}-letsencrypt kind: ClusterIssuer \ No newline at end of file diff --git a/api/helm/templates/configmap.yaml b/api/helm/templates/configmap.yaml index 39c5e996..41f37e42 100644 --- a/api/helm/templates/configmap.yaml +++ b/api/helm/templates/configmap.yaml @@ -25,7 +25,7 @@ data: app-health: {{ .Values.settings.healthEnabled | quote }} app-archive: {{ .Values.settings.archiveEnabled | quote }} - organization-name: {{ .Values.settings.organisationMame | quote }} + organization-name: {{ .Values.settings.organisationName | quote }} organization-email: {{ .Values.settings.email | quote }} organization-country: {{ .Values.settings.country | quote }} organization-state: {{ .Values.settings.state | quote }} diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index c0a8d1fe..68553258 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -12,97 +12,28 @@ metadata: helm.sh/chart: {{ include "chart" . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} - {{- with .Values.ingress.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} spec: tls: - hosts: - #{{- with .Values.settings.domains }} - {{- toYaml .Values.settings.domains | nindent 4 }} - #{{- end }} - #- {{ .domain | quote }} + {{- range .Values.settings.domains }} + - {{ . }} + {{- end }} secretName: {{ include "name" . }}-{{ .Values.settings.env }}-cert rules: -# - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} -# http: -# paths: -# - backend: -# serviceName: {{ include "name" . }} -# servicePort: 80 - {{- if eq .Values.settings.env "prod" }} - - host: {{ .Values.settings.name }}.{{ .Values.settings.domain }} - http: - paths: - - backend: - serviceName: {{ include "name" . }} - servicePort: 80 - - host: {{ .Values.settings.name }}.huwelijksplanner.online - http: - paths: - - backend: - serviceName: {{ include "name" . }} - servicePort: 80 - - host: {{ .Values.settings.name }}.trouwplanner.online - http: - paths: - - backend: - serviceName: {{ include "name" . }} - servicePort: 80 - - host: {{ .Values.settings.name }}.common-ground.nl - http: - paths: - - backend: - serviceName: {{ include "name" . }} - servicePort: 80 - - host: {{ .Values.settings.name }}.larping.eu + {{- range .Values.settings.domains }} + {{- if eq $.Values.settings.env "prod" }} + - host: {{ $.Values.settings.name }}.{{ . }} http: paths: - backend: - serviceName: {{ include "name" . }} - servicePort: 80 - - host: {{ .Values.settings.name }}.zaakonline.eu - http: - paths: - - backend: - serviceName: {{ include "name" . }} - servicePort: 80 + serviceName: {{ $.Values.settings.name }} + servicePort: 80 {{- else }} - - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} + - host: {{ $.Values.settings.name }}.{{ $.Values.settings.env }}.{{ . }} http: paths: - backend: - serviceName: {{ include "name" . }} - servicePort: 80 - - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.huwelijksplanner.online - http: - paths: - - backend: - serviceName: {{ include "name" . }} - servicePort: 80 - - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.trouwplanner.online - http: - paths: - - backend: - serviceName: {{ include "name" . }} - servicePort: 80 - - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.common-ground.nl - http: - paths: - - backend: - serviceName: {{ include "name" . }} - servicePort: 80 - - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.larping.eu - http: - paths: - - backend: - serviceName: {{ include "name" . }} - servicePort: 80 - - host: {{ .Values.settings.name }}.{{ .Values.settings.env }}.zaakonline.nl - http: - paths: - - backend: - serviceName: {{ include "name" . }} + serviceName: {{ $.Values.settings.name }} servicePort: 80 {{- end }} + {{- end }} diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index 2c8b5eba..b0610232 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -114,7 +114,7 @@ public function normalize($object, $format = null, array $context = []) //$additionalEntityDocs = $this->getAdditionalEntityDocs($entity); $entityDocs = $this->getAdditionalEntityDocs($entity); // Only run if we have aditional docs - if(in_array('properties',$entityDocs)){ + if(array_key_exists('properties',$entityDocs)){ $additionalDocs = array_merge($additionalDocs, $entityDocs['properties']); } From 456a6f0a21cacf01d32d9749fe14dd1c3156f95c Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Fri, 13 Dec 2019 07:56:14 +0100 Subject: [PATCH 143/182] Fix on gd install --- api/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/Dockerfile b/api/Dockerfile index cccb535c..df2d1875 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -29,6 +29,7 @@ RUN set -eux; \ $PHPIZE_DEPS \ icu-dev \ libzip-dev \ + libpng-dev \ postgresql-dev \ zlib-dev \ ; \ @@ -40,6 +41,7 @@ RUN set -eux; \ zip \ mysqli \ pdo_mysql \ + pcntl \ gd \ ; \ pecl install \ From 3f06e3b19192872b7f9a4587ccc87c2a8ec54bdc Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Fri, 13 Dec 2019 09:59:44 +0100 Subject: [PATCH 144/182] Switching around tests to prevent contamination --- .github/workflows/dockerimage.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 091c7edd..2b2a636f 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -61,12 +61,13 @@ jobs: run: docker ps - name: Dumping the logs run: docker-compose logs - - name: Security Checks - run: docker-compose exec -T php composer req sensiolabs/security-checker - name: Database Update run: docker-compose exec -T php bin/console doctrine:schema:update --force - name: Database Check run: docker-compose exec -T php bin/console doctrine:schema:validate + - name: Security Checks + run: docker-compose exec -T php composer req sensiolabs/security-checker + - name: Chores run: docker-compose down - name: Login to DockerHub Registry From 97b06876001770fe52fa52efb816ac6611247872 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Fri, 13 Dec 2019 10:35:05 +0100 Subject: [PATCH 145/182] fix on value generation --- api/helm/templates/certificate.yaml | 5 +++++ api/helm/templates/ingress.yaml | 1 + api/helm/templates/php-deployment.yaml | 2 +- api/helm/values.yaml | 14 +++++++------- api/templates/helm/Values.yaml.twig | 2 +- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/api/helm/templates/certificate.yaml b/api/helm/templates/certificate.yaml index 6d7d47d5..78415e0d 100644 --- a/api/helm/templates/certificate.yaml +++ b/api/helm/templates/certificate.yaml @@ -7,6 +7,11 @@ spec: duration: 24h renewBefore: 12h dnsNames: +# {{- if eq .Values.settings.env "prod" }} +# - {{ .Values.settings.name }}.{{ .Values.settings.domain }} +# {{- else }} +# - {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} +# {{- end }} {{- range .Values.settings.domains }} {{- if eq $.Values.settings.env "prod" }} - {{ $.Values.settings.name }}.{{ . }} diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index 68553258..a684f9fc 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -18,6 +18,7 @@ spec: {{- range .Values.settings.domains }} - {{ . }} {{- end }} +# - {{ .Values.settings.domain }} secretName: {{ include "name" . }}-{{ .Values.settings.env }}-cert rules: {{- range .Values.settings.domains }} diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index 611e5d39..2d5df508 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -9,7 +9,7 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: - replicas: 3 + replicas: 1 template: metadata: labels: diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 93067cb8..78a6fb18 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -12,12 +12,12 @@ settings: repro: 'https://github.com/ConductionNL/Proto-component-commonground' domain: conduction.nl domains: - - conduction.nl - - zaakonline.nl - - larping.eu - - common-ground.dev - - trouwplanner.online - - huwelijksplanner.online + - domain: conduction.nl + - domain: zaakonline.nl + - domain: larping.eu + - domain: common-ground.dev + - domain: trouwplanner.online + - domain: huwelijksplanner.online organisationName: Conduction email: info@conduction.nl country: Netherlands @@ -29,7 +29,7 @@ settings: debug: 1 replicaCount: 1 corsAllowOrigin: ['*'] - trustedHosts: '^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.nl$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' + trustedHosts: '^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' pullPolicy: Always # You will need these proxies on kubernetes trustedProxies: diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index c44953a6..70c4eb77 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -13,7 +13,7 @@ settings: domain: {{ app_domain }} domains: {% for domain in app_domains %} - - domain: {{ domain }} + - { domain }} {% endfor %} organisationName: {{ organization_name }} email: {{ organization_email }} From 96b4a9854d5e1b696683e8b95909b30636fe140d Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Fri, 13 Dec 2019 12:34:11 +0100 Subject: [PATCH 146/182] force deploy build --- api/helm/values.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 78a6fb18..37d92376 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -12,12 +12,12 @@ settings: repro: 'https://github.com/ConductionNL/Proto-component-commonground' domain: conduction.nl domains: - - domain: conduction.nl - - domain: zaakonline.nl - - domain: larping.eu - - domain: common-ground.dev - - domain: trouwplanner.online - - domain: huwelijksplanner.online + - conduction.nl + - zaakonline.nl + - larping.eu + - common-ground.dev + - trouwplanner.online + - huwelijksplanner.online organisationName: Conduction email: info@conduction.nl country: Netherlands From ab57e4295b1bebe4b9cc12d7eac678b7a7a9a61d Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Fri, 13 Dec 2019 12:36:42 +0100 Subject: [PATCH 147/182] Hot fix on value template --- api/templates/helm/Values.yaml.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 70c4eb77..aade15ab 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -13,7 +13,7 @@ settings: domain: {{ app_domain }} domains: {% for domain in app_domains %} - - { domain }} + - {{ domain }} {% endfor %} organisationName: {{ organization_name }} email: {{ organization_email }} From 5b4671c4375e7d69e20862726ef8590c11e0fafb Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Fri, 13 Dec 2019 13:17:50 +0100 Subject: [PATCH 148/182] Fis op symphony 4.5 compliance --- api/src/Repository/NLXRequestLogRepository.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/api/src/Repository/NLXRequestLogRepository.php b/api/src/Repository/NLXRequestLogRepository.php index bc1dad3c..69add53c 100644 --- a/api/src/Repository/NLXRequestLogRepository.php +++ b/api/src/Repository/NLXRequestLogRepository.php @@ -4,7 +4,8 @@ use App\Entity\NLXRequestLog; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; -use Symfony\Bridge\Doctrine\RegistryInterface; +use Doctrine\Common\Persistence\ManagerRegistry; + /** * @method NLXRequestLog|null find($id, $lockMode = null, $lockVersion = null) @@ -14,10 +15,10 @@ */ class NLXRequestLogRepository extends ServiceEntityRepository { - public function __construct(RegistryInterface $registry) - { - parent::__construct($registry, NLXRequestLog::class); - } + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, ExampleEntity::class); + } /** * @return NLXRequestLog[] Returns an array of NLXRequestLog objects From abc62fd83c1e361bbc70f02b5d1ee0c99f679540 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Fri, 13 Dec 2019 14:39:28 +0100 Subject: [PATCH 149/182] Update on number of pods --- api/helm/templates/php-deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index 2d5df508..611e5d39 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -9,7 +9,7 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: - replicas: 1 + replicas: 3 template: metadata: labels: From 7847c318c41baaad5c1cacab7de68b5eda54ded1 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Fri, 13 Dec 2019 14:46:02 +0100 Subject: [PATCH 150/182] Wierd bux fix on a missing composer install --- api/docker/php/docker-entrypoint.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/docker/php/docker-entrypoint.sh b/api/docker/php/docker-entrypoint.sh index 2f39d520..54b7c9e8 100755 --- a/api/docker/php/docker-entrypoint.sh +++ b/api/docker/php/docker-entrypoint.sh @@ -31,9 +31,10 @@ if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then #fi #fi - if [ "$APP_ENV" != 'prod' ]; then + #wierd bug fix... + #if [ "$APP_ENV" != 'prod' ]; then composer install --prefer-dist --no-progress --no-suggest --no-interaction - fi + #fi # Lets setup an nlx certificate if needed #if [ "$APP_ENV" != 'prod' ]; then From ee51e6b677cd5a289ac220820de06284c0abebb5 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sat, 14 Dec 2019 01:43:13 +0100 Subject: [PATCH 151/182] Added support for VNG cloud --- .env | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env b/.env index 1f2db881..48cea8f4 100644 --- a/.env +++ b/.env @@ -25,7 +25,7 @@ APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) inte # The urls on wich this api is available TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 -TRUSTED_HOSTS=^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost +TRUSTED_HOSTS=^(.+\.)?conduction\.nl$|^(.+\.)?vng\.cloud$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost ################################################## # Orgization details @@ -47,7 +47,7 @@ ORGANIZATION_UNIT_NAME=Common-Ground # The primary domain for this API @depracticed APP_DOMAIN=conduction.nl # he domains on wich you want to provide this component, the first wil be used as primary (or common in cert-manger terms) -APP_DOMAINS=["conduction.nl","zaakonline.nl","larping.eu","common-ground.dev","trouwplanner.online","huwelijksplanner.online"] +APP_DOMAINS=["conduction.nl","vng.cloud","zaakonline.nl","larping.eu","common-ground.dev","trouwplanner.online","huwelijksplanner.online"] # If set to true wil provide the component on an {APP_NAME}.{APP_DOMAIN} basis for production enviroment, and {APP_NAME}.{APP_ENV}.{APP_DOMAIN} basis for other enviroments. Wil skipp the {APP_NAME}. on both if set to false APP_USE_NAME_AS_SUBDOMAIN=true # The demo enviroment for this component @depracticed From fb8c1bfde9a378aa21bf25e43844ee4ad5b19ca8 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Tue, 17 Dec 2019 14:56:12 +0100 Subject: [PATCH 152/182] Fix on domains --- .env | 10 +- .github/workflows/dockerimage.yml | 2 +- api/Dockerfile | 3 - api/composer.json | 3 +- api/composer.lock | 1797 +++++++++-------- api/config/bundles.php | 29 +- api/config/packages/twig.yaml | 2 +- api/helm/templates/php-deployment.yaml | 2 +- api/helm/values.yaml | 13 +- ...iber.php => FieldsAndExtendSubscriber.php} | 49 +- api/symfony.lock | 6 +- api/templates/helm/Values.yaml.twig | 2 +- docker-compose.yml | 32 +- 13 files changed, 1013 insertions(+), 937 deletions(-) rename api/src/Subscriber/{FieldsSubscriber.php => FieldsAndExtendSubscriber.php} (53%) diff --git a/.env b/.env index 48cea8f4..f892ecbb 100644 --- a/.env +++ b/.env @@ -44,12 +44,12 @@ ORGANIZATION_UNIT_NAME=Common-Ground # Documentation settings ################################################## -# The primary domain for this API @depracticed -APP_DOMAIN=conduction.nl +# The subdomain for this component (should be www for applications) +APP_SUBDOMAIN=pc # he domains on wich you want to provide this component, the first wil be used as primary (or common in cert-manger terms) -APP_DOMAINS=["conduction.nl","vng.cloud","zaakonline.nl","larping.eu","common-ground.dev","trouwplanner.online","huwelijksplanner.online"] -# If set to true wil provide the component on an {APP_NAME}.{APP_DOMAIN} basis for production enviroment, and {APP_NAME}.{APP_ENV}.{APP_DOMAIN} basis for other enviroments. Wil skipp the {APP_NAME}. on both if set to false -APP_USE_NAME_AS_SUBDOMAIN=true +APP_DOMAINS=["conduction.nl","zaakonline.nl","huwelijksplanner.online","common-ground.dev"] + + # The demo enviroment for this component @depracticed APP_DEMO=pc.zaakonline.nl # he Repository for this component diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 091c7edd..763f5ae6 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -56,7 +56,7 @@ jobs: - name: Run the docker image run: docker-compose up -d - name: Taking some sleep - run: sleep 100 + run: sleep 200 - name: Check if all containers are running run: docker ps - name: Dumping the logs diff --git a/api/Dockerfile b/api/Dockerfile index df2d1875..a5bfe406 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -125,9 +125,6 @@ CMD ["php-fpm"] # depends on the "php" stage above, and with an litle bit of help from https://github.com/shiphp/nginx-env FROM shiphp/nginx-env AS api_platform_nginx -# We use our own more secure and limited config -#ONBUILD ADD docker/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf - # Due to our config we need a copy of the public folder for serving static content COPY docker/nginx/conf.d/default.conf.template /etc/nginx/conf.d/default.conf WORKDIR /srv/api diff --git a/api/composer.json b/api/composer.json index bc7545a9..0e20ae21 100644 --- a/api/composer.json +++ b/api/composer.json @@ -21,6 +21,7 @@ "symfony/flex": "^1.1", "symfony/framework-bundle": "4.3.*", "symfony/mercure-bundle": "*", + "symfony/property-access": "4.4.*", "symfony/yaml": "4.3.*", "tbbc/money-bundle": "^3.1", "webonyx/graphql-php": "^0.13.8" @@ -60,7 +61,7 @@ "extra" : { "symfony" : { "allow-contrib" : false, - "require" : "4.3.*" + "require" : "4.4.*" } }, "scripts": { diff --git a/api/composer.lock b/api/composer.lock index 3fc1d7d6..10571f7f 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -4,28 +4,28 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a5cf6c5b0e2fcb4b7558cd2635260c67", + "content-hash": "6dedf18848d212df8a091e39a77494e7", "packages": [ { "name": "api-platform/api-pack", - "version": "v1.2.0", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/api-platform/api-pack.git", - "reference": "9e3e7421415c747e676778f211434674324dcfa9" + "reference": "41364f8763475d7709c43f790aa77a4157d038e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/api-pack/zipball/9e3e7421415c747e676778f211434674324dcfa9", - "reference": "9e3e7421415c747e676778f211434674324dcfa9", + "url": "https://api.github.com/repos/api-platform/api-pack/zipball/41364f8763475d7709c43f790aa77a4157d038e2", + "reference": "41364f8763475d7709c43f790aa77a4157d038e2", "shasum": "" }, "require": { "api-platform/core": "^2.1", "doctrine/annotations": "^1.0", - "doctrine/doctrine-bundle": "^1.6", + "doctrine/doctrine-bundle": "^1.6 || ^2.0", "doctrine/orm": "^2.4.5", - "nelmio/cors-bundle": "^1.5", + "nelmio/cors-bundle": "^1.5 || ^2.0", "php": "^7.0", "phpdocumentor/reflection-docblock": "^3.0 || ^4.0", "symfony/asset": "*", @@ -40,33 +40,34 @@ "MIT" ], "description": "A pack for API Platform", - "time": "2019-01-12T11:48:48+00:00" + "time": "2019-11-12T17:43:33+00:00" }, { "name": "api-platform/core", - "version": "v2.4.7", + "version": "v2.5.3", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "53793261113b18931ce8a9e2f174f59fdaa0c1c5" + "reference": "2d402688c485457adbc771e347e6498e70c6f232" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/53793261113b18931ce8a9e2f174f59fdaa0c1c5", - "reference": "53793261113b18931ce8a9e2f174f59fdaa0c1c5", + "url": "https://api.github.com/repos/api-platform/core/zipball/2d402688c485457adbc771e347e6498e70c6f232", + "reference": "2d402688c485457adbc771e347e6498e70c6f232", "shasum": "" }, "require": { "doctrine/inflector": "^1.0", + "fig/link-util": "^1.0", "php": ">=7.1", "psr/cache": "^1.0", "psr/container": "^1.0", - "symfony/http-foundation": "^3.4 || ^4.0", - "symfony/http-kernel": "^3.4 || ^4.0", - "symfony/property-access": "^3.4 || ^4.0", - "symfony/property-info": "^3.4 || ^4.0", - "symfony/serializer": "^4.2.6", - "symfony/web-link": "^4.1", + "symfony/http-foundation": "^4.3.6 || ^5.0", + "symfony/http-kernel": "^4.3.7 || ^5.0", + "symfony/property-access": "^3.4 || ^4.0 || ^5.0", + "symfony/property-info": "^3.4 || ^4.0 || ^5.0", + "symfony/serializer": "^4.3 || ^5.0", + "symfony/web-link": "^4.1 || ^5.0", "willdurand/negotiation": "^2.0.3" }, "conflict": { @@ -79,19 +80,20 @@ "behat/mink-browserkit-driver": "^1.3.1", "behat/mink-extension": "^2.2", "behat/symfony2-extension": "^2.1.1", - "behatch/contexts": "3.1.0", + "behatch/contexts": "^3.1.0", "doctrine/annotations": "^1.7", + "doctrine/common": "^2.11", "doctrine/data-fixtures": "^1.2.2", - "doctrine/doctrine-bundle": "^1.8", + "doctrine/doctrine-bundle": "^1.8 || ^2.0", "doctrine/doctrine-cache-bundle": "^1.3.5", - "doctrine/mongodb-odm": "^2.0@beta", - "doctrine/mongodb-odm-bundle": "^4.0@beta", - "doctrine/orm": "^2.6.3", + "doctrine/mongodb-odm": "^2.0", + "doctrine/mongodb-odm-bundle": "^4.0", + "doctrine/orm": "^2.6.4", "elasticsearch/elasticsearch": "^6.0", "friendsofsymfony/user-bundle": "^2.2@dev", "guzzlehttp/guzzle": "^6.0", "jangregor/phpstan-prophecy": "^0.4.2", - "justinrainbow/json-schema": "^5.0", + "justinrainbow/json-schema": "^5.2.1", "nelmio/api-doc-bundle": "^2.13.4", "phpdocumentor/reflection-docblock": "^3.0 || ^4.0", "phpdocumentor/type-resolver": "^0.3 || ^0.4", @@ -106,32 +108,34 @@ "ramsey/uuid": "^3.7", "ramsey/uuid-doctrine": "^1.4", "sebastian/object-enumerator": "^3.0.3", - "symfony/asset": "^3.4 || ^4.0", - "symfony/cache": "^3.4 || ^4.0", - "symfony/config": "^3.4 || ^4.0", - "symfony/console": "^3.4 || ^4.0", - "symfony/css-selector": "^3.4 || ^4.0", + "symfony/asset": "^3.4 || ^4.0 || ^5.0", + "symfony/browser-kit": "^4.3 || ^5.0", + "symfony/cache": "^3.4 || ^4.0 || ^5.0", + "symfony/config": "^3.4 || ^4.0 || ^5.0", + "symfony/console": "^3.4 || ^4.0 || ^5.0", + "symfony/css-selector": "^3.4 || ^4.0 || ^5.0", "symfony/debug": "^3.4 || ^4.0", - "symfony/dependency-injection": "^3.4 || ^4.0", - "symfony/doctrine-bridge": "^3.4 || ^4.0", - "symfony/dom-crawler": "^3.4 || ^4.0", - "symfony/event-dispatcher": "^3.4 || ^4.0", - "symfony/expression-language": "^3.4 || ^4.0", - "symfony/finder": "^3.4 || ^4.0", - "symfony/form": "^3.4 || ^4.0", - "symfony/framework-bundle": "^4.2", + "symfony/dependency-injection": "^3.4 || ^4.0 || ^5.0", + "symfony/doctrine-bridge": "^3.4 || ^4.0 || ^5.0", + "symfony/dom-crawler": "^3.4 || ^4.0 || ^5.0", + "symfony/event-dispatcher": "^3.4 || ^4.0 || ^5.0", + "symfony/expression-language": "^3.4 || ^4.0 || ^5.0", + "symfony/finder": "^3.4 || ^4.0 || ^5.0", + "symfony/form": "^3.4 || ^4.0 || ^5.0", + "symfony/framework-bundle": "^4.3.2 || ^5.0", + "symfony/http-client": "^4.3 || ^5.0", "symfony/mercure-bundle": "*", - "symfony/messenger": "^4.2", - "symfony/phpunit-bridge": "^4.3@dev", - "symfony/routing": "^3.4 || ^4.0", - "symfony/security-bundle": "^3.4 || ^4.0", - "symfony/security-core": "^3.4 || ^4.0", - "symfony/twig-bundle": "^3.4 || ^4.0", - "symfony/validator": "^3.4 || ^4.0", - "symfony/web-profiler-bundle": "^4.2", - "symfony/yaml": "^3.4 || ^4.0", - "twig/twig": "^1.41 || ^2.10", - "webonyx/graphql-php": ">=0.13 <1.0" + "symfony/messenger": "^4.3 || ^5.0", + "symfony/phpunit-bridge": "^4.3 || ^5.0", + "symfony/routing": "^3.4 || ^4.3 || ^5.0", + "symfony/security-bundle": "^3.4 || ^4.0 || ^5.0", + "symfony/security-core": "^4.3 || ^5.0", + "symfony/twig-bundle": "^3.4 || ^4.0 || ^5.0", + "symfony/validator": "^3.4 || ^4.0 || ^5.0", + "symfony/web-profiler-bundle": "^4.2 || ^5.0", + "symfony/yaml": "^3.4 || ^4.0 || ^5.0", + "twig/twig": "^1.42.3 || ^2.12", + "webonyx/graphql-php": ">=0.13.1 <1.0" }, "suggest": { "doctrine/mongodb-odm-bundle": "To support MongoDB. Only versions 4.0 and later are supported.", @@ -184,7 +188,7 @@ "rest", "swagger" ], - "time": "2019-09-17T14:41:55+00:00" + "time": "2019-11-23T11:27:39+00:00" }, { "name": "api-platform/schema-generator", @@ -362,24 +366,24 @@ }, { "name": "composer/xdebug-handler", - "version": "1.3.3", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "46867cbf8ca9fb8d60c506895449eb799db1184f" + "reference": "cbe23383749496fe0f373345208b79568e4bc248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/46867cbf8ca9fb8d60c506895449eb799db1184f", - "reference": "46867cbf8ca9fb8d60c506895449eb799db1184f", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/cbe23383749496fe0f373345208b79568e4bc248", + "reference": "cbe23383749496fe0f373345208b79568e4bc248", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0", + "php": "^5.3.2 || ^7.0 || ^8.0", "psr/log": "^1.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" }, "type": "library", "autoload": { @@ -397,12 +401,12 @@ "email": "john-stevenson@blueyonder.co.uk" } ], - "description": "Restarts a process without xdebug.", + "description": "Restarts a process without Xdebug.", "keywords": [ "Xdebug", "performance" ], - "time": "2019-05-27T17:52:04+00:00" + "time": "2019-11-06T16:40:04+00:00" }, { "name": "conduction/commongroundbundle", @@ -484,16 +488,16 @@ }, { "name": "doctrine/annotations", - "version": "v1.7.0", + "version": "v1.8.0", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "fa4c4e861e809d6a1103bd620cce63ed91aedfeb" + "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/fa4c4e861e809d6a1103bd620cce63ed91aedfeb", - "reference": "fa4c4e861e809d6a1103bd620cce63ed91aedfeb", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/904dca4eb10715b92569fbcd79e201d5c349b6bc", + "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc", "shasum": "" }, "require": { @@ -502,7 +506,7 @@ }, "require-dev": { "doctrine/cache": "1.*", - "phpunit/phpunit": "^7.5@dev" + "phpunit/phpunit": "^7.5" }, "type": "library", "extra": { @@ -548,20 +552,20 @@ "docblock", "parser" ], - "time": "2019-08-08T18:11:40+00:00" + "time": "2019-10-01T18:55:10+00:00" }, { "name": "doctrine/cache", - "version": "v1.8.0", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57" + "reference": "382e7f4db9a12dc6c19431743a2b096041bcdd62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57", - "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57", + "url": "https://api.github.com/repos/doctrine/cache/zipball/382e7f4db9a12dc6c19431743a2b096041bcdd62", + "reference": "382e7f4db9a12dc6c19431743a2b096041bcdd62", "shasum": "" }, "require": { @@ -572,7 +576,7 @@ }, "require-dev": { "alcaeus/mongo-php-adapter": "^1.1", - "doctrine/coding-standard": "^4.0", + "doctrine/coding-standard": "^6.0", "mongodb/mongodb": "^1.1", "phpunit/phpunit": "^7.0", "predis/predis": "~1.0" @@ -583,7 +587,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8.x-dev" + "dev-master": "1.9.x-dev" } }, "autoload": { @@ -596,6 +600,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -604,10 +612,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -617,26 +621,33 @@ "email": "schmittjoh@gmail.com" } ], - "description": "Caching library offering an object-oriented API for many cache backends", - "homepage": "https://www.doctrine-project.org", + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", "keywords": [ + "abstraction", + "apcu", "cache", - "caching" + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" ], - "time": "2018-08-21T18:01:43+00:00" + "time": "2019-11-29T15:36:20+00:00" }, { "name": "doctrine/collections", - "version": "v1.6.2", + "version": "1.6.4", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "c5e0bc17b1620e97c968ac409acbff28b8b850be" + "reference": "6b1e4b2b66f6d6e49983cebfe23a21b7ccc5b0d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/c5e0bc17b1620e97c968ac409acbff28b8b850be", - "reference": "c5e0bc17b1620e97c968ac409acbff28b8b850be", + "url": "https://api.github.com/repos/doctrine/collections/zipball/6b1e4b2b66f6d6e49983cebfe23a21b7ccc5b0d7", + "reference": "6b1e4b2b66f6d6e49983cebfe23a21b7ccc5b0d7", "shasum": "" }, "require": { @@ -664,6 +675,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -672,10 +687,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -693,7 +704,7 @@ "iterators", "php" ], - "time": "2019-06-09T13:48:14+00:00" + "time": "2019-11-13T13:07:11+00:00" }, { "name": "doctrine/common", @@ -780,27 +791,30 @@ }, { "name": "doctrine/data-fixtures", - "version": "v1.3.2", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/data-fixtures.git", - "reference": "09b16943b27f3d80d63988d100ff256148c2f78b" + "reference": "608a35a3b5bcc4214d116603095f8b0c51091592" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/09b16943b27f3d80d63988d100ff256148c2f78b", - "reference": "09b16943b27f3d80d63988d100ff256148c2f78b", + "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/608a35a3b5bcc4214d116603095f8b0c51091592", + "reference": "608a35a3b5bcc4214d116603095f8b0c51091592", "shasum": "" }, "require": { - "doctrine/common": "~2.2", - "php": "^7.1" + "doctrine/common": "^2.11", + "php": "^7.2" }, "conflict": { "doctrine/phpcr-odm": "<1.3.0" }, "require-dev": { + "alcaeus/mongo-php-adapter": "^1.1", + "doctrine/coding-standard": "^6.0", "doctrine/dbal": "^2.5.4", + "doctrine/mongodb-odm": "^1.3.0", "doctrine/orm": "^2.5.4", "phpunit/phpunit": "^7.0" }, @@ -813,7 +827,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "1.4.x-dev" } }, "autoload": { @@ -836,35 +850,34 @@ "keywords": [ "database" ], - "time": "2019-07-10T18:30:35+00:00" + "time": "2019-10-30T20:03:18+00:00" }, { "name": "doctrine/dbal", - "version": "v2.9.2", + "version": "v2.10.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9" + "reference": "0c9a646775ef549eb0a213a4f9bd4381d9b4d934" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", - "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/0c9a646775ef549eb0a213a4f9bd4381d9b4d934", + "reference": "0c9a646775ef549eb0a213a4f9bd4381d9b4d934", "shasum": "" }, "require": { "doctrine/cache": "^1.0", "doctrine/event-manager": "^1.0", "ext-pdo": "*", - "php": "^7.1" + "php": "^7.2" }, "require-dev": { - "doctrine/coding-standard": "^5.0", - "jetbrains/phpstorm-stubs": "^2018.1.2", - "phpstan/phpstan": "^0.10.1", - "phpunit/phpunit": "^7.4", - "symfony/console": "^2.0.5|^3.0|^4.0", - "symfony/phpunit-bridge": "^3.4.5|^4.0.5" + "doctrine/coding-standard": "^6.0", + "jetbrains/phpstorm-stubs": "^2019.1", + "phpstan/phpstan": "^0.11.3", + "phpunit/phpunit": "^8.4.1", + "symfony/console": "^2.0.5|^3.0|^4.0|^5.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -875,7 +888,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.9.x-dev", + "dev-master": "2.10.x-dev", "dev-develop": "3.0.x-dev" } }, @@ -889,6 +902,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -897,10 +914,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -911,39 +924,50 @@ "keywords": [ "abstraction", "database", + "db2", "dbal", + "mariadb", + "mssql", "mysql", - "persistence", + "oci8", + "oracle", + "pdo", "pgsql", - "php", - "queryobject" - ], - "time": "2018-12-31T03:27:51+00:00" + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlanywhere", + "sqlite", + "sqlserver", + "sqlsrv" + ], + "time": "2019-11-03T16:50:43+00:00" }, { "name": "doctrine/doctrine-bundle", - "version": "1.11.2", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "28101e20776d8fa20a00b54947fbae2db0d09103" + "reference": "f96fac225563f5b3b4eeb2f80eb982b7f56484d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/28101e20776d8fa20a00b54947fbae2db0d09103", - "reference": "28101e20776d8fa20a00b54947fbae2db0d09103", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/f96fac225563f5b3b4eeb2f80eb982b7f56484d8", + "reference": "f96fac225563f5b3b4eeb2f80eb982b7f56484d8", "shasum": "" }, "require": { - "doctrine/dbal": "^2.5.12", - "doctrine/doctrine-cache-bundle": "~1.2", + "doctrine/dbal": "^2.9.0", "jdorn/sql-formatter": "^1.2.16", "php": "^7.1", - "symfony/config": "^3.4|^4.1", - "symfony/console": "^3.4|^4.1", - "symfony/dependency-injection": "^3.4|^4.1", - "symfony/doctrine-bridge": "^3.4|^4.1", - "symfony/framework-bundle": "^3.4|^4.1" + "symfony/cache": "^4.3.3|^5.0", + "symfony/config": "^4.3.3|^5.0", + "symfony/console": "^3.4.30|^4.3.3|^5.0", + "symfony/dependency-injection": "^4.3.3|^5.0", + "symfony/doctrine-bridge": "^4.3.7|^5.0", + "symfony/framework-bundle": "^3.4.30|^4.3.3|^5.0" }, "conflict": { "doctrine/orm": "<2.6", @@ -952,15 +976,14 @@ "require-dev": { "doctrine/coding-standard": "^6.0", "doctrine/orm": "^2.6", - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "7.0", - "symfony/cache": "^3.4|^4.1", + "phpunit/phpunit": "^7.5", "symfony/phpunit-bridge": "^4.2", - "symfony/property-info": "^3.4|^4.1", - "symfony/validator": "^3.4|^4.1", - "symfony/web-profiler-bundle": "^3.4|^4.1", - "symfony/yaml": "^3.4|^4.1", - "twig/twig": "^1.34|^2.4" + "symfony/property-info": "^4.3.3|^5.0", + "symfony/twig-bridge": "^3.4.30|^4.3.3|^5.0", + "symfony/validator": "^3.4.30|^4.3.3|^5.0", + "symfony/web-profiler-bundle": "^3.4.30|^4.3.3|^5.0", + "symfony/yaml": "^3.4.30|^4.3.3|^5.0", + "twig/twig": "^1.34|^2.12" }, "suggest": { "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", @@ -969,7 +992,7 @@ "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "1.11.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -983,20 +1006,20 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { - "name": "Doctrine Project", - "homepage": "http://www.doctrine-project.org/" + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" }, { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org/" } ], "description": "Symfony DoctrineBundle", @@ -1007,130 +1030,42 @@ "orm", "persistence" ], - "time": "2019-06-04T07:35:05+00:00" - }, - { - "name": "doctrine/doctrine-cache-bundle", - "version": "1.3.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/DoctrineCacheBundle.git", - "reference": "5514c90d9fb595e1095e6d66ebb98ce9ef049927" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineCacheBundle/zipball/5514c90d9fb595e1095e6d66ebb98ce9ef049927", - "reference": "5514c90d9fb595e1095e6d66ebb98ce9ef049927", - "shasum": "" - }, - "require": { - "doctrine/cache": "^1.4.2", - "doctrine/inflector": "~1.0", - "php": ">=5.3.2", - "symfony/doctrine-bridge": "~2.7|~3.3|~4.0" - }, - "require-dev": { - "instaclick/coding-standard": "~1.1", - "instaclick/object-calisthenics-sniffs": "dev-master", - "instaclick/symfony2-coding-standard": "dev-remaster", - "phpunit/phpunit": "~4.8.36|~5.6|~6.5|~7.0", - "predis/predis": "~0.8", - "satooshi/php-coveralls": "^1.0", - "squizlabs/php_codesniffer": "~1.5", - "symfony/console": "~2.7|~3.3|~4.0", - "symfony/finder": "~2.7|~3.3|~4.0", - "symfony/framework-bundle": "~2.7|~3.3|~4.0", - "symfony/phpunit-bridge": "~2.7|~3.3|~4.0", - "symfony/security-acl": "~2.7|~3.3", - "symfony/validator": "~2.7|~3.3|~4.0", - "symfony/yaml": "~2.7|~3.3|~4.0" - }, - "suggest": { - "symfony/security-acl": "For using this bundle to cache ACLs" - }, - "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Bundle\\DoctrineCacheBundle\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Fabio B. Silva", - "email": "fabio.bat.silva@gmail.com" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@hotmail.com" - }, - { - "name": "Doctrine Project", - "homepage": "http://www.doctrine-project.org/" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Symfony Bundle for Doctrine Cache", - "homepage": "https://www.doctrine-project.org", - "keywords": [ - "cache", - "caching" - ], - "time": "2018-11-09T06:25:35+00:00" + "time": "2019-11-28T08:38:10+00:00" }, { "name": "doctrine/doctrine-fixtures-bundle", - "version": "3.2.2", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineFixturesBundle.git", - "reference": "90e4a4f968b2dae40e290a6ee516957af043f16c" + "reference": "8f07fcfdac7f3591f3c4bf13a50cbae05f65ed70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/90e4a4f968b2dae40e290a6ee516957af043f16c", - "reference": "90e4a4f968b2dae40e290a6ee516957af043f16c", + "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/8f07fcfdac7f3591f3c4bf13a50cbae05f65ed70", + "reference": "8f07fcfdac7f3591f3c4bf13a50cbae05f65ed70", "shasum": "" }, "require": { "doctrine/data-fixtures": "^1.3", - "doctrine/doctrine-bundle": "^1.6", + "doctrine/doctrine-bundle": "^1.11|^2.0", "doctrine/orm": "^2.6.0", "php": "^7.1", - "symfony/doctrine-bridge": "~3.4|^4.1", - "symfony/framework-bundle": "^3.4|^4.1" + "symfony/config": "^3.4|^4.3|^5.0", + "symfony/console": "^3.4|^4.3|^5.0", + "symfony/dependency-injection": "^3.4|^4.3|^5.0", + "symfony/doctrine-bridge": "^3.4|^4.1|^5.0", + "symfony/http-kernel": "^3.4|^4.3|^5.0" }, "require-dev": { "doctrine/coding-standard": "^6.0", "phpunit/phpunit": "^7.4", - "symfony/phpunit-bridge": "^4.1" + "symfony/phpunit-bridge": "^4.1|^5.0" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "3.2.x-dev" + "dev-master": "3.3.x-dev" } }, "autoload": { @@ -1144,16 +1079,16 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Doctrine Project", "homepage": "http://www.doctrine-project.org" }, { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" } ], "description": "Symfony DoctrineFixturesBundle", @@ -1162,20 +1097,20 @@ "Fixture", "persistence" ], - "time": "2019-06-12T12:03:37+00:00" + "time": "2019-11-13T15:46:58+00:00" }, { "name": "doctrine/event-manager", - "version": "v1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3" + "reference": "629572819973f13486371cb611386eb17851e85c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3", - "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/629572819973f13486371cb611386eb17851e85c", + "reference": "629572819973f13486371cb611386eb17851e85c", "shasum": "" }, "require": { @@ -1185,7 +1120,7 @@ "doctrine/common": "<2.9@dev" }, "require-dev": { - "doctrine/coding-standard": "^4.0", + "doctrine/coding-standard": "^6.0", "phpunit/phpunit": "^7.0" }, "type": "library", @@ -1204,6 +1139,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -1212,10 +1151,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -1229,27 +1164,29 @@ "email": "ocramius@gmail.com" } ], - "description": "Doctrine Event Manager component", + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", "homepage": "https://www.doctrine-project.org/projects/event-manager.html", "keywords": [ "event", - "eventdispatcher", - "eventmanager" + "event dispatcher", + "event manager", + "event system", + "events" ], - "time": "2018-06-11T11:59:03+00:00" + "time": "2019-11-10T09:48:07+00:00" }, { "name": "doctrine/inflector", - "version": "v1.3.0", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "5527a48b7313d15261292c149e55e26eae771b0a" + "reference": "ec3a55242203ffa6a4b27c58176da97ff0a7aec1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a", - "reference": "5527a48b7313d15261292c149e55e26eae771b0a", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/ec3a55242203ffa6a4b27c58176da97ff0a7aec1", + "reference": "ec3a55242203ffa6a4b27c58176da97ff0a7aec1", "shasum": "" }, "require": { @@ -1274,6 +1211,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -1282,10 +1223,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -1303,20 +1240,20 @@ "singularize", "string" ], - "time": "2018-01-09T20:05:19+00:00" + "time": "2019-10-30T19:59:35+00:00" }, { "name": "doctrine/instantiator", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "a2c590166b2133a4633738648b6b064edae0814a" + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", - "reference": "a2c590166b2133a4633738648b6b064edae0814a", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1", + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1", "shasum": "" }, "require": { @@ -1359,20 +1296,20 @@ "constructor", "instantiate" ], - "time": "2019-03-17T17:37:11+00:00" + "time": "2019-10-21T16:45:58+00:00" }, { "name": "doctrine/lexer", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "e17f069ede36f7534b95adec71910ed1b49c74ea" + "reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/e17f069ede36f7534b95adec71910ed1b49c74ea", - "reference": "e17f069ede36f7534b95adec71910ed1b49c74ea", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6", + "reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6", "shasum": "" }, "require": { @@ -1386,7 +1323,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -1421,38 +1358,39 @@ "parser", "php" ], - "time": "2019-07-30T19:33:28+00:00" + "time": "2019-10-30T14:39:59+00:00" }, { "name": "doctrine/orm", - "version": "v2.6.3", + "version": "v2.7.0", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "434820973cadf2da2d66e7184be370084cc32ca8" + "reference": "4d763ca4c925f647b248b9fa01b5f47aa3685d62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/434820973cadf2da2d66e7184be370084cc32ca8", - "reference": "434820973cadf2da2d66e7184be370084cc32ca8", + "url": "https://api.github.com/repos/doctrine/orm/zipball/4d763ca4c925f647b248b9fa01b5f47aa3685d62", + "reference": "4d763ca4c925f647b248b9fa01b5f47aa3685d62", "shasum": "" }, "require": { - "doctrine/annotations": "~1.5", - "doctrine/cache": "~1.6", - "doctrine/collections": "^1.4", - "doctrine/common": "^2.7.1", - "doctrine/dbal": "^2.6", - "doctrine/instantiator": "~1.1", + "doctrine/annotations": "^1.8", + "doctrine/cache": "^1.9.1", + "doctrine/collections": "^1.5", + "doctrine/common": "^2.11", + "doctrine/dbal": "^2.9.3", + "doctrine/event-manager": "^1.1", + "doctrine/instantiator": "^1.3", + "doctrine/persistence": "^1.2", "ext-pdo": "*", "php": "^7.1", - "symfony/console": "~3.0|~4.0" + "symfony/console": "^3.0|^4.0|^5.0" }, "require-dev": { - "doctrine/coding-standard": "^1.0", - "phpunit/phpunit": "^6.5", - "squizlabs/php_codesniffer": "^3.2", - "symfony/yaml": "~3.4|~4.0" + "doctrine/coding-standard": "^5.0", + "phpunit/phpunit": "^7.5", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" @@ -1463,7 +1401,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6.x-dev" + "dev-master": "2.7.x-dev" } }, "autoload": { @@ -1476,6 +1414,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -1484,10 +1426,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -1498,25 +1436,25 @@ } ], "description": "Object-Relational-Mapper for PHP", - "homepage": "http://www.doctrine-project.org", + "homepage": "https://www.doctrine-project.org/projects/orm.html", "keywords": [ "database", "orm" ], - "time": "2018-11-20T23:46:46+00:00" + "time": "2019-11-19T08:38:05+00:00" }, { "name": "doctrine/persistence", - "version": "1.1.1", + "version": "1.3.3", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "3da7c9d125591ca83944f477e65ed3d7b4617c48" + "reference": "99b196bbd4715a94fa100fac664a351ffa46d6a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/3da7c9d125591ca83944f477e65ed3d7b4617c48", - "reference": "3da7c9d125591ca83944f477e65ed3d7b4617c48", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/99b196bbd4715a94fa100fac664a351ffa46d6a5", + "reference": "99b196bbd4715a94fa100fac664a351ffa46d6a5", "shasum": "" }, "require": { @@ -1531,19 +1469,20 @@ "doctrine/common": "<2.10@dev" }, "require-dev": { - "doctrine/coding-standard": "^5.0", - "phpstan/phpstan": "^0.8", + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan": "^0.11", "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "1.3.x-dev" } }, "autoload": { "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common" + "Doctrine\\Common\\": "lib/Doctrine/Common", + "Doctrine\\Persistence\\": "lib/Doctrine/Persistence" } }, "notification-url": "https://packagist.org/downloads/", @@ -1551,6 +1490,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -1559,10 +1502,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -1585,7 +1524,7 @@ "orm", "persistence" ], - "time": "2019-04-23T08:28:24+00:00" + "time": "2019-12-13T10:43:02+00:00" }, { "name": "doctrine/reflection", @@ -1780,16 +1719,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.15.3", + "version": "v2.16.1", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "705490b0f282f21017d73561e9498d2b622ee34c" + "reference": "c8afb599858876e95e8ebfcd97812d383fa23f02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/705490b0f282f21017d73561e9498d2b622ee34c", - "reference": "705490b0f282f21017d73561e9498d2b622ee34c", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/c8afb599858876e95e8ebfcd97812d383fa23f02", + "reference": "c8afb599858876e95e8ebfcd97812d383fa23f02", "shasum": "" }, "require": { @@ -1800,15 +1739,15 @@ "ext-tokenizer": "*", "php": "^5.6 || ^7.0", "php-cs-fixer/diff": "^1.3", - "symfony/console": "^3.4.17 || ^4.1.6", - "symfony/event-dispatcher": "^3.0 || ^4.0", - "symfony/filesystem": "^3.0 || ^4.0", - "symfony/finder": "^3.0 || ^4.0", - "symfony/options-resolver": "^3.0 || ^4.0", + "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0", + "symfony/event-dispatcher": "^3.0 || ^4.0 || ^5.0", + "symfony/filesystem": "^3.0 || ^4.0 || ^5.0", + "symfony/finder": "^3.0 || ^4.0 || ^5.0", + "symfony/options-resolver": "^3.0 || ^4.0 || ^5.0", "symfony/polyfill-php70": "^1.0", "symfony/polyfill-php72": "^1.4", - "symfony/process": "^3.0 || ^4.0", - "symfony/stopwatch": "^3.0 || ^4.0" + "symfony/process": "^3.0 || ^4.0 || ^5.0", + "symfony/stopwatch": "^3.0 || ^4.0 || ^5.0" }, "require-dev": { "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", @@ -1821,8 +1760,8 @@ "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.1", "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.1", "phpunitgoodpractices/traits": "^1.8", - "symfony/phpunit-bridge": "^4.3", - "symfony/yaml": "^3.0 || ^4.0" + "symfony/phpunit-bridge": "^4.3 || ^5.0", + "symfony/yaml": "^3.0 || ^4.0 || ^5.0" }, "suggest": { "ext-mbstring": "For handling non-UTF8 characters in cache signature.", @@ -1865,20 +1804,20 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2019-08-31T12:51:54+00:00" + "time": "2019-11-25T22:10:32+00:00" }, { "name": "gedmo/doctrine-extensions", - "version": "v2.4.37", + "version": "v2.4.38", "source": { "type": "git", "url": "https://github.com/Atlantic18/DoctrineExtensions.git", - "reference": "5dd471f656e46d815f063bf3f12c667649ec7ffb" + "reference": "81681364331b131518060e4776300a5346df1eb5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Atlantic18/DoctrineExtensions/zipball/5dd471f656e46d815f063bf3f12c667649ec7ffb", - "reference": "5dd471f656e46d815f063bf3f12c667649ec7ffb", + "url": "https://api.github.com/repos/Atlantic18/DoctrineExtensions/zipball/81681364331b131518060e4776300a5346df1eb5", + "reference": "81681364331b131518060e4776300a5346df1eb5", "shasum": "" }, "require": { @@ -1887,14 +1826,15 @@ "php": ">=5.3.2" }, "conflict": { - "doctrine/annotations": "<1.2" + "doctrine/annotations": "<1.2", + "doctrine/mongodb-odm": ">=2.0" }, "require-dev": { "doctrine/common": ">=2.5.0", - "doctrine/mongodb-odm": ">=1.0.2", + "doctrine/mongodb-odm": ">=1.0.2 <2.0", "doctrine/orm": ">=2.5.0", - "phpunit/phpunit": "^4.8.35|^5.7|^6.5", - "symfony/yaml": "~2.6|~3.0|~4.0" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", + "symfony/yaml": "~2.6 || ~3.0 || ~4.0" }, "suggest": { "doctrine/mongodb-odm": "to use the extensions with the MongoDB ODM", @@ -1916,10 +1856,6 @@ "MIT" ], "authors": [ - { - "name": "David Buchmann", - "email": "david@liip.ch" - }, { "name": "Gediminas Morkevicius", "email": "gediminas.morkevicius@gmail.com" @@ -1927,6 +1863,10 @@ { "name": "Gustavo Falco", "email": "comfortablynumb84@gmail.com" + }, + { + "name": "David Buchmann", + "email": "david@liip.ch" } ], "description": "Doctrine2 behavioral extensions", @@ -1946,48 +1886,50 @@ "tree", "uploadable" ], - "time": "2019-03-17T18:16:12+00:00" + "time": "2019-11-08T22:33:07+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "6.3.3", + "version": "6.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba" + "reference": "dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5", + "reference": "dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5", "shasum": "" }, "require": { + "ext-json": "*", "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.4", + "guzzlehttp/psr7": "^1.6.1", "php": ">=5.5" }, "require-dev": { "ext-curl": "*", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "psr/log": "^1.0" + "psr/log": "^1.1" }, "suggest": { + "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.3-dev" + "dev-master": "6.5-dev" } }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\": "src/" - } + }, + "files": [ + "src/functions_include.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2011,7 +1953,7 @@ "rest", "web service" ], - "time": "2018-04-22T15:46:56+00:00" + "time": "2019-12-07T18:20:45+00:00" }, { "name": "guzzlehttp/promises", @@ -2242,16 +2184,16 @@ }, { "name": "league/html-to-markdown", - "version": "4.8.2", + "version": "4.9.0", "source": { "type": "git", "url": "https://github.com/thephpleague/html-to-markdown.git", - "reference": "e747489191f8e9144a7270eb61f8b9516e99e413" + "reference": "71319108e3db506250b8987721b13568fd9fa446" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/e747489191f8e9144a7270eb61f8b9516e99e413", - "reference": "e747489191f8e9144a7270eb61f8b9516e99e413", + "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/71319108e3db506250b8987721b13568fd9fa446", + "reference": "71319108e3db506250b8987721b13568fd9fa446", "shasum": "" }, "require": { @@ -2261,7 +2203,7 @@ }, "require-dev": { "mikehaertl/php-shellcommand": "~1.1.0", - "phpunit/phpunit": "4.*", + "phpunit/phpunit": "^4.8|^5.7", "scrutinizer/ocular": "~1.1" }, "bin": [ @@ -2270,7 +2212,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.9-dev" + "dev-master": "4.10-dev" } }, "autoload": { @@ -2302,20 +2244,20 @@ "html", "markdown" ], - "time": "2019-08-02T11:57:39+00:00" + "time": "2019-11-02T14:54:14+00:00" }, { "name": "lexik/jwt-authentication-bundle", - "version": "v2.6.4", + "version": "v2.6.5", "source": { "type": "git", "url": "https://github.com/lexik/LexikJWTAuthenticationBundle.git", - "reference": "f79f20b282834878aab10530ca102a80396624ed" + "reference": "448551fc08c6cff37aad9d8f27f6b9615cd28966" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lexik/LexikJWTAuthenticationBundle/zipball/f79f20b282834878aab10530ca102a80396624ed", - "reference": "f79f20b282834878aab10530ca102a80396624ed", + "url": "https://api.github.com/repos/lexik/LexikJWTAuthenticationBundle/zipball/448551fc08c6cff37aad9d8f27f6b9615cd28966", + "reference": "448551fc08c6cff37aad9d8f27f6b9615cd28966", "shasum": "" }, "require": { @@ -2323,17 +2265,16 @@ "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" + "symfony/framework-bundle": "^3.4|^4.0|^5.0", + "symfony/security-bundle": "^3.4|^4.0|^5.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" + "symfony/browser-kit": "^3.4|^4.0|^5.0", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/dom-crawler": "^3.4|^4.0|^5.0", + "symfony/phpunit-bridge": "^3.4|^4.0|^5.0", + "symfony/var-dumper": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "gesdinet/jwt-refresh-token-bundle": "Implements a refresh token system over Json Web Tokens in Symfony", @@ -2399,7 +2340,7 @@ "rest", "symfony" ], - "time": "2019-07-29T10:02:31+00:00" + "time": "2019-11-22T14:22:26+00:00" }, { "name": "moneyphp/money", @@ -2521,30 +2462,29 @@ }, { "name": "nelmio/cors-bundle", - "version": "1.5.6", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/nelmio/NelmioCorsBundle.git", - "reference": "10a24c10f242440211ed31075e74f81661c690d9" + "reference": "9683e6d30d000ef998919261329d825de7c53499" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioCorsBundle/zipball/10a24c10f242440211ed31075e74f81661c690d9", - "reference": "10a24c10f242440211ed31075e74f81661c690d9", + "url": "https://api.github.com/repos/nelmio/NelmioCorsBundle/zipball/9683e6d30d000ef998919261329d825de7c53499", + "reference": "9683e6d30d000ef998919261329d825de7c53499", "shasum": "" }, "require": { - "symfony/framework-bundle": "^2.7 || ^3.0 || ^4.0" + "symfony/framework-bundle": "^4.3 || ^5.0" }, "require-dev": { - "matthiasnoback/symfony-dependency-injection-test": "^1.0 || ^2.0", - "mockery/mockery": "^0.9 || ^1.0", - "symfony/phpunit-bridge": "^2.7 || ^3.0 || ^4.0" + "mockery/mockery": "^1.2", + "symfony/phpunit-bridge": "^4.3 || ^5.0" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "1.5.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -2569,26 +2509,26 @@ "homepage": "https://github.com/nelmio/NelmioCorsBundle/contributors" } ], - "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Symfony2 application", + "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Symfony application", "keywords": [ "api", "cors", "crossdomain" ], - "time": "2019-06-17T08:53:14+00:00" + "time": "2019-11-15T08:54:08+00:00" }, { "name": "nikic/php-parser", - "version": "v4.2.4", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "97e59c7a16464196a8b9c77c47df68e4a39a45c4" + "reference": "9a9981c347c5c49d6dfe5cf826bb882b824080dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/97e59c7a16464196a8b9c77c47df68e4a39a45c4", - "reference": "97e59c7a16464196a8b9c77c47df68e4a39a45c4", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/9a9981c347c5c49d6dfe5cf826bb882b824080dc", + "reference": "9a9981c347c5c49d6dfe5cf826bb882b824080dc", "shasum": "" }, "require": { @@ -2596,6 +2536,7 @@ "php": ">=7.0" }, "require-dev": { + "ircmaxell/php-yacc": "0.0.5", "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" }, "bin": [ @@ -2604,7 +2545,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2626,7 +2567,7 @@ "parser", "php" ], - "time": "2019-09-01T07:51:21+00:00" + "time": "2019-11-08T13:50:10+00:00" }, { "name": "php-cs-fixer/diff", @@ -3112,44 +3053,46 @@ }, { "name": "ramsey/uuid", - "version": "3.8.0", + "version": "3.9.1", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "d09ea80159c1929d75b3f9c60504d613aeb4a1e3" + "reference": "5ac2740e0c8c599d2bbe7f113a939f2b5b216c67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/d09ea80159c1929d75b3f9c60504d613aeb4a1e3", - "reference": "d09ea80159c1929d75b3f9c60504d613aeb4a1e3", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/5ac2740e0c8c599d2bbe7f113a939f2b5b216c67", + "reference": "5ac2740e0c8c599d2bbe7f113a939f2b5b216c67", "shasum": "" }, "require": { - "paragonie/random_compat": "^1.0|^2.0|9.99.99", - "php": "^5.4 || ^7.0", + "ext-json": "*", + "paragonie/random_compat": "^1 | ^2 | 9.99.99", + "php": "^5.4 | ^7", "symfony/polyfill-ctype": "^1.8" }, "replace": { "rhumsaa/uuid": "self.version" }, "require-dev": { - "codeception/aspect-mock": "^1.0 | ~2.0.0", - "doctrine/annotations": "~1.2.0", - "goaop/framework": "1.0.0-alpha.2 | ^1.0 | ~2.1.0", - "ircmaxell/random-lib": "^1.1", + "codeception/aspect-mock": "^1 | ^2", + "doctrine/annotations": "^1.2", + "goaop/framework": "1.0.0-alpha.2 | ^1 | ^2.1", "jakub-onderka/php-parallel-lint": "^0.9.0", "mockery/mockery": "^0.9.9", "moontoast/math": "^1.1", - "php-mock/php-mock-phpunit": "^0.3|^1.1", - "phpunit/phpunit": "^4.7|^5.0|^6.5", + "paragonie/random-lib": "^2", + "php-mock/php-mock-phpunit": "^0.3 | ^1.1", + "phpunit/phpunit": "^4.8 | ^5.4 | ^6.5", "squizlabs/php_codesniffer": "^2.3" }, "suggest": { "ext-ctype": "Provides support for PHP Ctype functions", "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", + "ext-openssl": "Provides the OpenSSL extension for use with the OpenSslGenerator", "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", - "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, @@ -3162,13 +3105,21 @@ "autoload": { "psr-4": { "Ramsey\\Uuid\\": "src/" - } + }, + "files": [ + "src/functions.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + }, { "name": "Marijn Huizendveld", "email": "marijn.huizendveld@gmail.com" @@ -3176,11 +3127,6 @@ { "name": "Thibaud Fabre", "email": "thibaud@aztech.io" - }, - { - "name": "Ben Ramsey", - "email": "ben@benramsey.com", - "homepage": "https://benramsey.com" } ], "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", @@ -3190,7 +3136,7 @@ "identifier", "uuid" ], - "time": "2018-07-19T23:38:55+00:00" + "time": "2019-12-01T04:55:27+00:00" }, { "name": "ramsey/uuid-doctrine", @@ -3251,16 +3197,16 @@ }, { "name": "sensio/framework-extra-bundle", - "version": "v5.5.1", + "version": "v5.5.2", "source": { "type": "git", "url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git", - "reference": "dfc2c4df9f7d465a65c770e9feb578fe071636f7" + "reference": "92acfcc610e2180c52790ec3ff2e893f67e76b32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/dfc2c4df9f7d465a65c770e9feb578fe071636f7", - "reference": "dfc2c4df9f7d465a65c770e9feb578fe071636f7", + "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/92acfcc610e2180c52790ec3ff2e893f67e76b32", + "reference": "92acfcc610e2180c52790ec3ff2e893f67e76b32", "shasum": "" }, "require": { @@ -3325,7 +3271,7 @@ "annotations", "controllers" ], - "time": "2019-10-16T18:54:45+00:00" + "time": "2019-12-12T16:21:49+00:00" }, { "name": "sensiolabs/security-checker", @@ -3442,24 +3388,24 @@ }, { "name": "symfony/asset", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "3f97e57596884f7b9158d564a533112a0d19dbdd" + "reference": "7ec5fc653dab63d7519a6f411982ee224a696d66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/3f97e57596884f7b9158d564a533112a0d19dbdd", - "reference": "3f97e57596884f7b9158d564a533112a0d19dbdd", + "url": "https://api.github.com/repos/symfony/asset/zipball/7ec5fc653dab63d7519a6f411982ee224a696d66", + "reference": "7ec5fc653dab63d7519a6f411982ee224a696d66", "shasum": "" }, "require": { "php": "^7.1.3" }, "require-dev": { - "symfony/http-foundation": "~3.4|~4.0", - "symfony/http-kernel": "~3.4|~4.0" + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/http-kernel": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/http-foundation": "" @@ -3467,7 +3413,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -3494,34 +3440,35 @@ ], "description": "Symfony Asset Component", "homepage": "https://symfony.com", - "time": "2019-08-03T21:50:52+00:00" + "time": "2019-10-12T00:35:04+00:00" }, { "name": "symfony/cache", - "version": "v4.3.9", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "2a7bcc592adcaab9efc165bbced5a91fe905fad4" + "reference": "de737c81ea95018d11a3ef908ad2ebf203741b96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/2a7bcc592adcaab9efc165bbced5a91fe905fad4", - "reference": "2a7bcc592adcaab9efc165bbced5a91fe905fad4", + "url": "https://api.github.com/repos/symfony/cache/zipball/de737c81ea95018d11a3ef908ad2ebf203741b96", + "reference": "de737c81ea95018d11a3ef908ad2ebf203741b96", "shasum": "" }, "require": { "php": "^7.1.3", "psr/cache": "~1.0", "psr/log": "~1.0", - "symfony/cache-contracts": "^1.1", - "symfony/service-contracts": "^1.1", - "symfony/var-exporter": "^4.2" + "symfony/cache-contracts": "^1.1.7|^2", + "symfony/service-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.2|^5.0" }, "conflict": { "doctrine/dbal": "<2.5", "symfony/dependency-injection": "<3.4", - "symfony/var-dumper": "<3.4" + "symfony/http-kernel": "<4.4", + "symfony/var-dumper": "<4.4" }, "provide": { "psr/cache-implementation": "1.0", @@ -3534,14 +3481,14 @@ "doctrine/dbal": "~2.5", "predis/predis": "~1.1", "psr/simple-cache": "^1.0", - "symfony/config": "~4.2", - "symfony/dependency-injection": "~3.4|~4.1", - "symfony/var-dumper": "^4.1.1" + "symfony/config": "^4.2|^5.0", + "symfony/dependency-injection": "^3.4|^4.1|^5.0", + "symfony/var-dumper": "^4.4|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -3572,7 +3519,7 @@ "caching", "psr6" ], - "time": "2019-12-01T10:50:31+00:00" + "time": "2019-12-01T10:50:45+00:00" }, { "name": "symfony/cache-contracts", @@ -3634,32 +3581,32 @@ }, { "name": "symfony/config", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece" + "reference": "7aa5817f1b7a8ed377752b90fcc47dfb3c67b40c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/07d49c0f823e0bc367c6d84e35b61419188a5ece", - "reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece", + "url": "https://api.github.com/repos/symfony/config/zipball/7aa5817f1b7a8ed377752b90fcc47dfb3c67b40c", + "reference": "7aa5817f1b7a8ed377752b90fcc47dfb3c67b40c", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/filesystem": "~3.4|~4.0", + "symfony/filesystem": "^3.4|^4.0|^5.0", "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/finder": "<3.4" }, "require-dev": { - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~3.4|~4.0", - "symfony/finder": "~3.4|~4.0", - "symfony/messenger": "~4.1", - "symfony/yaml": "~3.4|~4.0" + "symfony/event-dispatcher": "^3.4|^4.0|^5.0", + "symfony/finder": "^3.4|^4.0|^5.0", + "symfony/messenger": "^4.1|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" @@ -3667,7 +3614,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -3694,7 +3641,7 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-12-01T10:50:45+00:00" }, { "name": "symfony/console", @@ -3900,25 +3847,25 @@ }, { "name": "symfony/dependency-injection", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9" + "reference": "ad46a4def1325befab696b49c839dffea3fc92bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d3ad14b66ac773ba6123622eb9b5b010165fe3d9", - "reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ad46a4def1325befab696b49c839dffea3fc92bd", + "reference": "ad46a4def1325befab696b49c839dffea3fc92bd", "shasum": "" }, "require": { "php": "^7.1.3", "psr/container": "^1.0", - "symfony/service-contracts": "^1.1.6" + "symfony/service-contracts": "^1.1.6|^2" }, "conflict": { - "symfony/config": "<4.3", + "symfony/config": "<4.3|>=5.0", "symfony/finder": "<3.4", "symfony/proxy-manager-bridge": "<3.4", "symfony/yaml": "<3.4" @@ -3929,8 +3876,8 @@ }, "require-dev": { "symfony/config": "^4.3", - "symfony/expression-language": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/config": "", @@ -3942,7 +3889,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -3969,20 +3916,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2019-08-26T16:27:33+00:00" + "time": "2019-12-01T10:19:36+00:00" }, { "name": "symfony/doctrine-bridge", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "d2967b2b43788bd3a7cddeb8bd4567e142b3821c" + "reference": "31c3d72f9e7a03e1b9d136084a9201c2225ee348" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/d2967b2b43788bd3a7cddeb8bd4567e142b3821c", - "reference": "d2967b2b43788bd3a7cddeb8bd4567e142b3821c", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/31c3d72f9e7a03e1b9d136084a9201c2225ee348", + "reference": "31c3d72f9e7a03e1b9d136084a9201c2225ee348", "shasum": "" }, "require": { @@ -3991,13 +3938,16 @@ "php": "^7.1.3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^1.1" + "symfony/service-contracts": "^1.1|^2" }, "conflict": { "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", "symfony/dependency-injection": "<3.4", - "symfony/form": "<4.3", - "symfony/messenger": "<4.3" + "symfony/form": "<4.4", + "symfony/http-kernel": "<4.3.7", + "symfony/messenger": "<4.3", + "symfony/security-core": "<4.4", + "symfony/validator": "<4.4" }, "require-dev": { "doctrine/annotations": "~1.7", @@ -4007,19 +3957,20 @@ "doctrine/dbal": "~2.4", "doctrine/orm": "^2.6.3", "doctrine/reflection": "~1.0", - "symfony/config": "^4.2", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/form": "~4.3", - "symfony/http-kernel": "~3.4|~4.0", - "symfony/messenger": "~4.3", - "symfony/property-access": "~3.4|~4.0", - "symfony/property-info": "~3.4|~4.0", - "symfony/proxy-manager-bridge": "~3.4|~4.0", - "symfony/security-core": "~3.4|~4.0", - "symfony/stopwatch": "~3.4|~4.0", - "symfony/translation": "~3.4|~4.0", - "symfony/validator": "^3.4.31|^4.3.4" + "symfony/config": "^4.2|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/form": "^4.4|^5.0", + "symfony/http-kernel": "^4.3.7", + "symfony/messenger": "^4.4|^5.0", + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/property-info": "^3.4|^4.0|^5.0", + "symfony/proxy-manager-bridge": "^3.4|^4.0|^5.0", + "symfony/security-core": "^4.4|^5.0", + "symfony/stopwatch": "^3.4|^4.0|^5.0", + "symfony/translation": "^3.4|^4.0|^5.0", + "symfony/validator": "^4.4|^5.0", + "symfony/var-dumper": "^3.4|^4.0|^5.0" }, "suggest": { "doctrine/data-fixtures": "", @@ -4032,7 +3983,7 @@ "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4059,20 +4010,20 @@ ], "description": "Symfony Doctrine Bridge", "homepage": "https://symfony.com", - "time": "2019-08-26T11:29:20+00:00" + "time": "2019-12-01T08:39:58+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "cc686552948d627528c0e2e759186dff67c2610e" + "reference": "36bbcab9369fc2f583220890efd43bf262d563fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/cc686552948d627528c0e2e759186dff67c2610e", - "reference": "cc686552948d627528c0e2e759186dff67c2610e", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/36bbcab9369fc2f583220890efd43bf262d563fd", + "reference": "36bbcab9369fc2f583220890efd43bf262d563fd", "shasum": "" }, "require": { @@ -4085,7 +4036,7 @@ }, "require-dev": { "masterminds/html5": "^2.6", - "symfony/css-selector": "~3.4|~4.0" + "symfony/css-selector": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/css-selector": "" @@ -4093,7 +4044,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4120,7 +4071,7 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-10-29T11:38:30+00:00" }, { "name": "symfony/dotenv", @@ -4179,6 +4130,62 @@ ], "time": "2019-08-03T21:50:52+00:00" }, + { + "name": "symfony/error-handler", + "version": "v4.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "a1ad02d62789efed1d2b2796f1c15e0c6a00fc3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/a1ad02d62789efed1d2b2796f1c15e0c6a00fc3b", + "reference": "a1ad02d62789efed1d2b2796f1c15e0c6a00fc3b", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/log": "~1.0", + "symfony/debug": "^4.4", + "symfony/var-dumper": "^4.4|^5.0" + }, + "require-dev": { + "symfony/http-kernel": "^4.4|^5.0", + "symfony/serializer": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "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 ErrorHandler Component", + "homepage": "https://symfony.com", + "time": "2019-12-01T08:46:01+00:00" + }, { "name": "symfony/event-dispatcher", "version": "v4.4.1", @@ -4309,27 +4316,27 @@ }, { "name": "symfony/expression-language", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "c8b47d8820d3bf75f757eec8a2647584c14cf0c6" + "reference": "8a1028a65623a8f7bba582b60e4fd308e6f43001" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/c8b47d8820d3bf75f757eec8a2647584c14cf0c6", - "reference": "c8b47d8820d3bf75f757eec8a2647584c14cf0c6", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/8a1028a65623a8f7bba582b60e4fd308e6f43001", + "reference": "8a1028a65623a8f7bba582b60e4fd308e6f43001", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/cache": "~3.4|~4.0", - "symfony/service-contracts": "^1.1" + "symfony/cache": "^3.4|^4.0|^5.0", + "symfony/service-contracts": "^1.1|^2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4356,20 +4363,20 @@ ], "description": "Symfony ExpressionLanguage Component", "homepage": "https://symfony.com", - "time": "2019-08-08T09:29:19+00:00" + "time": "2019-11-12T14:53:53+00:00" }, { "name": "symfony/filesystem", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263" + "reference": "40c2606131d56eff6f193b6e2ceb92414653b591" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/9abbb7ef96a51f4d7e69627bc6f63307994e4263", - "reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/40c2606131d56eff6f193b6e2ceb92414653b591", + "reference": "40c2606131d56eff6f193b6e2ceb92414653b591", "shasum": "" }, "require": { @@ -4379,7 +4386,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4406,20 +4413,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2019-08-20T14:07:54+00:00" + "time": "2019-11-26T23:16:41+00:00" }, { "name": "symfony/finder", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2" + "reference": "ce8743441da64c41e2a667b8eb66070444ed911e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/86c1c929f0a4b24812e1eb109262fc3372c8e9f2", - "reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2", + "url": "https://api.github.com/repos/symfony/finder/zipball/ce8743441da64c41e2a667b8eb66070444ed911e", + "reference": "ce8743441da64c41e2a667b8eb66070444ed911e", "shasum": "" }, "require": { @@ -4428,7 +4435,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4455,20 +4462,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2019-08-14T12:26:46+00:00" + "time": "2019-11-17T21:56:56+00:00" }, { "name": "symfony/flex", - "version": "v1.4.6", + "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/symfony/flex.git", - "reference": "133e649fdf08aeb8741be1ba955ccbe5cd17c696" + "reference": "952f45d1c5077e658cb16a61d11603bee873f968" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/133e649fdf08aeb8741be1ba955ccbe5cd17c696", - "reference": "133e649fdf08aeb8741be1ba955ccbe5cd17c696", + "url": "https://api.github.com/repos/symfony/flex/zipball/952f45d1c5077e658cb16a61d11603bee873f968", + "reference": "952f45d1c5077e658cb16a61d11603bee873f968", "shasum": "" }, "require": { @@ -4477,14 +4484,14 @@ }, "require-dev": { "composer/composer": "^1.0.2", - "symfony/dotenv": "^3.4|^4.0", - "symfony/phpunit-bridge": "^3.4.19|^4.1.8", - "symfony/process": "^2.7|^3.0|^4.0" + "symfony/dotenv": "^3.4|^4.0|^5.0", + "symfony/phpunit-bridge": "^3.4.19|^4.1.8|^5.0", + "symfony/process": "^2.7|^3.0|^4.0|^5.0" }, "type": "composer-plugin", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.5-dev" }, "class": "Symfony\\Flex\\Flex" }, @@ -4504,31 +4511,31 @@ } ], "description": "Composer plugin for Symfony", - "time": "2019-09-19T14:55:57+00:00" + "time": "2019-12-13T18:05:11+00:00" }, { "name": "symfony/form", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "eba11fd575e791d72030cb59215a9948791f1e74" + "reference": "08dfa1960bbd25caaf979a47e837696bf2ee6d65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/eba11fd575e791d72030cb59215a9948791f1e74", - "reference": "eba11fd575e791d72030cb59215a9948791f1e74", + "url": "https://api.github.com/repos/symfony/form/zipball/08dfa1960bbd25caaf979a47e837696bf2ee6d65", + "reference": "08dfa1960bbd25caaf979a47e837696bf2ee6d65", "shasum": "" }, "require": { "php": "^7.1.3", "symfony/event-dispatcher": "^4.3", - "symfony/intl": "^4.3", - "symfony/options-resolver": "~4.3", + "symfony/intl": "^4.4|^5.0", + "symfony/options-resolver": "~4.3|^5.0", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/property-access": "~3.4|~4.0", - "symfony/service-contracts": "~1.1" + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/service-contracts": "^1.1|^2" }, "conflict": { "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", @@ -4536,22 +4543,22 @@ "symfony/dependency-injection": "<3.4", "symfony/doctrine-bridge": "<3.4", "symfony/framework-bundle": "<3.4", - "symfony/http-kernel": "<4.3", + "symfony/http-kernel": "<4.4", "symfony/intl": "<4.3", "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": "^4.3", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/http-foundation": "~3.4|~4.0", - "symfony/http-kernel": "~4.3", - "symfony/security-csrf": "~3.4|~4.0", - "symfony/translation": "~4.2", - "symfony/validator": "^3.4.31|^4.3.4", - "symfony/var-dumper": "^4.3" + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/console": "^4.3|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/security-csrf": "^3.4|^4.0|^5.0", + "symfony/translation": "^4.2|^5.0", + "symfony/validator": "^3.4.31|^4.3.4|^5.0", + "symfony/var-dumper": "^4.3|^5.0" }, "suggest": { "symfony/security-csrf": "For protecting forms against CSRF attacks.", @@ -4561,7 +4568,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4588,7 +4595,7 @@ ], "description": "Symfony Form Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:55:16+00:00" + "time": "2019-12-01T09:13:30+00:00" }, { "name": "symfony/framework-bundle", @@ -4715,38 +4722,44 @@ }, { "name": "symfony/http-client", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "9a4fa769269ed730196a5c52c742b30600cf1e87" + "reference": "6c235cf15d8b516b41204a28d555685191409729" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/9a4fa769269ed730196a5c52c742b30600cf1e87", - "reference": "9a4fa769269ed730196a5c52c742b30600cf1e87", + "url": "https://api.github.com/repos/symfony/http-client/zipball/6c235cf15d8b516b41204a28d555685191409729", + "reference": "6c235cf15d8b516b41204a28d555685191409729", "shasum": "" }, "require": { "php": "^7.1.3", "psr/log": "^1.0", - "symfony/http-client-contracts": "^1.1.6", - "symfony/polyfill-php73": "^1.11" + "symfony/http-client-contracts": "^1.1.8|^2", + "symfony/polyfill-php73": "^1.11", + "symfony/service-contracts": "^1.0|^2" }, "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", "psr/http-client-implementation": "1.0", "symfony/http-client-implementation": "1.1" }, "require-dev": { + "guzzlehttp/promises": "^1.3.1", "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", - "symfony/http-kernel": "^4.3", - "symfony/process": "^4.2" + "symfony/dependency-injection": "^4.3|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/process": "^4.2|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4773,24 +4786,24 @@ ], "description": "Symfony HttpClient component", "homepage": "https://symfony.com", - "time": "2019-08-20T14:27:59+00:00" + "time": "2019-11-29T16:55:58+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v1.1.6", + "version": "v2.0.1", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "6005fe61a33724405d56eb5b055d5d370192a1bd" + "reference": "378868b61b85c5cac6822d4f84e26999c9f2e881" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/6005fe61a33724405d56eb5b055d5d370192a1bd", - "reference": "6005fe61a33724405d56eb5b055d5d370192a1bd", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/378868b61b85c5cac6822d4f84e26999c9f2e881", + "reference": "378868b61b85c5cac6822d4f84e26999c9f2e881", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.2.5" }, "suggest": { "symfony/http-client-implementation": "" @@ -4798,7 +4811,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -4830,7 +4843,7 @@ "interoperability", "standards" ], - "time": "2019-08-08T10:05:21+00:00" + "time": "2019-11-26T23:25:11+00:00" }, { "name": "symfony/http-foundation", @@ -4889,33 +4902,33 @@ }, { "name": "symfony/http-kernel", - "version": "v4.3.9", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "3feb99b01560f94173d8fbc5a203ea497d01d499" + "reference": "e4187780ed26129ee86d5234afbebf085e144f88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3feb99b01560f94173d8fbc5a203ea497d01d499", - "reference": "3feb99b01560f94173d8fbc5a203ea497d01d499", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e4187780ed26129ee86d5234afbebf085e144f88", + "reference": "e4187780ed26129ee86d5234afbebf085e144f88", "shasum": "" }, "require": { "php": "^7.1.3", "psr/log": "~1.0", - "symfony/debug": "~3.4|~4.0", - "symfony/event-dispatcher": "^4.3", - "symfony/http-foundation": "^4.1.1", - "symfony/polyfill-ctype": "~1.8", + "symfony/error-handler": "^4.4", + "symfony/event-dispatcher": "^4.4", + "symfony/http-foundation": "^4.4|^5.0", + "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9" }, "conflict": { "symfony/browser-kit": "<4.3", "symfony/config": "<3.4", + "symfony/console": ">=5", "symfony/dependency-injection": "<4.3", "symfony/translation": "<4.2", - "symfony/var-dumper": "<4.1.1", "twig/twig": "<1.34|<2.4,>=2" }, "provide": { @@ -4923,34 +4936,32 @@ }, "require-dev": { "psr/cache": "~1.0", - "symfony/browser-kit": "^4.3", - "symfony/config": "~3.4|~4.0", - "symfony/console": "~3.4|~4.0", - "symfony/css-selector": "~3.4|~4.0", - "symfony/dependency-injection": "^4.3", - "symfony/dom-crawler": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/finder": "~3.4|~4.0", - "symfony/process": "~3.4|~4.0", - "symfony/routing": "~3.4|~4.0", - "symfony/stopwatch": "~3.4|~4.0", - "symfony/templating": "~3.4|~4.0", - "symfony/translation": "~4.2", - "symfony/translation-contracts": "^1.1", - "symfony/var-dumper": "^4.1.1", - "twig/twig": "^1.34|^2.4" + "symfony/browser-kit": "^4.3|^5.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/console": "^3.4|^4.0", + "symfony/css-selector": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^4.3|^5.0", + "symfony/dom-crawler": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/finder": "^3.4|^4.0|^5.0", + "symfony/process": "^3.4|^4.0|^5.0", + "symfony/routing": "^3.4|^4.0|^5.0", + "symfony/stopwatch": "^3.4|^4.0|^5.0", + "symfony/templating": "^3.4|^4.0|^5.0", + "symfony/translation": "^4.2|^5.0", + "symfony/translation-contracts": "^1.1|^2", + "twig/twig": "^1.34|^2.4|^3.0" }, "suggest": { "symfony/browser-kit": "", "symfony/config": "", "symfony/console": "", - "symfony/dependency-injection": "", - "symfony/var-dumper": "" + "symfony/dependency-injection": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4977,7 +4988,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2019-12-01T14:00:23+00:00" + "time": "2019-12-01T14:06:38+00:00" }, { "name": "symfony/inflector", @@ -5039,16 +5050,16 @@ }, { "name": "symfony/intl", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "8db5505703c5bdb23d524fd994dad2f781966538" + "reference": "727fed5372915b5ea5e8177070f5e7e547063f24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/8db5505703c5bdb23d524fd994dad2f781966538", - "reference": "8db5505703c5bdb23d524fd994dad2f781966538", + "url": "https://api.github.com/repos/symfony/intl/zipball/727fed5372915b5ea5e8177070f5e7e547063f24", + "reference": "727fed5372915b5ea5e8177070f5e7e547063f24", "shasum": "" }, "require": { @@ -5056,7 +5067,7 @@ "symfony/polyfill-intl-icu": "~1.0" }, "require-dev": { - "symfony/filesystem": "~3.4|~4.0" + "symfony/filesystem": "^3.4|^4.0|^5.0" }, "suggest": { "ext-intl": "to use the component with locales other than \"en\"" @@ -5064,7 +5075,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5110,44 +5121,44 @@ "l10n", "localization" ], - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-11-26T23:16:41+00:00" }, { "name": "symfony/maker-bundle", - "version": "v1.13.0", + "version": "v1.14.3", "source": { "type": "git", "url": "https://github.com/symfony/maker-bundle.git", - "reference": "c4388410e2fb6321e77c5dd6e3cb2dba821f9fe6" + "reference": "c864e7f9b8d1e1f5f60acc3beda11299f637aded" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/c4388410e2fb6321e77c5dd6e3cb2dba821f9fe6", - "reference": "c4388410e2fb6321e77c5dd6e3cb2dba821f9fe6", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/c864e7f9b8d1e1f5f60acc3beda11299f637aded", + "reference": "c864e7f9b8d1e1f5f60acc3beda11299f637aded", "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" + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/filesystem": "^3.4|^4.0|^5.0", + "symfony/finder": "^3.4|^4.0|^5.0", + "symfony/framework-bundle": "^3.4|^4.0|^5.0", + "symfony/http-kernel": "^3.4|^4.0|^5.0" }, "require-dev": { - "doctrine/doctrine-bundle": "^1.8", + "doctrine/doctrine-bundle": "^1.8|^2.0", "doctrine/orm": "^2.3", "friendsofphp/php-cs-fixer": "^2.8", "friendsoftwig/twigcs": "^3.1.2", - "symfony/http-client": "^4.3", - "symfony/phpunit-bridge": "^3.4.19|^4.0", - "symfony/process": "^3.4|^4.0", - "symfony/security-core": "^3.4|^4.0", - "symfony/yaml": "^3.4|^4.0" + "symfony/http-client": "^4.3|^5.0", + "symfony/phpunit-bridge": "^4.3|^5.0", + "symfony/process": "^3.4|^4.0|^5.0", + "symfony/security-core": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "type": "symfony-bundle", "extra": { @@ -5178,33 +5189,37 @@ "scaffold", "scaffolding" ], - "time": "2019-08-18T17:34:03+00:00" + "time": "2019-11-07T00:56:03+00:00" }, { "name": "symfony/mercure", - "version": "v0.2.0", + "version": "v0.3.0", "source": { "type": "git", "url": "https://github.com/symfony/mercure.git", - "reference": "c74981184bf13f225c9a669cf28d06d0f4197593" + "reference": "999c125d3a8f96a2b6e9be3da40ff4c25844d1da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mercure/zipball/c74981184bf13f225c9a669cf28d06d0f4197593", - "reference": "c74981184bf13f225c9a669cf28d06d0f4197593", + "url": "https://api.github.com/repos/symfony/mercure/zipball/999c125d3a8f96a2b6e9be3da40ff4c25844d1da", + "reference": "999c125d3a8f96a2b6e9be3da40ff4c25844d1da", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/http-client": "^4.3" + "symfony/http-client": "^4.3.5|^5.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.2.4" + "symfony/phpunit-bridge": "^4.2.4|^5.0", + "symfony/stopwatch": "^4.3|^5.0" + }, + "suggest": { + "symfony/stopwatch": "Integration with the profiler performances" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "0.3.x-dev" }, "thanks": { "name": "dunglas/mercure", @@ -5238,31 +5253,33 @@ "sse", "updates" ], - "time": "2019-06-20T20:34:51+00:00" + "time": "2019-11-08T19:13:31+00:00" }, { "name": "symfony/mercure-bundle", - "version": "v0.1.2", + "version": "0.2.3", "source": { "type": "git", "url": "https://github.com/symfony/mercure-bundle.git", - "reference": "f8b538b94164fa46b80562ed6b0ba121cd3836dd" + "reference": "9c5fe6e761816449d84d5f0429e74415cb0590f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mercure-bundle/zipball/f8b538b94164fa46b80562ed6b0ba121cd3836dd", - "reference": "f8b538b94164fa46b80562ed6b0ba121cd3836dd", + "url": "https://api.github.com/repos/symfony/mercure-bundle/zipball/9c5fe6e761816449d84d5f0429e74415cb0590f2", + "reference": "9c5fe6e761816449d84d5f0429e74415cb0590f2", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/config": "^3.4|^4.0", - "symfony/dependency-injection": "^3.4|^4.0", - "symfony/http-kernel": "^3.4|^4.0", - "symfony/mercure": "^0.2" + "symfony/config": "^4.3.7|^5.0", + "symfony/dependency-injection": "^4.3.7|^5.0", + "symfony/http-kernel": "^4.3.7|^5.0", + "symfony/mercure": "^0.3" }, "require-dev": { - "symfony/phpunit-bridge": "^4.2.4" + "symfony/phpunit-bridge": "^4.3.7|^5.0", + "symfony/stopwatch": "^4.3.7|^5.0", + "symfony/var-dumper": "^4.3.7|^5.0" }, "suggest": { "symfony/messenger": "To use the Messenger integration" @@ -5270,7 +5287,7 @@ "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "0.2.x-dev" } }, "autoload": { @@ -5300,7 +5317,7 @@ "sse", "updates" ], - "time": "2019-06-24T19:45:57+00:00" + "time": "2019-11-24T10:29:29+00:00" }, { "name": "symfony/mime", @@ -5366,16 +5383,16 @@ }, { "name": "symfony/options-resolver", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "81c2e120522a42f623233968244baebd6b36cb6a" + "reference": "2be23e63f33de16b49294ea6581f462932a77e2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/81c2e120522a42f623233968244baebd6b36cb6a", - "reference": "81c2e120522a42f623233968244baebd6b36cb6a", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/2be23e63f33de16b49294ea6581f462932a77e2f", + "reference": "2be23e63f33de16b49294ea6581f462932a77e2f", "shasum": "" }, "require": { @@ -5384,7 +5401,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5416,20 +5433,20 @@ "configuration", "options" ], - "time": "2019-08-08T09:29:19+00:00" + "time": "2019-10-28T21:57:16+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "66810b9d6eb4af54d543867909d65ab9af654d7e" + "reference": "b3dffd68afa61ca70f2327f2dd9bbeb6aa53d70b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/66810b9d6eb4af54d543867909d65ab9af654d7e", - "reference": "66810b9d6eb4af54d543867909d65ab9af654d7e", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/b3dffd68afa61ca70f2327f2dd9bbeb6aa53d70b", + "reference": "b3dffd68afa61ca70f2327f2dd9bbeb6aa53d70b", "shasum": "" }, "require": { @@ -5442,7 +5459,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5474,7 +5491,7 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/polyfill-intl-idn", @@ -5712,16 +5729,16 @@ }, { "name": "symfony/process", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a" + "reference": "51c0135ef3f44c5803b33dc60e96bf4f77752726" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/e89969c00d762349f078db1128506f7f3dcc0d4a", - "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a", + "url": "https://api.github.com/repos/symfony/process/zipball/51c0135ef3f44c5803b33dc60e96bf4f77752726", + "reference": "51c0135ef3f44c5803b33dc60e96bf4f77752726", "shasum": "" }, "require": { @@ -5730,7 +5747,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5757,7 +5774,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-11-28T13:33:56+00:00" }, { "name": "symfony/property-access", @@ -5828,21 +5845,21 @@ }, { "name": "symfony/property-info", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "29546235b37f7bd279c763314cd4c962aedd1e6d" + "reference": "8afd280f159697177e48eefa89efd4db60a57665" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/29546235b37f7bd279c763314cd4c962aedd1e6d", - "reference": "29546235b37f7bd279c763314cd4c962aedd1e6d", + "url": "https://api.github.com/repos/symfony/property-info/zipball/8afd280f159697177e48eefa89efd4db60a57665", + "reference": "8afd280f159697177e48eefa89efd4db60a57665", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/inflector": "~3.4|~4.0" + "symfony/inflector": "^3.4|^4.0|^5.0" }, "conflict": { "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2", @@ -5852,9 +5869,9 @@ "require-dev": { "doctrine/annotations": "~1.7", "phpdocumentor/reflection-docblock": "^3.0|^4.0", - "symfony/cache": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/serializer": "~3.4|~4.0" + "symfony/cache": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/serializer": "^3.4|^4.0|^5.0" }, "suggest": { "phpdocumentor/reflection-docblock": "To use the PHPDoc", @@ -5865,7 +5882,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5900,20 +5917,20 @@ "type", "validator" ], - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-11-05T16:11:08+00:00" }, { "name": "symfony/routing", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "ff1049f6232dc5b6023b1ff1c6de56f82bcd264f" + "reference": "51f3f20ad29329a0bdf5c0e2f722d3764b065273" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/ff1049f6232dc5b6023b1ff1c6de56f82bcd264f", - "reference": "ff1049f6232dc5b6023b1ff1c6de56f82bcd264f", + "url": "https://api.github.com/repos/symfony/routing/zipball/51f3f20ad29329a0bdf5c0e2f722d3764b065273", + "reference": "51f3f20ad29329a0bdf5c0e2f722d3764b065273", "shasum": "" }, "require": { @@ -5927,11 +5944,11 @@ "require-dev": { "doctrine/annotations": "~1.2", "psr/log": "~1.0", - "symfony/config": "~4.2", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/http-foundation": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" + "symfony/config": "^4.2|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "doctrine/annotations": "For using the annotation loader", @@ -5943,7 +5960,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5976,7 +5993,7 @@ "uri", "url" ], - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-12-01T08:39:58+00:00" }, { "name": "symfony/security-bundle", @@ -6137,27 +6154,27 @@ }, { "name": "symfony/security-csrf", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "d218ba086ef4a68081f3dd5ec11611f5d64d58f3" + "reference": "aeed1a2315019b5a090f5ad34c01f1935ea9b757" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/d218ba086ef4a68081f3dd5ec11611f5d64d58f3", - "reference": "d218ba086ef4a68081f3dd5ec11611f5d64d58f3", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/aeed1a2315019b5a090f5ad34c01f1935ea9b757", + "reference": "aeed1a2315019b5a090f5ad34c01f1935ea9b757", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/security-core": "~3.4|~4.0" + "symfony/security-core": "^3.4|^4.0|^5.0" }, "conflict": { "symfony/http-foundation": "<3.4" }, "require-dev": { - "symfony/http-foundation": "~3.4|~4.0" + "symfony/http-foundation": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/http-foundation": "For using the class SessionTokenStorage." @@ -6165,7 +6182,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6192,26 +6209,26 @@ ], "description": "Symfony Security Component - CSRF Library", "homepage": "https://symfony.com", - "time": "2019-08-13T06:39:03+00:00" + "time": "2019-10-12T00:35:04+00:00" }, { "name": "symfony/security-guard", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/security-guard.git", - "reference": "cf06aa4f8ea38a769476c4f5989f1dc400a308a1" + "reference": "df82bbbd01486ff21a053d325cf9159b4d70b544" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-guard/zipball/cf06aa4f8ea38a769476c4f5989f1dc400a308a1", - "reference": "cf06aa4f8ea38a769476c4f5989f1dc400a308a1", + "url": "https://api.github.com/repos/symfony/security-guard/zipball/df82bbbd01486ff21a053d325cf9159b4d70b544", + "reference": "df82bbbd01486ff21a053d325cf9159b4d70b544", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/security-core": "~3.4.22|^4.2.3", - "symfony/security-http": "^4.3" + "symfony/security-core": "^3.4.22|^4.2.3|^5.0", + "symfony/security-http": "^4.4.1" }, "require-dev": { "psr/log": "~1.0" @@ -6219,7 +6236,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6246,36 +6263,37 @@ ], "description": "Symfony Security Component - Guard", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-11-30T09:49:41+00:00" }, { "name": "symfony/security-http", - "version": "v4.3.9", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "75e96df3a1b9b38c67e2fa208894f72dae5e1147" + "reference": "ff3ab7cda1703195dbe7f97cccaf77478126e0cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/75e96df3a1b9b38c67e2fa208894f72dae5e1147", - "reference": "75e96df3a1b9b38c67e2fa208894f72dae5e1147", + "url": "https://api.github.com/repos/symfony/security-http/zipball/ff3ab7cda1703195dbe7f97cccaf77478126e0cd", + "reference": "ff3ab7cda1703195dbe7f97cccaf77478126e0cd", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/http-foundation": "~3.4|~4.0", - "symfony/http-kernel": "^4.3", - "symfony/property-access": "~3.4|~4.0", - "symfony/security-core": "^4.3" + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/security-core": "^4.4" }, "conflict": { + "symfony/event-dispatcher": ">=5", "symfony/security-csrf": "<3.4.11|~4.0,<4.0.11" }, "require-dev": { "psr/log": "~1.0", - "symfony/routing": "~3.4|~4.0", - "symfony/security-csrf": "^3.4.11|^4.0.11" + "symfony/routing": "^3.4|^4.0|^5.0", + "symfony/security-csrf": "^3.4.11|^4.0.11|^5.0" }, "suggest": { "symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs", @@ -6284,7 +6302,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6311,20 +6329,20 @@ ], "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", - "time": "2019-11-30T13:16:45+00:00" + "time": "2019-12-01T08:46:01+00:00" }, { "name": "symfony/serializer", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "702900654e0ceed9ca7a9eccffb1d6ec69d7c8b6" + "reference": "842637bdcbed31c7dc62b3c30dfc8949f6457968" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/702900654e0ceed9ca7a9eccffb1d6ec69d7c8b6", - "reference": "702900654e0ceed9ca7a9eccffb1d6ec69d7c8b6", + "url": "https://api.github.com/repos/symfony/serializer/zipball/842637bdcbed31c7dc62b3c30dfc8949f6457968", + "reference": "842637bdcbed31c7dc62b3c30dfc8949f6457968", "shasum": "" }, "require": { @@ -6341,15 +6359,16 @@ "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.13|~4.0", - "symfony/validator": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" + "phpdocumentor/reflection-docblock": "^3.2|^4.0", + "symfony/cache": "^3.4|^4.0|^5.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/error-handler": "^4.4|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/property-info": "^3.4.13|~4.0|^5.0", + "symfony/validator": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", @@ -6364,7 +6383,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6391,7 +6410,7 @@ ], "description": "Symfony Serializer Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:55:16+00:00" + "time": "2019-11-28T13:33:56+00:00" }, { "name": "symfony/service-contracts", @@ -6453,26 +6472,26 @@ }, { "name": "symfony/stopwatch", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "1e4ff456bd625be5032fac9be4294e60442e9b71" + "reference": "5745b514fc56ae1907c6b8ed74f94f90f64694e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/1e4ff456bd625be5032fac9be4294e60442e9b71", - "reference": "1e4ff456bd625be5032fac9be4294e60442e9b71", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5745b514fc56ae1907c6b8ed74f94f90f64694e9", + "reference": "5745b514fc56ae1907c6b8ed74f94f90f64694e9", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/service-contracts": "^1.0" + "symfony/service-contracts": "^1.0|^2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6499,24 +6518,24 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2019-08-07T11:52:19+00:00" + "time": "2019-11-05T16:11:08+00:00" }, { "name": "symfony/translation-contracts", - "version": "v1.1.6", + "version": "v2.0.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "325b17c24f3ee23cbecfa63ba809c6d89b5fa04a" + "reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/325b17c24f3ee23cbecfa63ba809c6d89b5fa04a", - "reference": "325b17c24f3ee23cbecfa63ba809c6d89b5fa04a", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/8cc682ac458d75557203b2f2f14b0b92e1c744ed", + "reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.2.5" }, "suggest": { "symfony/translation-implementation": "" @@ -6524,7 +6543,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -6556,59 +6575,61 @@ "interoperability", "standards" ], - "time": "2019-08-02T12:15:04+00:00" + "time": "2019-11-18T17:27:11+00:00" }, { "name": "symfony/twig-bridge", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "cd6c551dc5d62b520d1a973fb4cb2c46bfc00b62" + "reference": "6121dd0156649047f38cfc02a5d64091692892f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/cd6c551dc5d62b520d1a973fb4cb2c46bfc00b62", - "reference": "cd6c551dc5d62b520d1a973fb4cb2c46bfc00b62", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/6121dd0156649047f38cfc02a5d64091692892f2", + "reference": "6121dd0156649047f38cfc02a5d64091692892f2", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/translation-contracts": "^1.1", - "twig/twig": "^1.41|^2.10" + "symfony/translation-contracts": "^1.1|^2", + "twig/twig": "^1.41|^2.10|^3.0" }, "conflict": { "symfony/console": "<3.4", - "symfony/form": "<4.3.4", + "symfony/form": "<4.4", "symfony/http-foundation": "<4.3", "symfony/translation": "<4.2", "symfony/workflow": "<4.3" }, "require-dev": { "egulias/email-validator": "^2.1.10", - "fig/link-util": "^1.0", - "symfony/asset": "~3.4|~4.0", - "symfony/console": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/finder": "~3.4|~4.0", - "symfony/form": "^4.3.4", - "symfony/http-foundation": "~4.3", - "symfony/http-kernel": "~3.4|~4.0", - "symfony/mime": "~4.3", + "symfony/asset": "^3.4|^4.0|^5.0", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/error-handler": "^4.4|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/finder": "^3.4|^4.0|^5.0", + "symfony/form": "^4.3.5", + "symfony/http-foundation": "^4.3|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/mime": "^4.3|^5.0", "symfony/polyfill-intl-icu": "~1.0", - "symfony/routing": "~3.4|~4.0", - "symfony/security-acl": "~2.8|~3.0", - "symfony/security-core": "~3.0|~4.0", - "symfony/security-csrf": "~3.4|~4.0", - "symfony/security-http": "~3.4|~4.0", - "symfony/stopwatch": "~3.4|~4.0", - "symfony/templating": "~3.4|~4.0", - "symfony/translation": "^4.2.1", - "symfony/var-dumper": "~3.4|~4.0", - "symfony/web-link": "~3.4|~4.0", - "symfony/workflow": "~4.3", - "symfony/yaml": "~3.4|~4.0" + "symfony/routing": "^3.4|^4.0|^5.0", + "symfony/security-acl": "^2.8|^3.0", + "symfony/security-core": "^3.0|^4.0|^5.0", + "symfony/security-csrf": "^3.4|^4.0|^5.0", + "symfony/security-http": "^3.4|^4.0|^5.0", + "symfony/stopwatch": "^3.4|^4.0|^5.0", + "symfony/templating": "^3.4|^4.0|^5.0", + "symfony/translation": "^4.2.1|^5.0", + "symfony/web-link": "^4.4|^5.0", + "symfony/workflow": "^4.3|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0", + "twig/cssinliner-extra": "^2.12", + "twig/inky-extra": "^2.12", + "twig/markdown-extra": "^2.12" }, "suggest": { "symfony/asset": "For using the AssetExtension", @@ -6630,7 +6651,7 @@ "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6657,7 +6678,7 @@ ], "description": "Symfony Twig Bridge", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-11-30T14:03:57+00:00" }, { "name": "symfony/twig-bundle", @@ -6738,56 +6759,55 @@ }, { "name": "symfony/validator", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "173b483999c2acad8e040633105733318dcc8a83" + "reference": "6b1774cf44c378617af362eaa154105952d488f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/173b483999c2acad8e040633105733318dcc8a83", - "reference": "173b483999c2acad8e040633105733318dcc8a83", + "url": "https://api.github.com/repos/symfony/validator/zipball/6b1774cf44c378617af362eaa154105952d488f8", + "reference": "6b1774cf44c378617af362eaa154105952d488f8", "shasum": "" }, "require": { "php": "^7.1.3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^1.1" + "symfony/translation-contracts": "^1.1|^2" }, "conflict": { "doctrine/lexer": "<1.0.2", "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", "symfony/dependency-injection": "<3.4", - "symfony/http-kernel": "<3.4", + "symfony/http-kernel": "<4.4", "symfony/intl": "<4.3", - "symfony/translation": "<4.2", + "symfony/translation": ">=5.0", "symfony/yaml": "<3.4" }, "require-dev": { "doctrine/annotations": "~1.7", "doctrine/cache": "~1.0", "egulias/email-validator": "^2.1.10", - "symfony/cache": "~3.4|~4.0", - "symfony/config": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/http-client": "^4.3", - "symfony/http-foundation": "~4.1", - "symfony/http-kernel": "~3.4|~4.0", - "symfony/intl": "^4.3", - "symfony/property-access": "~3.4|~4.0", - "symfony/property-info": "~3.4|~4.0", - "symfony/translation": "~4.2", - "symfony/var-dumper": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" + "symfony/cache": "^3.4|^4.0|^5.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/http-client": "^4.3|^5.0", + "symfony/http-foundation": "^4.1|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/intl": "^4.3|^5.0", + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/property-info": "^3.4|^4.0|^5.0", + "symfony/translation": "^4.2", + "symfony/yaml": "^3.4|^4.0|^5.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.", + "doctrine/cache": "For using the default cached annotation reader.", "egulias/email-validator": "Strict (RFC compliant) email validation", - "psr/cache-implementation": "For using the metadata cache.", + "psr/cache-implementation": "For using the mapping cache.", "symfony/config": "", "symfony/expression-language": "For using the Expression validator", "symfony/http-foundation": "", @@ -6800,7 +6820,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6827,7 +6847,83 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com", - "time": "2019-08-26T09:28:48+00:00" + "time": "2019-11-30T14:03:57+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v4.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "0a89a1dbbedd9fb2cfb2336556dec8305273c19a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0a89a1dbbedd9fb2cfb2336556dec8305273c19a", + "reference": "0a89a1dbbedd9fb2cfb2336556dec8305273c19a", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php72": "~1.5" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/console": "<3.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/process": "^4.4|^5.0", + "twig/twig": "^1.34|^2.4|^3.0" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "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 mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "time": "2019-11-28T13:33:56+00:00" }, { "name": "symfony/var-exporter", @@ -6891,29 +6987,32 @@ }, { "name": "symfony/web-link", - "version": "v4.3.4", + "version": "v4.4.1", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "4bd0ce7c54d604300deee8eb1b1beda856fbba20" + "reference": "bc6432b92681b2f28ced2f3bbcf051e75eea569c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/4bd0ce7c54d604300deee8eb1b1beda856fbba20", - "reference": "4bd0ce7c54d604300deee8eb1b1beda856fbba20", + "url": "https://api.github.com/repos/symfony/web-link/zipball/bc6432b92681b2f28ced2f3bbcf051e75eea569c", + "reference": "bc6432b92681b2f28ced2f3bbcf051e75eea569c", "shasum": "" }, "require": { - "fig/link-util": "^1.0", "php": "^7.1.3", - "psr/link": "^1.0" + "psr/link": "^1.0", + "symfony/polyfill-php72": "^1.5" }, "conflict": { "symfony/http-kernel": "<4.3" }, + "provide": { + "psr/link-implementation": "1.0" + }, "require-dev": { - "symfony/http-foundation": "~3.4|~4.0", - "symfony/http-kernel": "^4.3" + "symfony/http-foundation": "^4.4|^5.0", + "symfony/http-kernel": "^4.3|^5.0" }, "suggest": { "symfony/http-kernel": "" @@ -6921,7 +7020,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6960,7 +7059,7 @@ "psr13", "push" ], - "time": "2019-08-08T09:29:19+00:00" + "time": "2019-10-12T00:35:04+00:00" }, { "name": "symfony/yaml", @@ -7096,16 +7195,16 @@ }, { "name": "twig/twig", - "version": "v2.11.3", + "version": "v2.12.2", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "699ed2342557c88789a15402de5eb834dedd6792" + "reference": "d761fd1f1c6b867ae09a7d8119a6d95d06dc44ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/699ed2342557c88789a15402de5eb834dedd6792", - "reference": "699ed2342557c88789a15402de5eb834dedd6792", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/d761fd1f1c6b867ae09a7d8119a6d95d06dc44ed", + "reference": "d761fd1f1c6b867ae09a7d8119a6d95d06dc44ed", "shasum": "" }, "require": { @@ -7115,13 +7214,13 @@ }, "require-dev": { "psr/container": "^1.0", - "symfony/debug": "^2.7", - "symfony/phpunit-bridge": "^3.4.19|^4.1.8|^5.0" + "symfony/debug": "^3.4|^4.2", + "symfony/phpunit-bridge": "^4.4@dev|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.11-dev" + "dev-master": "2.12-dev" } }, "autoload": { @@ -7143,15 +7242,15 @@ "homepage": "http://fabien.potencier.org", "role": "Lead Developer" }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - }, { "name": "Twig Team", "homepage": "https://twig.symfony.com/contributors", "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" } ], "description": "Twig, the flexible, fast, and secure template language for PHP", @@ -7159,35 +7258,33 @@ "keywords": [ "templating" ], - "time": "2019-06-18T15:37:11+00:00" + "time": "2019-11-11T16:52:09+00:00" }, { "name": "webmozart/assert", - "version": "1.5.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" + "reference": "573381c0a64f155a0d9a23f4b0c797194805b925" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", + "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925", + "reference": "573381c0a64f155a0d9a23f4b0c797194805b925", "shasum": "" }, "require": { "php": "^5.3.3 || ^7.0", "symfony/polyfill-ctype": "^1.8" }, + "conflict": { + "vimeo/psalm": "<3.6.0" + }, "require-dev": { "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -7209,7 +7306,7 @@ "check", "validate" ], - "time": "2019-08-24T08:43:50+00:00" + "time": "2019-11-24T13:36:37+00:00" }, { "name": "webonyx/graphql-php", @@ -7345,82 +7442,6 @@ "description": "A pack for the Symfony web profiler", "time": "2018-12-10T12:11:44+00:00" }, - { - "name": "symfony/var-dumper", - "version": "v4.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "641043e0f3e615990a0f29479f9c117e8a6698c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/641043e0f3e615990a0f29479f9c117e8a6698c6", - "reference": "641043e0f3e615990a0f29479f9c117e8a6698c6", - "shasum": "" - }, - "require": { - "php": "^7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php72": "~1.5" - }, - "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", - "symfony/console": "<3.4" - }, - "require-dev": { - "ext-iconv": "*", - "symfony/console": "~3.4|~4.0", - "symfony/process": "~3.4|~4.0", - "twig/twig": "~1.34|~2.4" - }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" - }, - "bin": [ - "Resources/bin/var-dump-server" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.3-dev" - } - }, - "autoload": { - "files": [ - "Resources/functions/dump.php" - ], - "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "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 mechanism for exploring and dumping PHP variables", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "time": "2019-08-26T08:26:39+00:00" - }, { "name": "symfony/web-profiler-bundle", "version": "v4.3.4", diff --git a/api/config/bundles.php b/api/config/bundles.php index b3f9617a..aba2fb86 100644 --- a/api/config/bundles.php +++ b/api/config/bundles.php @@ -1,20 +1,19 @@ ['all' => true], - Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], - Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], - Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true], - Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], - Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true], - Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], - 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], - Conduction\CommonGroundBundle\CommonGroundBundle::class => ['all' => true], - Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], + Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], + Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], + Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], + Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true], + Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], + Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + 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], + Conduction\CommonGroundBundle\CommonGroundBundle::class => ['all' => true], + Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], - Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], - Tbbc\MoneyBundle\TbbcMoneyBundle::class => ['all' => true], + Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], + Tbbc\MoneyBundle\TbbcMoneyBundle::class => ['all' => true], ]; diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml index ee6c1853..481428f9 100644 --- a/api/config/packages/twig.yaml +++ b/api/config/packages/twig.yaml @@ -31,7 +31,7 @@ twig: app_version: '%env(APP_VERSION)%' app_env: '%env(APP_ENV)%' app_debug: '%env(APP_DEBUG)%' - app_domain: '%env(APP_DOMAIN)%' + app_subdomain: '%env(APP_SUBDOMAIN)%' app_domains: '%env(json:APP_DOMAINS)%' app_demo: '%env(APP_DEMO)%' app_repro: '%env(APP_REPRO)%' diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index 611e5d39..2d5df508 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -9,7 +9,7 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: - replicas: 3 + replicas: 1 template: metadata: labels: diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 37d92376..58891e1d 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -10,13 +10,14 @@ settings: version: V.0.1 description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' repro: 'https://github.com/ConductionNL/Proto-component-commonground' - domain: conduction.nl + subdomain: pc domains: - conduction.nl - - zaakonline.nl - - larping.eu - - common-ground.dev - - trouwplanner.online + # - vng.cloud + # - zaakonline.nl + # - larping.eu + # - common-ground.dev + # - trouwplanner.online - huwelijksplanner.online organisationName: Conduction email: info@conduction.nl @@ -29,7 +30,7 @@ settings: debug: 1 replicaCount: 1 corsAllowOrigin: ['*'] - trustedHosts: '^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' + trustedHosts: '^(.+\.)?conduction\.nl$|^(.+\.)?vng\.cloud$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' pullPolicy: Always # You will need these proxies on kubernetes trustedProxies: diff --git a/api/src/Subscriber/FieldsSubscriber.php b/api/src/Subscriber/FieldsAndExtendSubscriber.php similarity index 53% rename from api/src/Subscriber/FieldsSubscriber.php rename to api/src/Subscriber/FieldsAndExtendSubscriber.php index f842a8e2..5b9c7e04 100644 --- a/api/src/Subscriber/FieldsSubscriber.php +++ b/api/src/Subscriber/FieldsAndExtendSubscriber.php @@ -9,16 +9,19 @@ use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Component\PropertyAccess\PropertyAccess; -class FieldsSubscriber implements EventSubscriberInterface +class FieldsAndExtendSubscriber implements EventSubscriberInterface { private $params; private $serializer; + private $propertyAccessor; public function __construct(ParameterBagInterface $params, SerializerInterface $serializer) { $this->params = $params; $this->serializer = $serializer; + $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); } public static function getSubscribedEvents() @@ -32,9 +35,13 @@ public function FilterFields(GetResponseForControllerResultEvent $event) { $result = $event->getControllerResult(); $fields = $event->getRequest()->query->get('fields'); + $extends = $event->getRequest()->query->get('extend'); + // This needs to be bassed on the content-type + $type = 'jsonhal'; + // Only do somthing if fields is query supplied - if (!$fields) { + if (!$fields && $extends) { return $result; } @@ -42,6 +49,19 @@ public function FilterFields(GetResponseForControllerResultEvent $event) if (!is_array($fields)) { $fields = explode(',', $fields); } + if (!is_array($extends)) { + $extends= explode(',', $extends); + } + + // Its possible to nest fields for filterins + foreach($fields as $key->$value){ + // Lets check if the fields contain one or more .'s + if (strpos($value, '.') !== false) { + // This is where it gets complicated couse it could go on indevinitly + } + } + + // Overwrite maxdepth for extended properties // we always need to return an id and links (in order not to break stuff) if (!in_array('id', $fields)) { @@ -54,8 +74,31 @@ public function FilterFields(GetResponseForControllerResultEvent $event) // now we need to overide the normal subscriber $json = $this->serializer->serialize( $result, - 'jsonhal', ['enable_max_depth' => true, 'attributes'=> $fields] + $type, + ['enable_max_depth' => true, + 'attributes'=> $fields] ); + + + $jsonArray = json_decode($json, true); + + // The we want to extend properties from the extend query + foreach($extends as $extend){ + /* @todo add security checks */ + // Get new object for the extend + $extendObject = $this->propertyAccessor->getValue($result, $extend); + // turn to json + $extendjson = $this->serializer->serialize( + $result, + $type, + ['enable_max_depth' => true, + 'attributes'=> $fields] + ); + // add to the array + $jsonArray[$extend] = json_decode($extendjson, true); + } + + $json = json_encode($jsonArray); $response = new Response( $json, diff --git a/api/symfony.lock b/api/symfony.lock index 4942a3b5..92765b1f 100644 --- a/api/symfony.lock +++ b/api/symfony.lock @@ -73,9 +73,6 @@ "src/Repository/.gitignore" ] }, - "doctrine/doctrine-cache-bundle": { - "version": "1.3.5" - }, "doctrine/doctrine-fixtures-bundle": { "version": "3.0", "recipe": { @@ -305,6 +302,9 @@ "symfony/dotenv": { "version": "v4.3.1" }, + "symfony/error-handler": { + "version": "v4.4.1" + }, "symfony/event-dispatcher": { "version": "v4.3.1" }, diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index aade15ab..a328bd6b 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -10,7 +10,7 @@ settings: version: {{ app_version }} description: '{{ app_description }}' repro: '{{ app_repro }}' - domain: {{ app_domain }} + subdomain: {{ app_subdomain }} domains: {% for domain in app_domains %} - {{ domain }} diff --git a/docker-compose.yml b/docker-compose.yml index 3c8a82c8..62224f43 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,6 @@ x-cache: - ${CONTAINER_REGISTRY_BASE}/${CONTAINER_PROJECT_NAME}-varnish - ${CONTAINER_REGISTRY_BASE}/${CONTAINER_PROJECT_NAME}-admin - ${CONTAINER_REGISTRY_BASE}/${CONTAINER_PROJECT_NAME}-client - - ${CONTAINER_REGISTRY_BASE}/${CONTAINER_PROJECT_NAME}-h2-proxy services: php: @@ -30,13 +29,14 @@ services: - CONTAINER_REGISTRY_BASE=${CONTAINER_REGISTRY_BASE} - CONTAINER_PROJECT_NAME=${CONTAINER_PROJECT_NAME} - CONTAINER_REPRO=${CONTAINER_REPRO} - - DATABASE_URL=postgres://api-platform:!ChangeMe!@db/api?serverVersion=10.1 + #- DATABASE_URL=postgres://api-platform:!ChangeMe!@db/api?serverVersion=10.1 + - DATABASE_URL=mysql://api-platform:!ChangeMe!@db/api?serverVersion=10.1 - APP_ENV=${APP_ENV} - APP_DEBUG=${APP_DEBUG} - APP_VERSION=${APP_VERSION} - APP_NAME=${APP_NAME} - APP_TITLE=${APP_TITLE} - - APP_DOMAIN=${APP_DOMAIN} + - APP_SUBDOMAIN=${APP_SUBDOMAIN} - APP_DOMAINS=${APP_DOMAINS} - APP_DEMO=${APP_DEMO} - APP_REPRO=${APP_REPRO} @@ -167,15 +167,28 @@ services: networks: - nlx + #db: + # image: postgres:10-alpine + # environment: + # - POSTGRES_DB=api + # - POSTGRES_USER=api-platform + # You should definitely change the password in production + # - POSTGRES_PASSWORD=!ChangeMe! + # volumes: + # - db-data:/var/lib/postgresql/data:rw + db: - image: postgres:10-alpine + image: mysql:5.6 + restart: always environment: - - POSTGRES_DB=api - - POSTGRES_USER=api-platform - # You should definitely change the password in production - - POSTGRES_PASSWORD=!ChangeMe! + - MYSQL_ROOT_PASSWORD=example + - MYSQL_DATABASE=api + - MYSQL_USER=api-platform + - MYSQL_PASSWORD=!ChangeMe! volumes: - - db-data:/var/lib/postgresql/data:rw + - db-mysql:/var/lib/mysql:rw + ports: + - "3306:3306" mercure: # In production, you may want to use the managed version of Mercure, https://mercure.rocks @@ -250,4 +263,5 @@ networks: volumes: db-data: {} + db-mysql: {} nlx-data-2: {} From 5a4b50f6de09cd525d00b522a7f2f69009a51d70 Mon Sep 17 00:00:00 2001 From: Barry Date: Thu, 19 Dec 2019 16:03:20 +0100 Subject: [PATCH 153/182] DESIGN.md deleted --- DESIGN.md | 330 ------------------------------------------------------ 1 file changed, 330 deletions(-) delete mode 100644 DESIGN.md diff --git a/DESIGN.md b/DESIGN.md deleted file mode 100644 index cffb8595..00000000 --- a/DESIGN.md +++ /dev/null @@ -1,330 +0,0 @@ -# Design Considerations as Proposal - -Welcome, you are currently viewing the design decisions for the proto component. The proto component aims to provide a framework for the quick development of production apis for the commonground project. - -*Index* -- [The European factor](#the-european-factor) -- [On standards and standardisation](#on-standards-and-standardization) -- [NL API Strategie](#nl-api-strategie) - -*Design Choices* -- [NLX](#nlx) -- [English](#english) -- [Fields](#fields) -- [Search](#search) -- [Queries](#queries) -- [Extending](#extending) -- [Time travel](#timetravel) -- [Archivation](#archivation) -- [Audit trail](#audittrail) -- [Health checks](#healthchecks) -- [Notifications](#notifications) -- [Authentication](#authentication) -- [Authorization](#authorization) -- [Ordering](#ordering) -- [Translations](#translations) -- [Errors](#errors) -- [Arrays](#arrays) -- [Filtering](#filtering) - -*Implementation choices* -- [Api Versioning](#api-versioning) -- [Environments and name spacing](#environments-and-namespacing) -- [Domain Build-up and routing](#domain-build-up-and-routing) -- [Container Setup](#container-setup) - - -The European factor -------- -The proto-component isn't just a Dutch Component, it is in essence a Dutch translation of European components, nowhere is this more obvious than in the core code. Our component is based on [API Platform](https://api-platform.com/) an API specific version of the symfony framework. This framework is build by the lovely people of [Les Tilleuls](https://les-tilleuls.coop/en) and is build with support of the European Commission trough the [EU-FOSSA Hackathon](https://ec.europa.eu/info/news/first-eu-fossa-hackathon-it-happened-2019-may-03_en) and Digital Ocean trough [Hacktoberfest](https://hacktoberfest.digitalocean.com/). - -But it doesn't just end there. The [varnish container](https://hub.docker.com/r/eeacms/varnish/) that we use to speed up the API response is build and maintained by [EEA]() (The European Environment Agency) and the development team at conduction itself is attached to the [Odyssey program](https://www.odyssey.org/) and originated from the [startupinresidence](https://startupinresidence.com/) program. - -So you could say that both change and a European perspective is in our blood. - -On standards and standardization -------- -The specific goal of the proto component (which this current code base is a version of) is to provide a common architecture for common ground components. As such the common ground principles are leading in design choices, and within those principles international compliancy and technological invocation is deemed most important. **We do not want to make concessions to the current infrastructure.** As such the component might differ on [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index) and or other standards if they are deemed incompatible or out of line with (inter)national standards and or good practices. - -Unfortunately (inter)national standards can be conflicting. We therefore prioritize standards on several grounds - -- International is put before local -- Standards carried by a standard organization (like ISO, W3C etc) at put before floating standards (like RFC's) wichs are put before industry standards, good practices and so on. - -So if for instance a **local** standard is out of line with an **international** good practice we follow the international good practice. - -### Commonground specific standards - -This component was designed in line with the [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index), [commonground principles](https://vng.nl/onderwerpenindex/bestuur/samen-organiseren-2019/common-ground). - -## NL API Strategie - -The [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie) takes a special place in this component, it is designed as a set of guidelines for API's for the Dutch landscape. As such we follow it as close as possible. It dos however contains inconsistencies with both international standards and good practices. On those items we do not follow the norm but consider it our duty to try to change the norm. - -** We implement ** - -api-01, api-02, api-03, api-05, api-06, api-10, api-11, api-12, api-13,api-14, api-16, api-18, api-19, api-20, api-21, api-22, api-23, api-24, api-25, api-26, api-27, api-28, api-29, api-30, api-33, api-34, api-35, api-42 - -** We want to implement ** -- [api-14](https://docs.geostandaarden.nl/api/API-Strategie/#api-14) Use OAuth 2.0 for authorization - -** We do not implement ** - -- [api-04](https://docs.geostandaarden.nl/api/API-Strategie/#api-04) Define interfaces in Dutch unless there is an official English glossary (see [english](#english)) -- [api-09](https://docs.geostandaarden.nl/api/API-Strategie/#api-09) Implement custom representation if supported (see [fields](#fields)) -- [api-17](https://docs.geostandaarden.nl/api/API-Strategie/#api-17) Publish documentation in Dutch unless there is existing documentation in English or there is an official English glossary (see [english](#english)) -- [api-31](https://docs.geostandaarden.nl/api/API-Strategie/#api-31) Use the query parameter sorteer to sort (see [ordering](#ordering)) -- [api-32](https://docs.geostandaarden.nl/api/API-Strategie/#api-32) Use the query parameter zoek for full-text search (see [search](#search)) -- [api-36](https://docs.geostandaarden.nl/api/API-Strategie/#api-36) Provide a POST endpoint for GEO queries (see [queries](#queries)) -- [api-37](https://docs.geostandaarden.nl/api/API-Strategie/#api-37) Support mixed queries at POST endpoints available (see [queries](#queries)) -- [api-38](https://docs.geostandaarden.nl/api/API-Strategie/#api-38) Put results of a global spatial query in the relevant geometric context (see [queries](#queries)) - - -** We doubt or haven’t made a choice yet about** - -- [api-15](https://docs.geostandaarden.nl/api/API-Strategie/#api-15) Use PKI overheid certificates for access-restricted or purpose-limited API authentication -- [api-39](https://docs.geostandaarden.nl/api/API-Strategie/#api-39) Use ETRS89 as the preferred coordinate reference system (CRS) -- [api-40](https://docs.geostandaarden.nl/api/API-Strategie/#api-40) Pass the coordinate reference system (CRS) of the request and the response in the headers -- [api-41](https://docs.geostandaarden.nl/api/API-Strategie/#api-41) Use content negotiation to serve different CRS - -NLX -------- -We implement the [NLX system](https://docs.nlx.io/understanding-the-basics/introduction/) as part of the basic commonground infrastructure, as such nlx headers are used in the internal logging. -The following X-NLX headers have been implemented for that reason `X-NLX-Logrecord-ID`,`X-NLX-Request-Process-Id`,`X-NLX-Request-Data-Elements` and `X-NLX-Request-Data-Subject`, these are tied to the internal audit trail (see audit trail for more information), and `X-Audit-Toelichting` (from the ZGW APIs) is implemented as `X-Audit-Clarification`. We do not use other NLX headers since they (conform to the [NLX schema](https://docs.nlx.io/reference-information/transaction-log-headers/)) wil not reach the provider. - -We strongly discourage the use of the `X-NLX-Request-Data-Subject` header as it might allow private data (such as BSNs) to show up in logging. - -Please note that the use of nlx is optional. The component can be used without NLX. In that case set `X-NLX-Logrecord-ID` to false and provide (the normaly ignored) fields `X-NLX-Requester-User-Id`, `X-NLX-Request-Application-Id`, `X-NLX-Request-Subject-Identifier`, `X-NLX-Requester-Claims` and `X-NLX-Request-User` as if you are making an NLX call. This provides the API with enough credentials to make an complete audit trail. It also provides an easy implementation route to NLX since the only thing that would need to be changed at a later time is making you call to an nlx outway instead of the API directly. - -English -------- -The [NL API Standard](https://geonovum.github.io/KP-APIs/#api-04-define-interfaces-in-dutch-unless-there-is-an-official-english-glossary) describes that there is a preference for Dutch in API documentation. - -> Define resources and the underlying entities, fields and so on (the information model ad the external interface) in Dutch. English is allowed in case there is an official English glossary. - -We view this as a breach with good coding practice and international coding standards, all documentation and code is therefore supplied in English. We do however provide translation (or i18n) support. - -Fields -------- -A part of the [haal centraal](https://raw.githubusercontent.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/master/api-specificatie/Bevraging-Ingeschreven-Persoon/openapi.yaml) the concept of field limitations has been introduced its general purpose being to allow an application to limit the returned fields to prevent the unnecessary transportation of (private) data. In the [NL API Strategie](https://github.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/blob/master/features/fields.feature) this has been implemented as a parameter consisting of comma separated values. However the normal web standard for optional lists (conform w3c form standards) is an array. - -Search -------- -As part of [api-32](https://docs.geostandaarden.nl/api/API-Strategie/#api-32) a `zoeken` query has been introduced that can handle wildcards. This breaks best practice, first of allest practice is a `search` query parameter (see also the nodes on [English](#english)). Secondly wildcards are a sql concept, not a webconcept, they are also a rather old concept severely limiting the search options provided. Instead the [regular expression standard](https://en.wikipedia.org/wiki/Regular_expression) should be used. - -__solution__ -We implement a `search` query parameter on resource collections, that filters with regex. - -Queries -------- -In several examples of the nl api strategie we see query parameters being attached to post requests. This is unusual in the sence that sending query strings along with a post is considered bad practice (because query parameters end up as part of an url and are therefore logged by servers). But it is technically possible folowing RFC 3986. The real pain is that in the NL api-stratgie the POST requests seems to be used to search, ot in other words GET data. This is where compliance with HTTP (1.1) breaks. - -__solution__ -We do not implement a query endpoint on post requests. - -Api Versioning -------- -As per [landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning) we provide/ask major versions in the endpoint and minor versions in header, for this the `API-Version` is used (instead of the `api-version` header used in haal centraal) - -__solution__ -We implement both endpoint and header versioning - -Extending -------- -A part of the [haal centraal](https://raw.githubusercontent.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/master/api-specificatie/Bevraging-Ingeschreven-Perso on/openapi.yaml) the concept of extending has been introduced, its general purpose being to allow the inclusion of sub resources at an api level thereby preventing unnecessary API calls. In the [NL API Strategie](https://github.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/blob/master/features/expand.feature) this has been implemented as a parameter consisting of comma separated values. However the normal web standard for optional lists (conform w3c form standards) is an array. - -__solution__ -The extend parameter has been implemented as an array - -Archivation -------- -There is a need (by law) for archivation, meaning that we should only keep resources for a fixed amount of time and delete them thereafter. In line with the extending and fields principle whereby we only want resource properties that we need when we needed, it is deemed good practice make a sub resource of the archivation properties. For the archivation properties the [zgw](https://zaken-api.vng.cloud/api/v1/schema/#operation/zaak_list) is followed and translated to englisch. - - -```json -{ - "id": "e2984465-190a-4562-829e-a8cca81aa35d", - "nomination": "destroy", - "action_date": "2019-11-25T07:26:54Z", - "status": "to_be_archived", -} -``` - -This gives us an interesting thought, according to [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie/#api-10-implement-operations-that-do-not-fit-the-crud-model-as-sub-resources) sub resources should have their own endpoint. Therefore we could use a archive sub of a different resource for archivation rules e.g. /zaken/{uuid}/archivation for a verzoek. This in itself leads credence to the thought that archivation should have its own central crud api. - - -Audittrail -------- -For audittrail we use the base mechanism as provided by [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail), we do however diver on some key point, -- Personal data should never be part of a log, therefore only the user id with the client should be logged (instead of the name) -- Besides an endpoint per resource there should be a general enpoint to search all audit trials of a component -- [Time travel](#timetravel) in combination with objects versioning makes the return of complete objects unnecessary. But an audit rail endpoint should support the [extend](#extending) functionality to provide the option of obtaining complete objects. - - -__solution__ -In compliance with [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail) each individual object should support an /audittrail endpoint. You can look into the [tutorial](TUTORIAL.md) for specifications on how to activate an audit trail for a given object. - -Healthchecks -------- -From [issue 154](https://github.com/VNG-Realisatie/huwelijksplanner/issues/154) - -For healthchecks we use the health-json principle (or json-health to stay in line with json-ld and json-hal). This means the any endpoint `should` be capable of providing health information concerning that endpoint and services behind it. - -__solution__ -The use of a `Content-Type: application/health+json` header returns an health json schema. - - -Notifications -------- -For notifications we do not YET use the current [ZGW standard](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/notificaties) since there is an [dicusion](https://github.com/VNG-Realisatie/gemma-zaken/issues/1427#issuecomment-549272696) about the possible insecurity of sending properties or data objects along with a notification. It also doesn’t follow the [web standard](https://www.w3.org/TR/websub/). We wait for the conclusion of that discussion before making an implementation. - -__solution__ -In compliance with [w3.org](https://www.w3.org/TR/websub/) each endpoint `should` returns an header containing an subscription url. That can be used in accordance with the application to subscribe to both individual objects as collections whereby collections serve as 'kanalen'. We aim to implement the ZGW notificatie component, but feel that further features on that component would be required to make to be fully supported. We will supply feature requests per issue to support this effort. - -Authentication -------- - -__solution__ - -Authorization -------- -We implement user scopes as per [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/autorisatie-scopes) standard. But see problems with how the scopes are defined and named, and consider the general setup to be to focused on ZGW (including Dutch naming, zgw specific fields like maxVertrouwlijkheid and a lack of CRUD thinking). There is a further document concerning [Authentication and Authorization](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/authenticatie-autorisatie) that details how we should authenticate users and give them scopes. We agree with the principles of the document on application based authorization and the use of JWT tokens. But disagree on some key technical aspect. Most important being that the architecture doesn't take into consideration the use of one component by several organizations at once. Or scopes per property. - -__solution__ -No solution as of yet, so there is no implementation of Authorization or Scopes. We aim to implement the ZGW authorisatie component, but feel that further features on that component would be required to make to be fully supported. We will supply feature requests per issue to support this effort. - - -Timetravel -------- -A part of the [haal centraal](https://raw.githubusercontent.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/master/api-specificatie/Bevraging-Ingeschreven-Persoon/openapi.yaml) the concept of timetravel has been introduced, as in getting the version of an object as it was on a given date. For this the `geldigop` [see the docs](file:///C:/Users/ruben/Desktop/doc_gba_historie.html#operation/getBewoningen) header is used. In addition the `geldigvan` and `geldigtot` are introduced as collection filters. - -The commonground proto componant natively supports time traveling on all resources that are annotaded with the @Gedmo\Loggable, this is done by adding the ?validOn=[date] query to a request, date can either be a datetime or datedatime string. Any value supported by php's [strtotime()](https://www.php.net/manual/en/function.strtotime.php) is supported. Keep in mind that this returns the entity a as it was valid on that time or better put, the last changed version BEFORE that moment. To get a complete list of all changes on an item the [/audittrail](#Audittrail -) endpoint can be used. - -__solution__ -In compliance with [schema.org](https://schema.org/validFrom) `geldigop`,`geldigvan` and `geldigtot` are implemented as `validOn`,`validFrom` and `validUntil`. And can be used a query parameters on collection operations/ - -Additionally `validOn` can be used on a single object get request to get the version of that object on a given date, a 404 is returned if no version of that object can be given for the given date - -Ordering -------- -In the [zaak-api](https://zaken-api.vng.cloud/api/v1/schema/#operation/zaak_list) ordering is done in a single field parameter, we however prefer to be able to order on multiple fields in combination of ascending and descending orders. We therefore implement an order parameter as array where they key is the property on wish should be ordered and the value the type of ordering e.g. `?order[name]=desc&order[status]=asc`. The order in which the keys are added to the order array determines the order in which they are applied. - - -Translations -------- -We support translations trough the `Accept-Language` header (read the [docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language)), the fallback language for all messages is English - -Errors -------- -See [jsonapi](https://jsonapi.org/examples/#error-objects) and the [rfc](https://tools.ietf.org/html/rfc7807). - -Arrays -------- -The NL API standard uses comma notation on array's in http requests. E.g. fields=id,name,description however common browsers(based on chromium e.g. chrome and edge) use bracket notation for query style array's e.g. fields[]=id&fields[]=name,&fields[]=description. The difference of course is obvious since comma notation doesn't allow you to index arrays. [Interestingly enough there isn't actually a rfc spec for this](https://stackoverflow.com/questions/15854017/what-rfc-defines-arrays-transmitted-over-http). - -It is perceivable that in future iterations we would like to use indexed array in situations where the index of the array can't be assumed on basis of url notation, when indexes aren�t numerical, when we don�t want an index to start at 0 or when indexes are purpusly missing (comma notation of id,name,description would always refert to the equivalent of fields: [ - 0 => id, - 1 => name, - 2 => description -] - -__solution__ -We support both comma and bracket notation on array's, but only document bracket notation since it is preferred. - - -Container Setup -------- -https://medium.com/shiphp/building-a-custom-nginx-docker-image-with-environment-variables-in-the-config-4a0c36c4a617 - - -Filtering -------- -Because it is based on api-platform de proto component supports filter functions as in [api platform](https://api-platform.com/docs/core/filters/) additionally there are custom filter types available for common ground. - -__Regex Exact__ - -__Regex Contains__ - -__Like___ -The like filters is used to search for resources with the traditional sql LIKE operator. If pattern does not contain percent signs or underscores, then the pattern only represents the string itself; in that case LIKE acts like the equals operator. An underscore (_) in pattern stands for (matches) any single character; a percent sign (%) matches any sequence of zero or more characters. - -Some examples: - -'abc' LIKE 'abc' true -'abc' LIKE 'a%' true -'abc' LIKE '_b_' true -'abc' LIKE 'c' false - -LIKE pattern matching always covers the entire string. Therefore, if it's desired to match a sequence anywhere within a string, the pattern must start and end with a percent sign. - -To match a literal underscore or percent sign without matching other characters, the respective character in pattern must be preceded by a backlash. - -## Kubernetes - -### Loadbalancers -We no longer provide a load balancer per component, since this would require a IP address per component (and ipv 4 addresses are in short supply). Instead we make components available as an internal service. A central load balancer could then be used to provide several api’s in one - -### server naming -A component is (speaking in kubernetes terms) a service that is available at a name corresponding to its designation - -### Domain Build-up and routing -By convention the component assumes that you follow the common ground domain name build up, meaning {environment}.{component}.{rest of domain}. That means that only the first two url parts are used for routing. It is also assumed that when no environment is supplied the production environment should be offered E.g. a proper domain for the production API of the verzoeken registratie component would be prod.vrc.zaakonline.nl but it should also be reachable under vrc.zaakonline.nl. The proper location for the development environment should always be dev.vrc.zaakonlin.nl - -### Environments and namespacing -We assume that for that you want to run several environments for development purposes. We identify the following namespaces for support. -- prod (Production) -- acce (Acceptation) -- stag (Staging) -- test (Testing) -- dev (Development) - -Because we base the common ground infrastructure on kubernetes, and we want to keep a hard separation between environment we also assume that you are using your environment as a namespace - -Symfony library management gives us the option to define the libraries on a per environment base, you can find that definition in the [bundle config](api/config/bundles.php) - -Besides the API environments the component also ships with additional tools/environments but those are not meant to be deployed -- client (An react client frontend) -- admin (An read admin interface) - -On the local development docker deploy the client environment is used as default instead of the production version of the api. - - -## Data types - -| Period Designator | Description | -|-------------------|----------------------------------------------------------------------| -| Y | years | -| M | months | -| D | days | -| W | weeks. These get converted into days, so cannot be combined with D. | -| H | hours | -| M | minutes | -| S | seconds | - -### Types versus formats - -| Type | Format | Example | Source | Description | Documentation | -|---------|-----------|----------|--------|-------------|----------------------------------------------------------------------| -| integer | int32 | | | | | -| integer | int64 | | | | | -| string | float | 0.15625 | | | [wikipedia](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) | -| string | double | 0.15625 | | | [wikipedia](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) | -| integer | byte | | | | | -| integer | binary | | | | | -| string | date | | | | | -| string | date-time | | | | | -| string | duration | P23DT23H | | | [wikipedia](https://en.wikipedia.org/wiki/ISO_8601#Durations) | -| string | password | | | | | -| string | boolean | | | | | -| string | string | | | | | -| string | uuid | | | | | -| string | uri | | | | | -| string | email | | | | | -| string | rsin | | | | | -| string | bag | | | A BAG uuid | | -| string | bsn | | | | | -| string | iban | | | | | -| | | | | | | - - From c0522f9870ac4f461de357ff6e6123d367c84be3 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Fri, 20 Dec 2019 15:07:16 +0100 Subject: [PATCH 154/182] Remove pulling old images from workflow Edited base link to postman scripts to contain component shortcode and .json extension --- .github/workflows/dockerimage.yml | 2 -- api/config/packages/api_platform.yaml | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 05dfdb08..7a602d28 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -19,8 +19,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - - name: Pulling old images, if any - run: docker-compose pull --ignore-pull-failures - name: Setting APP_NAME run: | export NAME=$(grep APP_NAME= .env | cut -d '=' -f2) diff --git a/api/config/packages/api_platform.yaml b/api/config/packages/api_platform.yaml index 11f8555f..6624d8ab 100644 --- a/api/config/packages/api_platform.yaml +++ b/api/config/packages/api_platform.yaml @@ -34,7 +34,7 @@ api_platform: - Version: %env(APP_VERSION)% - Repository: [online](%env(APP_REPRO)%) / [zip](%env(APP_REPRO)%/archive/master.zip) - Docker Image: [online](%env(CONTAINER_REPRO)%) - - Datamodel: [postman](/schema/openapi.postman_collection) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) + - Datamodel: [postman](/schema/%env(APP_NAME)%.postman_collection.json) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) %env(APP_DESCRIPTION)% From 852abeb48f18418d2163278727aa0a48f18c1f5e Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sat, 21 Dec 2019 18:18:53 +0100 Subject: [PATCH 155/182] fix --- .../Subscriber/FieldsAndExtendSubscriber.php | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/api/src/Subscriber/FieldsAndExtendSubscriber.php b/api/src/Subscriber/FieldsAndExtendSubscriber.php index 5b9c7e04..22420329 100644 --- a/api/src/Subscriber/FieldsAndExtendSubscriber.php +++ b/api/src/Subscriber/FieldsAndExtendSubscriber.php @@ -36,9 +36,28 @@ public function FilterFields(GetResponseForControllerResultEvent $event) $result = $event->getControllerResult(); $fields = $event->getRequest()->query->get('fields'); $extends = $event->getRequest()->query->get('extend'); + $contentType= $event->getRequest()->headers->get('accept'); + if(!$contentType){ + $contentType= $event->getRequest()->headers->get('Accept'); + } // This needs to be bassed on the content-type - $type = 'jsonhal'; + + // Lets set a return content type + switch ($contentType) { + case 'application/json': + $renderType = "json"; + break; + case 'application/ld+json': + $renderType= "jsonld"; + break; + case 'application/hal+json': + $renderType= "jsonhal"; + break; + default: + $contentType = 'application/json'; + $renderType = "json"; + } // Only do somthing if fields is query supplied if (!$fields && $extends) { @@ -74,7 +93,7 @@ public function FilterFields(GetResponseForControllerResultEvent $event) // now we need to overide the normal subscriber $json = $this->serializer->serialize( $result, - $type, + $renderType, ['enable_max_depth' => true, 'attributes'=> $fields] ); @@ -103,7 +122,7 @@ public function FilterFields(GetResponseForControllerResultEvent $event) $response = new Response( $json, Response::HTTP_OK, - ['content-type' => 'application/json+hal'] + ['content-type' => $contentType] ); $event->setResponse($response); From b1b77c934fd2aeec56649a3a0eeeea198d174169 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sat, 21 Dec 2019 18:32:36 +0100 Subject: [PATCH 156/182] Composer update and mysql port fix --- api/composer.lock | 310 +++++++++++++++++---------------- api/helm/values.yaml | 7 +- api/public/schema/openapi.yaml | 79 ++++++++- api/symfony.lock | 3 + docker-compose.yml | 2 +- 5 files changed, 234 insertions(+), 167 deletions(-) diff --git a/api/composer.lock b/api/composer.lock index 10571f7f..57e16568 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -946,20 +946,21 @@ }, { "name": "doctrine/doctrine-bundle", - "version": "2.0.2", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "f96fac225563f5b3b4eeb2f80eb982b7f56484d8" + "reference": "0ef972d3b730f975c80db9fffa4b2a0258c91442" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/f96fac225563f5b3b4eeb2f80eb982b7f56484d8", - "reference": "f96fac225563f5b3b4eeb2f80eb982b7f56484d8", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/0ef972d3b730f975c80db9fffa4b2a0258c91442", + "reference": "0ef972d3b730f975c80db9fffa4b2a0258c91442", "shasum": "" }, "require": { "doctrine/dbal": "^2.9.0", + "doctrine/persistence": "^1.3.3", "jdorn/sql-formatter": "^1.2.16", "php": "^7.1", "symfony/cache": "^4.3.3|^5.0", @@ -967,7 +968,8 @@ "symfony/console": "^3.4.30|^4.3.3|^5.0", "symfony/dependency-injection": "^4.3.3|^5.0", "symfony/doctrine-bridge": "^4.3.7|^5.0", - "symfony/framework-bundle": "^3.4.30|^4.3.3|^5.0" + "symfony/framework-bundle": "^3.4.30|^4.3.3|^5.0", + "symfony/service-contracts": "^1.1.1|^2.0" }, "conflict": { "doctrine/orm": "<2.6", @@ -976,6 +978,7 @@ "require-dev": { "doctrine/coding-standard": "^6.0", "doctrine/orm": "^2.6", + "ocramius/proxy-manager": "^2.1", "phpunit/phpunit": "^7.5", "symfony/phpunit-bridge": "^4.2", "symfony/property-info": "^4.3.3|^5.0", @@ -1030,7 +1033,7 @@ "orm", "persistence" ], - "time": "2019-11-28T08:38:10+00:00" + "time": "2019-12-19T13:47:07+00:00" }, { "name": "doctrine/doctrine-fixtures-bundle", @@ -1665,22 +1668,25 @@ }, { "name": "fig/link-util", - "version": "1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/link-util.git", - "reference": "1a07821801a148be4add11ab0603e4af55a72fac" + "reference": "47f55860678a9e202206047bc02767556d298106" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/link-util/zipball/1a07821801a148be4add11ab0603e4af55a72fac", - "reference": "1a07821801a148be4add11ab0603e4af55a72fac", + "url": "https://api.github.com/repos/php-fig/link-util/zipball/47f55860678a9e202206047bc02767556d298106", + "reference": "47f55860678a9e202206047bc02767556d298106", "shasum": "" }, "require": { "php": ">=5.5.0", "psr/link": "~1.0@dev" }, + "provide": { + "psr/link-implementation": "1.0" + }, "require-dev": { "phpunit/phpunit": "^5.1", "squizlabs/php_codesniffer": "^2.3.1" @@ -1715,7 +1721,7 @@ "psr-13", "rest" ], - "time": "2016-10-17T18:31:11+00:00" + "time": "2019-12-18T15:40:05+00:00" }, { "name": "friendsofphp/php-cs-fixer", @@ -1890,16 +1896,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.5.0", + "version": "6.5.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5" + "reference": "0274c05370a7bc9bb3a33838858253418bd7d14b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5", - "reference": "dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/0274c05370a7bc9bb3a33838858253418bd7d14b", + "reference": "0274c05370a7bc9bb3a33838858253418bd7d14b", "shasum": "" }, "require": { @@ -1953,7 +1959,7 @@ "rest", "web service" ], - "time": "2019-12-07T18:20:45+00:00" + "time": "2019-12-21T08:51:15+00:00" }, { "name": "guzzlehttp/promises", @@ -2674,16 +2680,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.2", + "version": "4.3.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" + "reference": "2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62", + "reference": "2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62", "shasum": "" }, "require": { @@ -2721,7 +2727,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-09-12T14:27:41+00:00" + "time": "2019-12-20T13:40:23+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -3053,22 +3059,22 @@ }, { "name": "ramsey/uuid", - "version": "3.9.1", + "version": "3.9.2", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "5ac2740e0c8c599d2bbe7f113a939f2b5b216c67" + "reference": "7779489a47d443f845271badbdcedfe4df8e06fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/5ac2740e0c8c599d2bbe7f113a939f2b5b216c67", - "reference": "5ac2740e0c8c599d2bbe7f113a939f2b5b216c67", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/7779489a47d443f845271badbdcedfe4df8e06fb", + "reference": "7779489a47d443f845271badbdcedfe4df8e06fb", "shasum": "" }, "require": { "ext-json": "*", "paragonie/random_compat": "^1 | ^2 | 9.99.99", - "php": "^5.4 | ^7", + "php": "^5.4 | ^7 | ^8", "symfony/polyfill-ctype": "^1.8" }, "replace": { @@ -3078,13 +3084,13 @@ "codeception/aspect-mock": "^1 | ^2", "doctrine/annotations": "^1.2", "goaop/framework": "1.0.0-alpha.2 | ^1 | ^2.1", - "jakub-onderka/php-parallel-lint": "^0.9.0", - "mockery/mockery": "^0.9.9", + "jakub-onderka/php-parallel-lint": "^1", + "mockery/mockery": "^0.9.11 | ^1", "moontoast/math": "^1.1", "paragonie/random-lib": "^2", "php-mock/php-mock-phpunit": "^0.3 | ^1.1", "phpunit/phpunit": "^4.8 | ^5.4 | ^6.5", - "squizlabs/php_codesniffer": "^2.3" + "squizlabs/php_codesniffer": "^3.5" }, "suggest": { "ext-ctype": "Provides support for PHP Ctype functions", @@ -3136,7 +3142,7 @@ "identifier", "uuid" ], - "time": "2019-12-01T04:55:27+00:00" + "time": "2019-12-17T08:18:51+00:00" }, { "name": "ramsey/uuid-doctrine", @@ -3388,7 +3394,7 @@ }, { "name": "symfony/asset", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", @@ -3444,16 +3450,16 @@ }, { "name": "symfony/cache", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "de737c81ea95018d11a3ef908ad2ebf203741b96" + "reference": "6af64bab165e588300378a87bcd2df3c7c31c144" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/de737c81ea95018d11a3ef908ad2ebf203741b96", - "reference": "de737c81ea95018d11a3ef908ad2ebf203741b96", + "url": "https://api.github.com/repos/symfony/cache/zipball/6af64bab165e588300378a87bcd2df3c7c31c144", + "reference": "6af64bab165e588300378a87bcd2df3c7c31c144", "shasum": "" }, "require": { @@ -3519,7 +3525,7 @@ "caching", "psr6" ], - "time": "2019-12-01T10:50:45+00:00" + "time": "2019-12-16T10:45:21+00:00" }, { "name": "symfony/cache-contracts", @@ -3581,16 +3587,16 @@ }, { "name": "symfony/config", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "7aa5817f1b7a8ed377752b90fcc47dfb3c67b40c" + "reference": "6911d432edd5b50822986604fd5a5be3af856d30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/7aa5817f1b7a8ed377752b90fcc47dfb3c67b40c", - "reference": "7aa5817f1b7a8ed377752b90fcc47dfb3c67b40c", + "url": "https://api.github.com/repos/symfony/config/zipball/6911d432edd5b50822986604fd5a5be3af856d30", + "reference": "6911d432edd5b50822986604fd5a5be3af856d30", "shasum": "" }, "require": { @@ -3641,7 +3647,7 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2019-12-01T10:50:45+00:00" + "time": "2019-12-18T12:00:29+00:00" }, { "name": "symfony/console", @@ -3791,16 +3797,16 @@ }, { "name": "symfony/debug", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "b8600a1d7d20b0e80906398bb1f50612fa074a8e" + "reference": "5c4c1db977dc70bb3250e1308d3e8c6341aa38f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/b8600a1d7d20b0e80906398bb1f50612fa074a8e", - "reference": "b8600a1d7d20b0e80906398bb1f50612fa074a8e", + "url": "https://api.github.com/repos/symfony/debug/zipball/5c4c1db977dc70bb3250e1308d3e8c6341aa38f5", + "reference": "5c4c1db977dc70bb3250e1308d3e8c6341aa38f5", "shasum": "" }, "require": { @@ -3843,20 +3849,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2019-11-28T13:33:56+00:00" + "time": "2019-12-16T14:46:54+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "ad46a4def1325befab696b49c839dffea3fc92bd" + "reference": "79b0358207a3571cc3af02a57d0321927921f539" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ad46a4def1325befab696b49c839dffea3fc92bd", - "reference": "ad46a4def1325befab696b49c839dffea3fc92bd", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/79b0358207a3571cc3af02a57d0321927921f539", + "reference": "79b0358207a3571cc3af02a57d0321927921f539", "shasum": "" }, "require": { @@ -3916,25 +3922,25 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2019-12-01T10:19:36+00:00" + "time": "2019-12-19T16:00:02+00:00" }, { "name": "symfony/doctrine-bridge", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "31c3d72f9e7a03e1b9d136084a9201c2225ee348" + "reference": "3e40beb8dbb06d2967e37938f4c3f20f425137a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/31c3d72f9e7a03e1b9d136084a9201c2225ee348", - "reference": "31c3d72f9e7a03e1b9d136084a9201c2225ee348", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/3e40beb8dbb06d2967e37938f4c3f20f425137a6", + "reference": "3e40beb8dbb06d2967e37938f4c3f20f425137a6", "shasum": "" }, "require": { "doctrine/event-manager": "~1.0", - "doctrine/persistence": "~1.0", + "doctrine/persistence": "^1.3", "php": "^7.1.3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", @@ -3947,7 +3953,7 @@ "symfony/http-kernel": "<4.3.7", "symfony/messenger": "<4.3", "symfony/security-core": "<4.4", - "symfony/validator": "<4.4" + "symfony/validator": "<4.4.2|<5.0.2,>=5.0" }, "require-dev": { "doctrine/annotations": "~1.7", @@ -3969,7 +3975,7 @@ "symfony/security-core": "^4.4|^5.0", "symfony/stopwatch": "^3.4|^4.0|^5.0", "symfony/translation": "^3.4|^4.0|^5.0", - "symfony/validator": "^4.4|^5.0", + "symfony/validator": "^4.4.2|^5.0.2", "symfony/var-dumper": "^3.4|^4.0|^5.0" }, "suggest": { @@ -4010,11 +4016,11 @@ ], "description": "Symfony Doctrine Bridge", "homepage": "https://symfony.com", - "time": "2019-12-01T08:39:58+00:00" + "time": "2019-12-17T08:15:02+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", @@ -4132,16 +4138,16 @@ }, { "name": "symfony/error-handler", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "a1ad02d62789efed1d2b2796f1c15e0c6a00fc3b" + "reference": "6d7d7712a6ff5215ec26215672293b154f1db8c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/a1ad02d62789efed1d2b2796f1c15e0c6a00fc3b", - "reference": "a1ad02d62789efed1d2b2796f1c15e0c6a00fc3b", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/6d7d7712a6ff5215ec26215672293b154f1db8c1", + "reference": "6d7d7712a6ff5215ec26215672293b154f1db8c1", "shasum": "" }, "require": { @@ -4184,11 +4190,11 @@ ], "description": "Symfony ErrorHandler Component", "homepage": "https://symfony.com", - "time": "2019-12-01T08:46:01+00:00" + "time": "2019-12-16T14:46:54+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -4316,16 +4322,16 @@ }, { "name": "symfony/expression-language", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "8a1028a65623a8f7bba582b60e4fd308e6f43001" + "reference": "539e7ff0b635c8b90d8127bc929da781a96eab2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/8a1028a65623a8f7bba582b60e4fd308e6f43001", - "reference": "8a1028a65623a8f7bba582b60e4fd308e6f43001", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/539e7ff0b635c8b90d8127bc929da781a96eab2d", + "reference": "539e7ff0b635c8b90d8127bc929da781a96eab2d", "shasum": "" }, "require": { @@ -4363,11 +4369,11 @@ ], "description": "Symfony ExpressionLanguage Component", "homepage": "https://symfony.com", - "time": "2019-11-12T14:53:53+00:00" + "time": "2019-12-10T10:33:21+00:00" }, { "name": "symfony/filesystem", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", @@ -4417,7 +4423,7 @@ }, { "name": "symfony/finder", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -4515,16 +4521,16 @@ }, { "name": "symfony/form", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "08dfa1960bbd25caaf979a47e837696bf2ee6d65" + "reference": "7ed4441a347fe33299908a9aa24ff8a556848a16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/08dfa1960bbd25caaf979a47e837696bf2ee6d65", - "reference": "08dfa1960bbd25caaf979a47e837696bf2ee6d65", + "url": "https://api.github.com/repos/symfony/form/zipball/7ed4441a347fe33299908a9aa24ff8a556848a16", + "reference": "7ed4441a347fe33299908a9aa24ff8a556848a16", "shasum": "" }, "require": { @@ -4595,7 +4601,7 @@ ], "description": "Symfony Form Component", "homepage": "https://symfony.com", - "time": "2019-12-01T09:13:30+00:00" + "time": "2019-12-16T11:07:37+00:00" }, { "name": "symfony/framework-bundle", @@ -4722,16 +4728,16 @@ }, { "name": "symfony/http-client", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "6c235cf15d8b516b41204a28d555685191409729" + "reference": "9ebfc77b5018a05226b38642def82746f3e2ce0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/6c235cf15d8b516b41204a28d555685191409729", - "reference": "6c235cf15d8b516b41204a28d555685191409729", + "url": "https://api.github.com/repos/symfony/http-client/zipball/9ebfc77b5018a05226b38642def82746f3e2ce0f", + "reference": "9ebfc77b5018a05226b38642def82746f3e2ce0f", "shasum": "" }, "require": { @@ -4786,7 +4792,7 @@ ], "description": "Symfony HttpClient component", "homepage": "https://symfony.com", - "time": "2019-11-29T16:55:58+00:00" + "time": "2019-12-19T15:57:49+00:00" }, { "name": "symfony/http-client-contracts", @@ -4847,16 +4853,16 @@ }, { "name": "symfony/http-foundation", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "8bccc59e61b41963d14c3dbdb23181e5c932a1d5" + "reference": "fcae1cff5b57b2a9c3aabefeb1527678705ddb62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8bccc59e61b41963d14c3dbdb23181e5c932a1d5", - "reference": "8bccc59e61b41963d14c3dbdb23181e5c932a1d5", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/fcae1cff5b57b2a9c3aabefeb1527678705ddb62", + "reference": "fcae1cff5b57b2a9c3aabefeb1527678705ddb62", "shasum": "" }, "require": { @@ -4898,20 +4904,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2019-11-28T13:33:56+00:00" + "time": "2019-12-19T15:57:49+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "e4187780ed26129ee86d5234afbebf085e144f88" + "reference": "fe310d2e95cd4c356836c8ecb0895a46d97fede2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e4187780ed26129ee86d5234afbebf085e144f88", - "reference": "e4187780ed26129ee86d5234afbebf085e144f88", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/fe310d2e95cd4c356836c8ecb0895a46d97fede2", + "reference": "fe310d2e95cd4c356836c8ecb0895a46d97fede2", "shasum": "" }, "require": { @@ -4988,11 +4994,11 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2019-12-01T14:06:38+00:00" + "time": "2019-12-19T16:23:40+00:00" }, { "name": "symfony/inflector", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/inflector.git", @@ -5050,7 +5056,7 @@ }, { "name": "symfony/intl", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", @@ -5321,7 +5327,7 @@ }, { "name": "symfony/mime", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", @@ -5383,7 +5389,7 @@ }, { "name": "symfony/options-resolver", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", @@ -5729,16 +5735,16 @@ }, { "name": "symfony/process", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "51c0135ef3f44c5803b33dc60e96bf4f77752726" + "reference": "b84501ad50adb72a94fb460a5b5c91f693e99c9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/51c0135ef3f44c5803b33dc60e96bf4f77752726", - "reference": "51c0135ef3f44c5803b33dc60e96bf4f77752726", + "url": "https://api.github.com/repos/symfony/process/zipball/b84501ad50adb72a94fb460a5b5c91f693e99c9b", + "reference": "b84501ad50adb72a94fb460a5b5c91f693e99c9b", "shasum": "" }, "require": { @@ -5774,20 +5780,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2019-11-28T13:33:56+00:00" + "time": "2019-12-06T10:06:46+00:00" }, { "name": "symfony/property-access", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "bafdc8c3a9d2671af4a81baec0fcc4687c0c17bc" + "reference": "055fe3134f8f301ff44af314d83463b858ea6413" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/bafdc8c3a9d2671af4a81baec0fcc4687c0c17bc", - "reference": "bafdc8c3a9d2671af4a81baec0fcc4687c0c17bc", + "url": "https://api.github.com/repos/symfony/property-access/zipball/055fe3134f8f301ff44af314d83463b858ea6413", + "reference": "055fe3134f8f301ff44af314d83463b858ea6413", "shasum": "" }, "require": { @@ -5841,11 +5847,11 @@ "property path", "reflection" ], - "time": "2019-12-01T10:50:45+00:00" + "time": "2019-12-10T10:33:21+00:00" }, { "name": "symfony/property-info", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", @@ -5921,16 +5927,16 @@ }, { "name": "symfony/routing", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "51f3f20ad29329a0bdf5c0e2f722d3764b065273" + "reference": "628bcafae1b2043969378dcfbf9c196539a38722" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/51f3f20ad29329a0bdf5c0e2f722d3764b065273", - "reference": "51f3f20ad29329a0bdf5c0e2f722d3764b065273", + "url": "https://api.github.com/repos/symfony/routing/zipball/628bcafae1b2043969378dcfbf9c196539a38722", + "reference": "628bcafae1b2043969378dcfbf9c196539a38722", "shasum": "" }, "require": { @@ -5993,7 +5999,7 @@ "uri", "url" ], - "time": "2019-12-01T08:39:58+00:00" + "time": "2019-12-12T12:53:52+00:00" }, { "name": "symfony/security-bundle", @@ -6081,16 +6087,16 @@ }, { "name": "symfony/security-core", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "312c91f90786fd7add89e8542cfc98543f0e60db" + "reference": "52709ee2aafd13d777253d510d96fbf2ccc5a578" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/312c91f90786fd7add89e8542cfc98543f0e60db", - "reference": "312c91f90786fd7add89e8542cfc98543f0e60db", + "url": "https://api.github.com/repos/symfony/security-core/zipball/52709ee2aafd13d777253d510d96fbf2ccc5a578", + "reference": "52709ee2aafd13d777253d510d96fbf2ccc5a578", "shasum": "" }, "require": { @@ -6150,11 +6156,11 @@ ], "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", - "time": "2019-11-20T10:44:55+00:00" + "time": "2019-12-16T11:07:37+00:00" }, { "name": "symfony/security-csrf", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", @@ -6213,16 +6219,16 @@ }, { "name": "symfony/security-guard", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/security-guard.git", - "reference": "df82bbbd01486ff21a053d325cf9159b4d70b544" + "reference": "203a81f9fcfc3bbaba7f1103c261a30d2648611b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-guard/zipball/df82bbbd01486ff21a053d325cf9159b4d70b544", - "reference": "df82bbbd01486ff21a053d325cf9159b4d70b544", + "url": "https://api.github.com/repos/symfony/security-guard/zipball/203a81f9fcfc3bbaba7f1103c261a30d2648611b", + "reference": "203a81f9fcfc3bbaba7f1103c261a30d2648611b", "shasum": "" }, "require": { @@ -6263,20 +6269,20 @@ ], "description": "Symfony Security Component - Guard", "homepage": "https://symfony.com", - "time": "2019-11-30T09:49:41+00:00" + "time": "2019-12-07T16:27:44+00:00" }, { "name": "symfony/security-http", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "ff3ab7cda1703195dbe7f97cccaf77478126e0cd" + "reference": "8ab510f214fd9c37769378b5036da58d444fe142" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/ff3ab7cda1703195dbe7f97cccaf77478126e0cd", - "reference": "ff3ab7cda1703195dbe7f97cccaf77478126e0cd", + "url": "https://api.github.com/repos/symfony/security-http/zipball/8ab510f214fd9c37769378b5036da58d444fe142", + "reference": "8ab510f214fd9c37769378b5036da58d444fe142", "shasum": "" }, "require": { @@ -6329,20 +6335,20 @@ ], "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", - "time": "2019-12-01T08:46:01+00:00" + "time": "2019-12-13T12:11:48+00:00" }, { "name": "symfony/serializer", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "842637bdcbed31c7dc62b3c30dfc8949f6457968" + "reference": "e5bc3f6dee44dc06e7e640cce4baa741b73ecb6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/842637bdcbed31c7dc62b3c30dfc8949f6457968", - "reference": "842637bdcbed31c7dc62b3c30dfc8949f6457968", + "url": "https://api.github.com/repos/symfony/serializer/zipball/e5bc3f6dee44dc06e7e640cce4baa741b73ecb6e", + "reference": "e5bc3f6dee44dc06e7e640cce4baa741b73ecb6e", "shasum": "" }, "require": { @@ -6410,7 +6416,7 @@ ], "description": "Symfony Serializer Component", "homepage": "https://symfony.com", - "time": "2019-11-28T13:33:56+00:00" + "time": "2019-12-16T11:07:37+00:00" }, { "name": "symfony/service-contracts", @@ -6472,7 +6478,7 @@ }, { "name": "symfony/stopwatch", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -6579,16 +6585,16 @@ }, { "name": "symfony/twig-bridge", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "6121dd0156649047f38cfc02a5d64091692892f2" + "reference": "936cf6f5b973377345e8ac43870987ef8e747ce3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/6121dd0156649047f38cfc02a5d64091692892f2", - "reference": "6121dd0156649047f38cfc02a5d64091692892f2", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/936cf6f5b973377345e8ac43870987ef8e747ce3", + "reference": "936cf6f5b973377345e8ac43870987ef8e747ce3", "shasum": "" }, "require": { @@ -6678,7 +6684,7 @@ ], "description": "Symfony Twig Bridge", "homepage": "https://symfony.com", - "time": "2019-11-30T14:03:57+00:00" + "time": "2019-12-05T05:58:42+00:00" }, { "name": "symfony/twig-bundle", @@ -6759,16 +6765,16 @@ }, { "name": "symfony/validator", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "6b1774cf44c378617af362eaa154105952d488f8" + "reference": "79eb122bed116c1fbe0769698d5b46acce1860a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/6b1774cf44c378617af362eaa154105952d488f8", - "reference": "6b1774cf44c378617af362eaa154105952d488f8", + "url": "https://api.github.com/repos/symfony/validator/zipball/79eb122bed116c1fbe0769698d5b46acce1860a2", + "reference": "79eb122bed116c1fbe0769698d5b46acce1860a2", "shasum": "" }, "require": { @@ -6847,20 +6853,20 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com", - "time": "2019-11-30T14:03:57+00:00" + "time": "2019-12-17T08:15:02+00:00" }, { "name": "symfony/var-dumper", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "0a89a1dbbedd9fb2cfb2336556dec8305273c19a" + "reference": "be330f919bdb395d1e0c3f2bfb8948512d6bdd99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0a89a1dbbedd9fb2cfb2336556dec8305273c19a", - "reference": "0a89a1dbbedd9fb2cfb2336556dec8305273c19a", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/be330f919bdb395d1e0c3f2bfb8948512d6bdd99", + "reference": "be330f919bdb395d1e0c3f2bfb8948512d6bdd99", "shasum": "" }, "require": { @@ -6923,11 +6929,11 @@ "debug", "dump" ], - "time": "2019-11-28T13:33:56+00:00" + "time": "2019-12-18T13:41:29+00:00" }, { "name": "symfony/var-exporter", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", @@ -6987,7 +6993,7 @@ }, { "name": "symfony/web-link", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 58891e1d..c9735c5b 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -13,12 +13,9 @@ settings: subdomain: pc domains: - conduction.nl - # - vng.cloud - # - zaakonline.nl - # - larping.eu - # - common-ground.dev - # - trouwplanner.online + - zaakonline.nl - huwelijksplanner.online + - common-ground.dev organisationName: Conduction email: info@conduction.nl country: Netherlands diff --git a/api/public/schema/openapi.yaml b/api/public/schema/openapi.yaml index 3cd704c7..227109d9 100644 --- a/api/public/schema/openapi.yaml +++ b/api/public/schema/openapi.yaml @@ -10,7 +10,7 @@ info: - Version: V.0.1 - Repository: [online](https://github.com/ConductionNL/Proto-component-commonground) / [zip](https://github.com/ConductionNL/Proto-component-commonground/archive/master.zip) - Docker Image: [online](https://hub.docker.com/repository/docker/conduction/pc-php) - - Datamodel: [postman](/schema/openapi.postman_collection) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) + - Datamodel: [postman](/schema/pc.postman_collection.json) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) 'Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' @@ -32,9 +32,14 @@ paths: $ref: '#/components/schemas/ExampleEntity-read' application/ld+json: schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity-read' + type: object + properties: + 'hydra:member': { type: array, items: { $ref: '#/components/schemas/ExampleEntity:jsonld-read' } } + 'hydra:totalItems': { type: integer, minimum: 0 } + 'hydra:view': { type: object, properties: { '@id': { type: string, format: iri-reference }, '@type': { type: string }, 'hydra:first': { type: string, format: iri-reference }, 'hydra:last': { type: string, format: iri-reference }, 'hydra:next': { type: string, format: iri-reference } } } + 'hydra:search': { type: object, properties: { '@type': { type: string }, 'hydra:template': { type: string }, 'hydra:variableRepresentation': { type: string }, 'hydra:mapping': { type: array, items: { type: object, properties: { '@type': { type: string }, variable: { type: string }, property: { type: string }, required: { type: boolean } } } } } } + required: + - 'hydra:member' application/vnd.api+json: schema: type: array @@ -85,6 +90,7 @@ paths: description: 'The collection page number' schema: type: integer + default: 1 - name: Authorization description: 'The JWT of the entity performing the request' @@ -172,7 +178,7 @@ paths: $ref: '#/components/schemas/ExampleEntity-read' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity-read' + $ref: '#/components/schemas/ExampleEntity:jsonld-read' application/vnd.api+json: schema: $ref: '#/components/schemas/ExampleEntity-read' @@ -208,7 +214,7 @@ paths: $ref: '#/components/schemas/ExampleEntity-write' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity-write' + $ref: '#/components/schemas/ExampleEntity:jsonld-write' application/vnd.api+json: schema: $ref: '#/components/schemas/ExampleEntity-write' @@ -351,7 +357,7 @@ paths: $ref: '#/components/schemas/ExampleEntity-read' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity-read' + $ref: '#/components/schemas/ExampleEntity:jsonld-read' application/vnd.api+json: schema: $ref: '#/components/schemas/ExampleEntity-read' @@ -424,7 +430,7 @@ paths: $ref: '#/components/schemas/ExampleEntity-read' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity-read' + $ref: '#/components/schemas/ExampleEntity:jsonld-read' application/vnd.api+json: schema: $ref: '#/components/schemas/ExampleEntity-read' @@ -454,7 +460,7 @@ paths: $ref: '#/components/schemas/ExampleEntity-write' application/ld+json: schema: - $ref: '#/components/schemas/ExampleEntity-write' + $ref: '#/components/schemas/ExampleEntity:jsonld-write' application/vnd.api+json: schema: $ref: '#/components/schemas/ExampleEntity-write' @@ -528,6 +534,8 @@ components: properties: id: readOnly: true + externalDocs: + url: 'http://schema.org/identifier' type: string name: description: 'The name of this example property' @@ -555,6 +563,59 @@ components: camelCase: description: 'Proof that we camel case our api' type: string + 'ExampleEntity:jsonld-read': + type: object + description: 'This is an example entity.' + properties: + '@context': + readOnly: true + type: string + '@id': + readOnly: true + type: string + '@type': + readOnly: true + type: string + id: + readOnly: true + externalDocs: + url: 'http://schema.org/identifier' + type: string + name: + description: 'The name of this example property' + type: string + description: + description: 'The description of this example property' + type: string + camelCase: + description: 'Proof that we camel case our api' + type: string + required: + - name + 'ExampleEntity:jsonld-write': + type: object + description: 'This is an example entity.' + required: + - name + properties: + '@context': + readOnly: true + type: string + '@id': + readOnly: true + type: string + '@type': + readOnly: true + type: string + name: + description: 'The name of this example property' + type: string + description: + description: 'The description of this example property' + type: string + camelCase: + description: 'Proof that we camel case our api' + type: string definitions: ExampleEntity-read: properties: diff --git a/api/symfony.lock b/api/symfony.lock index 92765b1f..386193f5 100644 --- a/api/symfony.lock +++ b/api/symfony.lock @@ -178,6 +178,9 @@ "nikic/php-parser": { "version": "v4.2.2" }, + "php": { + "version": "7.3" + }, "php-cs-fixer/diff": { "version": "v1.3.0" }, diff --git a/docker-compose.yml b/docker-compose.yml index 62224f43..671f5c94 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -188,7 +188,7 @@ services: volumes: - db-mysql:/var/lib/mysql:rw ports: - - "3306:3306" + - "3366:3306" mercure: # In production, you may want to use the managed version of Mercure, https://mercure.rocks From 6d0718330a66dc4843f110893de469572da0aff9 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 23 Dec 2019 13:34:21 +0100 Subject: [PATCH 157/182] Removed composer update from the build --- api/Dockerfile | 6 ++++-- api/composer.lock | 10 +++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/api/Dockerfile b/api/Dockerfile index a5bfe406..699fc8be 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -83,6 +83,7 @@ ARG APP_ENV=prod # prevent the reinstallation of vendors at every changes in the source code COPY composer.json composer.lock symfony.lock ./ + RUN set -eux; \ composer install --prefer-dist --no-dev --no-scripts --no-progress --no-suggest; \ composer clear-cache @@ -105,10 +106,11 @@ RUN set -eux; \ composer dump-autoload --classmap-authoritative --no-dev; \ composer run-script --no-dev post-install-cmd; \ chmod +x bin/console; sync -VOLUME /srv/api/var # Now that we have our own composer lets update -RUN composer update --no-interaction +# RUN composer update --no-interaction + +VOLUME /srv/api/var COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint RUN chmod +x /usr/local/bin/docker-entrypoint diff --git a/api/composer.lock b/api/composer.lock index 57e16568..ea7b8f6f 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -1896,16 +1896,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.5.1", + "version": "6.5.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "0274c05370a7bc9bb3a33838858253418bd7d14b" + "reference": "43ece0e75098b7ecd8d13918293029e555a50f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/0274c05370a7bc9bb3a33838858253418bd7d14b", - "reference": "0274c05370a7bc9bb3a33838858253418bd7d14b", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82", + "reference": "43ece0e75098b7ecd8d13918293029e555a50f82", "shasum": "" }, "require": { @@ -1959,7 +1959,7 @@ "rest", "web service" ], - "time": "2019-12-21T08:51:15+00:00" + "time": "2019-12-23T11:57:10+00:00" }, { "name": "guzzlehttp/promises", From 51bad8172df1086c57c50eb7aeb1d15908b06598 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 23 Dec 2019 13:35:57 +0100 Subject: [PATCH 158/182] composer update test on proper composer file --- api/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/Dockerfile b/api/Dockerfile index 699fc8be..f1c508df 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -82,7 +82,7 @@ WORKDIR /srv/api ARG APP_ENV=prod # prevent the reinstallation of vendors at every changes in the source code -COPY composer.json composer.lock symfony.lock ./ +COPY composer.json composer.lock symfony.lock / RUN set -eux; \ composer install --prefer-dist --no-dev --no-scripts --no-progress --no-suggest; \ @@ -108,7 +108,7 @@ RUN set -eux; \ chmod +x bin/console; sync # Now that we have our own composer lets update -# RUN composer update --no-interaction + RUN composer update --no-interaction VOLUME /srv/api/var From 3d706bfb6fd63869404475a9d056d09a6983308c Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 23 Dec 2019 13:41:03 +0100 Subject: [PATCH 159/182] test with lose copy for composer lock --- api/Dockerfile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/api/Dockerfile b/api/Dockerfile index f1c508df..67bf2229 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -82,7 +82,9 @@ WORKDIR /srv/api ARG APP_ENV=prod # prevent the reinstallation of vendors at every changes in the source code -COPY composer.json composer.lock symfony.lock / +COPY composer.json /srv/api/composer.json +COPY composer.lock /srv/api/composer.lock +COPY symfony.lock /srv/api/symfony.lock RUN set -eux; \ composer install --prefer-dist --no-dev --no-scripts --no-progress --no-suggest; \ @@ -106,9 +108,6 @@ RUN set -eux; \ composer dump-autoload --classmap-authoritative --no-dev; \ composer run-script --no-dev post-install-cmd; \ chmod +x bin/console; sync - -# Now that we have our own composer lets update - RUN composer update --no-interaction VOLUME /srv/api/var From af69396c2fe5d06639d14a5d4370e29a0cc5497b Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 23 Dec 2019 13:46:06 +0100 Subject: [PATCH 160/182] This better be a single command-line thing --- api/Dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/api/Dockerfile b/api/Dockerfile index 67bf2229..c48a7b4b 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -82,9 +82,7 @@ WORKDIR /srv/api ARG APP_ENV=prod # prevent the reinstallation of vendors at every changes in the source code -COPY composer.json /srv/api/composer.json -COPY composer.lock /srv/api/composer.lock -COPY symfony.lock /srv/api/symfony.lock +COPY composer.json composer.lock symfony.lock ./ RUN set -eux; \ composer install --prefer-dist --no-dev --no-scripts --no-progress --no-suggest; \ From f8a00788435b277769a2074747314e2e87068aef Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 23 Dec 2019 13:51:42 +0100 Subject: [PATCH 161/182] Add Markdown and reStructuredText support --- api/composer.json | 2 + api/composer.lock | 177 ++++++++++++++++++++++++++++++++++++++++- api/config/bundles.php | 1 + api/symfony.lock | 9 +++ 4 files changed, 188 insertions(+), 1 deletion(-) diff --git a/api/composer.json b/api/composer.json index 0e20ae21..d04d452a 100644 --- a/api/composer.json +++ b/api/composer.json @@ -8,7 +8,9 @@ "api-platform/api-pack": "^1.1", "conduction/commongroundbundle": "dev-master", "doctrine/doctrine-fixtures-bundle": "^3.2", + "doctrine/rst-parser": "^0.1.0", "guzzlehttp/guzzle": "^6.3", + "knplabs/knp-markdown-bundle": "^1.8", "lexik/jwt-authentication-bundle": "^2.6", "phpdocumentor/reflection-docblock": "^4.3", "ramsey/uuid": "^3.8", diff --git a/api/composer.lock b/api/composer.lock index ea7b8f6f..10b82808 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": "6dedf18848d212df8a091e39a77494e7", + "content-hash": "48af4cac3c2eac2289e6cf339b11a6ea", "packages": [ { "name": "api-platform/api-pack", @@ -1604,6 +1604,69 @@ ], "time": "2018-06-14T14:45:07+00:00" }, + { + "name": "doctrine/rst-parser", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/rst-parser.git", + "reference": "49ea41cf15b93c4ac493df3f05c49999ef661cd4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/rst-parser/zipball/49ea41cf15b93c4ac493df3f05c49999ef661cd4", + "reference": "49ea41cf15b93c4ac493df3f05c49999ef661cd4", + "shasum": "" + }, + "require": { + "doctrine/event-manager": "^1.0", + "php": "^7.1", + "symfony/filesystem": "^4.1", + "twig/twig": "^2.5" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "gajus/dindent": "^2.0.2", + "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" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\RST\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Passault", + "email": "g.passault@gmail.com", + "homepage": "http://www.gregwar.com/" + }, + { + "name": "Jonathan H. Wage", + "email": "jonwage@gmail.com", + "homepage": "https://jwage.com" + } + ], + "description": "PHP library to parse reStructuredText documents and generate HTML or LaTeX documents.", + "homepage": "https://github.com/doctrine/rst-parser", + "keywords": [ + "html", + "latex", + "markup", + "parser", + "reStructuredText", + "rst" + ], + "time": "2019-04-15T19:55:14+00:00" + }, { "name": "easyrdf/easyrdf", "version": "0.9.1", @@ -2133,6 +2196,69 @@ ], "time": "2014-01-12T16:20:24+00:00" }, + { + "name": "knplabs/knp-markdown-bundle", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/KnpLabs/KnpMarkdownBundle.git", + "reference": "7238cc264eab9c42d1a5b71950b55fe3dd78ab38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/KnpLabs/KnpMarkdownBundle/zipball/7238cc264eab9c42d1a5b71950b55fe3dd78ab38", + "reference": "7238cc264eab9c42d1a5b71950b55fe3dd78ab38", + "shasum": "" + }, + "require": { + "michelf/php-markdown": "~1.4", + "php": "^7.1.3", + "symfony/dependency-injection": "~3.4|^4.0|^5.0", + "symfony/framework-bundle": "~3.4|^4.0|^5.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4.0 || ^5.0", + "symfony/templating": "~3.4|^4.0|^5.0" + }, + "suggest": { + "ext-sundown": "to use optional support for php-sundown extension instead of php implementation", + "symfony/twig-bundle": "to use the Twig markdown filter" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Knp\\Bundle\\MarkdownBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KnpLabs Team", + "homepage": "http://knplabs.com" + }, + { + "name": "Symfony Community", + "homepage": "http://github.com/KnpLabs/KnpMarkdownBundle/contributors" + } + ], + "description": "Knplabs markdown bundle transforms markdown into html", + "homepage": "http://github.com/KnpLabs/KnpMarkdownBundle", + "keywords": [ + "bundle", + "knp", + "knplabs", + "markdown" + ], + "time": "2019-11-26T13:18:52+00:00" + }, { "name": "lcobucci/jwt", "version": "3.3.1", @@ -2348,6 +2474,55 @@ ], "time": "2019-11-22T14:22:26+00:00" }, + { + "name": "michelf/php-markdown", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/michelf/php-markdown.git", + "reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/c83178d49e372ca967d1a8c77ae4e051b3a3c75c", + "reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": ">=4.3 <5.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Michelf\\": "Michelf/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" + } + ], + "description": "PHP Markdown", + "homepage": "https://michelf.ca/projects/php-markdown/", + "keywords": [ + "markdown" + ], + "time": "2019-12-02T02:32:27+00:00" + }, { "name": "moneyphp/money", "version": "v1.3.0", diff --git a/api/config/bundles.php b/api/config/bundles.php index aba2fb86..0b350522 100644 --- a/api/config/bundles.php +++ b/api/config/bundles.php @@ -16,4 +16,5 @@ Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], Tbbc\MoneyBundle\TbbcMoneyBundle::class => ['all' => true], + Knp\Bundle\MarkdownBundle\KnpMarkdownBundle::class => ['all' => true], ]; diff --git a/api/symfony.lock b/api/symfony.lock index 386193f5..e97be40b 100644 --- a/api/symfony.lock +++ b/api/symfony.lock @@ -106,6 +106,9 @@ "doctrine/reflection": { "version": "v1.0.0" }, + "doctrine/rst-parser": { + "version": "0.1.0" + }, "easyrdf/easyrdf": { "version": "0.9.1" }, @@ -139,6 +142,9 @@ "jdorn/sql-formatter": { "version": "v1.2.17" }, + "knplabs/knp-markdown-bundle": { + "version": "1.8.1" + }, "lcobucci/jwt": { "version": "3.3.1" }, @@ -157,6 +163,9 @@ "config/packages/lexik_jwt_authentication.yaml" ] }, + "michelf/php-markdown": { + "version": "1.9.0" + }, "moneyphp/money": { "version": "v1.3.0" }, From ab6425ee5126d307c7ce0a4ebde5befc53510364 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 23 Dec 2019 14:00:05 +0100 Subject: [PATCH 162/182] Added sleep before the database check --- .github/workflows/dockerimage.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 7a602d28..56f626c2 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -53,7 +53,7 @@ jobs: run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV --build-arg APP_BUILD=$APP_BUILD - name: Run the docker image run: docker-compose up -d - - name: Taking some sleep + - name: Taking some sleep (for containers to come up) run: sleep 200 - name: Check if all containers are running run: docker ps @@ -61,6 +61,8 @@ jobs: run: docker-compose logs - name: Database Update run: docker-compose exec -T php bin/console doctrine:schema:update --force + - name: Taking some more sleep (for database to be updated) + run: sleep 20 - name: Database Check run: docker-compose exec -T php bin/console doctrine:schema:validate - name: Security Checks From 76a6fccd79c8d53a6fc764905902386fb6846084 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 23 Dec 2019 18:06:00 +0100 Subject: [PATCH 163/182] Removed database checks --- .github/workflows/dockerimage.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 56f626c2..5be324ee 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -61,10 +61,10 @@ jobs: run: docker-compose logs - name: Database Update run: docker-compose exec -T php bin/console doctrine:schema:update --force - - name: Taking some more sleep (for database to be updated) - run: sleep 20 - - name: Database Check - run: docker-compose exec -T php bin/console doctrine:schema:validate + #- name: Taking some more sleep (for database to be updated) + # run: sleep 20 + #- name: Database Check + # run: docker-compose exec -T php bin/console doctrine:schema:validate - name: Security Checks run: docker-compose exec -T php composer req sensiolabs/security-checker From 2531b6a425f07328408de471bcda459a6cf4d42c Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sun, 29 Dec 2019 00:09:46 +0100 Subject: [PATCH 164/182] Added support for public code --- .env | 4 + AUTHORS.md | 1 + ROADMAP.md | 1 + TUTORIAL.md | 10 +- api/Dockerfile | 2 + api/config/packages/api_platform.yaml | 2 +- api/config/packages/doctrine.yaml | 4 + api/config/packages/twig.yaml | 35 +++++- api/docker/php/docker-entrypoint.sh | 6 +- api/helm/Chart.yaml | 4 +- api/public/schema/publiccode.yaml | 115 +++++++++++++++++ api/src/Command/PubliccodeCommand.php | 71 +++++++++++ .../Subscriber/FieldsAndExtendSubscriber.php | 19 +-- api/templates/helm/Chart.yaml.twig | 4 +- api/templates/publiccode/publiccode.yaml.twig | 117 ++++++++++++++++++ docker-compose.yml | 2 + 16 files changed, 371 insertions(+), 26 deletions(-) create mode 100644 AUTHORS.md create mode 100644 ROADMAP.md create mode 100644 api/public/schema/publiccode.yaml create mode 100644 api/src/Command/PubliccodeCommand.php create mode 100644 api/templates/publiccode/publiccode.yaml.twig diff --git a/.env b/.env index f892ecbb..e96a94ad 100644 --- a/.env +++ b/.env @@ -23,6 +23,10 @@ APP_BUILD=dev # The description for this api APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' + +APP_LOGO=pc.zaakonline.nl +APP_HOME=pc.zaakonline.nl + # The urls on wich this api is available TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 TRUSTED_HOSTS=^(.+\.)?conduction\.nl$|^(.+\.)?vng\.cloud$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost diff --git a/AUTHORS.md b/AUTHORS.md new file mode 100644 index 00000000..11794373 --- /dev/null +++ b/AUTHORS.md @@ -0,0 +1 @@ +# AUTHORS diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 00000000..437766dd --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1 @@ +# Roadmap diff --git a/TUTORIAL.md b/TUTORIAL.md index 356121e3..56565e51 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -306,15 +306,9 @@ More information on using data fixtures can be found at the [symfony website](ht ## Sharing your work A vital part of te common ground community is sharing your work, and telling other people what you are working. This way people can help you with problems that you run into. And keep tabs on any (security) updates that you make to you code. Sounds like a lot of work right? -Wel it actually isn't, there is a specific common ground platform over at common-ground.dev that reads repositories and updates user. So the only thing we need to do is tell this platform that we have started a new common ground repository. And tell it when we have updates ours. We can do all that by simply adding a webhook to our component. +Wel it actually isn't, there is a specific common ground platform over at common-ground.dev that reads repositories and updates user. So the only thing we need to do is tell this platform that we have started a new common ground repository. How do we do that? Simple we use the name common ground (or commonground) in the discription of our repository. common-ground.dev should then pick up our repository within the hour. -When using Github. To set up a webhook, go to the settings page of your repository or organization. From there, click Webhooks, then Add webhook. Use te following settings: -* Payload URL: https://www.common-ground.dev/webhook/github -* Content type: Application/JSON -* Secret: [leave blanck] -* Events: [just the push event] - -Now every time you update your repository the commonground dev page will alerted, rescan your repository and do al the appropriate platform actions. It just as easy as that. +Another option that we have is to declare our repository on [publiccode](), to do this you need to copy the publiccode.yaml from the [api/public/schema](api/public/schema]) folder to your root folder (dont forget to redo this every time you make a change to your repository). Continues integration diff --git a/api/Dockerfile b/api/Dockerfile index c48a7b4b..24fae412 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -118,6 +118,8 @@ CMD ["php-fpm"] # Let update the docs to show the latest chages # RUN bin/console api:swagger:export --output=/srv/api/public/schema/openapi.yaml --yaml --spec-version=3 +RUN bin/console app:publiccode:update --location=/srv/api/public/schema/ --spec-version=0.2 + ############################# # "nginx" stage # ############################# diff --git a/api/config/packages/api_platform.yaml b/api/config/packages/api_platform.yaml index 6624d8ab..58417518 100644 --- a/api/config/packages/api_platform.yaml +++ b/api/config/packages/api_platform.yaml @@ -20,7 +20,7 @@ parameters: env(CONTAINER_PROJECT_NAME): '' env(CONTAINER_REPRO): '' -api_platform: +api_platform: mapping: paths: ['%kernel.project_dir%/src/Entity'] diff --git a/api/config/packages/doctrine.yaml b/api/config/packages/doctrine.yaml index b935c8e3..dae8287b 100644 --- a/api/config/packages/doctrine.yaml +++ b/api/config/packages/doctrine.yaml @@ -1,3 +1,7 @@ +parameters: + env(DATABASE_URL): 'postgres://api-platform:!ChangeMe!@db/api?serverVersion=10.1' + # Organisation stuff + doctrine: dbal: # configure these for your database server diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml index 481428f9..0f182e22 100644 --- a/api/config/packages/twig.yaml +++ b/api/config/packages/twig.yaml @@ -1,12 +1,35 @@ parameters: - env(APP_DOMAINS): '[]' # Organisation stuff + env(GOOGLE_TAG_MANAGER_ID): '' + env(HUBSPOT_EMBED_CODE): '' + env(CONTAINER_REGISTRY_BASE): '' + env(CONTAINER_PROJECT_NAME): '' env(ORGANIZATION_NAME): '' - env(ORGANIZATION_EMAIL_ADDRESS): '' - env(ORGANIZATION_COUNTRY_NAME): '' - env(ORGANIZATION_STATE): '' - env(ORGANIZATION_LOCALITY): '' + env(ORGANIZATION_EMAIL_ADDRESS): '' + env(ORGANIZATION_COUNTRY_NAME): '' + env(ORGANIZATION_STATE): '' + env(ORGANIZATION_LOCALITY): '' env(ORGANIZATION_UNIT_NAME): '' + env(APP_NAME): '' + env(APP_TITLE): '' + env(APP_LOGO): '' + env(APP_HOME): '' + env(APP_VERSION): '' + env(APP_ENV): '' + env(APP_DEBUG): '' + env(APP_SUBDOMAIN): '' + env(APP_DOMAINS): '[]' + env(APP_DEMO): '' + env(APP_REPRO): '' + env(APP_DESCRIPTION): '' + env(AUTH_ENABLED): '' + env(AUDITTRAIL_ENABLED): '' + env(NOTIFICATION_ENABLED): '' + env(HEALTH_ENABLED): '' + env(TRUSTED_HOSTS): '' + env(TRUSTED_PROXIES): '' + env(NLX_OUTWAY): '' + env(NLX_INWAY): '' twig: default_path: '%kernel.project_dir%/templates' @@ -28,6 +51,8 @@ twig: app_name: '%env(APP_NAME)%' app_title: '%env(APP_TITLE)%' + app_logo: '%env(APP_LOGO)%' + app_home: '%env(APP_HOME)%' app_version: '%env(APP_VERSION)%' app_env: '%env(APP_ENV)%' app_debug: '%env(APP_DEBUG)%' diff --git a/api/docker/php/docker-entrypoint.sh b/api/docker/php/docker-entrypoint.sh index 54b7c9e8..59e902c4 100755 --- a/api/docker/php/docker-entrypoint.sh +++ b/api/docker/php/docker-entrypoint.sh @@ -69,7 +69,11 @@ if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then # this should only be done in an build echo "Updating Helm charts" - bin/console app:helm:update --location=/srv/api/helm --spec-version=3 + bin/console app:helm:update --location=/srv/api/helm --spec-version=3 + + # this should only be done in an build + echo "Updating publiccode charts" + bin/console app:publiccode:update --location=/srv/api/public/schema/ --spec-version=0.2 fi fi diff --git a/api/helm/Chart.yaml b/api/helm/Chart.yaml index 7c3c8a6a..22911f7f 100644 --- a/api/helm/Chart.yaml +++ b/api/helm/Chart.yaml @@ -3,5 +3,5 @@ appVersion: V.0.1 description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' name: pc version: 0.1.0 -home: https://common-ground.dev -icon: https://common-ground.dev/logo-250x250.png \ No newline at end of file +home: pc.zaakonline.nl +icon: pc.zaakonline.nl \ No newline at end of file diff --git a/api/public/schema/publiccode.yaml b/api/public/schema/publiccode.yaml new file mode 100644 index 00000000..1f17c57e --- /dev/null +++ b/api/public/schema/publiccode.yaml @@ -0,0 +1,115 @@ +publiccodeYmlVersion: "0.2" + +name: pc +applicationSuite: commonground +url: "https://github.com/ConductionNL/Proto-component-commonground" +landingURL: "pc.zaakonline.nl" +isBasedOn: "https://github.com/ConductionNL/Proto-component-commonground.git" softwareVersion: "V.0.1" +releaseDate: "2019-28-12" +logo: pc.zaakonline.nl +monochromeLogo: img/logo-mono.svg + +inputTypes: + - application/json + - application/xml + +outputTypes: + - application/json + - application/ld+json + - application/hal+json + - application/vnd.api+json + - application/health+json + - application/xml + - application/x-yaml + - text/csv + - text/html + +platforms: + - web + +categories: + - it-development + +usedBy: + - Gemeente Utrecht + - Gemeente Den Haag + - Gemeente Hoorn + + +roadmap: "https://github.com/ConductionNL/Proto-component-commonground/blob/master/ROADMAP.md" + +developmentStatus: development + +softwareType: "standalone/other" + +#intendedAudience: +# scope: +# - science-and-technology +# countries: +# - it +# - de +# unsupportedCountries: +# - us + +description: + en: +# localisedName: Medusa +# genericName: Text Editor +# shortDescription: > +# This description can have a maximum 150 +# characters long. We should not fill the +# remaining space with "Lorem Ipsum". End +# +# longDescription: > +# Very long description of this software, also split +# on multiple rows. You should note what the software +# is and why one should need it. + + documentation: "https://github.com/ConductionNL/Proto-component-commonground/blob/master/README.md" + apiDocumentation: "pc.zaakonline.nl" +# +# features: +# - Very important feature +# - Will run without a problem +# - Has zero bugs +# - Solves all the problems of the world +# screenshots: +# - img/sshot1.jpg +# - img/sshot2.jpg +# - img/sshot3.jpg +# videos: +# - https://youtube.com/xxxxxxxx +# awards: +# - 1st Price Software of the year + +legal: + license: EUPL-1.2 + mainCopyrightOwner: Conduction + repoOwner: Conduction + authorsFile: AUTHORS.md + +maintenance: + type: "internal" + + contractors: + - name: "Conduction B.V" + email: "info@conduction.nl" + website: "https://www.conduction.nl" + until: "2099-01-01" + + contacts: + - name: Ruben van der Linde + email: "ruben@conduction.nl" + affiliation: "Conduction B.V" + +localisation: + localisationReady: yes + availableLanguages: + - en + - nl + +dependsOn: + open: + - name: Kubernetes + versionMin: "1.15.5-do.1" + diff --git a/api/src/Command/PubliccodeCommand.php b/api/src/Command/PubliccodeCommand.php new file mode 100644 index 00000000..75c24371 --- /dev/null +++ b/api/src/Command/PubliccodeCommand.php @@ -0,0 +1,71 @@ +twig = $twig; + + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('app:publiccode:update') + // the short description shown while running "php bin/console list" + ->setDescription('Creates a new public chart.') + + // the full command description shown when running the command with + // the "--help" option + ->setHelp('see ehttps://github.com/italia/publiccode.yml') + ->setDescription('Publiccode.yml is a metadata standard for repositories containing software developed or acquired by the Public Administration, aimed at making them easily discoverabile and thus reusable by other entities.By including a publiccode.yml file in the root of a repository, and populating it with information about the software, technicians and civil servants can evaluate it. Automatic indexing tools can also be built, since the format is easily readable by both humans and machines.') + ->addOption('location', null, InputOption::VALUE_OPTIONAL, 'Write output to files in the given location', '/srv/api/public/schema/') + ->addOption('spec-version', null, InputOption::VALUE_OPTIONAL, 'Publiccode version to use ("0.1.0")', '0.1.0'); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + /** @var string $version */ + $version = $input->getOption('spec-version'); + + //if (!\in_array($version, ['0.1.0'], true)) { + // throw new InvalidOptionException(sprintf('This tool only supports version 2 and 3 of the OpenAPI specification ("%s" given).', $version)); + //} + + $publiccode = $this->twig->render('publiccode/publiccode.yaml.twig'); + + if (!empty($location = $input->getOption('location')) && \is_string($location)) { + file_put_contents($location.'/publiccode.yaml', $publiccode); + $io->success(sprintf('Data written to %s/publiccode.yaml (specification version %s).', $location, $version)); + } else { + // outputs multiple lines to the console (adding "\n" at the end of each line) + $output->writeln([ + 'Publiccode Chart', + '============', + $chart, + ]); + } + } +} diff --git a/api/src/Subscriber/FieldsAndExtendSubscriber.php b/api/src/Subscriber/FieldsAndExtendSubscriber.php index 22420329..d50440c7 100644 --- a/api/src/Subscriber/FieldsAndExtendSubscriber.php +++ b/api/src/Subscriber/FieldsAndExtendSubscriber.php @@ -33,6 +33,7 @@ public static function getSubscribedEvents() public function FilterFields(GetResponseForControllerResultEvent $event) { + /* @todo Contains a bug $result = $event->getControllerResult(); $fields = $event->getRequest()->query->get('fields'); $extends = $event->getRequest()->query->get('extend'); @@ -41,6 +42,12 @@ public function FilterFields(GetResponseForControllerResultEvent $event) $contentType= $event->getRequest()->headers->get('Accept'); } + + // Only do somthing if fields is query supplied + if (!$fields && !$extends) { + return $result; + } + // This needs to be bassed on the content-type // Lets set a return content type @@ -58,11 +65,6 @@ public function FilterFields(GetResponseForControllerResultEvent $event) $contentType = 'application/json'; $renderType = "json"; } - - // Only do somthing if fields is query supplied - if (!$fields && $extends) { - return $result; - } // let turn fields into an array if it isn't one already if (!is_array($fields)) { @@ -73,7 +75,7 @@ public function FilterFields(GetResponseForControllerResultEvent $event) } // Its possible to nest fields for filterins - foreach($fields as $key->$value){ + foreach($fields as $key=>$value){ // Lets check if the fields contain one or more .'s if (strpos($value, '.') !== false) { // This is where it gets complicated couse it could go on indevinitly @@ -101,9 +103,10 @@ public function FilterFields(GetResponseForControllerResultEvent $event) $jsonArray = json_decode($json, true); + // The we want to extend properties from the extend query foreach($extends as $extend){ - /* @todo add security checks */ + // @todo add security checks // Get new object for the extend $extendObject = $this->propertyAccessor->getValue($result, $extend); // turn to json @@ -117,6 +120,7 @@ public function FilterFields(GetResponseForControllerResultEvent $event) $jsonArray[$extend] = json_decode($extendjson, true); } + $json = json_encode($jsonArray); $response = new Response( @@ -126,5 +130,6 @@ public function FilterFields(GetResponseForControllerResultEvent $event) ); $event->setResponse($response); + */ } } diff --git a/api/templates/helm/Chart.yaml.twig b/api/templates/helm/Chart.yaml.twig index 821c26b2..38f81166 100644 --- a/api/templates/helm/Chart.yaml.twig +++ b/api/templates/helm/Chart.yaml.twig @@ -3,5 +3,5 @@ appVersion: {{ app_version }} description: '{{ app_description }}' name: {{ app_name|replace({' ': ''})|lower }} version: 0.1.0 -home: https://common-ground.dev -icon: https://common-ground.dev/logo-250x250.png \ No newline at end of file +home: {{ app_home }} +icon: {{ app_logo }} \ No newline at end of file diff --git a/api/templates/publiccode/publiccode.yaml.twig b/api/templates/publiccode/publiccode.yaml.twig new file mode 100644 index 00000000..88c1d8d1 --- /dev/null +++ b/api/templates/publiccode/publiccode.yaml.twig @@ -0,0 +1,117 @@ +{# Read https://docs.italia.it/italia/developers-italia/publiccodeyml-en/en/master/schema.core.html for the complete standard#} +publiccodeYmlVersion: "0.2" + +name: {{ app_name }} +applicationSuite: commonground +url: "{{ app_repro }}" +landingURL: "{{ app_demo }}" +isBasedOn: "https://github.com/ConductionNL/Proto-component-commonground.git" {# we asume that everything is based on the proto component #} +softwareVersion: "{{ app_version }}" +releaseDate: "{{ "now"|date("Y-d-m") }}" +logo: {{ app_logo }} +monochromeLogo: img/logo-mono.svg + +inputTypes: + - application/json + - application/xml + +outputTypes: + - application/json + - application/ld+json + - application/hal+json + - application/vnd.api+json + - application/health+json + - application/xml + - application/x-yaml + - text/csv + - text/html + +platforms: + - web + +categories: + - it-development + +usedBy: + - Gemeente Utrecht + - Gemeente Den Haag + - Gemeente Hoorn + + +roadmap: "{{ app_repro }}/blob/master/ROADMAP.md" + +developmentStatus: development + +softwareType: "standalone/other" + +#intendedAudience: +# scope: +# - science-and-technology +# countries: +# - it +# - de +# unsupportedCountries: +# - us + +description: + en: +# localisedName: Medusa +# genericName: Text Editor +# shortDescription: > +# This description can have a maximum 150 +# characters long. We should not fill the +# remaining space with "Lorem Ipsum". End +# +# longDescription: > +# Very long description of this software, also split +# on multiple rows. You should note what the software +# is and why one should need it. + + documentation: "{{ app_repro }}/blob/master/README.md" + apiDocumentation: "{{ app_demo }}" +# +# features: +# - Very important feature +# - Will run without a problem +# - Has zero bugs +# - Solves all the problems of the world +# screenshots: +# - img/sshot1.jpg +# - img/sshot2.jpg +# - img/sshot3.jpg +# videos: +# - https://youtube.com/xxxxxxxx +# awards: +# - 1st Price Software of the year + +legal: + license: EUPL-1.2 + mainCopyrightOwner: Conduction + repoOwner: Conduction + authorsFile: AUTHORS.md + +maintenance: + type: "internal" + + contractors: + - name: "Conduction B.V" + email: "info@conduction.nl" + website: "https://www.conduction.nl" + until: "2099-01-01" + + contacts: + - name: Ruben van der Linde + email: "ruben@conduction.nl" + affiliation: "Conduction B.V" + +localisation: + localisationReady: yes + availableLanguages: + - en + - nl + +dependsOn: + open: + - name: Kubernetes + versionMin: "1.15.5-do.1" + diff --git a/docker-compose.yml b/docker-compose.yml index 671f5c94..c6f6b218 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,6 +41,8 @@ services: - APP_DEMO=${APP_DEMO} - APP_REPRO=${APP_REPRO} - APP_DESCRIPTION=${APP_DESCRIPTION} + - APP_LOGO=${APP_LOGO} + - APP_HOME=${APP_HOME} - ORGANIZATION_NAME=${ORGANIZATION_NAME} - ORGANIZATION_EMAIL_ADDRESS=${ORGANIZATION_EMAIL_ADDRESS} - ORGANIZATION_COUNTRY_NAME=${ORGANIZATION_COUNTRY_NAME} From 440c2b619ea0af24bdd02912480e4906ea927674 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Dec 2019 23:11:15 +0000 Subject: [PATCH 165/182] Bump handlebars from 4.2.1 to 4.5.3 in /client Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.2.1 to 4.5.3. - [Release notes](https://github.com/wycats/handlebars.js/releases) - [Changelog](https://github.com/wycats/handlebars.js/blob/master/release-notes.md) - [Commits](https://github.com/wycats/handlebars.js/compare/v4.2.1...v4.5.3) Signed-off-by: dependabot[bot] --- client/yarn.lock | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/client/yarn.lock b/client/yarn.lock index bc383045..fa0625a8 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -2452,7 +2452,7 @@ commander@2.17.x: resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== -commander@^2.11.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: +commander@^2.11.0, commander@^2.19.0, commander@^2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -2462,6 +2462,11 @@ commander@~2.19.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== +commander@~2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + common-tags@^1.4.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" @@ -4337,9 +4342,9 @@ handle-thing@^2.0.0: integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== handlebars@^4.0.3: - version "4.2.1" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.2.1.tgz#dc69c0e61604224f0c23b38b5b6741db210b57da" - integrity sha512-bqPIlDk06UWbVEIFoYj+LVo42WhK96J+b25l7hbFDpxrOXMphFM3fNIm+cluwg4Pk2jiLjWU5nHQY7igGE75NQ== + version "4.5.3" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482" + integrity sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA== dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -9698,11 +9703,11 @@ uglify-js@3.4.x: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.6.0" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5" - integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg== + version "3.7.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a" + integrity sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg== dependencies: - commander "~2.20.0" + commander "~2.20.3" source-map "~0.6.1" unicode-canonical-property-names-ecmascript@^1.0.4: From 6760b7570c5ef212d4ce5d578bed7697cbf59872 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Dec 2019 23:11:15 +0000 Subject: [PATCH 166/182] Bump handlebars from 4.2.1 to 4.5.3 in /admin Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.2.1 to 4.5.3. - [Release notes](https://github.com/wycats/handlebars.js/releases) - [Changelog](https://github.com/wycats/handlebars.js/blob/master/release-notes.md) - [Commits](https://github.com/wycats/handlebars.js/compare/v4.2.1...v4.5.3) Signed-off-by: dependabot[bot] --- admin/yarn.lock | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/admin/yarn.lock b/admin/yarn.lock index 19be4de9..20e29249 100644 --- a/admin/yarn.lock +++ b/admin/yarn.lock @@ -2602,7 +2602,7 @@ commander@2.17.x: resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== -commander@^2.11.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.0: +commander@^2.11.0, commander@^2.19.0, commander@^2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== @@ -2612,6 +2612,11 @@ commander@~2.19.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== +commander@~2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + common-tags@^1.4.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" @@ -4545,9 +4550,9 @@ handle-thing@^2.0.0: integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== handlebars@^4.0.3: - version "4.2.1" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.2.1.tgz#dc69c0e61604224f0c23b38b5b6741db210b57da" - integrity sha512-bqPIlDk06UWbVEIFoYj+LVo42WhK96J+b25l7hbFDpxrOXMphFM3fNIm+cluwg4Pk2jiLjWU5nHQY7igGE75NQ== + version "4.5.3" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482" + integrity sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA== dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -10318,11 +10323,11 @@ uglify-js@3.4.x: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.6.0" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5" - integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg== + version "3.7.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a" + integrity sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg== dependencies: - commander "~2.20.0" + commander "~2.20.3" source-map "~0.6.1" unicode-canonical-property-names-ecmascript@^1.0.4: From ee89d3dc1be705525dcd91422277f07995e5b52c Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 30 Dec 2019 10:53:25 +0100 Subject: [PATCH 167/182] Update on public code --- TUTORIAL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TUTORIAL.md b/TUTORIAL.md index 56565e51..1a5877b0 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -308,7 +308,7 @@ A vital part of te common ground community is sharing your work, and telling oth Wel it actually isn't, there is a specific common ground platform over at common-ground.dev that reads repositories and updates user. So the only thing we need to do is tell this platform that we have started a new common ground repository. How do we do that? Simple we use the name common ground (or commonground) in the discription of our repository. common-ground.dev should then pick up our repository within the hour. -Another option that we have is to declare our repository on [publiccode](), to do this you need to copy the publiccode.yaml from the [api/public/schema](api/public/schema]) folder to your root folder (dont forget to redo this every time you make a change to your repository). +Another option that we have is to declare our repository on [publiccode](), to do this you need to copy the publiccode.yaml from the [api/public/schema](api/public/schema]) folder to your root folder (dont forget to redo this every time you make a major change to your repository concerning versioning or licencing). Continues integration From e09711985244bb9f7dd1dd2c7b09767cde62691b Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 30 Dec 2019 10:55:01 +0100 Subject: [PATCH 168/182] fix on publiccode template --- api/public/schema/publiccode.yaml | 3 ++- api/templates/publiccode/publiccode.yaml.twig | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/api/public/schema/publiccode.yaml b/api/public/schema/publiccode.yaml index 1f17c57e..67ea1827 100644 --- a/api/public/schema/publiccode.yaml +++ b/api/public/schema/publiccode.yaml @@ -4,7 +4,8 @@ name: pc applicationSuite: commonground url: "https://github.com/ConductionNL/Proto-component-commonground" landingURL: "pc.zaakonline.nl" -isBasedOn: "https://github.com/ConductionNL/Proto-component-commonground.git" softwareVersion: "V.0.1" +isBasedOn: "https://github.com/ConductionNL/Proto-component-commonground.git" +softwareVersion: "V.0.1" releaseDate: "2019-28-12" logo: pc.zaakonline.nl monochromeLogo: img/logo-mono.svg diff --git a/api/templates/publiccode/publiccode.yaml.twig b/api/templates/publiccode/publiccode.yaml.twig index 88c1d8d1..0d9dc439 100644 --- a/api/templates/publiccode/publiccode.yaml.twig +++ b/api/templates/publiccode/publiccode.yaml.twig @@ -5,7 +5,8 @@ name: {{ app_name }} applicationSuite: commonground url: "{{ app_repro }}" landingURL: "{{ app_demo }}" -isBasedOn: "https://github.com/ConductionNL/Proto-component-commonground.git" {# we asume that everything is based on the proto component #} +{# we asume that everything is based on the proto component #} +isBasedOn: "https://github.com/ConductionNL/Proto-component-commonground.git" softwareVersion: "{{ app_version }}" releaseDate: "{{ "now"|date("Y-d-m") }}" logo: {{ app_logo }} From 12732fd0538551c39909da97f5979cfd14fab00c Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 1 Jan 2020 10:31:52 +0100 Subject: [PATCH 169/182] update on dependencies --- api/composer.json | 6 +++--- api/public/schema/publiccode.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/composer.json b/api/composer.json index d04d452a..b69f6993 100644 --- a/api/composer.json +++ b/api/composer.json @@ -29,9 +29,9 @@ "webonyx/graphql-php": "^0.13.8" }, "require-dev" : { - "api-platform/schema-generator" : "^2.1", - "symfony/maker-bundle" : "^1.11", - "symfony/profiler-pack" : "^1.0" + "api-platform/schema-generator": "^2.1", + "symfony/maker-bundle": "^1.11", + "symfony/profiler-pack": "^1.0" }, "config" : { "preferred-install" : { diff --git a/api/public/schema/publiccode.yaml b/api/public/schema/publiccode.yaml index 67ea1827..66f44a92 100644 --- a/api/public/schema/publiccode.yaml +++ b/api/public/schema/publiccode.yaml @@ -6,7 +6,7 @@ url: "https://github.com/ConductionNL/Proto-component-commonground" landingURL: "pc.zaakonline.nl" isBasedOn: "https://github.com/ConductionNL/Proto-component-commonground.git" softwareVersion: "V.0.1" -releaseDate: "2019-28-12" +releaseDate: "2020-01-01" logo: pc.zaakonline.nl monochromeLogo: img/logo-mono.svg From 1e09b51a2d6ca17bf882499d0cce099dcaa57992 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Fri, 3 Jan 2020 17:23:38 +0100 Subject: [PATCH 170/182] removed vng.cloud --- .env | 2 +- .github/workflows/dockerimage.yml | 1 + api/src/Entity/ExampleEntity.php | 15 ++++++++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.env b/.env index e96a94ad..d41ad5c2 100644 --- a/.env +++ b/.env @@ -29,7 +29,7 @@ APP_HOME=pc.zaakonline.nl # The urls on wich this api is available TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 -TRUSTED_HOSTS=^(.+\.)?conduction\.nl$|^(.+\.)?vng\.cloud$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost +TRUSTED_HOSTS=^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost ################################################## # Orgization details diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 5be324ee..96e29ebb 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -34,6 +34,7 @@ jobs: if: contains( github.ref, 'master' ) || contains( github.base_ref, 'master' ) run: | echo ::set-env name=APP_ENV::prod + echo ::set-env name=APP_BUILD::prod echo "set APP_ENV to $APP_ENV" - name: Set APP_BUILD to APP_VERSION if: contains( github.ref, 'master' ) diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php index 47705b5c..2e65a2ba 100644 --- a/api/src/Entity/ExampleEntity.php +++ b/api/src/Entity/ExampleEntity.php @@ -11,6 +11,7 @@ use Gedmo\Mapping\Annotation as Gedmo; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Validator\Constraints as Assert; +use Ramsey\Uuid\Uuid; /** * This is an example entity. @@ -91,10 +92,18 @@ class ExampleEntity * @ORM\Column(type="string", length=255, nullable=true) */ private $camelCase; - - public function getId(): ?int + + + public function getId(): Uuid + { + return $this->id; + } + + public function setId(Uuid $id): self { - return $this->id; + $this->id = $id; + + return $this; } public function getName(): ?string From 518ceb288e190ba3f35f5aa9bb915d4dc6ce3104 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Fri, 3 Jan 2020 18:28:44 +0100 Subject: [PATCH 171/182] Moved public code from dockerfile to entrypoint --- api/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/Dockerfile b/api/Dockerfile index 24fae412..5036a777 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -117,8 +117,7 @@ CMD ["php-fpm"] # Let update the docs to show the latest chages # RUN bin/console api:swagger:export --output=/srv/api/public/schema/openapi.yaml --yaml --spec-version=3 - -RUN bin/console app:publiccode:update --location=/srv/api/public/schema/ --spec-version=0.2 +# RUN bin/console app:publiccode:update --location=/srv/api/public/schema/ --spec-version=0.2 ############################# # "nginx" stage # From c64be66ce1be3fdbc8b4cc0b37d75312fa6a5b10 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sun, 5 Jan 2020 15:54:12 +0100 Subject: [PATCH 172/182] domain to domains --- api/helm/templates/configmap.yaml | 2 +- api/helm/templates/php-deployment.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/helm/templates/configmap.yaml b/api/helm/templates/configmap.yaml index 41f37e42..dd422b1c 100644 --- a/api/helm/templates/configmap.yaml +++ b/api/helm/templates/configmap.yaml @@ -16,7 +16,7 @@ data: app-version: {{ .Values.settings.version | quote }} app-repro: {{ .Values.settings.repro | quote }} app-demo: {{ .Values.settings.demo | quote }} - app-domain: {{ .Values.settings.domain | quote }} + app-domains: {{ .Values.settings.domains | quote }} app-description: {{ .Values.settings.description | quote }} app-auth: {{ .Values.settings.authorisationEnabled | quote }} diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index 2d5df508..814d4fc6 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -77,11 +77,11 @@ spec: configMapKeyRef: name: {{ template "fullname" . }} key: app-demo - - name: APP_DOMAIN + - name: APP_DOMAINS valueFrom: configMapKeyRef: name: {{ template "fullname" . }} - key: app-domain + key: app-domains # organization - name: ORGANIZATION_NAME valueFrom: From e6efdbdc8b0bfc4864e285aa9f69655dcb281a5d Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sun, 5 Jan 2020 16:30:53 +0100 Subject: [PATCH 173/182] included the domains as a json value --- api/config/packages/twig.yaml | 3 ++- api/helm/templates/configmap.yaml | 3 ++- api/helm/templates/php-deployment.yaml | 2 +- api/helm/values.yaml | 1 + api/templates/helm/Values.yaml.twig | 1 + 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml index 0f182e22..eaef80d6 100644 --- a/api/config/packages/twig.yaml +++ b/api/config/packages/twig.yaml @@ -57,7 +57,8 @@ twig: app_env: '%env(APP_ENV)%' app_debug: '%env(APP_DEBUG)%' app_subdomain: '%env(APP_SUBDOMAIN)%' - app_domains: '%env(json:APP_DOMAINS)%' + app_domains: '%env(json:APP_DOMAINS)%' + app_domains_json: '%env(APP_DOMAINS)%' app_demo: '%env(APP_DEMO)%' app_repro: '%env(APP_REPRO)%' app_description: '%env(APP_DESCRIPTION)%' diff --git a/api/helm/templates/configmap.yaml b/api/helm/templates/configmap.yaml index dd422b1c..77e68c78 100644 --- a/api/helm/templates/configmap.yaml +++ b/api/helm/templates/configmap.yaml @@ -16,7 +16,8 @@ data: app-version: {{ .Values.settings.version | quote }} app-repro: {{ .Values.settings.repro | quote }} app-demo: {{ .Values.settings.demo | quote }} - app-domains: {{ .Values.settings.domains | quote }} + app-domains: {{ .Values.settings.domains | quote }} + app-domains-json: {{ .Values.settings.domainsJson | quote }} app-description: {{ .Values.settings.description | quote }} app-auth: {{ .Values.settings.authorisationEnabled | quote }} diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index 814d4fc6..d438ac3e 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -81,7 +81,7 @@ spec: valueFrom: configMapKeyRef: name: {{ template "fullname" . }} - key: app-domains + key: app-domains-json # organization - name: ORGANIZATION_NAME valueFrom: diff --git a/api/helm/values.yaml b/api/helm/values.yaml index c9735c5b..4ebf495f 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -16,6 +16,7 @@ settings: - zaakonline.nl - huwelijksplanner.online - common-ground.dev + domainsJson: ["conduction.nl","zaakonline.nl","huwelijksplanner.online","common-ground.dev"] organisationName: Conduction email: info@conduction.nl country: Netherlands diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index a328bd6b..afbd21ad 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -15,6 +15,7 @@ settings: {% for domain in app_domains %} - {{ domain }} {% endfor %} + domains_json: {{ app_domains_json }} organisationName: {{ organization_name }} email: {{ organization_email }} country: {{ organization_country }} From 90f2fc8bf2496d367f5f42dbc223f6d12c1aa276 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sun, 5 Jan 2020 16:55:55 +0100 Subject: [PATCH 174/182] domains from json --- api/config/packages/twig.yaml | 1 - api/templates/helm/Values.yaml.twig | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml index eaef80d6..5a403c45 100644 --- a/api/config/packages/twig.yaml +++ b/api/config/packages/twig.yaml @@ -58,7 +58,6 @@ twig: app_debug: '%env(APP_DEBUG)%' app_subdomain: '%env(APP_SUBDOMAIN)%' app_domains: '%env(json:APP_DOMAINS)%' - app_domains_json: '%env(APP_DOMAINS)%' app_demo: '%env(APP_DEMO)%' app_repro: '%env(APP_REPRO)%' app_description: '%env(APP_DESCRIPTION)%' diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index afbd21ad..25054083 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -15,7 +15,7 @@ settings: {% for domain in app_domains %} - {{ domain }} {% endfor %} - domains_json: {{ app_domains_json }} + domains_json: {{ app_domains_json | json_encode() }} organisationName: {{ organization_name }} email: {{ organization_email }} country: {{ organization_country }} From f8162de61f4b72f353922886a11b83fffb9687f8 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sun, 5 Jan 2020 17:21:04 +0100 Subject: [PATCH 175/182] fix on non-exisiting variable --- api/templates/helm/Values.yaml.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 25054083..320d577f 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -15,7 +15,7 @@ settings: {% for domain in app_domains %} - {{ domain }} {% endfor %} - domains_json: {{ app_domains_json | json_encode() }} + domains_json: {{ app_domains | json_encode() }} organisationName: {{ organization_name }} email: {{ organization_email }} country: {{ organization_country }} From 4e898db2108495eee2d1d51c12142463cea0e2b3 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sun, 5 Jan 2020 17:51:39 +0100 Subject: [PATCH 176/182] fix on value file --- api/templates/helm/Values.yaml.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 320d577f..12233fc4 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -15,7 +15,7 @@ settings: {% for domain in app_domains %} - {{ domain }} {% endfor %} - domains_json: {{ app_domains | json_encode() }} + domainsJson: {{ app_domains | json_encode() }} organisationName: {{ organization_name }} email: {{ organization_email }} country: {{ organization_country }} From ead310efecabfcf0cea01a3cbc543378e74d0d20 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sun, 5 Jan 2020 18:32:57 +0100 Subject: [PATCH 177/182] dump raw unsafe values --- api/templates/helm/Values.yaml.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index 12233fc4..ced66e43 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -15,7 +15,7 @@ settings: {% for domain in app_domains %} - {{ domain }} {% endfor %} - domainsJson: {{ app_domains | json_encode() }} + domainsJson: {{ app_domains | json_encode()| e }} organisationName: {{ organization_name }} email: {{ organization_email }} country: {{ organization_country }} From 0fa4c044a75ebcfd3b2016cb0587e78e28c672e0 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sun, 5 Jan 2020 18:54:38 +0100 Subject: [PATCH 178/182] fixed raw dump --- api/templates/helm/Values.yaml.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/templates/helm/Values.yaml.twig b/api/templates/helm/Values.yaml.twig index ced66e43..10375e26 100644 --- a/api/templates/helm/Values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -15,7 +15,7 @@ settings: {% for domain in app_domains %} - {{ domain }} {% endfor %} - domainsJson: {{ app_domains | json_encode()| e }} + domainsJson: {{ app_domains | json_encode()|raw }} organisationName: {{ organization_name }} email: {{ organization_email }} country: {{ organization_country }} From cde5820af43970f39e82dd7e4cd6626e039d961e Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sun, 5 Jan 2020 20:24:34 +0100 Subject: [PATCH 179/182] Test --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index d41ad5c2..dfe3cdd5 100644 --- a/.env +++ b/.env @@ -81,7 +81,7 @@ NOTIFICATION_ENABLED_AUTHORIZATION=sasd ################################################## AUTH_ENABLED=false -AUTH_PROVIDER=sasd +AUTH_PROVIDER=sasdadad AUTH_AUTHORIZATION=sasd ################################################## From 896d8da9cde626a3c39967f3f47f42c2b53ae05f Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sun, 5 Jan 2020 20:55:18 +0100 Subject: [PATCH 180/182] test --- api/helm/templates/php-deployment.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index d438ac3e..347f1381 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -77,11 +77,6 @@ spec: configMapKeyRef: name: {{ template "fullname" . }} key: app-demo - - name: APP_DOMAINS - valueFrom: - configMapKeyRef: - name: {{ template "fullname" . }} - key: app-domains-json # organization - name: ORGANIZATION_NAME valueFrom: From 83b9f72628a5e57d8a9b9599fd06047ee13ff455 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Fri, 10 Jan 2020 10:47:36 +0100 Subject: [PATCH 181/182] Removal of ExampleEntity --- api/helm/Chart.yaml | 2 +- api/helm/values.yaml | 8 +- api/public/schema/openapi.yaml | 660 +----------------------------- api/public/schema/publiccode.yaml | 4 +- api/src/Entity/ExampleEntity.php | 144 ------- 5 files changed, 17 insertions(+), 801 deletions(-) delete mode 100644 api/src/Entity/ExampleEntity.php diff --git a/api/helm/Chart.yaml b/api/helm/Chart.yaml index 22911f7f..d9f49077 100644 --- a/api/helm/Chart.yaml +++ b/api/helm/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 appVersion: V.0.1 description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' -name: pc +name: bs version: 0.1.0 home: pc.zaakonline.nl icon: pc.zaakonline.nl \ No newline at end of file diff --git a/api/helm/values.yaml b/api/helm/values.yaml index 4ebf495f..9d8c1621 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -4,9 +4,9 @@ settings: registryBase: docker.io/conduction - projectName: pc - name: pc - title: Proto Component + projectName: bs + name: bs + title: Berichten Service version: V.0.1 description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' repro: 'https://github.com/ConductionNL/Proto-component-commonground' @@ -28,7 +28,7 @@ settings: debug: 1 replicaCount: 1 corsAllowOrigin: ['*'] - trustedHosts: '^(.+\.)?conduction\.nl$|^(.+\.)?vng\.cloud$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' + trustedHosts: '^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' pullPolicy: Always # You will need these proxies on kubernetes trustedProxies: diff --git a/api/public/schema/openapi.yaml b/api/public/schema/openapi.yaml index 227109d9..2f4e8a23 100644 --- a/api/public/schema/openapi.yaml +++ b/api/public/schema/openapi.yaml @@ -1,673 +1,33 @@ openapi: 3.0.2 info: - title: 'Proto Component' + title: 'Berichten Service' version: V.0.1 description: | API Details - - Component: Proto Component - - Reference: pc + - Component: Berichten Service + - Reference: bs - Enviroment: dev - Version: V.0.1 - Repository: [online](https://github.com/ConductionNL/Proto-component-commonground) / [zip](https://github.com/ConductionNL/Proto-component-commonground/archive/master.zip) - - Docker Image: [online](https://hub.docker.com/repository/docker/conduction/pc-php) - - Datamodel: [postman](/schema/pc.postman_collection.json) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) + - Docker Image: [online](https://hub.docker.com/repository/docker/conduction/bs-php) + - Datamodel: [postman](/schema/bs.postman_collection.json) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) 'Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' -paths: - /example_entities: - get: - tags: - - ExampleEntity - operationId: getExampleEntityCollection - summary: 'Retrieves the collection of ExampleEntity resources.' - responses: - 200: - description: 'ExampleEntity collection response' - content: - application/hal+json: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity-read' - application/ld+json: - schema: - type: object - properties: - 'hydra:member': { type: array, items: { $ref: '#/components/schemas/ExampleEntity:jsonld-read' } } - 'hydra:totalItems': { type: integer, minimum: 0 } - 'hydra:view': { type: object, properties: { '@id': { type: string, format: iri-reference }, '@type': { type: string }, 'hydra:first': { type: string, format: iri-reference }, 'hydra:last': { type: string, format: iri-reference }, 'hydra:next': { type: string, format: iri-reference } } } - 'hydra:search': { type: object, properties: { '@type': { type: string }, 'hydra:template': { type: string }, 'hydra:variableRepresentation': { type: string }, 'hydra:mapping': { type: array, items: { type: object, properties: { '@type': { type: string }, variable: { type: string }, property: { type: string }, required: { type: boolean } } } } } } - required: - - 'hydra:member' - application/vnd.api+json: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity-read' - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity-read' - application/xml: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity-read' - application/x-yaml: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity-read' - text/csv: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity-read' - text/html: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity-read' - parameters: - - - name: like_name - in: query - required: false - schema: - type: string - - - name: like_description - in: query - required: false - schema: - type: string - - - name: page - in: query - required: false - description: 'The collection page number' - schema: - type: integer - default: 1 - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-NLX-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header - - - name: Link - description: 'A [websub](https://www.w3.org/TR/websub/#discovery) header like ; rel="hub"' - in: header - - - name: 'extend[]' - required: false - description: 'An array of nested objects to include in the return object' - in: query - schema: - type: array - - - name: 'fields[]' - required: false - description: 'An array of fields to return in output, wil return all fields is not supplied' - in: query - schema: - type: array - - - name: validOn - required: false - description: 'Returns object as valid on a given date time' - schema: - type: string - format: date-time - in: query - - - name: validFrom - required: false - description: 'Returns objects valid from a given date time' - schema: - type: string - format: date-time - in: query - - - name: validUntil - required: false - description: 'Returns objects valid until a given date time' - schema: - type: string - format: date-time - in: query - produces: - - application/health+json - post: - tags: - - ExampleEntity - operationId: postExampleEntityCollection - summary: 'Creates a ExampleEntity resource.' - responses: - 201: - description: 'ExampleEntity resource created' - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity:jsonld-read' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - links: - GetExampleEntityItem: - parameters: - id: '$response.body#/id' - operationId: getExampleEntityItem - description: 'The `id` value returned in the response can be used as the `id` parameter in `GET /example_entities/{id}`.' - 400: - description: 'Invalid input' - 404: - description: 'Resource not found' - requestBody: - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity:jsonld-write' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - description: 'The new ExampleEntity resource' - parameters: - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-NLX-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header - '/example_entities/{id}': - get: - tags: - - ExampleEntity - operationId: audittrailExampleEntityItem - summary: 'Retrieves a ExampleEntity resource.' - parameters: - - - name: id - in: path - required: true - schema: - type: string - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-NLX-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header - - - name: Link - description: 'A [websub](https://www.w3.org/TR/websub/#discovery) header like ; rel="hub"' - in: header - - - name: 'extend[]' - required: false - description: 'An array of nested objects to include in the return object' - in: query - schema: - type: array - - - name: 'fields[]' - required: false - description: 'An array of fields to return in output, wil return all fields is not supplied' - in: query - schema: - type: array - - - name: validOn - required: false - description: 'Returns object as valid on a given date time' - schema: - type: string - format: date-time - in: query - - - name: validFrom - required: false - description: 'Returns objects valid from a given date time' - schema: - type: string - format: date-time - in: query - - - name: validUntil - required: false - description: 'Returns objects valid until a given date time' - schema: - type: string - format: date-time - in: query - responses: - 200: - description: 'ExampleEntity resource response' - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity:jsonld-read' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - 404: - description: 'Resource not found' - produces: - - application/health+json - put: - tags: - - ExampleEntity - operationId: putExampleEntityItem - summary: 'Replaces the ExampleEntity resource.' - parameters: - - - name: id - in: path - required: true - schema: - type: string - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-NLX-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header - responses: - 200: - description: 'ExampleEntity resource updated' - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity:jsonld-read' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity-read' - 400: - description: 'Invalid input' - 404: - description: 'Resource not found' - requestBody: - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity:jsonld-write' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity-write' - description: 'The updated ExampleEntity resource' - delete: - tags: - - ExampleEntity - operationId: deleteExampleEntityItem - summary: 'Removes the ExampleEntity resource.' - responses: - 204: - description: 'ExampleEntity resource deleted' - 404: - description: 'Resource not found' - parameters: - - - name: id - in: path - required: true - schema: - type: string - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-NLX-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header -components: - schemas: - ExampleEntity-read: - type: object - description: 'This is an example entity.' - properties: - id: - readOnly: true - externalDocs: - url: 'http://schema.org/identifier' - type: string - name: - description: 'The name of this example property' - type: string - description: - description: 'The description of this example property' - type: string - camelCase: - description: 'Proof that we camel case our api' - type: string - required: - - name - ExampleEntity-write: - type: object - description: 'This is an example entity.' - required: - - name - properties: - name: - description: 'The name of this example property' - type: string - description: - description: 'The description of this example property' - type: string - camelCase: - description: 'Proof that we camel case our api' - type: string - 'ExampleEntity:jsonld-read': - type: object - description: 'This is an example entity.' - properties: - '@context': - readOnly: true - type: string - '@id': - readOnly: true - type: string - '@type': - readOnly: true - type: string - id: - readOnly: true - externalDocs: - url: 'http://schema.org/identifier' - type: string - name: - description: 'The name of this example property' - type: string - description: - description: 'The description of this example property' - type: string - camelCase: - description: 'Proof that we camel case our api' - type: string - required: - - name - 'ExampleEntity:jsonld-write': - type: object - description: 'This is an example entity.' - required: - - name - properties: - '@context': - readOnly: true - type: string - '@id': - readOnly: true - type: string - '@type': - readOnly: true - type: string - name: - description: 'The name of this example property' - type: string - description: - description: 'The description of this example property' - type: string - camelCase: - description: 'Proof that we camel case our api' - type: string -definitions: - ExampleEntity-read: - properties: - id: - example: e2984465-190a-4562-829e-a8cca81aa35d - format: uuid - name: - example: 'My Group' - maxLength: 255 - description: - example: 'Is the best group ever' - maxLength: 2555 - camelCase: - example: 'Best api ever' - maxLength: 255 - required: - - name - ExampleEntity-write: - properties: - name: - example: 'My Group' - maxLength: 255 - description: - example: 'Is the best group ever' - maxLength: 2555 - camelCase: - example: 'Best api ever' - maxLength: 255 - required: - - name -tags: - - - name: ExampleEntity - description: | - This is an example entity. - - With an adtional description, all in all its pritty nice [url](www.google.nl) +paths: { } +definitions: [] +tags: [] securityDefinitions: JWT-Oauth: type: oauth2 authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' flow: implicit - scopes: - read: 'read right to the ExampleEntity resource' - write: 'write right to the ExampleEntity resource' + scopes: [] JWT-Token: type: apiKey in: header name: Authorization - scopes: - read: 'read right to the ExampleEntity resource' - write: 'write right to the ExampleEntity resource' + scopes: [] host: irc.zaakonline.nl servers: - diff --git a/api/public/schema/publiccode.yaml b/api/public/schema/publiccode.yaml index 66f44a92..757ee744 100644 --- a/api/public/schema/publiccode.yaml +++ b/api/public/schema/publiccode.yaml @@ -1,12 +1,12 @@ publiccodeYmlVersion: "0.2" -name: pc +name: bs applicationSuite: commonground url: "https://github.com/ConductionNL/Proto-component-commonground" landingURL: "pc.zaakonline.nl" isBasedOn: "https://github.com/ConductionNL/Proto-component-commonground.git" softwareVersion: "V.0.1" -releaseDate: "2020-01-01" +releaseDate: "2020-10-01" logo: pc.zaakonline.nl monochromeLogo: img/logo-mono.svg diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php deleted file mode 100644 index 2e65a2ba..00000000 --- a/api/src/Entity/ExampleEntity.php +++ /dev/null @@ -1,144 +0,0 @@ -id; - } - - public function setId(Uuid $id): self - { - $this->id = $id; - - return $this; - } - - public function getName(): ?string - { - return $this->name; - } - - public function setName(string $name): self - { - $this->name = $name; - - return $this; - } - - public function getDescription(): ?string - { - return $this->description; - } - - public function setDescription(?string $description): self - { - $this->description = $description; - - return $this; - } - - public function getCamelCase(): ?string - { - return $this->camelCase; - } - - public function setCamelCase(?string $camelCase): self - { - $this->camelCase = $camelCase; - - return $this; - } -} From 584eabf15f8d14eb5436cb2d6b7c5e968d4b2cb9 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Fri, 10 Jan 2020 12:11:36 +0100 Subject: [PATCH 182/182] Setting subdomain --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index 0c7c2c26..eda2e563 100644 --- a/.env +++ b/.env @@ -48,7 +48,7 @@ ORGANIZATION_UNIT_NAME=Common-Ground ################################################## # The subdomain for this component (should be www for applications) -APP_SUBDOMAIN=pc +APP_SUBDOMAIN=bs # he domains on wich you want to provide this component, the first wil be used as primary (or common in cert-manger terms) APP_DOMAINS=["conduction.nl","zaakonline.nl","huwelijksplanner.online","common-ground.dev"]