MapProxy 2.1.0__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.
- MapProxy-2.1.0.dist-info/AUTHORS.txt +33 -0
- MapProxy-2.1.0.dist-info/COPYING.txt +60 -0
- MapProxy-2.1.0.dist-info/LICENSE.txt +202 -0
- MapProxy-2.1.0.dist-info/METADATA +165 -0
- MapProxy-2.1.0.dist-info/RECORD +459 -0
- MapProxy-2.1.0.dist-info/WHEEL +5 -0
- MapProxy-2.1.0.dist-info/entry_points.txt +4 -0
- MapProxy-2.1.0.dist-info/top_level.txt +1 -0
- mapproxy/__init__.py +0 -0
- mapproxy/cache/__init__.py +36 -0
- mapproxy/cache/azureblob.py +145 -0
- mapproxy/cache/base.py +120 -0
- mapproxy/cache/compact.py +665 -0
- mapproxy/cache/couchdb.py +301 -0
- mapproxy/cache/dummy.py +36 -0
- mapproxy/cache/file.py +200 -0
- mapproxy/cache/geopackage.py +647 -0
- mapproxy/cache/legend.py +87 -0
- mapproxy/cache/mbtiles.py +411 -0
- mapproxy/cache/meta.py +80 -0
- mapproxy/cache/path.py +261 -0
- mapproxy/cache/redis.py +152 -0
- mapproxy/cache/renderd.py +100 -0
- mapproxy/cache/riak.py +206 -0
- mapproxy/cache/s3.py +209 -0
- mapproxy/cache/tile.py +736 -0
- mapproxy/client/__init__.py +0 -0
- mapproxy/client/arcgis.py +82 -0
- mapproxy/client/cgi.py +141 -0
- mapproxy/client/http.py +295 -0
- mapproxy/client/log.py +33 -0
- mapproxy/client/tile.py +158 -0
- mapproxy/client/wms.py +255 -0
- mapproxy/compat/__init__.py +0 -0
- mapproxy/compat/image.py +86 -0
- mapproxy/config/__init__.py +22 -0
- mapproxy/config/config-schema.json +813 -0
- mapproxy/config/config.py +213 -0
- mapproxy/config/coverage.py +108 -0
- mapproxy/config/defaults.py +102 -0
- mapproxy/config/loader.py +2399 -0
- mapproxy/config/spec.py +657 -0
- mapproxy/config/validator.py +242 -0
- mapproxy/config_template/__init__.py +0 -0
- mapproxy/config_template/base_config/config.wsgi +10 -0
- mapproxy/config_template/base_config/full_example.yaml +598 -0
- mapproxy/config_template/base_config/full_seed_example.yaml +79 -0
- mapproxy/config_template/base_config/log.ini +35 -0
- mapproxy/config_template/base_config/mapproxy.yaml +60 -0
- mapproxy/config_template/base_config/seed.yaml +27 -0
- mapproxy/exception.py +149 -0
- mapproxy/featureinfo.py +251 -0
- mapproxy/grid.py +1199 -0
- mapproxy/image/__init__.py +549 -0
- mapproxy/image/fonts/DejaVuSans.ttf +0 -0
- mapproxy/image/fonts/DejaVuSansMono.ttf +0 -0
- mapproxy/image/fonts/LICENSE +99 -0
- mapproxy/image/fonts/__init__.py +0 -0
- mapproxy/image/mask.py +79 -0
- mapproxy/image/merge.py +323 -0
- mapproxy/image/message.py +357 -0
- mapproxy/image/opts.py +185 -0
- mapproxy/image/tile.py +171 -0
- mapproxy/image/transform.py +350 -0
- mapproxy/layer.py +489 -0
- mapproxy/multiapp.py +230 -0
- mapproxy/proj.py +309 -0
- mapproxy/request/__init__.py +18 -0
- mapproxy/request/arcgis.py +268 -0
- mapproxy/request/base.py +466 -0
- mapproxy/request/tile.py +131 -0
- mapproxy/request/wms/__init__.py +829 -0
- mapproxy/request/wms/exception.py +107 -0
- mapproxy/request/wmts.py +442 -0
- mapproxy/response.py +237 -0
- mapproxy/script/__init__.py +0 -0
- mapproxy/script/conf/__init__.py +0 -0
- mapproxy/script/conf/app.py +222 -0
- mapproxy/script/conf/caches.py +44 -0
- mapproxy/script/conf/geopackage.py +136 -0
- mapproxy/script/conf/layers.py +54 -0
- mapproxy/script/conf/seeds.py +36 -0
- mapproxy/script/conf/sources.py +88 -0
- mapproxy/script/conf/utils.py +148 -0
- mapproxy/script/defrag.py +187 -0
- mapproxy/script/export.py +337 -0
- mapproxy/script/grids.py +198 -0
- mapproxy/script/scales.py +134 -0
- mapproxy/script/util.py +410 -0
- mapproxy/script/wms_capabilities.py +160 -0
- mapproxy/seed/__init__.py +0 -0
- mapproxy/seed/cachelock.py +127 -0
- mapproxy/seed/cleanup.py +191 -0
- mapproxy/seed/config.py +481 -0
- mapproxy/seed/script.py +391 -0
- mapproxy/seed/seeder.py +551 -0
- mapproxy/seed/spec.py +66 -0
- mapproxy/seed/util.py +266 -0
- mapproxy/service/__init__.py +14 -0
- mapproxy/service/base.py +45 -0
- mapproxy/service/demo.py +364 -0
- mapproxy/service/kml.py +333 -0
- mapproxy/service/ows.py +39 -0
- mapproxy/service/template_helper.py +55 -0
- mapproxy/service/templates/demo/capabilities_demo.html +18 -0
- mapproxy/service/templates/demo/demo.html +181 -0
- mapproxy/service/templates/demo/openlayers-demo.cfg +16 -0
- mapproxy/service/templates/demo/static/img/blank.gif +0 -0
- mapproxy/service/templates/demo/static/img/east-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/north-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/south-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/west-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-minus-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-plus-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-world-mini.png +0 -0
- mapproxy/service/templates/demo/static/logo.png +0 -0
- mapproxy/service/templates/demo/static/ol.css +345 -0
- mapproxy/service/templates/demo/static/ol.js +4 -0
- mapproxy/service/templates/demo/static/proj4.min.js +1 -0
- mapproxy/service/templates/demo/static/proj4defs.js +1 -0
- mapproxy/service/templates/demo/static/site.css +137 -0
- mapproxy/service/templates/demo/static/theme/default/framedCloud.css +0 -0
- mapproxy/service/templates/demo/static/theme/default/google.css +17 -0
- mapproxy/service/templates/demo/static/theme/default/ie6-style.css +10 -0
- mapproxy/service/templates/demo/static/theme/default/style.css +482 -0
- mapproxy/service/templates/demo/static.html +34 -0
- mapproxy/service/templates/demo/tms_demo.html +117 -0
- mapproxy/service/templates/demo/wms_demo.html +144 -0
- mapproxy/service/templates/demo/wmts_demo.html +118 -0
- mapproxy/service/templates/tms_capabilities.xml +13 -0
- mapproxy/service/templates/tms_exception.xml +4 -0
- mapproxy/service/templates/tms_root_resource.xml +7 -0
- mapproxy/service/templates/tms_tilemap_capabilities.xml +14 -0
- mapproxy/service/templates/wms100capabilities.xml +112 -0
- mapproxy/service/templates/wms100exception.xml +4 -0
- mapproxy/service/templates/wms110capabilities.xml +152 -0
- mapproxy/service/templates/wms110exception.xml +5 -0
- mapproxy/service/templates/wms111capabilities.xml +183 -0
- mapproxy/service/templates/wms111exception.xml +5 -0
- mapproxy/service/templates/wms130capabilities.xml +326 -0
- mapproxy/service/templates/wms130exception.xml +8 -0
- mapproxy/service/templates/wmts100capabilities.xml +155 -0
- mapproxy/service/templates/wmts100exception.xml +9 -0
- mapproxy/service/tile.py +540 -0
- mapproxy/service/wms.py +868 -0
- mapproxy/service/wmts.py +387 -0
- mapproxy/source/__init__.py +83 -0
- mapproxy/source/arcgis.py +39 -0
- mapproxy/source/error.py +40 -0
- mapproxy/source/mapnik.py +262 -0
- mapproxy/source/tile.py +97 -0
- mapproxy/source/wms.py +273 -0
- mapproxy/srs.py +734 -0
- mapproxy/template.py +54 -0
- mapproxy/test/__init__.py +0 -0
- mapproxy/test/conftest.py +8 -0
- mapproxy/test/helper.py +255 -0
- mapproxy/test/http.py +511 -0
- mapproxy/test/image.py +219 -0
- mapproxy/test/mocker.py +2291 -0
- mapproxy/test/schemas/inspire/common/1.0/common.xsd +1461 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_bul.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_cze.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_dan.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_dut.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_eng.xsd +155 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_est.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_fin.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_fre.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_ger.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_gle.xsd +109 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_gre.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_hun.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_ita.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_lav.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_lit.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_mlt.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_pol.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_por.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_rum.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_slo.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_slv.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_spa.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_swe.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/network.xsd +521 -0
- mapproxy/test/schemas/inspire/inspire_vs/1.0/inspire_vs.xsd +19 -0
- mapproxy/test/schemas/kml/2.2.0/ReadMe.txt +14 -0
- mapproxy/test/schemas/kml/2.2.0/atom-author-link.xsd +66 -0
- mapproxy/test/schemas/kml/2.2.0/ogckml22.xsd +1646 -0
- mapproxy/test/schemas/kml/2.2.0/xAL.xsd +1680 -0
- mapproxy/test/schemas/ows/1.1.0/ReadMe.txt +87 -0
- mapproxy/test/schemas/ows/1.1.0/ows19115subset.xsd +235 -0
- mapproxy/test/schemas/ows/1.1.0/owsAll.xsd +23 -0
- mapproxy/test/schemas/ows/1.1.0/owsCommon.xsd +157 -0
- mapproxy/test/schemas/ows/1.1.0/owsContents.xsd +86 -0
- mapproxy/test/schemas/ows/1.1.0/owsDataIdentification.xsd +127 -0
- mapproxy/test/schemas/ows/1.1.0/owsDomainType.xsd +279 -0
- mapproxy/test/schemas/ows/1.1.0/owsExceptionReport.xsd +76 -0
- mapproxy/test/schemas/ows/1.1.0/owsGetCapabilities.xsd +112 -0
- mapproxy/test/schemas/ows/1.1.0/owsGetResourceByID.xsd +51 -0
- mapproxy/test/schemas/ows/1.1.0/owsInputOutputData.xsd +59 -0
- mapproxy/test/schemas/ows/1.1.0/owsManifest.xsd +125 -0
- mapproxy/test/schemas/ows/1.1.0/owsOperationsMetadata.xsd +140 -0
- mapproxy/test/schemas/ows/1.1.0/owsServiceIdentification.xsd +60 -0
- mapproxy/test/schemas/ows/1.1.0/owsServiceProvider.xsd +47 -0
- mapproxy/test/schemas/sld/1.1.0/sld_capabilities.xsd +27 -0
- mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.dtd +353 -0
- mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.xml +188 -0
- mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.dtd +524 -0
- mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.xml +260 -0
- mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.dtd +273 -0
- mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.xml +303 -0
- mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.dtd +6 -0
- mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.xml +33 -0
- mapproxy/test/schemas/wms/1.1.1/OGC-exception.xsd +68 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd +274 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd +5 -0
- mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.dtd +276 -0
- mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.xml +303 -0
- mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.dtd +6 -0
- mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.xml +33 -0
- mapproxy/test/schemas/wms/1.3.0/ReadMe.txt +8 -0
- mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xml +277 -0
- mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xsd +611 -0
- mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xml +34 -0
- mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xsd +28 -0
- mapproxy/test/schemas/wmsc/1.1.1/OGC-exception.xsd +68 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_MS_Capabilities.dtd +283 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_exception_1_1_1.dtd +5 -0
- mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.dtd +276 -0
- mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.xml +303 -0
- mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.dtd +6 -0
- mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.xml +33 -0
- mapproxy/test/schemas/wmts/1.0/ReadMe.txt +32 -0
- mapproxy/test/schemas/wmts/1.0/wmts.xsd +28 -0
- mapproxy/test/schemas/wmts/1.0/wmtsAbstract.wsdl +151 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_request.xsd +38 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_response.xsd +564 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_request.xsd +57 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_response.xsd +72 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetTile_request.xsd +91 -0
- mapproxy/test/schemas/wmts/1.0/wmtsKVP.xsd +76 -0
- mapproxy/test/schemas/wmts/1.0/wmtsPayload_response.xsd +70 -0
- mapproxy/test/schemas/xlink/1.0.0/ReadMe.txt +6 -0
- mapproxy/test/schemas/xlink/1.0.0/xlinks.xsd +122 -0
- mapproxy/test/schemas/xml.xsd +287 -0
- mapproxy/test/system/__init__.py +98 -0
- mapproxy/test/system/fixture/arcgis.yaml +57 -0
- mapproxy/test/system/fixture/auth.yaml +70 -0
- mapproxy/test/system/fixture/cache.mbtiles +0 -0
- mapproxy/test/system/fixture/cache_azureblob.yaml +59 -0
- mapproxy/test/system/fixture/cache_band_merge.yaml +73 -0
- mapproxy/test/system/fixture/cache_bulk_meta_tiles.yaml +24 -0
- mapproxy/test/system/fixture/cache_coverage.yaml +84 -0
- mapproxy/test/system/fixture/cache_data/dop_cache_EPSG3857/00/000/000/000/000/000/000.png +0 -0
- mapproxy/test/system/fixture/cache_data/wms_cache_EPSG900913/01/000/000/000/000/000/001.jpeg +0 -0
- mapproxy/test/system/fixture/cache_data/wms_cache_transparent_EPSG900913/01/000/000/000/000/000/001.png +0 -0
- mapproxy/test/system/fixture/cache_geopackage.yaml +56 -0
- mapproxy/test/system/fixture/cache_grid_names.yaml +50 -0
- mapproxy/test/system/fixture/cache_mbtiles.yaml +28 -0
- mapproxy/test/system/fixture/cache_s3.yaml +58 -0
- mapproxy/test/system/fixture/cache_source.yaml +81 -0
- mapproxy/test/system/fixture/combined_sources.yaml +130 -0
- mapproxy/test/system/fixture/coverage.yaml +77 -0
- mapproxy/test/system/fixture/demo.yaml +135 -0
- mapproxy/test/system/fixture/dimension.yaml +59 -0
- mapproxy/test/system/fixture/disable_storage.yaml +25 -0
- mapproxy/test/system/fixture/empty_ogrdata.geojson +1 -0
- mapproxy/test/system/fixture/formats.yaml +72 -0
- mapproxy/test/system/fixture/inspire.yaml +101 -0
- mapproxy/test/system/fixture/inspire_full.yaml +124 -0
- mapproxy/test/system/fixture/kml_layer.yaml +66 -0
- mapproxy/test/system/fixture/layer.yaml +260 -0
- mapproxy/test/system/fixture/layergroups.yaml +57 -0
- mapproxy/test/system/fixture/layergroups_root.yaml +106 -0
- mapproxy/test/system/fixture/legendgraphic.yaml +93 -0
- mapproxy/test/system/fixture/mapnik_source.yaml +66 -0
- mapproxy/test/system/fixture/mapproxy_export.yaml +12 -0
- mapproxy/test/system/fixture/mapserver.yaml +23 -0
- mapproxy/test/system/fixture/minimal_cgi.py +16 -0
- mapproxy/test/system/fixture/mixed_mode.yaml +49 -0
- mapproxy/test/system/fixture/multi_cache_layers.yaml +111 -0
- mapproxy/test/system/fixture/multiapp1.yaml +20 -0
- mapproxy/test/system/fixture/multiapp2.yaml +19 -0
- mapproxy/test/system/fixture/renderd_client.yaml +55 -0
- mapproxy/test/system/fixture/scalehints.yaml +70 -0
- mapproxy/test/system/fixture/seed.yaml +94 -0
- mapproxy/test/system/fixture/seed_mapproxy.yaml +39 -0
- mapproxy/test/system/fixture/seed_old.yaml +12 -0
- mapproxy/test/system/fixture/seed_timeouts.yaml +12 -0
- mapproxy/test/system/fixture/seed_timeouts_mapproxy.yaml +27 -0
- mapproxy/test/system/fixture/seedonly.yaml +51 -0
- mapproxy/test/system/fixture/sld.yaml +35 -0
- mapproxy/test/system/fixture/source_errors.yaml +84 -0
- mapproxy/test/system/fixture/source_errors_raise.yaml +82 -0
- mapproxy/test/system/fixture/tileservice_origin.yaml +26 -0
- mapproxy/test/system/fixture/tileservice_refresh.yaml +59 -0
- mapproxy/test/system/fixture/tilesource_minmax_res.yaml +22 -0
- mapproxy/test/system/fixture/util-conf-base-grids.yaml +5 -0
- mapproxy/test/system/fixture/util-conf-overwrite.yaml +13 -0
- mapproxy/test/system/fixture/util-conf-wms-111-cap.xml +90 -0
- mapproxy/test/system/fixture/util_grids.yaml +29 -0
- mapproxy/test/system/fixture/util_wms_capabilities111.xml +130 -0
- mapproxy/test/system/fixture/util_wms_capabilities130.xml +100 -0
- mapproxy/test/system/fixture/util_wms_capabilities_service_exception.xml +5 -0
- mapproxy/test/system/fixture/watermark.yaml +50 -0
- mapproxy/test/system/fixture/wms_srs_extent.yaml +39 -0
- mapproxy/test/system/fixture/wms_versions.yaml +38 -0
- mapproxy/test/system/fixture/wmts.yaml +134 -0
- mapproxy/test/system/fixture/wmts_dimensions.yaml +57 -0
- mapproxy/test/system/fixture/xslt_featureinfo.yaml +54 -0
- mapproxy/test/system/fixture/xslt_featureinfo_input.yaml +51 -0
- mapproxy/test/system/test_arcgis.py +156 -0
- mapproxy/test/system/test_auth.py +1133 -0
- mapproxy/test/system/test_behind_proxy.py +75 -0
- mapproxy/test/system/test_bulk_meta_tiles.py +106 -0
- mapproxy/test/system/test_cache_azureblob.py +127 -0
- mapproxy/test/system/test_cache_band_merge.py +103 -0
- mapproxy/test/system/test_cache_coverage.py +168 -0
- mapproxy/test/system/test_cache_geopackage.py +144 -0
- mapproxy/test/system/test_cache_grid_names.py +89 -0
- mapproxy/test/system/test_cache_mbtiles.py +85 -0
- mapproxy/test/system/test_cache_s3.py +115 -0
- mapproxy/test/system/test_cache_source.py +146 -0
- mapproxy/test/system/test_combined_sources.py +335 -0
- mapproxy/test/system/test_coverage.py +140 -0
- mapproxy/test/system/test_decorate_img.py +214 -0
- mapproxy/test/system/test_demo.py +56 -0
- mapproxy/test/system/test_demo_with_extra_service.py +57 -0
- mapproxy/test/system/test_dimensions.py +279 -0
- mapproxy/test/system/test_disable_storage.py +42 -0
- mapproxy/test/system/test_formats.py +219 -0
- mapproxy/test/system/test_inspire_vs.py +173 -0
- mapproxy/test/system/test_kml.py +264 -0
- mapproxy/test/system/test_layergroups.py +160 -0
- mapproxy/test/system/test_legendgraphic.py +308 -0
- mapproxy/test/system/test_mapnik.py +162 -0
- mapproxy/test/system/test_mapserver.py +83 -0
- mapproxy/test/system/test_mixed_mode_format.py +201 -0
- mapproxy/test/system/test_multi_cache_layers.py +169 -0
- mapproxy/test/system/test_multiapp.py +92 -0
- mapproxy/test/system/test_refresh.py +206 -0
- mapproxy/test/system/test_renderd_client.py +304 -0
- mapproxy/test/system/test_response_headers.py +54 -0
- mapproxy/test/system/test_scalehints.py +140 -0
- mapproxy/test/system/test_seed.py +425 -0
- mapproxy/test/system/test_seed_only.py +93 -0
- mapproxy/test/system/test_sld.py +120 -0
- mapproxy/test/system/test_source_errors.py +377 -0
- mapproxy/test/system/test_tilesource_minmax_res.py +54 -0
- mapproxy/test/system/test_tms.py +277 -0
- mapproxy/test/system/test_tms_origin.py +46 -0
- mapproxy/test/system/test_util_conf.py +434 -0
- mapproxy/test/system/test_util_export.py +210 -0
- mapproxy/test/system/test_util_grids.py +88 -0
- mapproxy/test/system/test_util_wms_capabilities.py +182 -0
- mapproxy/test/system/test_watermark.py +91 -0
- mapproxy/test/system/test_wms.py +1616 -0
- mapproxy/test/system/test_wms_srs_extent.py +165 -0
- mapproxy/test/system/test_wms_version.py +85 -0
- mapproxy/test/system/test_wmsc.py +116 -0
- mapproxy/test/system/test_wmts.py +334 -0
- mapproxy/test/system/test_wmts_dimensions.py +206 -0
- mapproxy/test/system/test_wmts_restful.py +198 -0
- mapproxy/test/system/test_xslt_featureinfo.py +423 -0
- mapproxy/test/test_http_helper.py +217 -0
- mapproxy/test/unit/__init__.py +0 -0
- mapproxy/test/unit/epsg +2 -0
- mapproxy/test/unit/polygons/polygons.dbf +0 -0
- mapproxy/test/unit/polygons/polygons.shp +0 -0
- mapproxy/test/unit/polygons/polygons.shx +0 -0
- mapproxy/test/unit/test_async.py +242 -0
- mapproxy/test/unit/test_auth.py +430 -0
- mapproxy/test/unit/test_cache.py +1356 -0
- mapproxy/test/unit/test_cache_azureblob.py +97 -0
- mapproxy/test/unit/test_cache_compact.py +324 -0
- mapproxy/test/unit/test_cache_couchdb.py +118 -0
- mapproxy/test/unit/test_cache_geopackage.py +256 -0
- mapproxy/test/unit/test_cache_redis.py +123 -0
- mapproxy/test/unit/test_cache_riak.py +80 -0
- mapproxy/test/unit/test_cache_s3.py +93 -0
- mapproxy/test/unit/test_cache_tile.py +477 -0
- mapproxy/test/unit/test_client.py +488 -0
- mapproxy/test/unit/test_client_arcgis.py +74 -0
- mapproxy/test/unit/test_client_cgi.py +140 -0
- mapproxy/test/unit/test_collections.py +116 -0
- mapproxy/test/unit/test_concat_legends.py +37 -0
- mapproxy/test/unit/test_conf_loader.py +1267 -0
- mapproxy/test/unit/test_conf_validator.py +427 -0
- mapproxy/test/unit/test_config.py +118 -0
- mapproxy/test/unit/test_decorate_img.py +185 -0
- mapproxy/test/unit/test_exceptions.py +270 -0
- mapproxy/test/unit/test_featureinfo.py +313 -0
- mapproxy/test/unit/test_file_lock_load.py +49 -0
- mapproxy/test/unit/test_geom.py +512 -0
- mapproxy/test/unit/test_grid.py +1279 -0
- mapproxy/test/unit/test_image.py +1051 -0
- mapproxy/test/unit/test_image_mask.py +181 -0
- mapproxy/test/unit/test_image_messages.py +209 -0
- mapproxy/test/unit/test_image_options.py +160 -0
- mapproxy/test/unit/test_isodate.py +118 -0
- mapproxy/test/unit/test_multiapp.py +163 -0
- mapproxy/test/unit/test_ogr_reader.py +51 -0
- mapproxy/test/unit/test_request.py +745 -0
- mapproxy/test/unit/test_request_wmts.py +178 -0
- mapproxy/test/unit/test_response.py +78 -0
- mapproxy/test/unit/test_seed.py +365 -0
- mapproxy/test/unit/test_seed_cachelock.py +91 -0
- mapproxy/test/unit/test_srs.py +215 -0
- mapproxy/test/unit/test_tiled_source.py +122 -0
- mapproxy/test/unit/test_tilefilter.py +31 -0
- mapproxy/test/unit/test_times.py +25 -0
- mapproxy/test/unit/test_timeutils.py +50 -0
- mapproxy/test/unit/test_util_conf_utils.py +75 -0
- mapproxy/test/unit/test_utils.py +476 -0
- mapproxy/test/unit/test_wms_capabilities.py +44 -0
- mapproxy/test/unit/test_wms_layer.py +113 -0
- mapproxy/test/unit/test_yaml.py +68 -0
- mapproxy/tilefilter.py +61 -0
- mapproxy/util/__init__.py +0 -0
- mapproxy/util/async_.py +229 -0
- mapproxy/util/collections.py +134 -0
- mapproxy/util/coverage.py +337 -0
- mapproxy/util/ext/__init__.py +14 -0
- mapproxy/util/ext/dictspec/__init__.py +1 -0
- mapproxy/util/ext/dictspec/spec.py +131 -0
- mapproxy/util/ext/dictspec/test/__init__.py +0 -0
- mapproxy/util/ext/dictspec/test/test_validator.py +278 -0
- mapproxy/util/ext/dictspec/validator.py +194 -0
- mapproxy/util/ext/local.py +198 -0
- mapproxy/util/ext/lockfile.py +140 -0
- mapproxy/util/ext/odict.py +321 -0
- mapproxy/util/ext/serving.py +491 -0
- mapproxy/util/ext/tempita/__init__.py +1093 -0
- mapproxy/util/ext/tempita/_looper.py +163 -0
- mapproxy/util/ext/tempita/string_utils.py +24 -0
- mapproxy/util/ext/wmsparse/__init__.py +3 -0
- mapproxy/util/ext/wmsparse/duration.py +600 -0
- mapproxy/util/ext/wmsparse/parse.py +307 -0
- mapproxy/util/ext/wmsparse/test/__init__.py +0 -0
- mapproxy/util/ext/wmsparse/test/test_parse.py +111 -0
- mapproxy/util/ext/wmsparse/test/test_util.py +23 -0
- mapproxy/util/ext/wmsparse/test/wms-example-111.xml +90 -0
- mapproxy/util/ext/wmsparse/test/wms-example-130.xml +120 -0
- mapproxy/util/ext/wmsparse/test/wms-large-111.xml +2114 -0
- mapproxy/util/ext/wmsparse/test/wms_nasa_cap.xml +386 -0
- mapproxy/util/ext/wmsparse/util.py +189 -0
- mapproxy/util/fs.py +164 -0
- mapproxy/util/geom.py +307 -0
- mapproxy/util/lib.py +117 -0
- mapproxy/util/lock.py +171 -0
- mapproxy/util/ogr.py +247 -0
- mapproxy/util/py.py +75 -0
- mapproxy/util/times.py +78 -0
- mapproxy/util/yaml.py +58 -0
- mapproxy/version.py +33 -0
- mapproxy/wsgiapp.py +167 -0
|
@@ -0,0 +1,1133 @@
|
|
|
1
|
+
# This file is part of the MapProxy project.
|
|
2
|
+
# Copyright (C) 2011 Omniscale <http://omniscale.de>
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
from __future__ import division
|
|
17
|
+
|
|
18
|
+
import pytest
|
|
19
|
+
|
|
20
|
+
from mapproxy.srs import bbox_equals
|
|
21
|
+
from mapproxy.util.geom import geom_support
|
|
22
|
+
|
|
23
|
+
from mapproxy.test.http import MockServ
|
|
24
|
+
from mapproxy.test.image import img_from_buf, create_tmp_image, is_transparent
|
|
25
|
+
from mapproxy.test.system import SysTest
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@pytest.fixture(scope="module")
|
|
29
|
+
def config_file():
|
|
30
|
+
return "auth.yaml"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
TESTSERVER_ADDRESS = "localhost", 42423
|
|
34
|
+
CAPABILITIES_REQ = "/service?request=GetCapabilities&service=WMS&Version=1.1.1"
|
|
35
|
+
MAP_REQ = (
|
|
36
|
+
"/service?request=GetMap&service=WMS&Version=1.1.1&SRS=EPSG:4326"
|
|
37
|
+
"&BBOX=-80,-40,0,0&WIDTH=200&HEIGHT=100&styles=&FORMAT=image/png&"
|
|
38
|
+
)
|
|
39
|
+
FI_REQ = (
|
|
40
|
+
"/service?request=GetFeatureInfo&service=WMS&Version=1.1.1&SRS=EPSG:4326"
|
|
41
|
+
"&BBOX=-80,-40,0,0&WIDTH=200&HEIGHT=100&styles=&FORMAT=image/png&X=10&Y=10&"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
pytestmark = pytest.mark.skipif(not geom_support, reason="Shapely required")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class TestWMSAuth(SysTest):
|
|
49
|
+
|
|
50
|
+
# ###
|
|
51
|
+
# see mapproxy.test.unit.test_auth for WMS GetMap request tests
|
|
52
|
+
# ###
|
|
53
|
+
def test_capabilities_authorize_all(self, app):
|
|
54
|
+
|
|
55
|
+
def auth(service, layers, **kw):
|
|
56
|
+
assert service == "wms.capabilities"
|
|
57
|
+
assert len(layers) == 8
|
|
58
|
+
return {"authorized": "full"}
|
|
59
|
+
|
|
60
|
+
resp = app.get(CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth})
|
|
61
|
+
xml = resp.lxml
|
|
62
|
+
assert xml.xpath("//Layer/Name/text()") == [
|
|
63
|
+
"layer1",
|
|
64
|
+
"layer1a",
|
|
65
|
+
"layer1b",
|
|
66
|
+
"layer2",
|
|
67
|
+
"layer2a",
|
|
68
|
+
"layer2b",
|
|
69
|
+
"layer2b1",
|
|
70
|
+
"layer3",
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
def test_capabilities_authorize_none(self, app):
|
|
74
|
+
|
|
75
|
+
def auth(service, layers, **kw):
|
|
76
|
+
assert service == "wms.capabilities"
|
|
77
|
+
assert len(layers) == 8
|
|
78
|
+
return {"authorized": "none"}
|
|
79
|
+
|
|
80
|
+
app.get(
|
|
81
|
+
CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth}, status=403
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def test_capabilities_unauthenticated(self, app):
|
|
85
|
+
|
|
86
|
+
def auth(service, layers, **kw):
|
|
87
|
+
assert service == "wms.capabilities"
|
|
88
|
+
assert len(layers) == 8
|
|
89
|
+
return {"authorized": "unauthenticated"}
|
|
90
|
+
|
|
91
|
+
app.get(
|
|
92
|
+
CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth}, status=401
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
def test_capabilities_authorize_partial(self, app):
|
|
96
|
+
|
|
97
|
+
def auth(service, layers, **kw):
|
|
98
|
+
assert service == "wms.capabilities"
|
|
99
|
+
assert len(layers) == 8
|
|
100
|
+
return {
|
|
101
|
+
"authorized": "partial",
|
|
102
|
+
"layers": {
|
|
103
|
+
"layer1a": {"map": True},
|
|
104
|
+
"layer2": {"map": True},
|
|
105
|
+
"layer2b": {"map": True},
|
|
106
|
+
"layer2b1": {"map": True},
|
|
107
|
+
},
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
resp = app.get(CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth})
|
|
111
|
+
xml = resp.lxml
|
|
112
|
+
# layer1a not included cause root layer (layer1) is not permitted
|
|
113
|
+
assert xml.xpath("//Layer/Name/text()") == ["layer2", "layer2b", "layer2b1"]
|
|
114
|
+
|
|
115
|
+
def test_capabilities_authorize_partial_limited_to(self, app):
|
|
116
|
+
|
|
117
|
+
def auth(service, layers, **kw):
|
|
118
|
+
assert service == "wms.capabilities"
|
|
119
|
+
assert len(layers) == 8
|
|
120
|
+
return {
|
|
121
|
+
"authorized": "partial",
|
|
122
|
+
"layers": {
|
|
123
|
+
"layer1a": {"map": True},
|
|
124
|
+
"layer2": {
|
|
125
|
+
"map": True,
|
|
126
|
+
"limited_to": {
|
|
127
|
+
"srs": "EPSG:4326",
|
|
128
|
+
"geometry": [-40.0, -50.0, 0.0, 5.0],
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
"layer2b": {"map": True},
|
|
132
|
+
"layer2b1": {"map": True},
|
|
133
|
+
},
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
resp = app.get(CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth})
|
|
137
|
+
xml = resp.lxml
|
|
138
|
+
# layer1a not included cause root layer (layer1) is not permitted
|
|
139
|
+
assert xml.xpath("//Layer/Name/text()") == ["layer2", "layer2b", "layer2b1"]
|
|
140
|
+
limited_bbox = xml.xpath("//Layer/LatLonBoundingBox")[1]
|
|
141
|
+
assert float(limited_bbox.attrib["minx"]) == -40.0
|
|
142
|
+
assert float(limited_bbox.attrib["miny"]) == -50.0
|
|
143
|
+
assert float(limited_bbox.attrib["maxx"]) == 0.0
|
|
144
|
+
assert float(limited_bbox.attrib["maxy"]) == 5.0
|
|
145
|
+
|
|
146
|
+
def test_capabilities_authorize_partial_global_limited(self, app):
|
|
147
|
+
|
|
148
|
+
def auth(service, layers, **kw):
|
|
149
|
+
assert service == "wms.capabilities"
|
|
150
|
+
assert len(layers) == 8
|
|
151
|
+
return {
|
|
152
|
+
"authorized": "partial",
|
|
153
|
+
"limited_to": {
|
|
154
|
+
"srs": "EPSG:4326",
|
|
155
|
+
"geometry": [171.0, -50.0, 178.0, 5.0],
|
|
156
|
+
},
|
|
157
|
+
"layers": {
|
|
158
|
+
"layer1": {"map": True},
|
|
159
|
+
"layer1a": {"map": True},
|
|
160
|
+
"layer2": {"map": True},
|
|
161
|
+
"layer2b": {"map": True},
|
|
162
|
+
"layer2b1": {"map": True},
|
|
163
|
+
},
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
resp = app.get(CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth})
|
|
167
|
+
xml = resp.lxml
|
|
168
|
+
# print resp.body
|
|
169
|
+
# layer2/2b/2b1 not included because coverage of 2b1 is outside of global limited_to
|
|
170
|
+
assert xml.xpath("//Layer/Name/text()") == ["layer1", "layer1a"]
|
|
171
|
+
limited_bbox = xml.xpath("//Layer/LatLonBoundingBox")[1]
|
|
172
|
+
assert float(limited_bbox.attrib["minx"]) == 171.0
|
|
173
|
+
assert float(limited_bbox.attrib["miny"]) == -50.0
|
|
174
|
+
assert float(limited_bbox.attrib["maxx"]) == 178.0
|
|
175
|
+
assert float(limited_bbox.attrib["maxy"]) == 5.0
|
|
176
|
+
|
|
177
|
+
def test_capabilities_authorize_partial_with_fi(self, app):
|
|
178
|
+
|
|
179
|
+
def auth(service, layers, **kw):
|
|
180
|
+
assert service == "wms.capabilities"
|
|
181
|
+
assert len(layers) == 8
|
|
182
|
+
return {
|
|
183
|
+
"authorized": "partial",
|
|
184
|
+
"layers": {
|
|
185
|
+
"layer1": {"map": True},
|
|
186
|
+
"layer1a": {"map": True},
|
|
187
|
+
"layer2": {"map": True, "featureinfo": True},
|
|
188
|
+
"layer2b": {"map": True, "featureinfo": True},
|
|
189
|
+
"layer2b1": {"map": True, "featureinfo": True},
|
|
190
|
+
},
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
resp = app.get(CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth})
|
|
194
|
+
xml = resp.lxml
|
|
195
|
+
assert xml.xpath("//Layer/Name/text()") == [
|
|
196
|
+
"layer1",
|
|
197
|
+
"layer1a",
|
|
198
|
+
"layer2",
|
|
199
|
+
"layer2b",
|
|
200
|
+
"layer2b1",
|
|
201
|
+
]
|
|
202
|
+
layers = xml.xpath("//Layer")
|
|
203
|
+
assert layers[3][0].text == "layer2"
|
|
204
|
+
assert layers[3].attrib["queryable"] == "1"
|
|
205
|
+
assert layers[4][0].text == "layer2b"
|
|
206
|
+
assert layers[4].attrib["queryable"] == "1"
|
|
207
|
+
assert layers[5][0].text == "layer2b1"
|
|
208
|
+
assert layers[5].attrib["queryable"] == "1"
|
|
209
|
+
|
|
210
|
+
def test_get_map_authorized(self, app):
|
|
211
|
+
|
|
212
|
+
def auth(service, layers, query_extent, **kw):
|
|
213
|
+
assert query_extent == ("EPSG:4326", (-80.0, -40.0, 0.0, 0.0))
|
|
214
|
+
assert service == "wms.map"
|
|
215
|
+
assert len(layers) == 1
|
|
216
|
+
return {"authorized": "partial", "layers": {"layer1": {"map": True}}}
|
|
217
|
+
|
|
218
|
+
resp = app.get(
|
|
219
|
+
MAP_REQ + "layers=layer1", extra_environ={"mapproxy.authorize": auth}
|
|
220
|
+
)
|
|
221
|
+
assert resp.content_type == "image/png"
|
|
222
|
+
|
|
223
|
+
def test_get_map_authorized_limited(self, app):
|
|
224
|
+
|
|
225
|
+
def auth(service, layers, query_extent, **kw):
|
|
226
|
+
assert query_extent == ("EPSG:4326", (-80.0, -40.0, 0.0, 0.0))
|
|
227
|
+
assert service == "wms.map"
|
|
228
|
+
assert len(layers) == 1
|
|
229
|
+
return {
|
|
230
|
+
"authorized": "partial",
|
|
231
|
+
"layers": {
|
|
232
|
+
"layer1": {
|
|
233
|
+
"map": True,
|
|
234
|
+
"limited_to": {
|
|
235
|
+
"srs": "EPSG:4326",
|
|
236
|
+
"geometry": [-40.0, -40.0, 0.0, 0.0],
|
|
237
|
+
},
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
resp = app.get(
|
|
243
|
+
MAP_REQ + "layers=layer1", extra_environ={"mapproxy.authorize": auth}
|
|
244
|
+
)
|
|
245
|
+
assert resp.content_type == "image/png"
|
|
246
|
+
img = img_from_buf(resp.body)
|
|
247
|
+
# left part not authorized, only bgcolor
|
|
248
|
+
assert len(img.crop((0, 0, 100, 100)).getcolors()) == 1
|
|
249
|
+
# right part authorized, bgcolor + text
|
|
250
|
+
assert len(img.crop((100, 0, 200, 100)).getcolors()) >= 2
|
|
251
|
+
|
|
252
|
+
def test_get_map_authorized_global_limited(self, app):
|
|
253
|
+
|
|
254
|
+
def auth(service, layers, query_extent, **kw):
|
|
255
|
+
assert query_extent == ("EPSG:4326", (-80.0, -40.0, 0.0, 0.0))
|
|
256
|
+
assert service == "wms.map"
|
|
257
|
+
assert len(layers) == 1
|
|
258
|
+
return {
|
|
259
|
+
"authorized": "partial",
|
|
260
|
+
"limited_to": {
|
|
261
|
+
"srs": "EPSG:4326",
|
|
262
|
+
"geometry": [-20.0, -40.0, 0.0, 0.0],
|
|
263
|
+
},
|
|
264
|
+
"layers": {
|
|
265
|
+
"layer1": {
|
|
266
|
+
"map": True,
|
|
267
|
+
"limited_to": {
|
|
268
|
+
"srs": "EPSG:4326",
|
|
269
|
+
"geometry": [-40.0, -40.0, 0.0, 0.0],
|
|
270
|
+
},
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
resp = app.get(
|
|
276
|
+
MAP_REQ + "layers=layer1", extra_environ={"mapproxy.authorize": auth}
|
|
277
|
+
)
|
|
278
|
+
assert resp.content_type == "image/png"
|
|
279
|
+
img = img_from_buf(resp.body)
|
|
280
|
+
# left part not authorized, only bgcolor
|
|
281
|
+
assert len(img.crop((0, 0, 100, 100)).getcolors()) == 1
|
|
282
|
+
# right part authorized, bgcolor + text
|
|
283
|
+
assert len(img.crop((100, 0, 200, 100)).getcolors()) >= 2
|
|
284
|
+
|
|
285
|
+
def test_get_map_authorized_none(self, app):
|
|
286
|
+
|
|
287
|
+
def auth(service, layers, query_extent, **kw):
|
|
288
|
+
assert query_extent == ("EPSG:4326", (-80.0, -40.0, 0.0, 0.0))
|
|
289
|
+
assert service == "wms.map"
|
|
290
|
+
assert len(layers) == 1
|
|
291
|
+
return {"authorized": "partial", "layers": {"layer1": {"map": False}}}
|
|
292
|
+
|
|
293
|
+
app.get(
|
|
294
|
+
MAP_REQ + "layers=layer1",
|
|
295
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
296
|
+
status=403,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
def test_get_featureinfo_limited_to_inside(self, app):
|
|
300
|
+
|
|
301
|
+
def auth(service, layers, query_extent, **kw):
|
|
302
|
+
assert query_extent == ("EPSG:4326", (-80.0, -40.0, 0.0, 0.0))
|
|
303
|
+
assert service == "wms.featureinfo"
|
|
304
|
+
assert len(layers) == 1
|
|
305
|
+
return {
|
|
306
|
+
"authorized": "partial",
|
|
307
|
+
"layers": {
|
|
308
|
+
"layer1b": {
|
|
309
|
+
"featureinfo": True,
|
|
310
|
+
"limited_to": {
|
|
311
|
+
"srs": "EPSG:4326",
|
|
312
|
+
"geometry": [-80.0, -40.0, 0.0, 0.0],
|
|
313
|
+
},
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
serv = MockServ(port=42423)
|
|
319
|
+
serv.expects(
|
|
320
|
+
"/service?request=GetFeatureInfo&service=WMS&Version=1.1.1&SRS=EPSG:4326"
|
|
321
|
+
"&BBOX=-80.0,-40.0,0.0,0.0&WIDTH=200&HEIGHT=100&styles=&FORMAT=image/png&X=10&Y=10"
|
|
322
|
+
"&query_layers=fi&layers=fi"
|
|
323
|
+
)
|
|
324
|
+
serv.returns(b"infoinfo")
|
|
325
|
+
with serv:
|
|
326
|
+
resp = app.get(
|
|
327
|
+
FI_REQ + "query_layers=layer1b&layers=layer1b",
|
|
328
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
329
|
+
)
|
|
330
|
+
assert resp.body == b"infoinfo"
|
|
331
|
+
|
|
332
|
+
def test_get_featureinfo_limited_to_outside(self, app):
|
|
333
|
+
|
|
334
|
+
def auth(service, layers, query_extent, **kw):
|
|
335
|
+
assert query_extent == ("EPSG:4326", (-80.0, -40.0, 0.0, 0.0))
|
|
336
|
+
assert service == "wms.featureinfo"
|
|
337
|
+
assert len(layers) == 1
|
|
338
|
+
return {
|
|
339
|
+
"authorized": "partial",
|
|
340
|
+
"layers": {
|
|
341
|
+
"layer1b": {
|
|
342
|
+
"featureinfo": True,
|
|
343
|
+
"limited_to": {
|
|
344
|
+
"srs": "EPSG:4326",
|
|
345
|
+
"geometry": [-80.0, -40.0, 0.0, -10.0],
|
|
346
|
+
},
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
resp = app.get(
|
|
352
|
+
FI_REQ + "query_layers=layer1b&layers=layer1b",
|
|
353
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
354
|
+
)
|
|
355
|
+
# empty response, FI request is outside of limited_to geometry
|
|
356
|
+
assert resp.body == b""
|
|
357
|
+
|
|
358
|
+
def test_get_featureinfo_global_limited(self, app):
|
|
359
|
+
|
|
360
|
+
def auth(service, layers, query_extent, **kw):
|
|
361
|
+
assert query_extent == ("EPSG:4326", (-80.0, -40.0, 0.0, 0.0))
|
|
362
|
+
assert service == "wms.featureinfo"
|
|
363
|
+
assert len(layers) == 1
|
|
364
|
+
return {
|
|
365
|
+
"authorized": "partial",
|
|
366
|
+
"limited_to": {
|
|
367
|
+
"srs": "EPSG:4326",
|
|
368
|
+
"geometry": [-40.0, -40.0, 0.0, 0.0],
|
|
369
|
+
},
|
|
370
|
+
"layers": {"layer1b": {"featureinfo": True}},
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
resp = app.get(
|
|
374
|
+
FI_REQ + "query_layers=layer1b&layers=layer1b",
|
|
375
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
376
|
+
)
|
|
377
|
+
# empty response, FI request is outside of limited_to geometry
|
|
378
|
+
assert resp.body == b""
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
TMS_CAPABILITIES_REQ = "/tms/1.0.0"
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
class TestTMSAuth(SysTest):
|
|
385
|
+
|
|
386
|
+
def test_capabilities_authorize_all(self, app):
|
|
387
|
+
|
|
388
|
+
def auth(service, layers, environ, **kw):
|
|
389
|
+
assert environ["PATH_INFO"] == "/tms/1.0.0"
|
|
390
|
+
assert service == "tms"
|
|
391
|
+
assert len(layers) == 6
|
|
392
|
+
return {"authorized": "full"}
|
|
393
|
+
|
|
394
|
+
resp = app.get(TMS_CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth})
|
|
395
|
+
xml = resp.lxml
|
|
396
|
+
assert xml.xpath("//TileMap/@title") == [
|
|
397
|
+
"layer 1a",
|
|
398
|
+
"layer 1b",
|
|
399
|
+
"layer 1",
|
|
400
|
+
"layer 2a",
|
|
401
|
+
"layer 2b1",
|
|
402
|
+
"layer 3",
|
|
403
|
+
]
|
|
404
|
+
|
|
405
|
+
def test_capabilities_authorize_none(self, app):
|
|
406
|
+
|
|
407
|
+
def auth(service, layers, **kw):
|
|
408
|
+
assert service == "tms"
|
|
409
|
+
assert len(layers) == 6
|
|
410
|
+
return {"authorized": "none"}
|
|
411
|
+
|
|
412
|
+
app.get(
|
|
413
|
+
TMS_CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth}, status=403
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
def test_capabilities_unauthenticated(self, app):
|
|
417
|
+
|
|
418
|
+
def auth(service, layers, **kw):
|
|
419
|
+
assert service == "tms"
|
|
420
|
+
assert len(layers) == 6
|
|
421
|
+
return {"authorized": "unauthenticated"}
|
|
422
|
+
|
|
423
|
+
app.get(
|
|
424
|
+
TMS_CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth}, status=401
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
def test_capabilities_authorize_partial(self, app):
|
|
428
|
+
|
|
429
|
+
def auth(service, layers, **kw):
|
|
430
|
+
assert service == "tms"
|
|
431
|
+
assert len(layers) == 6
|
|
432
|
+
return {
|
|
433
|
+
"authorized": "partial",
|
|
434
|
+
"layers": {
|
|
435
|
+
"layer1a": {"tile": True},
|
|
436
|
+
"layer1b": {"tile": False},
|
|
437
|
+
"layer2": {"tile": True},
|
|
438
|
+
"layer2b": {"tile": True},
|
|
439
|
+
"layer2b1": {"tile": True},
|
|
440
|
+
},
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
resp = app.get(TMS_CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth})
|
|
444
|
+
xml = resp.lxml
|
|
445
|
+
assert xml.xpath("//TileMap/@title") == ["layer 1a", "layer 2b1"]
|
|
446
|
+
|
|
447
|
+
def test_layer_capabilities_authorize_none(self, app):
|
|
448
|
+
|
|
449
|
+
def auth(service, layers, **kw):
|
|
450
|
+
assert service == "tms"
|
|
451
|
+
assert len(layers) == 1
|
|
452
|
+
return {"authorized": "none"}
|
|
453
|
+
|
|
454
|
+
app.get(
|
|
455
|
+
TMS_CAPABILITIES_REQ + "/layer1",
|
|
456
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
457
|
+
status=403,
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
def test_layer_capabilities_authorize_all(self, app):
|
|
461
|
+
|
|
462
|
+
def auth(service, layers, **kw):
|
|
463
|
+
assert service == "tms"
|
|
464
|
+
assert len(layers) == 1
|
|
465
|
+
return {"authorized": "full"}
|
|
466
|
+
|
|
467
|
+
resp = app.get(
|
|
468
|
+
TMS_CAPABILITIES_REQ + "/layer1", extra_environ={"mapproxy.authorize": auth}
|
|
469
|
+
)
|
|
470
|
+
xml = resp.lxml
|
|
471
|
+
assert xml.xpath("//TileMap/Title/text()") == ["layer 1"]
|
|
472
|
+
|
|
473
|
+
def test_layer_capabilities_authorize_partial(self, app):
|
|
474
|
+
|
|
475
|
+
def auth(service, layers, **kw):
|
|
476
|
+
assert service == "tms"
|
|
477
|
+
assert len(layers) == 1
|
|
478
|
+
return {"authorized": "partial", "layers": {"layer1": {"tile": True}}}
|
|
479
|
+
|
|
480
|
+
resp = app.get(
|
|
481
|
+
TMS_CAPABILITIES_REQ + "/layer1", extra_environ={"mapproxy.authorize": auth}
|
|
482
|
+
)
|
|
483
|
+
xml = resp.lxml
|
|
484
|
+
assert xml.xpath("//TileMap/Title/text()") == ["layer 1"]
|
|
485
|
+
|
|
486
|
+
def test_layer_capabilities_deny_partial(self, app):
|
|
487
|
+
|
|
488
|
+
def auth(service, layers, **kw):
|
|
489
|
+
assert service == "tms"
|
|
490
|
+
assert len(layers) == 1
|
|
491
|
+
return {"authorized": "partial", "layers": {"layer1": {"tile": False}}}
|
|
492
|
+
|
|
493
|
+
app.get(
|
|
494
|
+
TMS_CAPABILITIES_REQ + "/layer1",
|
|
495
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
496
|
+
status=403,
|
|
497
|
+
)
|
|
498
|
+
|
|
499
|
+
def test_get_tile(self, app):
|
|
500
|
+
|
|
501
|
+
def auth(service, layers, environ, query_extent, **kw):
|
|
502
|
+
assert environ["PATH_INFO"] == "/tms/1.0.0/layer1_EPSG900913/0/0/0.png"
|
|
503
|
+
assert service == "tms"
|
|
504
|
+
assert query_extent[0] == "EPSG:900913"
|
|
505
|
+
assert bbox_equals(
|
|
506
|
+
query_extent[1], (-20037508.342789244, -20037508.342789244, 0, 0)
|
|
507
|
+
)
|
|
508
|
+
assert len(layers) == 1
|
|
509
|
+
return {"authorized": "partial", "layers": {"layer1": {"tile": True}}}
|
|
510
|
+
|
|
511
|
+
resp = app.get(
|
|
512
|
+
TMS_CAPABILITIES_REQ + "/layer1_EPSG900913/0/0/0.png",
|
|
513
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
514
|
+
)
|
|
515
|
+
assert resp.content_type == "image/png"
|
|
516
|
+
assert resp.content_length > 1000
|
|
517
|
+
|
|
518
|
+
def test_get_tile_global_limited_to(self, app):
|
|
519
|
+
# check with limited_to for all layers
|
|
520
|
+
auth_dict = {
|
|
521
|
+
"authorized": "partial",
|
|
522
|
+
"limited_to": {"geometry": [-180, -89, -90, 89], "srs": "EPSG:4326"},
|
|
523
|
+
"layers": {"layer3": {"tile": True}},
|
|
524
|
+
}
|
|
525
|
+
self.check_get_tile_limited_to(app, auth_dict)
|
|
526
|
+
|
|
527
|
+
def test_get_tile_layer_limited_to(self, app):
|
|
528
|
+
# check with limited_to for one layer
|
|
529
|
+
auth_dict = {
|
|
530
|
+
"authorized": "partial",
|
|
531
|
+
"layers": {
|
|
532
|
+
"layer3": {
|
|
533
|
+
"tile": True,
|
|
534
|
+
"limited_to": {
|
|
535
|
+
"geometry": [-180, -89, -90, 89],
|
|
536
|
+
"srs": "EPSG:4326",
|
|
537
|
+
},
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
self.check_get_tile_limited_to(app, auth_dict)
|
|
543
|
+
|
|
544
|
+
def check_get_tile_limited_to(self, app, auth_dict):
|
|
545
|
+
|
|
546
|
+
def auth(service, layers, environ, query_extent, **kw):
|
|
547
|
+
assert environ["PATH_INFO"] == "/tms/1.0.0/layer3/0/0/0.jpeg"
|
|
548
|
+
assert service == "tms"
|
|
549
|
+
assert len(layers) == 1
|
|
550
|
+
assert query_extent[0] == "EPSG:900913"
|
|
551
|
+
assert bbox_equals(
|
|
552
|
+
query_extent[1], (-20037508.342789244, -20037508.342789244, 0, 0)
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
return auth_dict
|
|
556
|
+
|
|
557
|
+
serv = MockServ(port=42423)
|
|
558
|
+
serv.expects("/1/0/0.png")
|
|
559
|
+
serv.returns(
|
|
560
|
+
create_tmp_image((256, 256), color=(255, 0, 0)),
|
|
561
|
+
headers={"content-type": "image/png"},
|
|
562
|
+
)
|
|
563
|
+
with serv:
|
|
564
|
+
resp = app.get(
|
|
565
|
+
TMS_CAPABILITIES_REQ + "/layer3/0/0/0.jpeg",
|
|
566
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
567
|
+
)
|
|
568
|
+
|
|
569
|
+
assert resp.content_type == "image/png"
|
|
570
|
+
|
|
571
|
+
img = img_from_buf(resp.body)
|
|
572
|
+
img = img.convert("RGBA")
|
|
573
|
+
# left part authorized, red
|
|
574
|
+
assert img.crop((0, 0, 127, 255)).getcolors()[0] == (
|
|
575
|
+
127 * 255,
|
|
576
|
+
(255, 0, 0, 255),
|
|
577
|
+
)
|
|
578
|
+
# right part not authorized, transparent
|
|
579
|
+
assert img.crop((129, 0, 255, 255)).getcolors()[0][1][3] == 0
|
|
580
|
+
|
|
581
|
+
def test_get_tile_authorize_none(self, app):
|
|
582
|
+
|
|
583
|
+
def auth(service, layers, **kw):
|
|
584
|
+
assert service == "tms"
|
|
585
|
+
assert len(layers) == 1
|
|
586
|
+
return {"authorized": "none"}
|
|
587
|
+
|
|
588
|
+
app.get(
|
|
589
|
+
TMS_CAPABILITIES_REQ + "/layer1/0/0/0.png",
|
|
590
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
591
|
+
status=403,
|
|
592
|
+
)
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
class TestKMLAuth(SysTest):
|
|
596
|
+
|
|
597
|
+
def test_superoverlay_authorize_all(self, app):
|
|
598
|
+
|
|
599
|
+
def auth(service, layers, environ, **kw):
|
|
600
|
+
assert environ["PATH_INFO"] == "/kml/layer1/0/0/0.kml"
|
|
601
|
+
assert service == "kml"
|
|
602
|
+
assert len(layers) == 1
|
|
603
|
+
return {"authorized": "full"}
|
|
604
|
+
|
|
605
|
+
resp = app.get(
|
|
606
|
+
"/kml/layer1/0/0/0.kml", extra_environ={"mapproxy.authorize": auth}
|
|
607
|
+
)
|
|
608
|
+
xml = resp.lxml
|
|
609
|
+
assert xml.xpath(
|
|
610
|
+
"kml:Document/kml:name/text()",
|
|
611
|
+
namespaces={"kml": "http://www.opengis.net/kml/2.2"},
|
|
612
|
+
) == ["layer1"]
|
|
613
|
+
|
|
614
|
+
def test_superoverlay_authorize_none(self, app):
|
|
615
|
+
|
|
616
|
+
def auth(service, layers, **kw):
|
|
617
|
+
assert service == "kml"
|
|
618
|
+
assert len(layers) == 1
|
|
619
|
+
return {"authorized": "none"}
|
|
620
|
+
|
|
621
|
+
app.get(
|
|
622
|
+
"/kml/layer1/0/0/0.kml",
|
|
623
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
624
|
+
status=403,
|
|
625
|
+
)
|
|
626
|
+
|
|
627
|
+
def test_superoverlay_unauthenticated(self, app):
|
|
628
|
+
|
|
629
|
+
def auth(service, layers, **kw):
|
|
630
|
+
assert service == "kml"
|
|
631
|
+
assert len(layers) == 1
|
|
632
|
+
return {"authorized": "unauthenticated"}
|
|
633
|
+
|
|
634
|
+
app.get(
|
|
635
|
+
"/kml/layer1/0/0/0.kml",
|
|
636
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
637
|
+
status=401,
|
|
638
|
+
)
|
|
639
|
+
|
|
640
|
+
def test_superoverlay_authorize_partial(self, app):
|
|
641
|
+
|
|
642
|
+
def auth(service, layers, query_extent, **kw):
|
|
643
|
+
assert service == "kml"
|
|
644
|
+
assert len(layers) == 1
|
|
645
|
+
assert query_extent[0] == "EPSG:900913"
|
|
646
|
+
assert bbox_equals(
|
|
647
|
+
query_extent[1],
|
|
648
|
+
(
|
|
649
|
+
-20037508.342789244,
|
|
650
|
+
-20037508.342789244,
|
|
651
|
+
20037508.342789244,
|
|
652
|
+
20037508.342789244,
|
|
653
|
+
),
|
|
654
|
+
)
|
|
655
|
+
|
|
656
|
+
return {"authorized": "partial", "layers": {"layer1": {"tile": True}}}
|
|
657
|
+
|
|
658
|
+
resp = app.get(
|
|
659
|
+
"/kml/layer1/0/0/0.kml", extra_environ={"mapproxy.authorize": auth}
|
|
660
|
+
)
|
|
661
|
+
xml = resp.lxml
|
|
662
|
+
assert xml.xpath(
|
|
663
|
+
"kml:Document/kml:name/text()",
|
|
664
|
+
namespaces={"kml": "http://www.opengis.net/kml/2.2"},
|
|
665
|
+
) == ["layer1"]
|
|
666
|
+
|
|
667
|
+
def test_superoverlay_deny_partial(self, app):
|
|
668
|
+
|
|
669
|
+
def auth(service, layers, **kw):
|
|
670
|
+
assert service == "kml"
|
|
671
|
+
assert len(layers) == 1
|
|
672
|
+
return {"authorized": "partial", "layers": {"layer1": {"tile": False}}}
|
|
673
|
+
|
|
674
|
+
app.get(
|
|
675
|
+
"/kml/layer1/0/0/0.kml",
|
|
676
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
677
|
+
status=403,
|
|
678
|
+
)
|
|
679
|
+
|
|
680
|
+
def test_get_tile_global_limited_to(self, app):
|
|
681
|
+
# check with limited_to for all layers
|
|
682
|
+
auth_dict = {
|
|
683
|
+
"authorized": "partial",
|
|
684
|
+
"limited_to": {"geometry": [-180, -89, -90, 89], "srs": "EPSG:4326"},
|
|
685
|
+
"layers": {"layer3": {"tile": True}},
|
|
686
|
+
}
|
|
687
|
+
self.check_get_tile_limited_to(app, auth_dict)
|
|
688
|
+
|
|
689
|
+
def test_get_tile_layer_limited_to(self, app):
|
|
690
|
+
# check with limited_to for one layer
|
|
691
|
+
auth_dict = {
|
|
692
|
+
"authorized": "partial",
|
|
693
|
+
"layers": {
|
|
694
|
+
"layer3": {
|
|
695
|
+
"tile": True,
|
|
696
|
+
"limited_to": {
|
|
697
|
+
"geometry": [-180, -89, -90, 89],
|
|
698
|
+
"srs": "EPSG:4326",
|
|
699
|
+
},
|
|
700
|
+
}
|
|
701
|
+
},
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
self.check_get_tile_limited_to(app, auth_dict)
|
|
705
|
+
|
|
706
|
+
def check_get_tile_limited_to(self, app, auth_dict):
|
|
707
|
+
|
|
708
|
+
def auth(service, layers, environ, query_extent, **kw):
|
|
709
|
+
assert environ["PATH_INFO"] == "/kml/layer3_EPSG900913/1/0/0.jpeg"
|
|
710
|
+
assert service == "kml"
|
|
711
|
+
assert len(layers) == 1
|
|
712
|
+
assert query_extent[0] == "EPSG:900913"
|
|
713
|
+
assert bbox_equals(
|
|
714
|
+
query_extent[1], (-20037508.342789244, -20037508.342789244, 0, 0)
|
|
715
|
+
)
|
|
716
|
+
return auth_dict
|
|
717
|
+
|
|
718
|
+
serv = MockServ(port=42423)
|
|
719
|
+
serv.expects("/1/0/0.png")
|
|
720
|
+
serv.returns(
|
|
721
|
+
create_tmp_image((256, 256), color=(255, 0, 0)),
|
|
722
|
+
headers={"content-type": "image/png"},
|
|
723
|
+
)
|
|
724
|
+
with serv:
|
|
725
|
+
resp = app.get(
|
|
726
|
+
"/kml/layer3_EPSG900913/1/0/0.jpeg",
|
|
727
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
728
|
+
)
|
|
729
|
+
|
|
730
|
+
assert resp.content_type == "image/png"
|
|
731
|
+
|
|
732
|
+
img = img_from_buf(resp.body)
|
|
733
|
+
img = img.convert("RGBA")
|
|
734
|
+
# left part authorized, red
|
|
735
|
+
assert img.crop((0, 0, 127, 255)).getcolors()[0] == (
|
|
736
|
+
127 * 255,
|
|
737
|
+
(255, 0, 0, 255),
|
|
738
|
+
)
|
|
739
|
+
# right part not authorized, transparent
|
|
740
|
+
assert img.crop((129, 0, 255, 255)).getcolors()[0][1][3] == 0
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
WMTS_CAPABILITIES_REQ = "/wmts/1.0.0/WMTSCapabilities.xml"
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
class TestWMTSAuth(SysTest):
|
|
747
|
+
|
|
748
|
+
def test_capabilities_authorize_all(self, app):
|
|
749
|
+
|
|
750
|
+
def auth(service, layers, environ, **kw):
|
|
751
|
+
assert environ["PATH_INFO"] == "/wmts/1.0.0/WMTSCapabilities.xml"
|
|
752
|
+
assert service == "wmts"
|
|
753
|
+
assert len(layers) == 6
|
|
754
|
+
return {"authorized": "full"}
|
|
755
|
+
|
|
756
|
+
resp = app.get(
|
|
757
|
+
WMTS_CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth}
|
|
758
|
+
)
|
|
759
|
+
xml = resp.lxml
|
|
760
|
+
assert set(
|
|
761
|
+
xml.xpath(
|
|
762
|
+
"//wmts:Layer/ows:Title/text()",
|
|
763
|
+
namespaces={
|
|
764
|
+
"wmts": "http://www.opengis.net/wmts/1.0",
|
|
765
|
+
"ows": "http://www.opengis.net/ows/1.1",
|
|
766
|
+
},
|
|
767
|
+
)
|
|
768
|
+
) == set(
|
|
769
|
+
["layer 1b", "layer 1a", "layer 2a", "layer 2b1", "layer 1", "layer 3"]
|
|
770
|
+
)
|
|
771
|
+
|
|
772
|
+
def test_capabilities_authorize_none(self, app):
|
|
773
|
+
|
|
774
|
+
def auth(service, layers, **kw):
|
|
775
|
+
assert service == "wmts"
|
|
776
|
+
assert len(layers) == 6
|
|
777
|
+
return {"authorized": "none"}
|
|
778
|
+
|
|
779
|
+
app.get(
|
|
780
|
+
WMTS_CAPABILITIES_REQ,
|
|
781
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
782
|
+
status=403,
|
|
783
|
+
)
|
|
784
|
+
|
|
785
|
+
def test_capabilities_unauthenticated(self, app):
|
|
786
|
+
|
|
787
|
+
def auth(service, layers, **kw):
|
|
788
|
+
assert service == "wmts"
|
|
789
|
+
assert len(layers) == 6
|
|
790
|
+
return {"authorized": "unauthenticated"}
|
|
791
|
+
|
|
792
|
+
app.get(
|
|
793
|
+
WMTS_CAPABILITIES_REQ,
|
|
794
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
795
|
+
status=401,
|
|
796
|
+
)
|
|
797
|
+
|
|
798
|
+
def test_capabilities_authorize_partial(self, app):
|
|
799
|
+
|
|
800
|
+
def auth(service, layers, **kw):
|
|
801
|
+
assert service == "wmts"
|
|
802
|
+
assert len(layers) == 6
|
|
803
|
+
return {
|
|
804
|
+
"authorized": "partial",
|
|
805
|
+
"layers": {
|
|
806
|
+
"layer1a": {"tile": True},
|
|
807
|
+
"layer1b": {"tile": False},
|
|
808
|
+
"layer2": {"tile": True},
|
|
809
|
+
"layer2b": {"tile": True},
|
|
810
|
+
"layer2b1": {"tile": True},
|
|
811
|
+
},
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
resp = app.get(
|
|
815
|
+
WMTS_CAPABILITIES_REQ, extra_environ={"mapproxy.authorize": auth}
|
|
816
|
+
)
|
|
817
|
+
xml = resp.lxml
|
|
818
|
+
assert set(
|
|
819
|
+
xml.xpath(
|
|
820
|
+
"//wmts:Layer/ows:Title/text()",
|
|
821
|
+
namespaces={
|
|
822
|
+
"wmts": "http://www.opengis.net/wmts/1.0",
|
|
823
|
+
"ows": "http://www.opengis.net/ows/1.1",
|
|
824
|
+
},
|
|
825
|
+
)
|
|
826
|
+
) == set(["layer 1a", "layer 2b1"])
|
|
827
|
+
|
|
828
|
+
def test_get_tile(self, app):
|
|
829
|
+
|
|
830
|
+
def auth(service, layers, environ, query_extent, **kw):
|
|
831
|
+
assert environ["PATH_INFO"] == "/wmts/layer1/GLOBAL_MERCATOR/0/0/0.png"
|
|
832
|
+
assert service == "wmts"
|
|
833
|
+
assert len(layers) == 1
|
|
834
|
+
assert query_extent[0] == "EPSG:900913"
|
|
835
|
+
assert bbox_equals(
|
|
836
|
+
query_extent[1],
|
|
837
|
+
(
|
|
838
|
+
-20037508.342789244,
|
|
839
|
+
-20037508.342789244,
|
|
840
|
+
20037508.342789244,
|
|
841
|
+
20037508.342789244,
|
|
842
|
+
),
|
|
843
|
+
)
|
|
844
|
+
return {"authorized": "partial", "layers": {"layer1": {"tile": True}}}
|
|
845
|
+
|
|
846
|
+
resp = app.get(
|
|
847
|
+
"/wmts/layer1/GLOBAL_MERCATOR/0/0/0.png",
|
|
848
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
849
|
+
)
|
|
850
|
+
assert resp.content_type == "image/png"
|
|
851
|
+
assert resp.content_length > 1000
|
|
852
|
+
|
|
853
|
+
def test_get_tile_global_limited_to(self, app):
|
|
854
|
+
# check with limited_to for all layers
|
|
855
|
+
auth_dict = {
|
|
856
|
+
"authorized": "partial",
|
|
857
|
+
"limited_to": {"geometry": [-180, -89, -90, 89], "srs": "EPSG:4326"},
|
|
858
|
+
"layers": {"layer3": {"tile": True}},
|
|
859
|
+
}
|
|
860
|
+
self.check_get_tile_limited_to(app, auth_dict)
|
|
861
|
+
|
|
862
|
+
def test_get_tile_layer_limited_to(self, app):
|
|
863
|
+
# check with limited_to for one layer
|
|
864
|
+
auth_dict = {
|
|
865
|
+
"authorized": "partial",
|
|
866
|
+
"layers": {
|
|
867
|
+
"layer3": {
|
|
868
|
+
"tile": True,
|
|
869
|
+
"limited_to": {
|
|
870
|
+
"geometry": [-180, -89, -90, 89],
|
|
871
|
+
"srs": "EPSG:4326",
|
|
872
|
+
},
|
|
873
|
+
}
|
|
874
|
+
},
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
self.check_get_tile_limited_to(app, auth_dict)
|
|
878
|
+
|
|
879
|
+
def check_get_tile_limited_to(self, app, auth_dict):
|
|
880
|
+
|
|
881
|
+
def auth(service, layers, environ, query_extent, **kw):
|
|
882
|
+
assert environ["PATH_INFO"] == "/wmts/layer3/GLOBAL_MERCATOR/1/0/0.jpeg"
|
|
883
|
+
assert service == "wmts"
|
|
884
|
+
assert len(layers) == 1
|
|
885
|
+
assert query_extent[0] == "EPSG:900913"
|
|
886
|
+
assert bbox_equals(
|
|
887
|
+
query_extent[1], (-20037508.342789244, 0, 0, 20037508.342789244)
|
|
888
|
+
)
|
|
889
|
+
return auth_dict
|
|
890
|
+
|
|
891
|
+
serv = MockServ(port=42423)
|
|
892
|
+
serv.expects("/1/0/1.png")
|
|
893
|
+
serv.returns(
|
|
894
|
+
create_tmp_image((256, 256), color=(255, 0, 0)),
|
|
895
|
+
headers={"content-type": "image/png"},
|
|
896
|
+
)
|
|
897
|
+
with serv:
|
|
898
|
+
resp = app.get(
|
|
899
|
+
"/wmts/layer3/GLOBAL_MERCATOR/1/0/0.jpeg",
|
|
900
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
901
|
+
)
|
|
902
|
+
|
|
903
|
+
assert resp.content_type == "image/png"
|
|
904
|
+
|
|
905
|
+
img = img_from_buf(resp.body)
|
|
906
|
+
img = img.convert("RGBA")
|
|
907
|
+
# left part authorized, red
|
|
908
|
+
assert img.crop((0, 0, 127, 255)).getcolors()[0] == (
|
|
909
|
+
127 * 255,
|
|
910
|
+
(255, 0, 0, 255),
|
|
911
|
+
)
|
|
912
|
+
# right part not authorized, transparent
|
|
913
|
+
assert img.crop((129, 0, 255, 255)).getcolors()[0][1][3] == 0
|
|
914
|
+
|
|
915
|
+
def test_get_tile_limited_to_outside(self, app):
|
|
916
|
+
|
|
917
|
+
def auth(service, layers, environ, **kw):
|
|
918
|
+
assert environ["PATH_INFO"] == "/wmts/layer3/GLOBAL_MERCATOR/2/0/0.jpeg"
|
|
919
|
+
assert service == "wmts"
|
|
920
|
+
assert len(layers) == 1
|
|
921
|
+
return {
|
|
922
|
+
"authorized": "partial",
|
|
923
|
+
"limited_to": {"geometry": [0, -89, 90, 89], "srs": "EPSG:4326"},
|
|
924
|
+
"layers": {"layer3": {"tile": True}},
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
resp = app.get(
|
|
928
|
+
"/wmts/layer3/GLOBAL_MERCATOR/2/0/0.jpeg",
|
|
929
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
930
|
+
)
|
|
931
|
+
|
|
932
|
+
assert resp.content_type == "image/png"
|
|
933
|
+
is_transparent(resp.body)
|
|
934
|
+
|
|
935
|
+
def test_get_tile_limited_to_inside(self, app):
|
|
936
|
+
|
|
937
|
+
def auth(service, layers, environ, **kw):
|
|
938
|
+
assert environ["PATH_INFO"] == "/wmts/layer3/GLOBAL_MERCATOR/1/0/0.jpeg"
|
|
939
|
+
assert service == "wmts"
|
|
940
|
+
assert len(layers) == 1
|
|
941
|
+
return {
|
|
942
|
+
"authorized": "partial",
|
|
943
|
+
"limited_to": {"geometry": [-180, -89, 180, 89], "srs": "EPSG:4326"},
|
|
944
|
+
"layers": {"layer3": {"tile": True}},
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
serv = MockServ(port=42423)
|
|
948
|
+
serv.expects("/1/0/1.png")
|
|
949
|
+
serv.returns(
|
|
950
|
+
create_tmp_image((256, 256), color=(255, 0, 0)),
|
|
951
|
+
headers={"content-type": "image/png"},
|
|
952
|
+
)
|
|
953
|
+
with serv:
|
|
954
|
+
resp = app.get(
|
|
955
|
+
"/wmts/layer3/GLOBAL_MERCATOR/1/0/0.jpeg",
|
|
956
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
957
|
+
)
|
|
958
|
+
|
|
959
|
+
assert resp.content_type == "image/jpeg"
|
|
960
|
+
|
|
961
|
+
img = img_from_buf(resp.body)
|
|
962
|
+
assert img.getcolors()[0] == (256 * 256, (255, 0, 0))
|
|
963
|
+
|
|
964
|
+
def test_get_tile_kvp(self, app):
|
|
965
|
+
|
|
966
|
+
def auth(service, layers, environ, **kw):
|
|
967
|
+
assert environ["PATH_INFO"] == "/service"
|
|
968
|
+
assert service == "wmts"
|
|
969
|
+
assert len(layers) == 1
|
|
970
|
+
return {"authorized": "partial", "layers": {"layer1": {"tile": True}}}
|
|
971
|
+
|
|
972
|
+
resp = app.get(
|
|
973
|
+
"/service?service=WMTS&version=1.0.0&layer=layer1&request=GetTile&"
|
|
974
|
+
"style=&tilematrixset=GLOBAL_MERCATOR&tilematrix=00&tilerow=0&tilecol=0&format=image/png",
|
|
975
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
976
|
+
)
|
|
977
|
+
assert resp.content_type == "image/png"
|
|
978
|
+
|
|
979
|
+
def test_get_tile_authorize_none(self, app):
|
|
980
|
+
|
|
981
|
+
def auth(service, layers, **kw):
|
|
982
|
+
assert service == "wmts"
|
|
983
|
+
assert len(layers) == 1
|
|
984
|
+
return {"authorized": "none"}
|
|
985
|
+
|
|
986
|
+
app.get(
|
|
987
|
+
"/wmts/layer1/GLOBAL_MERCATOR/0/0/0.png",
|
|
988
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
989
|
+
status=403,
|
|
990
|
+
)
|
|
991
|
+
|
|
992
|
+
def test_get_tile_authorize_none_kvp(self, app):
|
|
993
|
+
|
|
994
|
+
def auth(service, layers, environ, **kw):
|
|
995
|
+
assert environ["PATH_INFO"] == "/service"
|
|
996
|
+
assert service == "wmts"
|
|
997
|
+
assert len(layers) == 1
|
|
998
|
+
return {"authorized": "partial", "layers": {"layer1": {"tile": False}}}
|
|
999
|
+
|
|
1000
|
+
app.get(
|
|
1001
|
+
"/service?service=WMTS&version=1.0.0&layer=layer1&request=GetTile&"
|
|
1002
|
+
"style=&tilematrixset=GLOBAL_MERCATOR&tilematrix=00&tilerow=0&tilecol=0&format=image/png",
|
|
1003
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
1004
|
+
status=403,
|
|
1005
|
+
)
|
|
1006
|
+
|
|
1007
|
+
def test_get_featureinfo_kvp(self, app):
|
|
1008
|
+
|
|
1009
|
+
def auth(service, layers, environ, **kw):
|
|
1010
|
+
assert environ["PATH_INFO"] == "/service"
|
|
1011
|
+
assert service == "wmts.featureinfo"
|
|
1012
|
+
assert len(layers) == 1
|
|
1013
|
+
return {"authorized": "partial", "layers": {"layer1b": {"featureinfo": True}}}
|
|
1014
|
+
|
|
1015
|
+
serv = MockServ(port=42423)
|
|
1016
|
+
serv.expects(
|
|
1017
|
+
"/service?request=GetFeatureInfo&service=WMS&Version=1.1.1&SRS=EPSG:900913"
|
|
1018
|
+
"&BBOX=-20037508.342789244,-20037508.342789244,20037508.342789244,20037508.342789244"
|
|
1019
|
+
"&WIDTH=256&HEIGHT=256&styles=&FORMAT=image/png&X=10&Y=20"
|
|
1020
|
+
"&query_layers=fi&layers=fi&info_format=application/json"
|
|
1021
|
+
)
|
|
1022
|
+
serv.returns(b"{}")
|
|
1023
|
+
with serv:
|
|
1024
|
+
resp = app.get(
|
|
1025
|
+
"/service?service=WMTS&version=1.0.0&layer=layer1b&request=GetFeatureInfo&"
|
|
1026
|
+
"style=&tilematrixset=GLOBAL_MERCATOR&tilematrix=00&tilerow=0&tilecol=0&format=image/png"
|
|
1027
|
+
"&infoformat=application/json&i=10&j=20",
|
|
1028
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
1029
|
+
)
|
|
1030
|
+
assert resp.content_type == "application/json"
|
|
1031
|
+
|
|
1032
|
+
def test_get_featureinfo_kvp_authorized_none(self, app):
|
|
1033
|
+
|
|
1034
|
+
def auth(service, layers, environ, **kw):
|
|
1035
|
+
assert environ["PATH_INFO"] == "/service"
|
|
1036
|
+
assert service == "wmts.featureinfo"
|
|
1037
|
+
assert len(layers) == 1
|
|
1038
|
+
return {"authorized": "partial", "layers": {"layer1b": {"tile": True}}}
|
|
1039
|
+
|
|
1040
|
+
app.get(
|
|
1041
|
+
"/service?service=WMTS&version=1.0.0&layer=layer1b&request=GetFeatureInfo&"
|
|
1042
|
+
"style=&tilematrixset=GLOBAL_MERCATOR&tilematrix=00&tilerow=0&tilecol=0&format=image/png"
|
|
1043
|
+
"&infoformat=application/json&i=10&j=20",
|
|
1044
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
1045
|
+
status=403,
|
|
1046
|
+
)
|
|
1047
|
+
|
|
1048
|
+
def test_get_featureinfo_rest(self, app):
|
|
1049
|
+
|
|
1050
|
+
def auth(service, layers, environ, **kw):
|
|
1051
|
+
assert environ["PATH_INFO"].startswith('/wmts/layer1b/')
|
|
1052
|
+
assert service == "wmts.featureinfo"
|
|
1053
|
+
assert len(layers) == 1
|
|
1054
|
+
return {"authorized": "partial", "layers": {"layer1b": {"featureinfo": True}}}
|
|
1055
|
+
|
|
1056
|
+
serv = MockServ(port=42423)
|
|
1057
|
+
serv.expects(
|
|
1058
|
+
"/service?request=GetFeatureInfo&service=WMS&Version=1.1.1&SRS=EPSG:900913"
|
|
1059
|
+
"&BBOX=-20037508.342789244,-20037508.342789244,20037508.342789244,20037508.342789244"
|
|
1060
|
+
"&WIDTH=256&HEIGHT=256&styles=&FORMAT=image/png&X=10&Y=20"
|
|
1061
|
+
"&query_layers=fi&layers=fi&info_format=application/json"
|
|
1062
|
+
)
|
|
1063
|
+
serv.returns(b"{}")
|
|
1064
|
+
with serv:
|
|
1065
|
+
resp = app.get(
|
|
1066
|
+
"/wmts/layer1b/GLOBAL_MERCATOR/00/0/0/10/20.geojson",
|
|
1067
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
1068
|
+
)
|
|
1069
|
+
assert resp.content_type == "application/json"
|
|
1070
|
+
|
|
1071
|
+
def test_get_featureinfo_rest_authorized_none(self, app):
|
|
1072
|
+
|
|
1073
|
+
def auth(service, layers, environ, **kw):
|
|
1074
|
+
assert environ["PATH_INFO"].startswith('/wmts/layer1b/')
|
|
1075
|
+
assert service == "wmts.featureinfo"
|
|
1076
|
+
assert len(layers) == 1
|
|
1077
|
+
return {"authorized": "partial", "layers": {"layer1b": {"tile": True}}}
|
|
1078
|
+
|
|
1079
|
+
app.get(
|
|
1080
|
+
"/wmts/layer1b/GLOBAL_MERCATOR/00/0/0/10/20.geojson",
|
|
1081
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
1082
|
+
status=403,
|
|
1083
|
+
)
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
class TestDemoAuth(SysTest):
|
|
1087
|
+
|
|
1088
|
+
def test_authorize_all(self, app):
|
|
1089
|
+
|
|
1090
|
+
def auth(service, layers, environ, **kw):
|
|
1091
|
+
return {"authorized": "full"}
|
|
1092
|
+
|
|
1093
|
+
app.get("/demo", extra_environ={"mapproxy.authorize": auth})
|
|
1094
|
+
|
|
1095
|
+
def test_authorize_none(self, app):
|
|
1096
|
+
|
|
1097
|
+
def auth(service, layers, environ, **kw):
|
|
1098
|
+
return {"authorized": "none"}
|
|
1099
|
+
|
|
1100
|
+
app.get("/demo", extra_environ={"mapproxy.authorize": auth}, status=403)
|
|
1101
|
+
|
|
1102
|
+
def test_unauthenticated(self, app):
|
|
1103
|
+
|
|
1104
|
+
def auth(service, layers, environ, **kw):
|
|
1105
|
+
return {"authorized": "unauthenticated"}
|
|
1106
|
+
|
|
1107
|
+
app.get("/demo", extra_environ={"mapproxy.authorize": auth}, status=401)
|
|
1108
|
+
|
|
1109
|
+
def test_superoverlay_authorize_none(self, app):
|
|
1110
|
+
|
|
1111
|
+
def auth(service, layers, **kw):
|
|
1112
|
+
assert service == "kml"
|
|
1113
|
+
assert len(layers) == 1
|
|
1114
|
+
return {"authorized": "none"}
|
|
1115
|
+
|
|
1116
|
+
app.get(
|
|
1117
|
+
"/kml/layer1/0/0/0.kml",
|
|
1118
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
1119
|
+
status=403,
|
|
1120
|
+
)
|
|
1121
|
+
|
|
1122
|
+
def test_superoverlay_unauthenticated(self, app):
|
|
1123
|
+
|
|
1124
|
+
def auth(service, layers, **kw):
|
|
1125
|
+
assert service == "kml"
|
|
1126
|
+
assert len(layers) == 1
|
|
1127
|
+
return {"authorized": "unauthenticated"}
|
|
1128
|
+
|
|
1129
|
+
app.get(
|
|
1130
|
+
"/kml/layer1/0/0/0.kml",
|
|
1131
|
+
extra_environ={"mapproxy.authorize": auth},
|
|
1132
|
+
status=401,
|
|
1133
|
+
)
|