c2cgeoportal-geoportal 2.6.0__py2.py3-none-any.whl → 2.8.1.180__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- c2cgeoportal_geoportal/__init__.py +245 -95
- c2cgeoportal_geoportal/lib/__init__.py +67 -43
- c2cgeoportal_geoportal/lib/authentication.py +50 -26
- c2cgeoportal_geoportal/lib/bashcolor.py +17 -13
- c2cgeoportal_geoportal/lib/cacheversion.py +16 -8
- c2cgeoportal_geoportal/lib/caching.py +65 -193
- c2cgeoportal_geoportal/lib/check_collector.py +17 -10
- c2cgeoportal_geoportal/lib/checker.py +67 -65
- c2cgeoportal_geoportal/lib/common_headers.py +167 -0
- c2cgeoportal_geoportal/lib/dbreflection.py +61 -46
- c2cgeoportal_geoportal/lib/filter_capabilities.py +126 -88
- c2cgeoportal_geoportal/lib/fulltextsearch.py +6 -5
- c2cgeoportal_geoportal/lib/functionality.py +20 -17
- c2cgeoportal_geoportal/lib/headers.py +14 -5
- c2cgeoportal_geoportal/lib/i18n.py +4 -4
- c2cgeoportal_geoportal/lib/layers.py +30 -11
- c2cgeoportal_geoportal/lib/lingua_extractor.py +363 -240
- c2cgeoportal_geoportal/lib/loader.py +11 -16
- c2cgeoportal_geoportal/lib/metrics.py +28 -17
- c2cgeoportal_geoportal/lib/oauth2.py +392 -206
- c2cgeoportal_geoportal/lib/wmstparsing.py +105 -84
- c2cgeoportal_geoportal/lib/xsd.py +26 -16
- c2cgeoportal_geoportal/resources.py +15 -9
- c2cgeoportal_geoportal/scaffolds/advance_create/ci/config.yaml +26 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.dockerignore +6 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.eslintrc.yaml +19 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+dot+prospector.yaml → advance_create/{{cookiecutter.project}}/geoportal/.prospector.yaml} +8 -2
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/Dockerfile_tmpl → advance_create/{{cookiecutter.project}}/geoportal/Dockerfile} +22 -15
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/alembic.yaml_tmpl → advance_create/{{cookiecutter.project}}/geoportal/alembic.yaml} +1 -1
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/development.ini_tmpl → advance_create/{{cookiecutter.project}}/geoportal/development.ini} +34 -15
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/gunicorn.conf.py +100 -0
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/lingua-client.cfg +1 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/production.ini +38 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/setup.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/setup.py} +6 -7
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/tsconfig.json +8 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/webpack.api.js +77 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/webpack.apps.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/webpack.apps.js} +29 -28
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.commons.js +4 -7
- c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/webpack.config.js +1 -1
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__.py +42 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/authentication.py +10 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/dev.py +14 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/models.py +8 -0
- c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/multi_organization.py +7 -0
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/resources.py +4 -3
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/static-ngeo/api/index.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/api/index.js} +1 -2
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/static-ngeo/js/+package+module.js_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static-ngeo/js/{{cookiecutter.package}}module.js} +4 -4
- c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal/subscribers.py_tmpl → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/subscribers.py} +1 -3
- c2cgeoportal_geoportal/scaffolds/advance_update/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/{update/geoportal/CONST_Makefile_tmpl → advance_update/{{cookiecutter.project}}/geoportal/CONST_Makefile} +3 -27
- c2cgeoportal_geoportal/scaffolds/create/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.dockerignore +14 -0
- c2cgeoportal_geoportal/scaffolds/create/{+dot+editorconfig → {{cookiecutter.project}}/.editorconfig} +2 -5
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/main.yaml +57 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/rebuild.yaml +46 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.github/workflows/update_l10n.yaml +66 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.gitignore +16 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierignore +1 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/.prettierrc.yaml +2 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Dockerfile +76 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/Makefile +70 -0
- c2cgeoportal_geoportal/scaffolds/create/{README.rst_tmpl → {{cookiecutter.project}}/README.rst} +4 -4
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/build +186 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/config.yaml +22 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/docker-compose-check +25 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/ci/requirements.txt +1 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-db.yaml +26 -0
- c2cgeoportal_geoportal/scaffolds/create/{docker-compose-lib.yaml → {{cookiecutter.project}}/docker-compose-lib.yaml} +165 -22
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose-qgis.yaml +23 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/docker-compose.override.sample.yaml +66 -0
- c2cgeoportal_geoportal/scaffolds/create/{docker-compose.yaml → {{cookiecutter.project}}/docker-compose.yaml} +20 -15
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.default +101 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/env.project +69 -0
- c2cgeoportal_geoportal/scaffolds/create/{geoportal/vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/vars.yaml} +126 -36
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/mobile.css +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/data/Readme.txt +3 -3
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/demo.map.tmpl +224 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/mapserver/mapserver.conf +15 -0
- c2cgeoportal_geoportal/scaffolds/create/{mapserver/mapserver.map.tmpl_tmpl → {{cookiecutter.project}}/mapserver/mapserver.map.tmpl} +9 -18
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Landscape.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A3_Portrait.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Landscape.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/A4_Portrait.jrxml +13 -8
- c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/config.yaml.tmpl +11 -4
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation.properties +4 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}/localisation_fr.properties +4 -0
- c2cgeoportal_geoportal/scaffolds/create/{project.yaml_tmpl → {{cookiecutter.project}}/project.yaml} +6 -6
- c2cgeoportal_geoportal/scaffolds/create/{pyproject.toml → {{cookiecutter.project}}/pyproject.toml} +4 -0
- c2cgeoportal_geoportal/scaffolds/create/{qgisserver/pg_service.conf.tmpl_tmpl → {{cookiecutter.project}}/qgisserver/pg_service.conf.tmpl} +2 -2
- c2cgeoportal_geoportal/scaffolds/create/{run_alembic.sh → {{cookiecutter.project}}/run_alembic.sh} +3 -5
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-backup +110 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/scripts/db-restore +114 -0
- c2cgeoportal_geoportal/scaffolds/create/{setup.cfg_tmpl → {{cookiecutter.project}}/setup.cfg} +1 -1
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/spell-ignore-words.txt +5 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/__init__.py +0 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tests/test_app.py +38 -0
- c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/tilegeneration/config.yaml.tmpl +195 -0
- c2cgeoportal_geoportal/scaffolds/update/cookiecutter.json +18 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/.upgrade.yaml +61 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_CHANGELOG.txt +273 -0
- c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_create_template/tests/test_testapp.py +48 -0
- c2cgeoportal_geoportal/scaffolds/update/{geoportal → {{cookiecutter.project}}/geoportal}/CONST_config-schema.yaml +64 -17
- c2cgeoportal_geoportal/scaffolds/update/{geoportal/CONST_vars.yaml_tmpl → {{cookiecutter.project}}/geoportal/CONST_vars.yaml} +396 -19
- c2cgeoportal_geoportal/scripts/__init__.py +16 -30
- c2cgeoportal_geoportal/scripts/c2cupgrade.py +272 -234
- c2cgeoportal_geoportal/scripts/create_demo_theme.py +3 -6
- c2cgeoportal_geoportal/scripts/manage_users.py +34 -39
- c2cgeoportal_geoportal/scripts/pcreate.py +310 -0
- c2cgeoportal_geoportal/scripts/theme2fts.py +128 -24
- c2cgeoportal_geoportal/scripts/urllogin.py +19 -11
- c2cgeoportal_geoportal/templates/login.html +88 -84
- c2cgeoportal_geoportal/templates/notlogin.html +59 -59
- c2cgeoportal_geoportal/templates/testi18n.html +6 -8
- c2cgeoportal_geoportal/views/__init__.py +23 -6
- c2cgeoportal_geoportal/views/dev.py +9 -7
- c2cgeoportal_geoportal/views/dynamic.py +56 -19
- c2cgeoportal_geoportal/views/entry.py +85 -24
- c2cgeoportal_geoportal/views/fulltextsearch.py +29 -23
- c2cgeoportal_geoportal/views/geometry_processing.py +17 -9
- c2cgeoportal_geoportal/views/i18n.py +91 -9
- c2cgeoportal_geoportal/views/layers.py +166 -133
- c2cgeoportal_geoportal/views/login.py +161 -93
- c2cgeoportal_geoportal/views/mapserverproxy.py +47 -31
- c2cgeoportal_geoportal/views/memory.py +12 -12
- c2cgeoportal_geoportal/views/ogcproxy.py +52 -30
- c2cgeoportal_geoportal/views/pdfreport.py +30 -26
- c2cgeoportal_geoportal/views/printproxy.py +60 -52
- c2cgeoportal_geoportal/views/profile.py +24 -23
- c2cgeoportal_geoportal/views/proxy.py +88 -72
- c2cgeoportal_geoportal/views/raster.py +37 -26
- c2cgeoportal_geoportal/views/resourceproxy.py +13 -11
- c2cgeoportal_geoportal/views/shortener.py +27 -25
- c2cgeoportal_geoportal/views/theme.py +472 -332
- c2cgeoportal_geoportal/views/tinyowsproxy.py +42 -44
- c2cgeoportal_geoportal/views/vector_tiles.py +80 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/METADATA +19 -8
- c2cgeoportal_geoportal-2.8.1.180.dist-info/RECORD +191 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/WHEEL +1 -1
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/entry_points.txt +3 -0
- tests/__init__.py +10 -5
- tests/test_cachebuster.py +3 -5
- tests/test_caching.py +18 -26
- tests/test_checker.py +1 -3
- tests/test_decimaljson.py +5 -5
- tests/test_headerstween.py +1 -3
- tests/test_i18n.py +2 -2
- tests/test_init.py +16 -20
- tests/test_locale_negociator.py +4 -6
- tests/test_mapserverproxy_route_predicate.py +1 -4
- tests/test_raster.py +15 -17
- tests/test_wmstparsing.py +10 -12
- tests/xmlstr.py +1 -3
- c2cgeoportal_geoportal/scaffolds/__init__.py +0 -227
- c2cgeoportal_geoportal/scaffolds/create/+dot+dockerignore_tmpl +0 -12
- c2cgeoportal_geoportal/scaffolds/create/+dot+github/workflows/main.yaml_tmpl +0 -89
- c2cgeoportal_geoportal/scaffolds/create/+dot+github/workflows/rebuild.yaml_tmpl +0 -78
- c2cgeoportal_geoportal/scaffolds/create/+dot+gitignore_tmpl +0 -16
- c2cgeoportal_geoportal/scaffolds/create/Dockerfile_tmpl +0 -67
- c2cgeoportal_geoportal/scaffolds/create/Makefile +0 -3
- c2cgeoportal_geoportal/scaffolds/create/build_tmpl +0 -167
- c2cgeoportal_geoportal/scaffolds/create/ci/config.yaml_tmpl +0 -23
- c2cgeoportal_geoportal/scaffolds/create/ci/requirements.txt +0 -1
- c2cgeoportal_geoportal/scaffolds/create/ci/trigger +0 -68
- c2cgeoportal_geoportal/scaffolds/create/docker-compose.override.sample.yaml +0 -54
- c2cgeoportal_geoportal/scaffolds/create/env.default_tmpl +0 -67
- c2cgeoportal_geoportal/scaffolds/create/env.project_tmpl +0 -48
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+dockerignore_tmpl +0 -6
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+dot+eslintrc_tmpl +0 -15
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/__init__.py_tmpl +0 -58
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/models.py_tmpl +0 -10
- c2cgeoportal_geoportal/scaffolds/create/geoportal/+package+_geoportal/static/robot.txt +0 -3
- c2cgeoportal_geoportal/scaffolds/create/geoportal/production.ini_tmpl +0 -106
- c2cgeoportal_geoportal/scaffolds/create/geoportal/tools/extract-messages.js +0 -39
- c2cgeoportal_geoportal/scaffolds/create/geoportal/tsconfig.json_tmpl +0 -9
- c2cgeoportal_geoportal/scaffolds/create/geoportal/webpack.api.js_tmpl +0 -72
- c2cgeoportal_geoportal/scaffolds/create/mapserver/demo.map.tmpl_tmpl +0 -262
- c2cgeoportal_geoportal/scaffolds/create/mapserver/tinyows.xml +0 -36
- c2cgeoportal_geoportal/scaffolds/create/print/print-apps/+package+/config.yaml +0 -168
- c2cgeoportal_geoportal/scaffolds/create/qgisserver/geomapfish.yaml.tmpl_tmpl +0 -16
- c2cgeoportal_geoportal/scaffolds/create/spell-ignore-words.txt +0 -1
- c2cgeoportal_geoportal/scaffolds/create/tilegeneration/config.yaml.tmpl_tmpl +0 -185
- c2cgeoportal_geoportal/scaffolds/create/yamllint.yaml +0 -11
- c2cgeoportal_geoportal/scaffolds/update/+dot+upgrade.yaml_tmpl +0 -181
- c2cgeoportal_geoportal/scaffolds/update/CONST_CHANGELOG.txt_tmpl +0 -454
- c2cgeoportal_geoportal/templates/dynamic.js +0 -21
- c2cgeoportal_geoportal-2.6.0.dist-info/RECORD +0 -173
- /c2cgeoportal_geoportal/{scaffolds/create/geoportal/+package+_geoportal/static/css/desktop.css → py.typed} +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create/geoportal/Makefile_tmpl → advance_create/{{cookiecutter.project}}/geoportal/Makefile} +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/alembic.ini +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/language_mapping +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/lingua-server.cfg +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create → advance_create/{{cookiecutter.project}}}/geoportal/requirements.txt +0 -0
- /c2cgeoportal_geoportal/scaffolds/{create/geoportal/+package+_geoportal → advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/views/__init__.py +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/locale/en/LC_MESSAGES/+package+_geoportal-client.po → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/locale/en/LC_MESSAGES/{{cookiecutter.package}}_geoportal-client.po} +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/static/css/iframe_api.css → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/desktop.css} +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal/static/css/mobile.css → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/static/css/iframe_api.css} +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/banner_left.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/banner_right.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/blank.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-blue.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-gold.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker-green.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/images/markers/marker.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{geoportal/+package+_geoportal → {{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal}/static/robot.txt.tmpl +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/data/TM_EUROPE_BORDERS-0.3.sql +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arial.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arialbd.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Arialbi.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Ariali.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Bold.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-BoldItalic.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Italic.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/NotoSans-Regular.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdana.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanab.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanai.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts/Verdanaz.ttf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/fonts.conf +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{mapserver → {{cookiecutter.project}}/mapserver}/tinyows.xml.tmpl +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/legend.jrxml +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/logo.png +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/north.svg +0 -0
- /c2cgeoportal_geoportal/scaffolds/create/{print/print-apps/+package+ → {{cookiecutter.project}}/print/print-apps/{{cookiecutter.package}}}/results.jrxml +0 -0
- {c2cgeoportal_geoportal-2.6.0.dist-info → c2cgeoportal_geoportal-2.8.1.180.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2011-2021, Camptocamp SA
|
1
|
+
# Copyright (c) 2011-2023, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -32,17 +30,21 @@ import logging
|
|
32
30
|
import os
|
33
31
|
import subprocess
|
34
32
|
from time import sleep
|
35
|
-
from typing import Dict
|
33
|
+
from typing import Any, Dict, List, Mapping, Optional, Union, cast
|
36
34
|
from urllib.parse import urljoin
|
37
35
|
|
38
36
|
import c2cwsgiutils.health_check
|
37
|
+
import pyramid.config
|
38
|
+
import pyramid.request
|
39
39
|
import requests
|
40
40
|
|
41
41
|
LOG = logging.getLogger(__name__)
|
42
42
|
|
43
43
|
|
44
|
-
def build_url(
|
45
|
-
|
44
|
+
def build_url(
|
45
|
+
name: str, path: str, request: pyramid.request.Request, headers: Optional[Dict[str, str]] = None
|
46
|
+
) -> Dict[str, Union[str, Dict[str, str]]]:
|
47
|
+
"""Build an URL and headers for the checkers."""
|
46
48
|
base_internal_url = request.registry.settings["checker"]["base_internal_url"]
|
47
49
|
url = urljoin(base_internal_url, path)
|
48
50
|
|
@@ -55,7 +57,9 @@ def build_url(name, path, request, headers=None):
|
|
55
57
|
return {"url": url, "headers": headers}
|
56
58
|
|
57
59
|
|
58
|
-
def _build_headers(
|
60
|
+
def _build_headers(
|
61
|
+
request: pyramid.request.Request, headers: Optional[Dict[str, str]] = None
|
62
|
+
) -> Dict[str, str]:
|
59
63
|
if headers is None:
|
60
64
|
headers = {}
|
61
65
|
headers["Cache-Control"] = "no-cache"
|
@@ -67,45 +71,43 @@ def _build_headers(request, headers=None):
|
|
67
71
|
return headers
|
68
72
|
|
69
73
|
|
70
|
-
def _routes(settings, health_check):
|
74
|
+
def _routes(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
|
71
75
|
routes_settings = settings["routes"]
|
72
76
|
for route in routes_settings["routes"]:
|
73
77
|
if route.get("checker_name", route["name"]) not in routes_settings["disable"]:
|
74
78
|
name = "checker_routes_" + route.get("checker_name", route["name"])
|
75
79
|
|
76
80
|
class GetRequest:
|
77
|
-
"""
|
78
|
-
Get the request information about the current route name
|
79
|
-
"""
|
81
|
+
"""Get the request information about the current route name."""
|
80
82
|
|
81
|
-
def __init__(self, route_name, type_):
|
83
|
+
def __init__(self, route_name: str, type_: str) -> None:
|
82
84
|
self.route_name = route_name
|
83
85
|
self.type = type_
|
84
86
|
|
85
|
-
def __call__(self, request):
|
87
|
+
def __call__(self, request: pyramid.request.Request) -> Union[str, Dict[str, str]]:
|
86
88
|
return build_url("route", request.route_path(self.route_name), request)[self.type]
|
87
89
|
|
88
90
|
health_check.add_url_check(
|
89
|
-
url=GetRequest(route["name"], "url"),
|
91
|
+
url=GetRequest(route["name"], "url"), # type: ignore
|
90
92
|
name=name,
|
91
93
|
params=route.get("params", None),
|
92
|
-
headers=GetRequest(route["name"], "headers"),
|
94
|
+
headers=GetRequest(route["name"], "headers"), # type: ignore
|
93
95
|
level=route["level"],
|
94
96
|
timeout=30,
|
95
97
|
)
|
96
98
|
|
97
99
|
|
98
|
-
def _pdf3(settings, health_check):
|
100
|
+
def _pdf3(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
|
99
101
|
print_settings = settings["print"]
|
100
102
|
if "spec" not in print_settings:
|
101
103
|
return
|
102
104
|
|
103
|
-
def check(request):
|
105
|
+
def check(request: pyramid.request.Request) -> None:
|
104
106
|
path = request.route_path("printproxy_report_create", format="pdf")
|
105
107
|
url_headers = build_url("Check the printproxy request (create)", path, request)
|
106
108
|
|
107
109
|
session = requests.session()
|
108
|
-
resp = session.post(json=print_settings["spec"], timeout=30, **url_headers)
|
110
|
+
resp = session.post(json=print_settings["spec"], timeout=30, **url_headers) # type: ignore
|
109
111
|
resp.raise_for_status()
|
110
112
|
|
111
113
|
job = resp.json()
|
@@ -115,44 +117,46 @@ def _pdf3(settings, health_check):
|
|
115
117
|
done = False
|
116
118
|
while not done:
|
117
119
|
sleep(1)
|
118
|
-
resp = session.get(timeout=30, **url_headers)
|
120
|
+
resp = session.get(timeout=30, **url_headers) # type: ignore
|
119
121
|
resp.raise_for_status()
|
120
122
|
|
121
123
|
status = resp.json()
|
122
124
|
if "error" in status:
|
123
|
-
raise Exception(
|
125
|
+
raise Exception( # pylint: disable=broad-exception-raised
|
126
|
+
f"Failed to do the printing: {status['error']}",
|
127
|
+
)
|
124
128
|
done = status["done"]
|
125
129
|
|
126
130
|
path = request.route_path("printproxy_report_get", ref=job["ref"])
|
127
131
|
url_headers = build_url("Check the printproxy pdf retrieve", path, request)
|
128
|
-
resp = session.get(timeout=30, **url_headers)
|
132
|
+
resp = session.get(timeout=30, **url_headers) # type: ignore
|
129
133
|
resp.raise_for_status()
|
130
134
|
|
131
135
|
health_check.add_custom_check(name="checker_print", check_cb=check, level=print_settings["level"])
|
132
136
|
|
133
137
|
|
134
|
-
def _fts(settings, health_check):
|
138
|
+
def _fts(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
|
135
139
|
fts_settings = settings["fulltextsearch"]
|
136
140
|
if fts_settings.get("disable", False):
|
137
141
|
return
|
138
142
|
|
139
|
-
def get_both(request):
|
143
|
+
def get_both(request: pyramid.request.Request) -> Dict[str, Union[str, Dict[str, str]]]:
|
140
144
|
return build_url("Check the fulltextsearch", request.route_path("fulltextsearch"), request)
|
141
145
|
|
142
|
-
def check(_request, response):
|
146
|
+
def check(_request: pyramid.request.Request, response: pyramid.response.Response) -> None:
|
143
147
|
assert response.json()["features"], "No result"
|
144
148
|
|
145
149
|
health_check.add_url_check(
|
146
150
|
name="checker_fulltextsearch",
|
147
|
-
url=lambda r: get_both(r)["url"],
|
148
|
-
headers=lambda r: get_both(r)["headers"],
|
151
|
+
url=lambda r: get_both(r)["url"], # type: ignore
|
152
|
+
headers=lambda r: get_both(r)["headers"], # type: ignore
|
149
153
|
params={"query": fts_settings["search"], "limit": "1"},
|
150
154
|
check_cb=check,
|
151
155
|
level=fts_settings["level"],
|
152
156
|
)
|
153
157
|
|
154
158
|
|
155
|
-
def _themes_errors(settings, health_check):
|
159
|
+
def _themes_errors(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
|
156
160
|
from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
|
157
161
|
from c2cgeoportal_commons.models.main import Interface # pylint: disable=import-outside-toplevel
|
158
162
|
|
@@ -160,7 +164,7 @@ def _themes_errors(settings, health_check):
|
|
160
164
|
default_params = themes_settings.get("params", {})
|
161
165
|
interfaces_settings = themes_settings["interfaces"]
|
162
166
|
|
163
|
-
def check(request):
|
167
|
+
def check(request: pyramid.request.Request) -> None:
|
164
168
|
path = request.route_path("themes")
|
165
169
|
session = requests.session()
|
166
170
|
for (interface,) in DBSession.query(Interface.name).all():
|
@@ -171,52 +175,53 @@ def _themes_errors(settings, health_check):
|
|
171
175
|
|
172
176
|
interface_url_headers = build_url("checker_themes " + interface, path, request)
|
173
177
|
|
174
|
-
response = session.get(params=params, timeout=120, **interface_url_headers)
|
178
|
+
response = session.get(params=params, timeout=120, **interface_url_headers) # type: ignore
|
175
179
|
response.raise_for_status()
|
176
180
|
|
177
181
|
result = response.json()
|
178
182
|
if result["errors"]:
|
179
183
|
raise c2cwsgiutils.health_check.JsonCheckException(
|
180
|
-
"Interface '{}' has error in Theme."
|
184
|
+
f"Interface '{interface}' has error in Theme.", result["errors"]
|
181
185
|
)
|
182
186
|
|
183
187
|
health_check.add_custom_check(name="checker_themes", check_cb=check, level=themes_settings["level"])
|
184
188
|
|
185
189
|
|
186
|
-
def _lang_files(
|
190
|
+
def _lang_files(
|
191
|
+
global_settings: Dict[str, Any],
|
192
|
+
settings: Dict[str, Any],
|
193
|
+
health_check: c2cwsgiutils.health_check.HealthCheck,
|
194
|
+
) -> None:
|
187
195
|
lang_settings = settings["lang"]
|
188
196
|
available_locale_names = global_settings["available_locale_names"]
|
189
197
|
|
190
198
|
default_name = global_settings["default_locale_name"]
|
191
|
-
assert (
|
192
|
-
default_name in available_locale_names
|
193
|
-
|
194
|
-
default_name, ", ".join(available_locale_names)
|
199
|
+
assert default_name in available_locale_names, (
|
200
|
+
f"default_locale_name '{default_name}' not in available_locale_names: "
|
201
|
+
f"{', '.join(available_locale_names)}"
|
195
202
|
)
|
196
203
|
|
197
204
|
for type_ in lang_settings.get("files", []):
|
198
205
|
for lang in available_locale_names:
|
199
206
|
if type_ == "ngeo":
|
200
|
-
url = "/etc/geomapfish/static/{lang}.json"
|
207
|
+
url = f"/etc/geomapfish/static/{lang}.json"
|
201
208
|
else:
|
202
|
-
raise Exception(
|
203
|
-
"Your language type value '
|
209
|
+
raise Exception( # pylint: disable=broad-exception-raised
|
210
|
+
f"Your language type value '{type_}' is not valid, available values [ngeo]",
|
204
211
|
)
|
205
212
|
|
206
|
-
name = "checker_lang_{}_{}"
|
213
|
+
name = f"checker_lang_{type_}_{lang}"
|
207
214
|
|
208
215
|
class GetRequest:
|
209
|
-
"""
|
210
|
-
Get the request information about the current route name
|
211
|
-
"""
|
216
|
+
"""Get the request information about the current route name."""
|
212
217
|
|
213
|
-
def __init__(self, name, url, lang, type_):
|
218
|
+
def __init__(self, name: str, url: str, lang: str, type_: str) -> None:
|
214
219
|
self.name = name
|
215
220
|
self.url = url
|
216
221
|
self.lang = lang
|
217
222
|
self.type = type_
|
218
223
|
|
219
|
-
def __call__(self, request):
|
224
|
+
def __call__(self, request: pyramid.request.Request) -> Union[str, Mapping[str, str]]:
|
220
225
|
return build_url(
|
221
226
|
self.name,
|
222
227
|
request.static_path(
|
@@ -227,27 +232,27 @@ def _lang_files(global_settings, settings, health_check):
|
|
227
232
|
|
228
233
|
health_check.add_url_check(
|
229
234
|
name=name,
|
230
|
-
url=GetRequest(name, url, lang, "url"),
|
231
|
-
headers=GetRequest(name, url, lang, "headers"),
|
235
|
+
url=GetRequest(name, url, lang, "url"), # type: ignore
|
236
|
+
headers=GetRequest(name, url, lang, "headers"), # type: ignore
|
232
237
|
level=lang_settings["level"],
|
233
238
|
)
|
234
239
|
|
235
240
|
|
236
|
-
def _phantomjs(settings, health_check):
|
241
|
+
def _phantomjs(settings: Dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
|
237
242
|
phantomjs_settings = settings["phantomjs"]
|
238
243
|
for route in phantomjs_settings["routes"]:
|
239
244
|
if route.get("checker_name", route["name"]) in phantomjs_settings["disable"]:
|
240
245
|
continue
|
241
246
|
|
242
247
|
class _Check:
|
243
|
-
def __init__(self, route):
|
248
|
+
def __init__(self, route: Dict[str, Any]) -> None:
|
244
249
|
self.route = route
|
245
250
|
|
246
|
-
def __call__(self, request):
|
251
|
+
def __call__(self, request: pyramid.request.Request) -> None:
|
247
252
|
path = request.route_path(self.route["name"], _query=self.route.get("params", {}))
|
248
|
-
url = build_url("Check", path, request)["url"]
|
253
|
+
url: str = cast(str, build_url("Check", path, request)["url"])
|
249
254
|
|
250
|
-
cmd = ["
|
255
|
+
cmd: List[str] = ["check-example", url]
|
251
256
|
env = dict(os.environ)
|
252
257
|
for name, value in self.route.get("environment", {}).items():
|
253
258
|
if isinstance(value, (list, dict)):
|
@@ -259,27 +264,24 @@ def _phantomjs(settings, health_check):
|
|
259
264
|
try:
|
260
265
|
subprocess.check_output(cmd, env=env, timeout=70)
|
261
266
|
except subprocess.CalledProcessError as exception:
|
262
|
-
raise Exception(
|
263
|
-
"{} exit with code: {}\n
|
264
|
-
|
265
|
-
|
266
|
-
)
|
267
|
+
raise Exception( # pylint: disable=broad-exception-raised
|
268
|
+
f"{' '.join(exception.cmd)} exit with code: {exception.returncode}\n"
|
269
|
+
f"{exception.output.decode('utf-8')[:10000]}"
|
270
|
+
) from exception
|
267
271
|
except subprocess.TimeoutExpired as exception:
|
268
|
-
raise Exception(
|
269
|
-
"""Timeout:
|
270
|
-
command: {}
|
272
|
+
raise Exception( # pylint: disable=broad-exception-raised
|
273
|
+
f"""Timeout:
|
274
|
+
command: {' '.join(exception.cmd)}
|
271
275
|
output:
|
272
|
-
{}"""
|
273
|
-
|
274
|
-
)
|
275
|
-
)
|
276
|
+
{exception.output.decode('utf-8')}"""
|
277
|
+
) from exception
|
276
278
|
|
277
279
|
name = "checker_phantomjs_" + route.get("checker_name", route["name"])
|
278
280
|
health_check.add_custom_check(name=name, check_cb=_Check(route), level=route["level"])
|
279
281
|
|
280
282
|
|
281
|
-
def init(config, health_check):
|
282
|
-
"""
|
283
|
+
def init(config: pyramid.config.Configurator, health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
|
284
|
+
"""Initialize the checkers."""
|
283
285
|
global_settings = config.get_settings()
|
284
286
|
if "checker" not in global_settings:
|
285
287
|
return
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# Copyright (c) 2012-2024, Camptocamp SA
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
10
|
+
# this list of conditions and the following disclaimer in the documentation
|
11
|
+
# and/or other materials provided with the distribution.
|
12
|
+
|
13
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
14
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
15
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
16
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
17
|
+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
18
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
19
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
20
|
+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
21
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
22
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
23
|
+
|
24
|
+
# The views and conclusions contained in the software and documentation are those
|
25
|
+
# of the authors and should not be interpreted as representing official policies,
|
26
|
+
# either expressed or implied, of the FreeBSD Project.
|
27
|
+
|
28
|
+
|
29
|
+
import logging
|
30
|
+
from enum import Enum
|
31
|
+
from typing import Any, Dict, List, Optional, cast
|
32
|
+
|
33
|
+
import pyramid.request
|
34
|
+
import pyramid.response
|
35
|
+
|
36
|
+
_LOG = logging.getLogger(__name__)
|
37
|
+
|
38
|
+
|
39
|
+
class Cache(Enum):
|
40
|
+
"""Enumeration for the possible cache values."""
|
41
|
+
|
42
|
+
# For responses that do not depend on authentication
|
43
|
+
PUBLIC = 0
|
44
|
+
# For responses that do not depends on authentication
|
45
|
+
# We use a small cache (e.g. 10s) instead of no cache to protect the service against too high traffic.
|
46
|
+
PUBLIC_NO = 1
|
47
|
+
# For responses that can depend on authentication
|
48
|
+
PRIVATE = 2
|
49
|
+
# See PUBLIC_NO and PRIVATE
|
50
|
+
PRIVATE_NO = 3
|
51
|
+
|
52
|
+
|
53
|
+
CORS_METHODS = "HEAD, GET, POST, PUT, DELETE"
|
54
|
+
|
55
|
+
|
56
|
+
def _set_cors_headers(
|
57
|
+
request: pyramid.request.Request,
|
58
|
+
response: pyramid.response.Response,
|
59
|
+
service_name: str,
|
60
|
+
service_headers_settings: Dict[str, Any],
|
61
|
+
credentials: bool,
|
62
|
+
) -> None:
|
63
|
+
"""Handle CORS requests, as specified in https://www.w3.org/TR/cors/."""
|
64
|
+
response.vary = (response.vary or ()) + ("Origin",)
|
65
|
+
|
66
|
+
if "Origin" not in request.headers:
|
67
|
+
return # Not a CORS request if this header is missing
|
68
|
+
origin = request.headers["Origin"]
|
69
|
+
|
70
|
+
if request.method == "OPTIONS" and "Access-Control-Request-Method" not in request.headers:
|
71
|
+
_LOG.warning("CORS preflight query missing the Access-Control-Request-Method header")
|
72
|
+
return
|
73
|
+
|
74
|
+
allowed_origins = cast(List[str], service_headers_settings.get("access_control_allow_origin", []))
|
75
|
+
if origin not in allowed_origins:
|
76
|
+
if "*" in allowed_origins:
|
77
|
+
origin = "*"
|
78
|
+
credentials = False # Force no credentials
|
79
|
+
else:
|
80
|
+
_LOG.warning("CORS query not allowed for origin=%s, service=%s", origin, service_name)
|
81
|
+
return
|
82
|
+
|
83
|
+
response.headers.update(
|
84
|
+
{"Access-Control-Allow-Origin": origin, "Access-Control-Allow-Methods": CORS_METHODS}
|
85
|
+
)
|
86
|
+
|
87
|
+
max_age = service_headers_settings.get("access_control_max_age", 3600)
|
88
|
+
response.headers["Access-Control-Max-Age"] = str(max_age)
|
89
|
+
|
90
|
+
if credentials:
|
91
|
+
response.headers["Access-Control-Allow-Credentials"] = "true"
|
92
|
+
|
93
|
+
if request.method != "OPTIONS":
|
94
|
+
return
|
95
|
+
|
96
|
+
response.cache_control.max_age = max_age
|
97
|
+
|
98
|
+
if not service_headers_settings or "access_control_allow_origin" not in service_headers_settings:
|
99
|
+
_LOG.warning("CORS query not configured for service=%s", service_name)
|
100
|
+
return
|
101
|
+
|
102
|
+
requested_headers = request.headers.get("Access-Control-Request-Headers", False)
|
103
|
+
if requested_headers:
|
104
|
+
# For the moment, we allow all requested headers
|
105
|
+
response.headers["Access-Control-Allow-Headers"] = requested_headers
|
106
|
+
|
107
|
+
# If we start using headers in responses, we'll have to add
|
108
|
+
# Access-Control-Expose-Headers
|
109
|
+
|
110
|
+
|
111
|
+
def _set_common_headers(
|
112
|
+
request: pyramid.request.Request,
|
113
|
+
response: pyramid.response.Response,
|
114
|
+
service_headers_settings: Dict[str, Dict[str, str]],
|
115
|
+
cache: Cache,
|
116
|
+
content_type: Optional[str],
|
117
|
+
) -> pyramid.response.Response:
|
118
|
+
"""Set the common headers."""
|
119
|
+
|
120
|
+
del request # Unused
|
121
|
+
|
122
|
+
response.headers.update(service_headers_settings.get("headers", {}))
|
123
|
+
|
124
|
+
if cache in (Cache.PRIVATE, Cache.PRIVATE_NO):
|
125
|
+
response.vary = (response.vary or ()) + ("Cookie",)
|
126
|
+
|
127
|
+
maxage = (
|
128
|
+
service_headers_settings.get("cache_control_max_age", 3600)
|
129
|
+
if cache in (Cache.PUBLIC, Cache.PRIVATE)
|
130
|
+
else service_headers_settings.get("cache_control_max_age_nocache", 10)
|
131
|
+
)
|
132
|
+
response.cache_control.max_age = maxage
|
133
|
+
if maxage == 0:
|
134
|
+
response.cache_control.no_cache = True
|
135
|
+
response.cache_control.no_store = True
|
136
|
+
elif cache in (Cache.PUBLIC, Cache.PUBLIC_NO):
|
137
|
+
response.cache_control.public = True
|
138
|
+
elif cache in (Cache.PRIVATE, Cache.PRIVATE_NO):
|
139
|
+
response.cache_control.private = True
|
140
|
+
else:
|
141
|
+
raise Exception("Invalid cache type") # pylint: disable=broad-exception-raised
|
142
|
+
|
143
|
+
if content_type is not None:
|
144
|
+
response.content_type = content_type
|
145
|
+
|
146
|
+
return response
|
147
|
+
|
148
|
+
|
149
|
+
def set_common_headers(
|
150
|
+
request: pyramid.request.Request,
|
151
|
+
service_name: str,
|
152
|
+
cache: Cache,
|
153
|
+
response: pyramid.response.Response = None,
|
154
|
+
credentials: bool = True,
|
155
|
+
content_type: Optional[str] = None,
|
156
|
+
) -> pyramid.response.Response:
|
157
|
+
"""Set the common headers."""
|
158
|
+
if response is None:
|
159
|
+
response = request.response
|
160
|
+
|
161
|
+
headers_settings = request.registry.settings.get("headers", {})
|
162
|
+
service_headers_settings = headers_settings.get(service_name, {})
|
163
|
+
|
164
|
+
_set_cors_headers(request, response, service_name, service_headers_settings, credentials)
|
165
|
+
if request.method == "OPTIONS":
|
166
|
+
return response
|
167
|
+
return _set_common_headers(request, response, service_headers_settings, cache, content_type)
|