environnement complet autonome, révision complete de la méthode, ajout de configuration
Some checks failed
Cadoles/hydra-sql/pipeline/head There was a failure building this commit
Cadoles/hydra-sql/pipeline/pr-develop There was a failure building this commit

This commit is contained in:
Rudy Masson 2022-12-09 17:31:07 +01:00
parent b451566452
commit 6fc004a549
110 changed files with 1829 additions and 372 deletions

View File

@ -0,0 +1 @@
Deny from all

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"body":{"manifests":{"symfony\/lock":{"manifest":{"copy-from-recipe":{"config\/":"%CONFIG_DIR%\/"},"env":{"#1":"Choose one of the stores below","#2":"postgresql+advisory:\/\/db_user:db_password@localhost\/db_name","LOCK_DSN":"flock"}},"files":{"config\/packages\/lock.yaml":{"contents":["framework:"," lock: '%env(LOCK_DSN)%'",""],"executable":false}},"ref":"8e937ff2b4735d110af1770f242c1107fdab4c8e"}}},"headers":{"content-length":["352"],"source-age":["0"],"expires":["Fri, 09 Dec 2022 12:15:54 GMT"],"x-fastly-request-id":["99362e6c20c56fe300b3fbae10ad542b415cb911"],"access-control-allow-origin":["*"],"vary":["Authorization,Accept-Encoding,Origin"],"x-timer":["S1670587854.441342,VS0,VE164"],"x-cache-hits":["1"],"x-cache":["HIT"],"x-served-by":["cache-cdg20748-CDG"],"via":["1.1 varnish"],"date":["Fri, 09 Dec 2022 12:10:54 GMT"],"accept-ranges":["bytes"],"content-encoding":["gzip"],"x-github-request-id":["3B8E:2C5C:B4970C:BED891:6392F768"],"x-xss-protection":["1; mode=block"],"x-frame-options":["deny"],"x-content-type-options":["nosniff"],"strict-transport-security":["max-age=31536000"],"etag":["W\/\"2e6659df1a8da63f494cd2e51c30da415ec2b01bc06adc2d981c9c6dd7fa8299\""],"content-type":["text\/plain; charset=utf-8"],"content-security-policy":["default-src 'none'; style-src 'unsafe-inline'; sandbox"],"cache-control":["max-age=300"]}}

View File

@ -0,0 +1 @@
{"packages":[],"notify-batch":"https:\/\/packagist.org\/downloads\/","providers-url":"\/p\/%package%$%hash%.json","metadata-url":"\/p2\/%package%.json","metadata-changes-url":"https:\/\/packagist.org\/metadata\/changes.json","search":"https:\/\/packagist.org\/search.json?q=%query%&type=%type%","list":"https:\/\/packagist.org\/packages\/list.json","security-advisories":{"metadata":true,"api-url":"https:\/\/packagist.org\/api\/security-advisories\/","query-all":true},"providers-api":"https:\/\/packagist.org\/providers\/%package%.json","warning":"Support for Composer 1 is deprecated and some packages will not be available. You should upgrade to Composer 2. See https:\/\/blog.packagist.com\/deprecating-composer-1-support\/","warning-versions":"<1.99","info":"\u001b[37;44m#StandWith\u001b[30;43mUkraine\u001b[0m","provider-includes":{"p\/provider-2013$%hash%.json":{"sha256":"b44886fcd737666278fdeeb1310c04738b061d24209ad9ecbd64ec79c7522963"},"p\/provider-2014$%hash%.json":{"sha256":"888fa232c102b40ad0297eeca56c3a521c92ed41f730cd4ff0c4c4ef0421efca"},"p\/provider-2015$%hash%.json":{"sha256":"b9d2681c2c485ee49dcfea744c671859b1985e41d31eac5088038f251676fbf0"},"p\/provider-2016$%hash%.json":{"sha256":"22dff292b911025270420b24e40892957f47f51ca29e3beaac51a3893865859a"},"p\/provider-2017$%hash%.json":{"sha256":"6e1c3fa3413924c9a93c6f7f4fb1728e0908be0e636a5c246d7c3cc9dc1242a3"},"p\/provider-2018$%hash%.json":{"sha256":"514873a99f0d86586918b4580e5c31b8e406fa90c240f1c5251a0181c32ba980"},"p\/provider-2019$%hash%.json":{"sha256":"036fa273e0543546296c27837b7758a51a7c7d8103b272cb7adc0f3ea98abe12"},"p\/provider-2020$%hash%.json":{"sha256":"309afbb790764f2d9ce2ff2e143d36375682f17c216f83f50bab6ceee80168ed"},"p\/provider-2021$%hash%.json":{"sha256":"0a595abd163ad7fca0eb8ebffe4fbdbbe6880b51d7b3e49215176843faa0edfc"},"p\/provider-2022-01$%hash%.json":{"sha256":"38a0cc7197e15fafb9ab4ff0eb41b38cc38a40ebce671811362813844d53033d"},"p\/provider-2022-04$%hash%.json":{"sha256":"8f32bdb14f0d9516f2e8817f9e2f0c4a03cbcdbf98d04169df8feb07cb7bc0c8"},"p\/provider-2022-07$%hash%.json":{"sha256":"1e10bff9c03f4a375595e85f97b480297d87ee4d3774ad72034926e513bd31f8"},"p\/provider-2022-10$%hash%.json":{"sha256":"a7bcf1b2efe8b64aa5566ba4b71a6753ed824c7383854844d6debcb482a937cc"},"p\/provider-archived$%hash%.json":{"sha256":"e5e1699564fbcf305223672940613f94a9ac63f8380db826a764d2bb72c6164b"},"p\/provider-latest$%hash%.json":{"sha256":"ee6ee624fce1034d6c01d78519fa7fcf36e9c7c4a4a5637ee2dcb04a70ba7957"}},"last-modified":"Fri, 09 Dec 2022 12:03:30 GMT"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"minified":"composer/2.0","packages":{"psr/cache":[{"name":"psr/cache","description":"Common interface for caching libraries","keywords":["cache","psr","psr-6"],"homepage":"","version":"3.0.0","version_normalized":"3.0.0.0","license":["MIT"],"authors":[{"name":"PHP-FIG","homepage":"https://www.php-fig.org/"}],"source":{"url":"https://github.com/php-fig/cache.git","type":"git","reference":"aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"},"dist":{"url":"https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf","type":"zip","shasum":"","reference":"aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"},"type":"library","time":"2021-02-03T23:26:27+00:00","autoload":{"psr-4":{"Psr\\Cache\\":"src/"}},"extra":{"branch-alias":{"dev-master":"1.0.x-dev"}},"require":{"php":">=8.0.0"},"support":{"source":"https://github.com/php-fig/cache/tree/3.0.0"}},{"version":"2.0.0","version_normalized":"2.0.0.0","source":{"url":"https://github.com/php-fig/cache.git","type":"git","reference":"213f9dbc5b9bfbc4f8db86d2838dc968752ce13b"},"dist":{"url":"https://api.github.com/repos/php-fig/cache/zipball/213f9dbc5b9bfbc4f8db86d2838dc968752ce13b","type":"zip","shasum":"","reference":"213f9dbc5b9bfbc4f8db86d2838dc968752ce13b"},"time":"2021-02-03T23:23:37+00:00","support":{"source":"https://github.com/php-fig/cache/tree/2.0.0"}},{"version":"1.0.1","version_normalized":"1.0.1.0","authors":[{"name":"PHP-FIG","homepage":"http://www.php-fig.org/"}],"source":{"url":"https://github.com/php-fig/cache.git","type":"git","reference":"d11b50ad223250cf17b86e38383413f5a6764bf8"},"dist":{"url":"https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8","type":"zip","shasum":"","reference":"d11b50ad223250cf17b86e38383413f5a6764bf8"},"time":"2016-08-06T20:24:11+00:00","require":{"php":">=5.3.0"},"support":{"source":"https://github.com/php-fig/cache/tree/master"}},{"version":"1.0.0","version_normalized":"1.0.0.0","source":{"url":"https://github.com/php-fig/cache.git","type":"git","reference":"9e66031f41fbbdda45ee11e93c45d480ccba3eb3"},"dist":{"url":"https://api.github.com/repos/php-fig/cache/zipball/9e66031f41fbbdda45ee11e93c45d480ccba3eb3","type":"zip","shasum":"","reference":"9e66031f41fbbdda45ee11e93c45d480ccba3eb3"},"time":"2015-12-11T02:52:07+00:00","support":{"issues":"https://github.com/php-fig/cache/issues","source":"https://github.com/php-fig/cache/tree/master"}}]},"security-advisories":[],"last-modified":"Fri, 24 Jun 2022 06:27:35 GMT"}

View File

@ -0,0 +1 @@
{"minified":"composer/2.0","packages":{"psr/container":[{"name":"psr/container","description":"Common Container Interface (PHP FIG PSR-11)","keywords":["container","psr","container-interop","PSR-11","container-interface"],"homepage":"https://github.com/php-fig/container","version":"2.0.2","version_normalized":"2.0.2.0","license":["MIT"],"authors":[{"name":"PHP-FIG","homepage":"https://www.php-fig.org/"}],"source":{"url":"https://github.com/php-fig/container.git","type":"git","reference":"c71ecc56dfe541dbd90c5360474fbc405f8d5963"},"dist":{"url":"https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963","type":"zip","shasum":"","reference":"c71ecc56dfe541dbd90c5360474fbc405f8d5963"},"type":"library","time":"2021-11-05T16:47:00+00:00","autoload":{"psr-4":{"Psr\\Container\\":"src/"}},"extra":{"branch-alias":{"dev-master":"2.0.x-dev"}},"require":{"php":">=7.4.0"},"support":{"issues":"https://github.com/php-fig/container/issues","source":"https://github.com/php-fig/container/tree/2.0.2"}},{"version":"2.0.1","version_normalized":"2.0.1.0","source":{"url":"https://github.com/php-fig/container.git","type":"git","reference":"2ae37329ee82f91efadc282cc2d527fd6065a5ef"},"dist":{"url":"https://api.github.com/repos/php-fig/container/zipball/2ae37329ee82f91efadc282cc2d527fd6065a5ef","type":"zip","shasum":"","reference":"2ae37329ee82f91efadc282cc2d527fd6065a5ef"},"time":"2021-03-24T13:40:57+00:00","require":{"php":">=7.2.0"},"support":{"issues":"https://github.com/php-fig/container/issues","source":"https://github.com/php-fig/container/tree/2.0.1"}},{"version":"2.0.0","version_normalized":"2.0.0.0","source":{"url":"https://github.com/php-fig/container.git","type":"git","reference":"68f5200c33f18c018db17eb869d4b0f97da17cad"},"dist":{"url":"https://api.github.com/repos/php-fig/container/zipball/68f5200c33f18c018db17eb869d4b0f97da17cad","type":"zip","shasum":"","reference":"68f5200c33f18c018db17eb869d4b0f97da17cad"},"time":"2021-03-05T16:02:18+00:00","support":{"issues":"https://github.com/php-fig/container/issues","source":"https://github.com/php-fig/container/tree/2.0.0"}},{"version":"1.1.2","version_normalized":"1.1.2.0","source":{"url":"https://github.com/php-fig/container.git","type":"git","reference":"513e0666f7216c7459170d56df27dfcefe1689ea"},"dist":{"url":"https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea","type":"zip","shasum":"","reference":"513e0666f7216c7459170d56df27dfcefe1689ea"},"time":"2021-11-05T16:50:12+00:00","require":{"php":">=7.4.0"},"support":{"issues":"https://github.com/php-fig/container/issues","source":"https://github.com/php-fig/container/tree/1.1.2"},"extra":"__unset"},{"version":"1.1.1","version_normalized":"1.1.1.0","source":{"url":"https://github.com/php-fig/container.git","type":"git","reference":"8622567409010282b7aeebe4bb841fe98b58dcaf"},"dist":{"url":"https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf","type":"zip","shasum":"","reference":"8622567409010282b7aeebe4bb841fe98b58dcaf"},"time":"2021-03-05T17:36:06+00:00","require":{"php":">=7.2.0"},"support":{"issues":"https://github.com/php-fig/container/issues","source":"https://github.com/php-fig/container/tree/1.1.1"}},{"version":"1.1.0","version_normalized":"1.1.0.0","source":{"url":"https://github.com/php-fig/container.git","type":"git","reference":"9fc7aab7a78057a124384358ebae8a1711b6f6fc"},"dist":{"url":"https://api.github.com/repos/php-fig/container/zipball/9fc7aab7a78057a124384358ebae8a1711b6f6fc","type":"zip","shasum":"","reference":"9fc7aab7a78057a124384358ebae8a1711b6f6fc"},"time":"2021-03-05T15:48:30+00:00","extra":{"branch-alias":{"dev-master":"1.1.x-dev"}},"support":{"issues":"https://github.com/php-fig/container/issues","source":"https://github.com/php-fig/container/tree/1.1.0"}},{"version":"1.0.0","version_normalized":"1.0.0.0","authors":[{"name":"PHP-FIG","homepage":"http://www.php-fig.org/"}],"source":{"url":"https://github.com/php-fig/container.git","type":"git","reference":"b7ce3b176482dbbc1245ebf52b181af44c2cf55f"},"dist":{"url":"https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f","type":"zip","shasum":"","reference":"b7ce3b176482dbbc1245ebf52b181af44c2cf55f"},"time":"2017-02-14T16:28:37+00:00","extra":{"branch-alias":{"dev-master":"1.0.x-dev"}},"require":{"php":">=5.3.0"},"support":{"issues":"https://github.com/php-fig/container/issues","source":"https://github.com/php-fig/container/tree/master"}}]},"security-advisories":[],"last-modified":"Mon, 04 Jul 2022 04:48:24 GMT"}

View File

@ -0,0 +1 @@
{"minified":"composer/2.0","packages":{"psr/event-dispatcher":[{"name":"psr/event-dispatcher","description":"Standard interfaces for event handling.","keywords":["events","psr","psr-14"],"homepage":"","version":"1.0.0","version_normalized":"1.0.0.0","license":["MIT"],"authors":[{"name":"PHP-FIG","homepage":"http://www.php-fig.org/"}],"source":{"url":"https://github.com/php-fig/event-dispatcher.git","type":"git","reference":"dbefd12671e8a14ec7f180cab83036ed26714bb0"},"dist":{"url":"https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0","type":"zip","shasum":"","reference":"dbefd12671e8a14ec7f180cab83036ed26714bb0"},"type":"library","time":"2019-01-08T18:20:26+00:00","autoload":{"psr-4":{"Psr\\EventDispatcher\\":"src/"}},"extra":{"branch-alias":{"dev-master":"1.0.x-dev"}},"require":{"php":">=7.2.0"},"support":{"issues":"https://github.com/php-fig/event-dispatcher/issues","source":"https://github.com/php-fig/event-dispatcher/tree/1.0.0"}},{"version":"0.7.0","version_normalized":"0.7.0.0","source":{"url":"https://github.com/php-fig/event-dispatcher.git","type":"git","reference":"8380006c4192e22528ce40c3a56b81590707128a"},"dist":{"url":"https://api.github.com/repos/php-fig/event-dispatcher/zipball/8380006c4192e22528ce40c3a56b81590707128a","type":"zip","shasum":"","reference":"8380006c4192e22528ce40c3a56b81590707128a"},"time":"2018-12-26T17:32:27+00:00","support":{"issues":"https://github.com/php-fig/event-dispatcher/issues","source":"https://github.com/php-fig/event-dispatcher/tree/master"}},{"version":"0.6.0","version_normalized":"0.6.0.0","source":{"url":"https://github.com/php-fig/event-dispatcher.git","type":"git","reference":"14a25ea9045cfc34c9edc31ad468a5cc6e914a8c"},"dist":{"url":"https://api.github.com/repos/php-fig/event-dispatcher/zipball/14a25ea9045cfc34c9edc31ad468a5cc6e914a8c","type":"zip","shasum":"","reference":"14a25ea9045cfc34c9edc31ad468a5cc6e914a8c"},"time":"2018-09-27T17:52:39+00:00","require":{"php":">=7.1.0"},"support":{"issues":"https://github.com/php-fig/event-dispatcher/issues","source":"https://github.com/php-fig/event-dispatcher/tree/0.6.0"}},{"version":"0.5.0","version_normalized":"0.5.0.0","source":{"url":"https://github.com/php-fig/event-dispatcher.git","type":"git","reference":"3a8ccc0acc46f76270726cbed7f9a84cce47c12c"},"dist":{"url":"https://api.github.com/repos/php-fig/event-dispatcher/zipball/3a8ccc0acc46f76270726cbed7f9a84cce47c12c","type":"zip","shasum":"","reference":"3a8ccc0acc46f76270726cbed7f9a84cce47c12c"},"time":"2018-09-15T17:00:24+00:00","support":{"issues":"https://github.com/php-fig/event-dispatcher/issues","source":"https://github.com/php-fig/event-dispatcher/tree/0.5.0"}},{"version":"0.4.0","version_normalized":"0.4.0.0","source":{"url":"https://github.com/php-fig/event-dispatcher.git","type":"git","reference":"909879458094ebe1491f04de5782366e056b66e7"},"dist":{"url":"https://api.github.com/repos/php-fig/event-dispatcher/zipball/909879458094ebe1491f04de5782366e056b66e7","type":"zip","shasum":"","reference":"909879458094ebe1491f04de5782366e056b66e7"},"time":"2018-08-20T08:14:46+00:00","support":{"issues":"https://github.com/php-fig/event-dispatcher/issues","source":"https://github.com/php-fig/event-dispatcher/tree/0.4.0"}},{"version":"0.3.0","version_normalized":"0.3.0.0","source":{"url":"https://github.com/php-fig/event-dispatcher.git","type":"git","reference":"ba7f8a4012b3527dcbb194ed6acf5470b6b484d3"},"dist":{"url":"https://api.github.com/repos/php-fig/event-dispatcher/zipball/ba7f8a4012b3527dcbb194ed6acf5470b6b484d3","type":"zip","shasum":"","reference":"ba7f8a4012b3527dcbb194ed6acf5470b6b484d3"},"time":"2018-08-03T04:05:55+00:00","autoload":{"psr-4":{"Psr\\Event\\Dispatcher\\":"src/"}},"support":{"issues":"https://github.com/php-fig/event-dispatcher/issues","source":"https://github.com/php-fig/event-dispatcher/tree/alpha3"}}]},"security-advisories":[],"last-modified":"Wed, 29 Jun 2022 17:22:48 GMT"}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"minified":"composer/2.0","packages":{"symfony/apache-pack":[{"name":"symfony/apache-pack","description":"A pack for Apache support in Symfony","keywords":[],"homepage":"","version":"v1.0.1","version_normalized":"1.0.1.0","license":["MIT"],"authors":[],"source":{"url":"https://github.com/symfony/apache-pack.git","type":"git","reference":"3aa5818d73ad2551281fc58a75afd9ca82622e6c"},"dist":{"url":"https://api.github.com/repos/symfony/apache-pack/zipball/3aa5818d73ad2551281fc58a75afd9ca82622e6c","type":"zip","shasum":"","reference":"3aa5818d73ad2551281fc58a75afd9ca82622e6c"},"type":"symfony-pack","time":"2017-12-12T01:46:35+00:00","support":{"issues":"https://github.com/symfony/apache-pack/issues","source":"https://github.com/symfony/apache-pack/tree/master"}},{"version":"v1.0.0","version_normalized":"1.0.0.0","source":{"url":"https://github.com/symfony/apache-pack.git","type":"git","reference":"450b8490bd887de3f29390e254f9a5025353c173"},"dist":{"url":"https://api.github.com/repos/symfony/apache-pack/zipball/450b8490bd887de3f29390e254f9a5025353c173","type":"zip","shasum":"","reference":"450b8490bd887de3f29390e254f9a5025353c173"},"type":"metapackage","time":"2017-11-23T14:58:24+00:00"}]},"security-advisories":[],"last-modified":"Tue, 19 Jul 2022 12:40:23 GMT"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"minified":"composer/2.0","packages":{"symfony/polyfill-php81":[{"name":"symfony/polyfill-php81","description":"Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions","keywords":["compatibility","portable","polyfill","shim"],"homepage":"https://symfony.com","version":"v1.27.0","version_normalized":"1.27.0.0","license":["MIT"],"authors":[{"name":"Nicolas Grekas","email":"p@tchwork.com"},{"name":"Symfony Community","homepage":"https://symfony.com/contributors"}],"source":{"url":"https://github.com/symfony/polyfill-php81.git","type":"git","reference":"707403074c8ea6e2edaf8794b0157a0bfa52157a"},"dist":{"url":"https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a","type":"zip","shasum":"","reference":"707403074c8ea6e2edaf8794b0157a0bfa52157a"},"type":"library","funding":[{"url":"https://symfony.com/sponsor","type":"custom"},{"url":"https://github.com/fabpot","type":"github"},{"url":"https://tidelift.com/funding/github/packagist/symfony/symfony","type":"tidelift"}],"time":"2022-11-03T14:55:06+00:00","autoload":{"files":["bootstrap.php"],"psr-4":{"Symfony\\Polyfill\\Php81\\":""},"classmap":["Resources/stubs"]},"extra":{"branch-alias":{"dev-main":"1.27-dev"},"thanks":{"name":"symfony/polyfill","url":"https://github.com/symfony/polyfill"}},"require":{"php":">=7.1"},"support":{"source":"https://github.com/symfony/polyfill-php81/tree/v1.27.0"}},{"version":"v1.26.0","version_normalized":"1.26.0.0","source":{"url":"https://github.com/symfony/polyfill-php81.git","type":"git","reference":"13f6d1271c663dc5ae9fb843a8f16521db7687a1"},"dist":{"url":"https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1","type":"zip","shasum":"","reference":"13f6d1271c663dc5ae9fb843a8f16521db7687a1"},"time":"2022-05-24T11:49:31+00:00","extra":{"branch-alias":{"dev-main":"1.26-dev"},"thanks":{"name":"symfony/polyfill","url":"https://github.com/symfony/polyfill"}},"support":{"source":"https://github.com/symfony/polyfill-php81/tree/v1.26.0"}},{"version":"v1.25.0","version_normalized":"1.25.0.0","source":{"url":"https://github.com/symfony/polyfill-php81.git","type":"git","reference":"5de4ba2d41b15f9bd0e19b2ab9674135813ec98f"},"dist":{"url":"https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f","type":"zip","shasum":"","reference":"5de4ba2d41b15f9bd0e19b2ab9674135813ec98f"},"time":"2021-09-13T13:58:11+00:00","extra":{"branch-alias":{"dev-main":"1.23-dev"},"thanks":{"name":"symfony/polyfill","url":"https://github.com/symfony/polyfill"}},"support":{"source":"https://github.com/symfony/polyfill-php81/tree/v1.25.0"}},{"version":"v1.24.0","version_normalized":"1.24.0.0","support":{"source":"https://github.com/symfony/polyfill-php81/tree/v1.24.0"}},{"version":"v1.23.0","version_normalized":"1.23.0.0","source":{"url":"https://github.com/symfony/polyfill-php81.git","type":"git","reference":"e66119f3de95efc359483f810c4c3e6436279436"},"dist":{"url":"https://api.github.com/repos/symfony/polyfill-php81/zipball/e66119f3de95efc359483f810c4c3e6436279436","type":"zip","shasum":"","reference":"e66119f3de95efc359483f810c4c3e6436279436"},"time":"2021-05-21T13:25:03+00:00","support":{"source":"https://github.com/symfony/polyfill-php81/tree/v1.23.0"}},{"version":"v1.22.1","version_normalized":"1.22.1.0","source":{"url":"https://github.com/symfony/polyfill-php81.git","type":"git","reference":"00dedc6d362a1b863dda3f8243516da9fdfbe657"},"dist":{"url":"https://api.github.com/repos/symfony/polyfill-php81/zipball/00dedc6d362a1b863dda3f8243516da9fdfbe657","type":"zip","shasum":"","reference":"00dedc6d362a1b863dda3f8243516da9fdfbe657"},"time":"2021-01-07T16:49:33+00:00","autoload":{"files":["bootstrap.php"],"psr-4":{"Symfony\\Polyfill\\Php81\\":""}},"extra":{"branch-alias":{"dev-main":"1.22-dev"},"thanks":{"name":"symfony/polyfill","url":"https://github.com/symfony/polyfill"}},"support":{"source":"https://github.com/symfony/polyfill-php81/tree/v1.22.1"}},{"version":"v1.22.0","version_normalized":"1.22.0.0","support":{"source":"https://github.com/symfony/polyfill-php81/tree/v1.22.0"}}]},"security-advisories":[],"last-modified":"Thu, 10 Nov 2022 10:19:20 GMT"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"minified":"composer/2.0","packages":{"symfony/rate-limiter":[{"name":"symfony/rate-limiter","description":"Provides a Token Bucket implementation to rate limit input and output in your application","keywords":["limiter","rate-limiter"],"homepage":"https://symfony.com","version":"6.3.x-dev","version_normalized":"6.3.9999999.9999999-dev","license":["MIT"],"authors":[{"name":"Wouter de Jong","email":"wouter@wouterj.nl"},{"name":"Symfony Community","homepage":"https://symfony.com/contributors"}],"source":{"url":"https://github.com/symfony/rate-limiter.git","type":"git","reference":"3ef69420bd95f6c1a6b03688a026b3c1b2bedf54"},"dist":{"url":"https://api.github.com/repos/symfony/rate-limiter/zipball/3ef69420bd95f6c1a6b03688a026b3c1b2bedf54","type":"zip","shasum":"","reference":"3ef69420bd95f6c1a6b03688a026b3c1b2bedf54"},"type":"library","funding":[{"url":"https://symfony.com/sponsor","type":"custom"},{"url":"https://github.com/fabpot","type":"github"},{"url":"https://tidelift.com/funding/github/packagist/symfony/symfony","type":"tidelift"}],"time":"2022-10-24T08:47:45+00:00","autoload":{"psr-4":{"Symfony\\Component\\RateLimiter\\":""},"exclude-from-classmap":["/Tests/"]},"require":{"php":">=8.1","symfony/options-resolver":"^5.4|^6.0"},"require-dev":{"psr/cache":"^1.0|^2.0|^3.0","symfony/lock":"^5.4|^6.0"},"suggest":{"symfony/lock":"For preventing race conditions in rate limiters"},"support":{"source":"https://github.com/symfony/rate-limiter/tree/v6.2.0-BETA1"}},{"version":"6.2.x-dev","version_normalized":"6.2.9999999.9999999-dev","default-branch":true,"support":{"source":"https://github.com/symfony/rate-limiter/tree/v6.2.0"}},{"version":"6.1.x-dev","version_normalized":"6.1.9999999.9999999-dev","source":{"url":"https://github.com/symfony/rate-limiter.git","type":"git","reference":"9e75706446f7c3686773c408f422ffb5ec4ba32b"},"dist":{"url":"https://api.github.com/repos/symfony/rate-limiter/zipball/9e75706446f7c3686773c408f422ffb5ec4ba32b","type":"zip","shasum":"","reference":"9e75706446f7c3686773c408f422ffb5ec4ba32b"},"time":"2022-07-20T13:46:29+00:00","require":{"symfony/lock":"^5.4|^6.0","symfony/options-resolver":"^5.4|^6.0","php":">=8.1"},"require-dev":{"psr/cache":"^1.0|^2.0|^3.0"},"support":{"source":"https://github.com/symfony/rate-limiter/tree/v6.1.3"},"suggest":"__unset"},{"version":"6.0.x-dev","version_normalized":"6.0.9999999.9999999-dev","source":{"url":"https://github.com/symfony/rate-limiter.git","type":"git","reference":"4ec5e896c183969fff9402e23e83b4ef715309e8"},"dist":{"url":"https://api.github.com/repos/symfony/rate-limiter/zipball/4ec5e896c183969fff9402e23e83b4ef715309e8","type":"zip","shasum":"","reference":"4ec5e896c183969fff9402e23e83b4ef715309e8"},"time":"2022-07-20T13:45:53+00:00","require":{"php":">=8.0.2","symfony/lock":"^5.4|^6.0","symfony/options-resolver":"^5.4|^6.0"},"support":{"source":"https://github.com/symfony/rate-limiter/tree/6.0"},"default-branch":"__unset"},{"version":"5.4.x-dev","version_normalized":"5.4.9999999.9999999-dev","source":{"url":"https://github.com/symfony/rate-limiter.git","type":"git","reference":"a79d4fe5a330f95ca85a87b1321911bdeadb4db9"},"dist":{"url":"https://api.github.com/repos/symfony/rate-limiter/zipball/a79d4fe5a330f95ca85a87b1321911bdeadb4db9","type":"zip","shasum":"","reference":"a79d4fe5a330f95ca85a87b1321911bdeadb4db9"},"time":"2022-12-09T07:37:05+00:00","require":{"php":">=7.2.5","symfony/lock":"^5.2|^6.0","symfony/options-resolver":"^5.1|^6.0"},"support":{"source":"https://github.com/symfony/rate-limiter/tree/5.4"}},{"version":"5.3.x-dev","version_normalized":"5.3.9999999.9999999-dev","source":{"url":"https://github.com/symfony/rate-limiter.git","type":"git","reference":"8548671cdaf45a9e35053268b2b3cd7785df5193"},"dist":{"url":"https://api.github.com/repos/symfony/rate-limiter/zipball/8548671cdaf45a9e35053268b2b3cd7785df5193","type":"zip","shasum":"","reference":"8548671cdaf45a9e35053268b2b3cd7785df5193"},"time":"2022-01-02T09:52:31+00:00","require":{"php":">=7.2.5","symfony/lock":"^5.2","symfony/options-resolver":"^5.1"},"support":{"source":"https://github.com/symfony/rate-limiter/tree/5.3"}},{"version":"5.2.x-dev","version_normalized":"5.2.9999999.9999999-dev","source":{"url":"https://github.com/symfony/rate-limiter.git","type":"git","reference":"fba2944fb7e2edc84f92b2ba3ab028a739f45637"},"dist":{"url":"https://api.github.com/repos/symfony/rate-limiter/zipball/fba2944fb7e2edc84f92b2ba3ab028a739f45637","type":"zip","shasum":"","reference":"fba2944fb7e2edc84f92b2ba3ab028a739f45637"},"time":"2021-07-15T22:07:55+00:00","support":{"source":"https://github.com/symfony/rate-limiter/tree/5.2"}}]},"last-modified":"Fri, 09 Dec 2022 07:37:56 GMT"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
Deny from all

32
.env
View File

@ -18,17 +18,25 @@ APP_ENV=dev
APP_SECRET=406ccaa0c76a451fdcc2307ea146cbef APP_SECRET=406ccaa0c76a451fdcc2307ea146cbef
###< symfony/framework-bundle ### ###< symfony/framework-bundle ###
# string pour la requête sql qui va récupérer le mot de passe # configuration bdd
queryHashPassword="SELECT password from USER WHERE email = :email;" dsn="pgsql:host='postgres';port=5432;dbname=lasql"
queryFetchDatas="SELECT email,lastname,firstname,random, password from USER WHERE email = :email;" db_user="lasql"
urlDatabase="mysql:host=db;port=3306;dbname=remote;" db_password="lasql"
dbUser="remote"
dbPassword="remote"
url_login_challenge_accept="http://sso.mse.local:4445/oauth2/auth/requests/login/accept?login_challenge=" # connexion hydra
url_login_challenge="http://sso.mse.local:4445/oauth2/auth/requests/login?login_challenge=" HYDRA_ADMIN_BASE_URL='http://hydra:4445'
url_login_challenge_reject="http://sso.mse.local:4445/oauth2/auth/requests/login/reject?login_challenge=" LOGOUT_REDIRECT_URL_PATTERN='http://localhost:4445/logout?return=%s'
url_consent_challenge_reject="http://sso.mse.local:4445/oauth2/auth/requests/consent/reject?consent_challenge="
url_consent_challenge="http://sso.mse.local:4445/oauth2/auth/requests/consent?consent_challenge=" url_login_challenge_accept="http://hydra:4445/oauth2/auth/requests/login/accept?login_challenge="
url_consent_challenge_accept="http://sso.mse.local:4445/oauth2/auth/requests/consent/accept?consent_challenge=" url_login_challenge="http://hydra:4445/oauth2/auth/requests/login?login_challenge="
url_login_challenge_reject="http://hydra:4445/oauth2/auth/requests/login/reject?login_challenge="
url_consent_challenge_reject="http://hydra:4445/oauth2/auth/requests/consent/reject?consent_challenge="
url_consent_challenge="http://hydra:4445/oauth2/auth/requests/consent?consent_challenge="
url_consent_challenge_accept="http://hydra:4445/oauth2/auth/requests/consent/accept?consent_challenge="
###> symfony/lock ###
# Choose one of the stores below
# postgresql+advisory://db_user:db_password@localhost/db_name
LOCK_DSN=flock
###< symfony/lock ###

View File

@ -0,0 +1 @@
Deny from all

View File

@ -10,11 +10,13 @@
"doctrine/annotations": "^1.13", "doctrine/annotations": "^1.13",
"symfony/apache-pack": "^1.0", "symfony/apache-pack": "^1.0",
"symfony/console": "5.4.*", "symfony/console": "5.4.*",
"symfony/dependency-injection": "5.4.*",
"symfony/dotenv": "5.4.*", "symfony/dotenv": "5.4.*",
"symfony/flex": "^1.17|^2", "symfony/flex": "^1.17|^2",
"symfony/form": "5.4.*", "symfony/form": "5.4.*",
"symfony/framework-bundle": "5.4.*", "symfony/framework-bundle": "5.4.*",
"symfony/http-client": "5.4.*", "symfony/http-client": "5.4.*",
"symfony/rate-limiter": "5.4.*",
"symfony/runtime": "5.4.*", "symfony/runtime": "5.4.*",
"symfony/security-bundle": "5.4.*", "symfony/security-bundle": "5.4.*",
"symfony/twig-bundle": "5.4.*", "symfony/twig-bundle": "5.4.*",

163
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "90cbb93fd73462f1836880cd629e8594", "content-hash": "70867e31e3b952d600febc856fbb544a",
"packages": [ "packages": [
{ {
"name": "doctrine/annotations", "name": "doctrine/annotations",
@ -733,16 +733,16 @@
}, },
{ {
"name": "symfony/dependency-injection", "name": "symfony/dependency-injection",
"version": "v5.4.7", "version": "v5.4.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/dependency-injection.git", "url": "https://github.com/symfony/dependency-injection.git",
"reference": "35588b2afb08ea3a142d62fefdcad4cb09be06ed" "reference": "a93e1863500940780fc1235f52d54397be2d14b3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/35588b2afb08ea3a142d62fefdcad4cb09be06ed", "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a93e1863500940780fc1235f52d54397be2d14b3",
"reference": "35588b2afb08ea3a142d62fefdcad4cb09be06ed", "reference": "a93e1863500940780fc1235f52d54397be2d14b3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -802,7 +802,7 @@
"description": "Allows you to standardize and centralize the way objects are constructed in your application", "description": "Allows you to standardize and centralize the way objects are constructed in your application",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/dependency-injection/tree/v5.4.7" "source": "https://github.com/symfony/dependency-injection/tree/v5.4.16"
}, },
"funding": [ "funding": [
{ {
@ -818,7 +818,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-03-08T15:43:06+00:00" "time": "2022-11-25T07:33:13+00:00"
}, },
{ {
"name": "symfony/deprecation-contracts", "name": "symfony/deprecation-contracts",
@ -1989,6 +1989,85 @@
], ],
"time": "2022-04-02T06:04:20+00:00" "time": "2022-04-02T06:04:20+00:00"
}, },
{
"name": "symfony/lock",
"version": "v5.4.15",
"source": {
"type": "git",
"url": "https://github.com/symfony/lock.git",
"reference": "109a20faa6119578b46457ef8cffb9389e20e5ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/lock/zipball/109a20faa6119578b46457ef8cffb9389e20e5ca",
"reference": "109a20faa6119578b46457ef8cffb9389e20e5ca",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"psr/log": "^1|^2|^3",
"symfony/deprecation-contracts": "^2.1|^3",
"symfony/polyfill-php80": "^1.16"
},
"conflict": {
"doctrine/dbal": "<2.13"
},
"require-dev": {
"doctrine/dbal": "^2.13|^3.0",
"predis/predis": "~1.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Lock\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jérémy Derussé",
"email": "jeremy@derusse.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Creates and manages locks, a mechanism to provide exclusive access to a shared resource",
"homepage": "https://symfony.com",
"keywords": [
"cas",
"flock",
"locking",
"mutex",
"redlock",
"semaphore"
],
"support": {
"source": "https://github.com/symfony/lock/tree/v5.4.15"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-10-27T07:55:40+00:00"
},
{ {
"name": "symfony/options-resolver", "name": "symfony/options-resolver",
"version": "v5.4.3", "version": "v5.4.3",
@ -2879,6 +2958,76 @@
], ],
"time": "2022-03-30T13:40:48+00:00" "time": "2022-03-30T13:40:48+00:00"
}, },
{
"name": "symfony/rate-limiter",
"version": "v5.4.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/rate-limiter.git",
"reference": "1a3a43eeb498290100e4a1559f4a48be14900bc2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/rate-limiter/zipball/1a3a43eeb498290100e4a1559f4a48be14900bc2",
"reference": "1a3a43eeb498290100e4a1559f4a48be14900bc2",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/lock": "^5.2|^6.0",
"symfony/options-resolver": "^5.1|^6.0"
},
"require-dev": {
"psr/cache": "^1.0|^2.0|^3.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\RateLimiter\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Wouter de Jong",
"email": "wouter@wouterj.nl"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Provides a Token Bucket implementation to rate limit input and output in your application",
"homepage": "https://symfony.com",
"keywords": [
"limiter",
"rate-limiter"
],
"support": {
"source": "https://github.com/symfony/rate-limiter/tree/v5.4.11"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-07-20T13:00:38+00:00"
},
{ {
"name": "symfony/routing", "name": "symfony/routing",
"version": "v5.4.3", "version": "v5.4.3",

Binary file not shown.

View File

@ -0,0 +1,2 @@
framework:
lock: '%env(LOCK_DSN)%'

View File

@ -5,15 +5,30 @@ security:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers: providers:
users_in_memory: { memory: null } pdo_user_provider:
id: App\Security\PdoUserProvider
firewalls: firewalls:
dev: dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/ pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false security: false
main: main:
lazy: true # lazy: true
provider: users_in_memory stateless: false
provider: pdo_user_provider
custom_authenticators:
- App\Security\PdoUserAuthenticator
entry_point: form_login
form_login:
login_path: app_login
check_path: app_login
username_parameter: login
password_parameter: password
enable_csrf: true
login_throttling:
max_attempts: 3
logout: true
# activate different ways to authenticate # activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall # https://symfony.com/doc/current/security.html#the-firewall
@ -23,8 +38,9 @@ security:
# Easy way to control access for large sections of your site # Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used # Note: Only the *first* access control that matches will be used
access_control: access_control:
# - { path: ^/admin, roles: ROLE_ADMIN } - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
# - { path: ^/profile, roles: ROLE_USER } - { path: ^/connect, roles: ROLE_USER }
# - { path: ^/connect, roles: [IS_AUTHENTICATED_FULLY, ROLE_USER] }
when@test: when@test:
security: security:

View File

@ -0,0 +1,8 @@
pdo:
column_login_name: email
column_password_name: password
table_name: usager
data_to_fetch:
- email
- lastname
- firstname

View File

@ -6,19 +6,24 @@
parameters: parameters:
fetchDatas: "lastname, firstname, email, random" fetchDatas: "lastname, firstname, email, random"
# Paramètres de connexion base de données: "nome du serveur", "nom utilisateur", "mot de passe", "nom de la bdd", "port" # Paramètres de connexion base de données: "nome du serveur", "nom utilisateur", "mot de passe", "nom de la bdd", "port"
urlDatabase: "%env(resolve:urlDatabase)%" database.dsn: "%env(resolve:dsn)%"
dbUser: "%env(resolve:dbUser)%" database.user: "%env(resolve:db_user)%"
dbPassword: "%env(resolve:dbPassword)%" database.password: "%env(resolve:db_password)%"
queryHashPassword: "%env(resolve:queryHashPassword)%"
queryFetchDatas: "%env(resolve:queryFetchDatas)%" # algorythme de hahshage utilisé "md5", "sha256", "haval160,4", etc.
hashMethod: hashAlgo: "sha256"
passwordColumnName: "password" passwordColumnName: "password"
userTableName: "USER" userTableName: "USER"
emailColumnName: "email" emailColumnName: "email"
urlLogoutSuccess: "http://portal.mse.local:8000/logout-success" urlLogoutSuccess: "http://portal.mse.local:8000/logout-success"
urlIssuer: urlIssuer:
- "http://portal.mse.local:8000/" - "http://localhost:8000/"
hydra_admin_base_url: '%env(HYDRA_ADMIN_BASE_URL)%'
logout_redirect_url_pattern: '%env(LOGOUT_REDIRECT_URL_PATTERN)%'
base_url: '%env(BASE_URL)%'
env(BASE_URL): 'http://localhost:8080'
url_login_challenge: '%env(resolve:url_login_challenge)%' url_login_challenge: '%env(resolve:url_login_challenge)%'
url_login_challenge_reject: '%env(resolve:url_login_challenge_reject)%' url_login_challenge_reject: '%env(resolve:url_login_challenge_reject)%'
url_login_challenge_accept: '%env(resolve:url_login_challenge_accept)%' url_login_challenge_accept: '%env(resolve:url_login_challenge_accept)%'
@ -40,5 +45,19 @@ services:
- '../src/Entity/' - '../src/Entity/'
- '../src/Kernel.php' - '../src/Kernel.php'
App\Security\PdoUserAuthenticator:
arguments:
$baseUrl: '%base_url%'
App\Pdo\PdoRequest:
arguments:
$config: []
$dsn: "%database.dsn%"
$user: "%database.user%"
$password: "%database.password%"
App\Hydra\Client:
arguments:
$client: '@http_client'
$hydraAdminBaseUrl: '%hydra_admin_base_url%'
# add more service definitions when explicit configuration is needed # add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones # please note that last definitions always *replace* previous ones

View File

@ -0,0 +1,18 @@
{
"client_id": "oidc-test",
"client_name": "OIDC Test",
"client_secret": "oidc-test-123456",
"grant_types": [
"authorization_code",
"refresh_token"
],
"jwks": {},
"metadata": {},
"token_endpoint_auth_method": "client_secret_basic",
"post_logout_redirect_uris": ["http://localhost:8000"],
"redirect_uris": ["http://localhost:8000/oauth2/callback"],
"response_types": [
"code"
],
"scope": "openid email"
}

View File

@ -0,0 +1 @@
postgres:5432:lasql:lasql:lasql

View File

@ -0,0 +1,14 @@
{
"Servers": {
"1": {
"Name": "postgres",
"Group": "Servers",
"Host": "postgres",
"Port": 5432,
"MaintenanceDB": "postgres",
"Username": "lasql",
"PassFile": "/pgpass",
"SSLMode": "prefer"
}
}
}

View File

@ -0,0 +1,7 @@
-- IF NOT EXISTS (SELECT * FROM pg_user WHERE usename = 'lasql')then
-- CREATE USER lasql WITH PASSWORD 'lasql';
-- END IF;
-- GRANT ALL PRIVILEGES ON DATABASE lasql TO lasql;
-- ALTER USER lasql WITH SUPERUSER;

View File

@ -0,0 +1,2 @@
SELECT 'CREATE DATABASE hydra' WHERE NOT EXISTS (SELECT * FROM pg_database WHERE datname = 'hydra')\gexec
GRANT ALL PRIVILEGES ON DATABASE hydra TO lasql

View File

@ -0,0 +1,12 @@
CREATE TABLE IF NOT EXISTS usager (
email VARCHAR ( 100 ) UNIQUE NOT NULL,
password VARCHAR ( 255 ) NOT NULL,
lastname VARCHAR ( 255 ) NOT NULL,
firstname VARCHAR ( 255 ) NOT NULL
);
INSERT INTO usager (email, password, lastname, firstname) VALUES
('test1@test.com', '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92', 'Locke', 'John'),
('test2@test.com', '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92', 'Dubois', 'Angela'),
('test3@test.com', '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92', 'Dupont', 'Henri'),
('test4@test.com', '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92', 'Durand', 'Isabelle');
GRANT ALL PRIVILEGES ON DATABASE usager TO lasql

View File

@ -20,8 +20,8 @@
# regular expression must be changed accordingly: # regular expression must be changed accordingly:
# ProxyPassMatch ^/path-to-app/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/project/public/$1 # ProxyPassMatch ^/path-to-app/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/project/public/$1
DocumentRoot /loginappsql/public DocumentRoot /var/www/public
<Directory /loginappsql/public> <Directory /var/www/public>
# enable the .htaccess rewrites # enable the .htaccess rewrites
AllowOverride All AllowOverride All
Require all granted Require all granted

View File

@ -23,8 +23,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
php${PHP_VERSION}-xml php${PHP_VERSION}-bcmath \ php${PHP_VERSION}-xml php${PHP_VERSION}-bcmath \
php${PHP_VERSION}-zip php${PHP_VERSION}-fpm \ php${PHP_VERSION}-zip php${PHP_VERSION}-fpm \
php${PHP_VERSION}-mbstring \ php${PHP_VERSION}-mbstring \
php${PHP_VERSION}-mysql \ php${PHP_VERSION}-pgsql \
php${PHP_VERSION}-pdo-mysql \ php${PHP_VERSION}-pdo-pgsql \
php${PHP_VERSION}-ssh2 libxml2-utils \ php${PHP_VERSION}-ssh2 libxml2-utils \
locales \ locales \
apache2 \ apache2 \
@ -48,15 +48,15 @@ RUN wget -q -O /usr/local/bin/waitforit https://github.com/maxcnunes/waitforit/r
# Install superfsmon to restart supervisor programs on file changes # Install superfsmon to restart supervisor programs on file changes
RUN pip3 install wheel superfsmon RUN pip3 install wheel superfsmon
VOLUME /loginappsql VOLUME /var/www
VOLUME /loginappsql/var/logs VOLUME /var/www/var/logs
VOLUME /loginappsql/var/cache VOLUME /var/www/var/cache
# Install composer # Install composer
COPY install-composer.sh /loginappsql/install-composer.sh COPY install-composer.sh /var/www/install-composer.sh
RUN chmod +x /loginappsql/install-composer.sh &&\ RUN chmod +x /var/www/install-composer.sh &&\
/loginappsql/install-composer.sh &&\ /var/www/install-composer.sh &&\
rm -f /loginappsql/install-composer.sh rm -f /var/www/install-composer.sh
# On active les mods d'apache nécessaires # On active les mods d'apache nécessaires
RUN a2enmod rewrite RUN a2enmod rewrite
@ -73,7 +73,7 @@ COPY www.conf /etc/php/8.1/fpm/pool.d/www.conf
EXPOSE 5000 EXPOSE 5000
EXPOSE 80 EXPOSE 80
WORKDIR /loginappsql WORKDIR /var/www
# On démarre php-fpm une fois pour créer les sockets # On démarre php-fpm une fois pour créer les sockets
RUN service php8.1-fpm start RUN service php8.1-fpm start
@ -90,7 +90,7 @@ RUN chmod +x /root/first-run.sh
RUN sed -i 's/^\$\(PrivDropTo.*\)$/#\1/' /etc/rsyslog.conf RUN sed -i 's/^\$\(PrivDropTo.*\)$/#\1/' /etc/rsyslog.conf
RUN sed -i '/imklog/s/^/#/' /etc/rsyslog.conf RUN sed -i '/imklog/s/^/#/' /etc/rsyslog.conf
COPY rsyslog.conf /etc/rsyslog.d/loginappsql.conf COPY rsyslog.conf /etc/rsyslog.d/var/www.conf
COPY supervisor.ini /etc/supervisor/supervisor.ini COPY supervisor.ini /etc/supervisor/supervisor.ini
COPY php.ini /etc/php/8.1/fpm/php.ini COPY php.ini /etc/php/8.1/fpm/php.ini

View File

@ -8,8 +8,8 @@ set -xeo pipefail
[ ! -d /var/www/.cache ] && sudo mkdir -p /var/www/.cache [ ! -d /var/www/.cache ] && sudo mkdir -p /var/www/.cache
[ -d /var/www/.cache ] && sudo chown -R www-data: /var/www/.cache [ -d /var/www/.cache ] && sudo chown -R www-data: /var/www/.cache
sudo chown -R www-data: /loginappsql sudo chown -R www-data: /var/www
cp /bin/composer.phar /loginappsql/composer.phar cp /bin/composer.phar /var/www/composer.phar
cd /loginappsql cd /var/www
php composer.phar install php composer.phar install

View File

@ -1,7 +1,6 @@
user: www-data user: www-data
group: www-data group: www-data
paths: paths:
- /loginappsql/node_modules - /var/www/node_modules
- /loginappsql/vendor - /var/www/vendor
- /loginappsql
- /var/www - /var/www

View File

@ -16,7 +16,7 @@ stderr_logfile_maxbytes=0
[program:apache2] [program:apache2]
environment=HOSTNAME="%(ENV_HOSTNAME)s" environment=HOSTNAME="%(ENV_HOSTNAME)s"
command = apachectl -D "FOREGROUND" command = apachectl -D "FOREGROUND"
directory = /loginappsql directory = /var/www
user = root user = root
autostart = true autostart = true
stdout_logfile=/dev/stdout stdout_logfile=/dev/stdout
@ -29,7 +29,7 @@ environment=HOSTNAME="%(ENV_HOSTNAME)s"
command = /usr/sbin/php-fpm8.1 -F command = /usr/sbin/php-fpm8.1 -F
autostart = true autostart = true
autorestart = true autorestart = true
directory = /loginappsql directory = /var/www
user = root user = root
stdout_logfile=/dev/stdout stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0 stdout_logfile_maxbytes=0

View File

@ -1,41 +1,107 @@
version: "3.8" version: "3.8"
services: services:
loginappsql: loginappsql:
container_name: loginappsql container_name: loginappsql
build: build:
context: ./containers/loginappsql context: ./containers/loginappsql
args: args:
- HTTP_PROXY=${HTTP_PROXY}
- HTTPS_PROXY=${HTTPS_PROXY}
- http_proxy=${http_proxy}
- https_proxy=${https_proxy}
user: ${FIXUID:-1000}:${FIXGID:-1000}
ports:
- 8080:80
volumes:
- .:/var/www
- /etc/localtime:/etc/localtime:ro
- $HOME/.ssh:/root/.host-ssh:ro
tmpfs:
- /var/www/var/logs:uid=${FIXUID:-1000},gid=${FIXGID:-1000}
- /var/www/var/cache:uid=${FIXUID:-1000},gid=${FIXGID:-1000}
- /var/www/public/build:uid=${FIXUID:-1000},gid=${FIXGID:-1000}
- /tmp
links:
- hydra
extra_hosts:
- "localhost:127.0.0.1"
- "localhost:host-gateway"
- "host.docker.internal:host-gateway"
environment:
- HTTP_PROXY=${HTTP_PROXY} - HTTP_PROXY=${HTTP_PROXY}
- HTTPS_PROXY=${HTTPS_PROXY} - HTTPS_PROXY=${HTTPS_PROXY}
- http_proxy=${http_proxy} - http_proxy=${http_proxy}
- https_proxy=${https_proxy} - https_proxy=${https_proxy}
user: ${FIXUID:-1000}:${FIXGID:-1000} - TZ=Europe/Paris
ports: - HYDRA_ADMIN_BASE_URL=http://hydra:4445
- 5002:80 - TRUSTED_PROXIES=127.0.0.1,REMOTE_ADDR,localhost
volumes:
- .:/loginappsql
- /etc/localtime:/etc/localtime:ro
- $HOME/.ssh:/root/.host-ssh:ro
tmpfs:
- /loginappsql/var/logs:uid=${FIXUID:-1000},gid=${FIXGID:-1000}
- /loginappsql/var/cache:uid=${FIXUID:-1000},gid=${FIXGID:-1000}
- /loginappsql/public/build:uid=${FIXUID:-1000},gid=${FIXGID:-1000}
- /tmp
extra_hosts: oidc-test:
- "loginappsql.local:127.0.0.1" image: bornholm/oidc-test:v0.0.0-1-g936a77e
- "sso.mse.local:host-gateway" environment:
- "host.docker.internal:host-gateway" - LOG_LEVEL=0
environment: - HTTP_ADDRESS=0.0.0.0:8000
- HTTP_PROXY=${HTTP_PROXY} - OIDC_CLIENT_ID=oidc-test
- HTTPS_PROXY=${HTTPS_PROXY} - OIDC_CLIENT_SECRET=oidc-test-123456
- http_proxy=${http_proxy} - OIDC_ISSUER_URL=http://localhost:8081/
- https_proxy=${https_proxy} - OIDC_REDIRECT_URL=http://localhost:8000
- TZ=Europe/Paris - OIDC_POST_LOGOUT_REDIRECT_URL=http://localhost:8000
networks: depends_on:
- mse-network hydra:
condition: service_healthy
network_mode: host
networks: restart: unless-stopped
mse-network: hydra:
external: image: docker.io/cadoles/hydra-v1:latest
name: mse_default volumes:
- ./containers/compose/hydra/clients.d:/etc/hydra/clients.d
environment:
- LOG_LEAK_SENSITIVE_VALUES=true
- HYDRA_ALLOW_INSECURE=yes
- HYDRA_URLS_SELF_ISSUER=http://localhost:8081/
- HYDRA_URLS_LOGOUT=http://localhost:8080/logout
- HYDRA_URLS_LOGIN=http://localhost:8080/
- HYDRA_URLS_CONSENT=http://localhost:8080/connect/consent
- HYDRA_LEVEL=debug
- HYDRA_DSN=postgres://lasql:lasql@postgres:5432/hydra
- HYDRA_WAIT4X_DATABASE_DSN=postgres://lasql:lasql@postgres:5432/hydra?sslmode=disable
- HYDRA_WAIT4X_DATABASE_TYPE=postgresql
ports:
- 8081:4444
links:
- postgres
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:4444/.well-known/openid-configuration"]
interval: 10s
timeout: 10s
retries: 10
start_period: 10s
restart: unless-stopped
postgres:
image: postgres:15-alpine
restart: always
environment:
POSTGRES_USER: lasql
POSTGRES_DB: lasql
POSTGRES_PASSWORD: lasql
volumes:
- ./containers/compose/postgres/init-db.d:/docker-entrypoint-initdb.d/:ro
- postgres:/var/lib/pgsql/data
- /etc/localtime:/etc/localtime:ro
pgadmin:
image: dpage/pgadmin4
ports:
- 8085:80
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: admin@admin.com
PGADMIN_DEFAULT_PASSWORD: admin
PGADMIN_SERVER_JSON_FILE: /pgadminfile/server.json
volumes:
- ./containers/compose/pgadmin:/pgadminfile/:ro
volumes:
postgres:

View File

@ -3,171 +3,55 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\User; use App\Entity\User;
use App\Form\UserType; use App\Hydra\Client;
use App\Services\PdoServices; use App\Hydra\HydraService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class MainController extends AbstractController class MainController extends AbstractController
{ {
/** public HydraService $hydra;
* @var Session public Client $client;
*/ public SessionInterface $session;
private $session;
/** public function __construct(SessionInterface $session, HydraService $hydra, Client $client)
* @var UrlGeneratorInterface
*/
private $router;
/**
* @var HttpClientInterface
*/
public $client;
private $pdoServices;
public function __construct(PdoServices $pdoServices, HttpClientInterface $client, SessionInterface $session, UrlGeneratorInterface $router)
{ {
$this->pdoServices = $pdoServices;
$this->session = $session; $this->session = $session;
$this->client = $client; $this->client = $client;
$this->router = $router; $this->hydra = $hydra;
} }
/** /**
* @Route("/oauth/login", name="app_login") * @Route("/", name="app_home")
*/ */
public function loginOidc(Request $request) public function home(Request $request)
{ {
$challenge = $request->query->get('login_challenge'); return $this->hydra->handleLoginRequest($request);
// S'il n'y a pas de challenge, on déclenche une bad request
if (!$challenge) {
throw new BadRequestException('pas de challenge');
}
// On vérifie que la requête d'identification provient bien de hydra
$response = $this->client->request('GET', $this->getParameter('url_login_challenge').$challenge, [
'headers' => [
'Content-Type: application/json',
],
]);
if (200 !== $response->getStatusCode()) {
$this->session->clear();
throw new BadRequestException('pa de code 200');
}
// si le challenge est validé par hydra, on le stocke en session pour l'utiliser par la suite et on redirige vers une route interne protégée qui va déclencher l'identification FranceConnect
$this->session->set('challenge', $challenge);
return $this->redirectToRoute('oauth_login');
} }
/** /**
* @Route("/oauth/connect", name="oauth_login") * @Route("/connect/login-accept", name="app_login_accept")
*/ */
public function oauth(Request $request) public function loginAccept(Request $request)
{ {
if ($request->headers->get('referer') !== $this->router->generate('oauth_login', [], 0) && !in_array($request->headers->get('referer'), $this->getParameter('urlIssuer'))) { /** @var User */
throw new BadRequestException('Vous devez passer par le issuer pour vous connecter'); $user = $this->getUser();
} $loginAcceptRes = $this->client->acceptLoginRequest($this->session->get('challenge'), [
'subject' => $user->getLogin(),
'remember' => true,
])->toArray();
$user = new User(); return new RedirectResponse($loginAcceptRes['redirect_to']);
$loginForm = $this->createForm(UserType::class, $user);
$loginForm->handleRequest($request);
if ($loginForm->isSubmitted() && $loginForm->isValid()) {
$email = $loginForm->get('email')->getData();
try {
// requête préparée
$datas = $this->pdoServices->fetchDatas($email);
if (!$datas) {
// Si le hash du password n'est pas trouvé, c'est que l'email n'existe pas, on retourne la page de login avec une erreur
return $this->render('login.html.twig', [
'form' => $loginForm->createView(),
'error_mail' => 'mail non trouvé',
]);
}
$hashPassword = $datas[$this->getParameter('passwordColumnName')];
$password = $loginForm->get('password')->getData();
if ($this->pdoServices->verifyPassword($password, $hashPassword)) {
// On défait la mot de passe qui ne servira plus
unset($datas[$this->getParameter('passwordColumnName')]);
$this->session->set('datas', $datas);
$response = $this->client->request('PUT', $this->getParameter('url_login_challenge_accept').$this->session->get('challenge'), [
'json' => [
'subject' => $email,
'acr' => 'string',
],
]);
// On initie l'acceptation du login challenge émis par hydra et on récupère l'url de redirection
$redirect_to = $response->toArray()['redirect_to'];
return $this->redirect($redirect_to, 301);
} else {
return $this->render('login.html.twig', [
'form' => $loginForm->createView(),
'error_password' => 'Le mot de passe est incorrect',
]);
}
} catch (\Exception $e) {
dd($e);
}
}
return $this->render('login.html.twig', [
'form' => $loginForm->createView(),
]);
} }
/** /**
* @Route("/oauth/consent", name="consent") * @Route("/connect/consent", name="app_consent")
*/ */
public function consent(Request $request) public function consent(Request $request)
{ {
$challenge = $request->query->get('consent_challenge'); return $this->hydra->handleConsentRequest($request);
if (!$challenge) {
throw new BadRequestException("Le challenge n'est pas disponible");
}
// Vérification du consent_challenge avec hydra
$response = $this->client->request('GET', $this->getParameter('url_consent_challenge').$challenge, [
'headers' => [
'Content-Type: application/json',
],
]);
if (200 !== $response->getStatusCode()) {
$this->session->clear();
throw new BadRequestException("Le challenge n'est pas authorisé");
}
$response = $this->client->request('PUT', $this->getParameter('url_consent_challenge_accept').$challenge, [
'headers' => [
'Content-Type: application/json',
],
'json' => [
'grant_scope' => ['openid', 'offline_access'],
'session' => [
'id_token' => [
'user' => $this->session->get('datas'),
],
],
],
]);
$redirect_to = $response->toArray()['redirect_to'];
return $this->redirect($redirect_to, 301);
}
/**
* @Route("/oauth/logout", name="app_logout")
*/
public function logout()
{
$this->session->clear();
return $this->redirect($this->getParameter('urlLogoutSuccess'));
} }
} }

View File

@ -0,0 +1,34 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
{
/**
* @Route("/login", name="app_login")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
if ($error) {
}
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/logout", name="app_logout")
*/
public function logout(Request $request)
{
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\DependencyInjection;
use App\Pdo\PdoRequest;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class PdoConfiguration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('pdo');
$treeBuilder->getRootNode()->children()
->scalarNode(PdoRequest::COLUMN_LOGIN_NAME)->isRequired()->cannotBeEmpty()->end()
->scalarNode(PdoRequest::COLUMN_PASSWORD_NAME)->isRequired()->cannotBeEmpty()->end()
->scalarNode(PdoRequest::TABLE_NAME)->isRequired()->cannotBeEmpty()->end()
->arrayNode(PdoRequest::DATA_TO_FETCH)
->scalarPrototype()->end()
->end()
->end();
return $treeBuilder;
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\DependencyInjection;
use App\Pdo\PdoRequest;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
class PdoExtension extends Extension implements CompilerPassInterface
{
/** @var array */
protected $pdoConfig;
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new PdoConfiguration();
$config = $this->processConfiguration($configuration, $configs);
$this->pdoConfig = $config;
}
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition(PdoRequest::class);
$definition->replaceArgument('$config', $this->pdoConfig);
}
}

View File

@ -2,25 +2,27 @@
namespace App\Entity; namespace App\Entity;
use App\Validator as AcmeAssert; use Symfony\Component\Security\Core\User\UserInterface;
class User class User implements UserInterface
{ {
private string $email; /** @var array */
protected $attributes;
private string $login;
private string $password; private string $password;
private string $rememberMe; private bool $rememberMe;
public function getEmail(): ?string public function __construct($login, $password, $attributes, $rememberMe = false)
{ {
return $this->email; $this->password = $password;
$this->login = $login;
$this->attributes = $attributes;
$this->rememberMe = $rememberMe;
} }
public function setEmail(string $email): self public function getLogin(): ?string
{ {
$this->email = $email; return $this->login;
return $this;
} }
public function getPassword(): string public function getPassword(): string
@ -28,22 +30,37 @@ class User
return $this->password; return $this->password;
} }
public function setPassword(string $password): self public function getAttributes(): array
{ {
$this->password = $password; return $this->attributes;
return $this;
} }
public function getRememberMe(): string public function getRememberMe(): bool
{ {
return $this->rememberMe; return $this->rememberMe;
} }
public function setRememberMe(bool $rememberMe): self public function getRoles(): array
{ {
$this->rememberMe = $rememberMe; return ['ROLE_USER'];
}
return $this; public function getSalt(): ?string
{
return null;
}
public function eraseCredentials()
{
}
public function getUsername(): string
{
return $this->login;
}
public function getUserIdentifier(): string
{
return $this->login;
} }
} }

View File

@ -0,0 +1,36 @@
<?php
namespace App\EventListener;
use App\Hydra\HydraService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Event\LogoutEvent;
class LogoutSubscriber implements EventSubscriberInterface
{
public function __construct(
private UrlGeneratorInterface $urlGenerator,
private HydraService $hydra
) {
}
public static function getSubscribedEvents(): array
{
return [LogoutEvent::class => 'onLogout'];
}
public function onLogout(LogoutEvent $event): void
{
// get the security token of the session that is about to be logged out
// get the current request
$request = $event->getRequest();
// get the current response, if it is already set by another listener
$response = $event->getResponse();
// configure a custom logout response to the homepage
$response = $this->hydra->handleLogoutRequest($request);
$event->setResponse($response);
}
}

View File

@ -1,41 +0,0 @@
<?php
namespace App\Form;
use App\Entity\User;
use App\Validator\ExistingEmail;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('email', EmailType::class, [
"required"=>true
])
->add("password", PasswordType::class, [
"attr" => ["class" => "password-field"],
"required" => true,
"label"=>"Mot de passe"
])
->add('rememberMe', CheckboxType::class, [
"required"=> false,
"label"=> "Se souvenir de moi"
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
"data_class" => User::class,
]);
}
}

139
src/Hydra/Client.php Normal file
View File

@ -0,0 +1,139 @@
<?php
namespace App\Hydra;
use App\Hydra\Exception\InvalidChallengeException;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
class Client
{
protected $client;
protected $hydraAdminBaseUrl;
public function __construct(HttpClientInterface $client, string $hydraAdminBaseUrl)
{
$this->client = $client;
$this->hydraAdminBaseUrl = $hydraAdminBaseUrl;
}
public function fetchLoginRequestInfo(string $loginChallenge): ResponseInterface
{
$response = $this->client->request(
'GET',
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/login',
[
'query' => [
'login_challenge' => $loginChallenge,
]
]
);
switch ($response->getStatusCode()) {
case 404:
throw new InvalidChallengeException();
}
return $response;
}
public function fetchLogoutRequestInfo(string $logoutChallenge): ResponseInterface
{
$response = $this->client->request(
'GET',
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/logout',
[
'query' => [
'logout_challenge' => $logoutChallenge,
]
]
);
switch ($response->getStatusCode()) {
case 404:
throw new InvalidChallengeException();
}
return $response;
}
public function fetchConsentRequestInfo(string $consentChallenge): ResponseInterface
{
$response = $this->client->request(
'GET',
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/consent',
[
'query' => [
'consent_challenge' => $consentChallenge,
]
]
);
switch ($response->getStatusCode()) {
case 404:
throw new InvalidChallengeException();
}
return $response;
}
public function acceptLoginRequest(string $loginChallenge, array $payload): ResponseInterface
{
$response = $this->client->request(
'PUT',
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/login/accept',
[
'query' => [
'login_challenge' => $loginChallenge,
],
'headers' => [
'Content-Type' => 'application/json'
],
'body' => json_encode($payload),
]
);
return $response;
}
public function acceptConsentRequest(string $consentChallenge, array $payload): ResponseInterface
{
$response = $this->client->request(
'PUT',
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/consent/accept',
[
'query' => [
'consent_challenge' => $consentChallenge,
],
'headers' => [
'Content-Type' => 'application/json'
],
'body' => json_encode($payload),
]
);
return $response;
}
public function acceptLogoutRequest(string $logoutChallenge): ResponseInterface
{
$response = $this->client->request(
'PUT',
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/logout/accept',
[
'query' => [
'logout_challenge' => $logoutChallenge,
],
'headers' => [
'Content-Type' => 'application/json'
],
]
);
return $response;
}
}

View File

@ -0,0 +1,9 @@
<?php
namespace App\Hydra\Exception;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
class InvalidChallengeException extends BadRequestException
{
}

View File

@ -0,0 +1,9 @@
<?php
namespace App\Hydra\Exception;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
class InvalidIssuerException extends BadRequestException
{
}

View File

@ -0,0 +1,85 @@
<?php
namespace App\Hydra;
use App\Hydra\Exception\InvalidChallengeException;
use App\Services\PdoService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class HydraService extends AbstractController
{
public SessionInterface $session;
public UrlGeneratorInterface $router;
public Client $client;
public PdoService $pdoServices;
public TokenStorageInterface $tokenStorage;
public function __construct(PdoService $pdoServices, Client $client, SessionInterface $session, UrlGeneratorInterface $router, TokenStorageInterface $tokenStorage)
{
$this->pdoServices = $pdoServices;
$this->session = $session;
$this->client = $client;
$this->router = $router;
$this->tokenStorage = $tokenStorage;
}
public function handleLoginRequest(Request $request)
{
$challenge = $request->query->get('login_challenge');
// S'il n'y a pas de challenge, on déclenche une bad request
if (empty($challenge)) {
throw new InvalidChallengeException();
}
// Fetch Hydra login request info
$res = $this->client->fetchLoginRequestInfo($challenge);
$loginRequestInfo = $res->toArray();
if (200 !== $res->getStatusCode()) {
$this->session->clear();
throw new BadRequestException('pas de code 200');
}
// si le challenge est validé par hydra, on le stocke en session pour l'utiliser par la suite et on redirige vers une route interne protégée qui va déclencher l'identification FranceConnect
$this->session->set('challenge', $loginRequestInfo['challenge']);
return $this->redirectToRoute('app_login');
}
public function handleConsentRequest(Request $request)
{
$challenge = $request->query->get('consent_challenge');
if (!$challenge) {
throw new BadRequestException("Le challenge n'est pas disponible");
}
$consentRequestInfo = $this->client->fetchConsentRequestInfo($challenge)->toArray();
/** @var User */
$user = $this->getUser();
$consentAcceptResponse = $this->client->acceptConsentRequest($consentRequestInfo['challenge'], [
'grant_scope' => $consentRequestInfo['requested_scope'],
'session' => [
'id_token' => $user->getAttributes(),
],
])->toArray();
return new RedirectResponse($consentAcceptResponse['redirect_to']);
}
public function handleLogoutRequest(Request $request)
{
$logoutChallenge = $request->get('logout_challenge');
if (empty($logoutChallenge)) {
throw new InvalidChallengeException();
}
$logoutRequestInfo = $this->client->fetchLogoutRequestInfo($logoutChallenge)->toArray();
$logoutAcceptRes = $this->client->acceptLogoutRequest($logoutRequestInfo['challenge'])->toArray();
$this->session->clear();
$this->tokenStorage->setToken();
return new RedirectResponse($logoutAcceptRes['redirect_to']);
}
}

View File

@ -2,10 +2,31 @@
namespace App; namespace App;
use App\DependencyInjection\PdoExtension;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\HttpKernel\Kernel as BaseKernel; use Symfony\Component\HttpKernel\Kernel as BaseKernel;
class Kernel extends BaseKernel class Kernel extends BaseKernel
{ {
use MicroKernelTrait; use MicroKernelTrait {
registerContainerConfiguration as microKernelConfigureContainer;
}
/**
* {@inheritdoc}
*/
public function registerContainerConfiguration(LoaderInterface $loader)
{
$this->microKernelConfigureContainer($loader);
$loader->load(function (ContainerBuilder $container) use ($loader) {
$envLanguage = \getenv('APP_LOCALES');
$container->registerExtension(new PdoExtension());
$loader->load($this->getConfigDir().'/pdo_configuration/*.{yml,yaml}', 'glob');
});
}
} }

View File

@ -0,0 +1,7 @@
<?php
namespace App\Pdo\Exception;
class InvalidPasswordException
{
}

Some files were not shown because too many files have changed in this diff Show More