environnement complet autonome, révision complete de la méthode, ajout de configuration #2
|
@ -0,0 +1 @@
|
|||
Deny from all
|
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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"]}}
|
|
@ -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
|
@ -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"}
|
|
@ -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"}
|
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -0,0 +1 @@
|
|||
Deny from all
|
32
.env
32
.env
|
@ -18,17 +18,25 @@ APP_ENV=dev
|
|||
APP_SECRET=406ccaa0c76a451fdcc2307ea146cbef
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
# string pour la requête sql qui va récupérer le mot de passe
|
||||
queryHashPassword="SELECT password from USER WHERE email = :email;"
|
||||
queryFetchDatas="SELECT email,lastname,firstname,random, password from USER WHERE email = :email;"
|
||||
urlDatabase="mysql:host=db;port=3306;dbname=remote;"
|
||||
dbUser="remote"
|
||||
dbPassword="remote"
|
||||
# configuration bdd
|
||||
dsn="pgsql:host='postgres';port=5432;dbname=lasql"
|
||||
db_user="lasql"
|
||||
db_password="lasql"
|
||||
|
||||
url_login_challenge_accept="http://sso.mse.local:4445/oauth2/auth/requests/login/accept?login_challenge="
|
||||
url_login_challenge="http://sso.mse.local:4445/oauth2/auth/requests/login?login_challenge="
|
||||
url_login_challenge_reject="http://sso.mse.local:4445/oauth2/auth/requests/login/reject?login_challenge="
|
||||
# connexion hydra
|
||||
HYDRA_ADMIN_BASE_URL='http://hydra:4445'
|
||||
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_consent_challenge_accept="http://sso.mse.local:4445/oauth2/auth/requests/consent/accept?consent_challenge="
|
||||
|
||||
url_login_challenge_accept="http://hydra:4445/oauth2/auth/requests/login/accept?login_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 ###
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Deny from all
|
|
@ -10,11 +10,13 @@
|
|||
"doctrine/annotations": "^1.13",
|
||||
"symfony/apache-pack": "^1.0",
|
||||
"symfony/console": "5.4.*",
|
||||
"symfony/dependency-injection": "5.4.*",
|
||||
"symfony/dotenv": "5.4.*",
|
||||
"symfony/flex": "^1.17|^2",
|
||||
"symfony/form": "5.4.*",
|
||||
"symfony/framework-bundle": "5.4.*",
|
||||
"symfony/http-client": "5.4.*",
|
||||
"symfony/rate-limiter": "5.4.*",
|
||||
"symfony/runtime": "5.4.*",
|
||||
"symfony/security-bundle": "5.4.*",
|
||||
"symfony/twig-bundle": "5.4.*",
|
||||
|
|
|
@ -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": "90cbb93fd73462f1836880cd629e8594",
|
||||
"content-hash": "70867e31e3b952d600febc856fbb544a",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
|
@ -733,16 +733,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/dependency-injection",
|
||||
"version": "v5.4.7",
|
||||
"version": "v5.4.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dependency-injection.git",
|
||||
"reference": "35588b2afb08ea3a142d62fefdcad4cb09be06ed"
|
||||
"reference": "a93e1863500940780fc1235f52d54397be2d14b3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/35588b2afb08ea3a142d62fefdcad4cb09be06ed",
|
||||
"reference": "35588b2afb08ea3a142d62fefdcad4cb09be06ed",
|
||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a93e1863500940780fc1235f52d54397be2d14b3",
|
||||
"reference": "a93e1863500940780fc1235f52d54397be2d14b3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -802,7 +802,7 @@
|
|||
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/dependency-injection/tree/v5.4.7"
|
||||
"source": "https://github.com/symfony/dependency-injection/tree/v5.4.16"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -818,7 +818,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-08T15:43:06+00:00"
|
||||
"time": "2022-11-25T07:33:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
|
@ -1989,6 +1989,85 @@
|
|||
],
|
||||
"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",
|
||||
"version": "v5.4.3",
|
||||
|
@ -2879,6 +2958,76 @@
|
|||
],
|
||||
"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",
|
||||
"version": "v5.4.3",
|
||||
|
|
BIN
composer.phar
BIN
composer.phar
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
framework:
|
||||
lock: '%env(LOCK_DSN)%'
|
|
@ -5,15 +5,30 @@ security:
|
|||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
|
||||
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
|
||||
providers:
|
||||
users_in_memory: { memory: null }
|
||||
pdo_user_provider:
|
||||
id: App\Security\PdoUserProvider
|
||||
firewalls:
|
||||
dev:
|
||||
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
||||
security: false
|
||||
main:
|
||||
lazy: true
|
||||
provider: users_in_memory
|
||||
# lazy: true
|
||||
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
|
||||
# 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
|
||||
# Note: Only the *first* access control that matches will be used
|
||||
access_control:
|
||||
# - { path: ^/admin, roles: ROLE_ADMIN }
|
||||
# - { path: ^/profile, roles: ROLE_USER }
|
||||
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||
- { path: ^/connect, roles: ROLE_USER }
|
||||
# - { path: ^/connect, roles: [IS_AUTHENTICATED_FULLY, ROLE_USER] }
|
||||
|
||||
when@test:
|
||||
security:
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
pdo:
|
||||
column_login_name: email
|
||||
column_password_name: password
|
||||
table_name: usager
|
||||
data_to_fetch:
|
||||
- email
|
||||
- lastname
|
||||
- firstname
|
|
@ -6,19 +6,24 @@
|
|||
parameters:
|
||||
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"
|
||||
urlDatabase: "%env(resolve:urlDatabase)%"
|
||||
dbUser: "%env(resolve:dbUser)%"
|
||||
dbPassword: "%env(resolve:dbPassword)%"
|
||||
queryHashPassword: "%env(resolve:queryHashPassword)%"
|
||||
queryFetchDatas: "%env(resolve:queryFetchDatas)%"
|
||||
hashMethod:
|
||||
database.dsn: "%env(resolve:dsn)%"
|
||||
database.user: "%env(resolve:db_user)%"
|
||||
database.password: "%env(resolve:db_password)%"
|
||||
|
||||
# algorythme de hahshage utilisé "md5", "sha256", "haval160,4", etc.
|
||||
hashAlgo: "sha256"
|
||||
passwordColumnName: "password"
|
||||
userTableName: "USER"
|
||||
emailColumnName: "email"
|
||||
urlLogoutSuccess: "http://portal.mse.local:8000/logout-success"
|
||||
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_reject: '%env(resolve:url_login_challenge_reject)%'
|
||||
url_login_challenge_accept: '%env(resolve:url_login_challenge_accept)%'
|
||||
|
@ -40,5 +45,19 @@ services:
|
|||
- '../src/Entity/'
|
||||
- '../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
|
||||
# please note that last definitions always *replace* previous ones
|
||||
|
|
|
@ -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"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
postgres:5432:lasql:lasql:lasql
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"Servers": {
|
||||
"1": {
|
||||
"Name": "postgres",
|
||||
"Group": "Servers",
|
||||
"Host": "postgres",
|
||||
"Port": 5432,
|
||||
"MaintenanceDB": "postgres",
|
||||
"Username": "lasql",
|
||||
"PassFile": "/pgpass",
|
||||
"SSLMode": "prefer"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -20,8 +20,8 @@
|
|||
# regular expression must be changed accordingly:
|
||||
# ProxyPassMatch ^/path-to-app/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/project/public/$1
|
||||
|
||||
DocumentRoot /loginappsql/public
|
||||
<Directory /loginappsql/public>
|
||||
DocumentRoot /var/www/public
|
||||
<Directory /var/www/public>
|
||||
# enable the .htaccess rewrites
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
|
|
|
@ -23,8 +23,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
|
|||
php${PHP_VERSION}-xml php${PHP_VERSION}-bcmath \
|
||||
php${PHP_VERSION}-zip php${PHP_VERSION}-fpm \
|
||||
php${PHP_VERSION}-mbstring \
|
||||
php${PHP_VERSION}-mysql \
|
||||
php${PHP_VERSION}-pdo-mysql \
|
||||
php${PHP_VERSION}-pgsql \
|
||||
php${PHP_VERSION}-pdo-pgsql \
|
||||
php${PHP_VERSION}-ssh2 libxml2-utils \
|
||||
locales \
|
||||
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
|
||||
RUN pip3 install wheel superfsmon
|
||||
|
||||
VOLUME /loginappsql
|
||||
VOLUME /loginappsql/var/logs
|
||||
VOLUME /loginappsql/var/cache
|
||||
VOLUME /var/www
|
||||
VOLUME /var/www/var/logs
|
||||
VOLUME /var/www/var/cache
|
||||
|
||||
# Install composer
|
||||
COPY install-composer.sh /loginappsql/install-composer.sh
|
||||
RUN chmod +x /loginappsql/install-composer.sh &&\
|
||||
/loginappsql/install-composer.sh &&\
|
||||
rm -f /loginappsql/install-composer.sh
|
||||
COPY install-composer.sh /var/www/install-composer.sh
|
||||
RUN chmod +x /var/www/install-composer.sh &&\
|
||||
/var/www/install-composer.sh &&\
|
||||
rm -f /var/www/install-composer.sh
|
||||
|
||||
# On active les mods d'apache nécessaires
|
||||
RUN a2enmod rewrite
|
||||
|
@ -73,7 +73,7 @@ COPY www.conf /etc/php/8.1/fpm/pool.d/www.conf
|
|||
EXPOSE 5000
|
||||
EXPOSE 80
|
||||
|
||||
WORKDIR /loginappsql
|
||||
WORKDIR /var/www
|
||||
|
||||
# On démarre php-fpm une fois pour créer les sockets
|
||||
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 '/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 php.ini /etc/php/8.1/fpm/php.ini
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ set -xeo pipefail
|
|||
[ ! -d /var/www/.cache ] && sudo mkdir -p /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
|
||||
cd /loginappsql
|
||||
cp /bin/composer.phar /var/www/composer.phar
|
||||
cd /var/www
|
||||
php composer.phar install
|
|
@ -1,7 +1,6 @@
|
|||
user: www-data
|
||||
group: www-data
|
||||
paths:
|
||||
- /loginappsql/node_modules
|
||||
- /loginappsql/vendor
|
||||
- /loginappsql
|
||||
- /var/www/node_modules
|
||||
- /var/www/vendor
|
||||
- /var/www
|
|
@ -16,7 +16,7 @@ stderr_logfile_maxbytes=0
|
|||
[program:apache2]
|
||||
environment=HOSTNAME="%(ENV_HOSTNAME)s"
|
||||
command = apachectl -D "FOREGROUND"
|
||||
directory = /loginappsql
|
||||
directory = /var/www
|
||||
user = root
|
||||
autostart = true
|
||||
stdout_logfile=/dev/stdout
|
||||
|
@ -29,7 +29,7 @@ environment=HOSTNAME="%(ENV_HOSTNAME)s"
|
|||
command = /usr/sbin/php-fpm8.1 -F
|
||||
autostart = true
|
||||
autorestart = true
|
||||
directory = /loginappsql
|
||||
directory = /var/www
|
||||
user = root
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
|
|
|
@ -11,20 +11,21 @@ services:
|
|||
- https_proxy=${https_proxy}
|
||||
user: ${FIXUID:-1000}:${FIXGID:-1000}
|
||||
ports:
|
||||
- 5002:80
|
||||
- 8080:80
|
||||
volumes:
|
||||
- .:/loginappsql
|
||||
- .:/var/www
|
||||
- /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}
|
||||
- /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:
|
||||
- "loginappsql.local:127.0.0.1"
|
||||
- "sso.mse.local:host-gateway"
|
||||
- "localhost:127.0.0.1"
|
||||
- "localhost:host-gateway"
|
||||
- "host.docker.internal:host-gateway"
|
||||
environment:
|
||||
- HTTP_PROXY=${HTTP_PROXY}
|
||||
|
@ -32,10 +33,75 @@ services:
|
|||
- http_proxy=${http_proxy}
|
||||
- https_proxy=${https_proxy}
|
||||
- TZ=Europe/Paris
|
||||
networks:
|
||||
- mse-network
|
||||
- HYDRA_ADMIN_BASE_URL=http://hydra:4445
|
||||
- TRUSTED_PROXIES=127.0.0.1,REMOTE_ADDR,localhost
|
||||
|
||||
networks:
|
||||
mse-network:
|
||||
external:
|
||||
name: mse_default
|
||||
oidc-test:
|
||||
image: bornholm/oidc-test:v0.0.0-1-g936a77e
|
||||
environment:
|
||||
- LOG_LEVEL=0
|
||||
- HTTP_ADDRESS=0.0.0.0:8000
|
||||
- OIDC_CLIENT_ID=oidc-test
|
||||
- OIDC_CLIENT_SECRET=oidc-test-123456
|
||||
- OIDC_ISSUER_URL=http://localhost:8081/
|
||||
- OIDC_REDIRECT_URL=http://localhost:8000
|
||||
- OIDC_POST_LOGOUT_REDIRECT_URL=http://localhost:8000
|
||||
depends_on:
|
||||
hydra:
|
||||
condition: service_healthy
|
||||
network_mode: host
|
||||
|
||||
restart: unless-stopped
|
||||
hydra:
|
||||
image: docker.io/cadoles/hydra-v1:latest
|
||||
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:
|
|
@ -3,171 +3,55 @@
|
|||
namespace App\Controller;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Form\UserType;
|
||||
use App\Services\PdoServices;
|
||||
use App\Hydra\Client;
|
||||
use App\Hydra\HydraService;
|
||||
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\Annotation\Route;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class MainController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @var Session
|
||||
*/
|
||||
private $session;
|
||||
public HydraService $hydra;
|
||||
public Client $client;
|
||||
public SessionInterface $session;
|
||||
|
||||
/**
|
||||
* @var UrlGeneratorInterface
|
||||
*/
|
||||
private $router;
|
||||
|
||||
/**
|
||||
* @var HttpClientInterface
|
||||
*/
|
||||
public $client;
|
||||
private $pdoServices;
|
||||
|
||||
public function __construct(PdoServices $pdoServices, HttpClientInterface $client, SessionInterface $session, UrlGeneratorInterface $router)
|
||||
public function __construct(SessionInterface $session, HydraService $hydra, Client $client)
|
||||
{
|
||||
$this->pdoServices = $pdoServices;
|
||||
$this->session = $session;
|
||||
$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');
|
||||
// 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');
|
||||
return $this->hydra->handleLoginRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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'))) {
|
||||
throw new BadRequestException('Vous devez passer par le issuer pour vous connecter');
|
||||
}
|
||||
/** @var User */
|
||||
$user = $this->getUser();
|
||||
$loginAcceptRes = $this->client->acceptLoginRequest($this->session->get('challenge'), [
|
||||
'subject' => $user->getLogin(),
|
||||
'remember' => true,
|
||||
])->toArray();
|
||||
|
||||
$user = new User();
|
||||
$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(),
|
||||
]);
|
||||
return new RedirectResponse($loginAcceptRes['redirect_to']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/oauth/consent", name="consent")
|
||||
* @Route("/connect/consent", name="app_consent")
|
||||
*/
|
||||
public function consent(Request $request)
|
||||
{
|
||||
$challenge = $request->query->get('consent_challenge');
|
||||
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'));
|
||||
return $this->hydra->handleConsentRequest($request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -2,25 +2,27 @@
|
|||
|
||||
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 $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;
|
||||
return $this->login;
|
||||
}
|
||||
|
||||
public function getPassword(): string
|
||||
|
@ -28,22 +30,37 @@ class User
|
|||
return $this->password;
|
||||
}
|
||||
|
||||
public function setPassword(string $password): self
|
||||
public function getAttributes(): array
|
||||
{
|
||||
$this->password = $password;
|
||||
|
||||
return $this;
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
public function getRememberMe(): string
|
||||
public function getRememberMe(): bool
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Hydra\Exception;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
|
||||
class InvalidChallengeException extends BadRequestException
|
||||
{
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Hydra\Exception;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
|
||||
class InvalidIssuerException extends BadRequestException
|
||||
{
|
||||
}
|
|
@ -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']);
|
||||
}
|
||||
}
|
|
@ -2,10 +2,31 @@
|
|||
|
||||
namespace App;
|
||||
|
||||
use App\DependencyInjection\PdoExtension;
|
||||
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;
|
||||
|
||||
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');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue