Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to latest Python packages/security fixes. #905

Merged
merged 3 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ default_language_version:
python: python3.11
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-added-large-files
- id: check-merge-conflict
Expand All @@ -17,20 +17,20 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/asottile/pyupgrade
rev: v3.17.0
rev: v3.19.0
hooks:
- id: pyupgrade
args:
- --py310-plus
- --keep-runtime-typing
- repo: https://github.com/adamchainz/django-upgrade
rev: "1.20.0"
rev: "1.22.1"
hooks:
- id: django-upgrade
args:
- --target-version=4.2
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.5
rev: v0.7.2
hooks:
- id: ruff
args:
Expand All @@ -39,6 +39,6 @@ repos:
- --config=pyproject.toml
- --exit-non-zero-on-fix
- repo: https://github.com/psf/black
rev: 24.4.2
rev: 24.10.0
hooks:
- id: black
65 changes: 30 additions & 35 deletions src/dso_api/dynamic_api/views/mvt.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import logging
import time

from django.core.exceptions import FieldDoesNotExist, PermissionDenied
from django.core.exceptions import PermissionDenied
from django.http import Http404
from django.urls.base import reverse
from django.views.generic import TemplateView
from schematools.contrib.django.models import Dataset
from schematools.exceptions import SchemaObjectNotFound
from schematools.types import DatasetTableSchema
from vectortiles.postgis.views import MVTView
from vectortiles import VectorLayer
from vectortiles.backends import BaseVectorLayerMixin
from vectortiles.views import MVTView

from dso_api.dynamic_api.datasets import get_active_datasets
from dso_api.dynamic_api.permissions import CheckPermissionsMixin
Expand Down Expand Up @@ -90,7 +91,6 @@ def get_context_data(self, **kwargs):
context["name"] = dataset_name
context["tables"] = geo_tables
context["schema"] = models[geo_tables[0]].table_schema().dataset

return context


Expand All @@ -112,6 +112,29 @@ def setup(self, request, *args, **kwargs):
self.model = model
self.check_permissions(request, [self.model])

def get_layers(self):
"""Provide all layer definitions for this rendering."""
schema: DatasetTableSchema = self.model.table_schema()
layer: BaseVectorLayerMixin = VectorLayer()
layer.id = "default"
layer.model = self.model
layer.queryset = self.model.objects.all()
layer.geom_field = schema.main_geometry_field.python_name

# If we are zoomed far out (low z), only fetch the geometry field for a smaller payload.
# The cutoff is arbitrary. Play around with
# https://www.maptiler.com/google-maps-coordinates-tile-bounds-projection/#14/4.92/52.37
# to get a feel for the MVT zoom levels and how much detail a single tile should contain.
if self.z >= 15:
user_scopes = self.request.user_scopes
layer.tile_fields = tuple(
f.name
for f in self.model._meta.get_fields()
if f.name != layer.geom_field
and user_scopes.has_field_access(self.model.get_field_schema(f))
)
return [layer]

def get(self, request, *args, **kwargs):
kwargs.pop("dataset_name")
kwargs.pop("table_name")
Expand All @@ -127,40 +150,12 @@ def get(self, request, *args, **kwargs):
)
return result

def get_queryset(self):
return self.model.objects.all()

@property
def vector_tile_fields(self) -> tuple:
# If we are zoomed far out (low z), only fetch the geometry field for a smaller payload.
# The cutoff is arbitrary. Play around with
# https://www.maptiler.com/google-maps-coordinates-tile-bounds-projection/#14/4.92/52.37
# to get a feel for the MVT zoom levels and how much detail a single tile should contain.
if self.z < 15:
return ()

geom_name = self.vector_tile_geom_name
user_scopes = self.request.user_scopes
return tuple(
f.name
for f in self.model._meta.get_fields()
if f.name != geom_name and user_scopes.has_field_access(self.model.get_field_schema(f))
)

@property
def vector_tile_geom_name(self) -> str:
schema: DatasetTableSchema = self.model.table_schema()
try:
return schema.main_geometry_field.python_name
except SchemaObjectNotFound as e:
raise FieldDoesNotExist(f"No field named '{schema.main_geometry}'") from e

def check_permissions(self, request, models) -> None:
"""Override CheckPermissionsMixin to add extra checks"""
super().check_permissions(request, models)

# Check whether the geometry field can be accessed, otherwise reading MVT is pointless.
model_field = self.model._meta.get_field(self.vector_tile_geom_name)
field_schema = self.model.get_field_schema(model_field)
if not self.request.user_scopes.has_field_access(field_schema):
if not self.request.user_scopes.has_field_access(
self.model.table_schema().main_geometry_field
):
raise PermissionDenied()
12 changes: 6 additions & 6 deletions src/dso_api/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,8 @@
from typing import Final

import environ
import sentry_sdk
import sentry_sdk.utils
from corsheaders.defaults import default_headers
from pythonjsonlogger import jsonlogger
from sentry_sdk.integrations.django import DjangoIntegration
from sentry_sdk.integrations.logging import LoggingIntegration

from dso_api.sentry import before_send

env = environ.Env()
_USE_SECRET_STORE = os.path.exists("/mnt/secrets-store")
Expand Down Expand Up @@ -239,6 +233,12 @@

SENTRY_DSN = env.str("SENTRY_DSN", default="")
if SENTRY_DSN:
import sentry_sdk.utils
from sentry_sdk.integrations.django import DjangoIntegration
from sentry_sdk.integrations.logging import LoggingIntegration

from dso_api.sentry import before_send

sentry_sdk.init(
dsn=SENTRY_DSN,
environment="dso-api",
Expand Down
18 changes: 9 additions & 9 deletions src/requirements.in
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
Django == 4.2.16
django-environ == 0.11.2
django-cors-headers == 4.4.0
django-cors-headers == 4.6.0
django-healthchecks == 1.5.0
django-postgres-unlimited-varchar == 1.1.2
django-redis == 5.4.0
django-gisserver == 1.4.1
django-vectortiles == 0.2.0
django-vectortiles == 1.0.1
djangorestframework == 3.15.2
djangorestframework-csv == 3.0.2
djangorestframework-gis == 1.1
amsterdam-schema-tools[django] == 6.1.1
azure-identity == 1.17.1
azure-monitor-opentelemetry == 1.6.2
azure-identity == 1.19.0
azure-monitor-opentelemetry == 1.6.4
cachetools == 5.5.0
datadiensten-apikeyclient == 0.6.0
datapunt-authorization-django==1.3.3
Expand All @@ -23,14 +23,14 @@ Markdown == 3.7
more-ds == 0.0.6
more-itertools == 10.5.0
openapi-spec-validator == 0.7.1
orjson == 3.10.7
orjson == 3.10.11
python-json-logger==2.0.7
python-string-utils == 1.0.0
requests == 2.32.3
sentry-sdk == 2.14.0
sentry-sdk == 2.18.0
urllib3 == 2.2.3
urllib3-mock == 0.3.3
whitenoise == 6.7.0
whitenoise == 6.8.2
zipp == 3.20.2

# Packaging
Expand All @@ -42,7 +42,7 @@ uwsgi-readiness-check == 0.2.0

# Testing
bandit == 1.7.10
cryptography >= 42.0.8
cryptography >= 43.0.3
flake8 == 7.1.1
flake8-blind-except == 0.2.1
flake8-colors == 0.1.9
Expand All @@ -51,5 +51,5 @@ flake8-raise == 0.0.5
mapbox-vector-tile == 2.1.0
pytest == 8.3.3
pytest-django == 4.9.0
pytest-cov == 5.0.0
pytest-cov == 6.0.0
python-owasp-zap-v2.4 == 0.1.0
Loading