Merge branch 'refs/heads/master' into netgis_map_client_update
# Conflicts: # templates/map/client/config.json
This commit is contained in:
@@ -34,7 +34,9 @@ class Command(BaseKonovaCommand):
|
||||
def recalculate_parcels(self, options: dict):
|
||||
force_all = options.get("force_all", False)
|
||||
|
||||
geometry_objects = Geometry.objects.all().exclude(
|
||||
geometry_objects = Geometry.objects.filter(
|
||||
geom__isempty=False,
|
||||
).exclude(
|
||||
geom=None
|
||||
)
|
||||
|
||||
@@ -48,11 +50,14 @@ class Command(BaseKonovaCommand):
|
||||
"geometry__id",
|
||||
flat=True
|
||||
)
|
||||
# ... and resolve into Geometry objects again ...
|
||||
intersected_geom_objs = Geometry.objects.filter(
|
||||
id__in=geom_with_intersection_ids
|
||||
)
|
||||
# Filter those geometries out (they have intersections and do not need to be processed)
|
||||
geometry_objects = geometry_objects.difference(intersected_geom_objs)
|
||||
# ... to be able to use the way more efficient difference() function ...
|
||||
geometry_objects_ids = geometry_objects.difference(intersected_geom_objs).values_list("id", flat=True)
|
||||
# ... so we can resolve these into proper Geometry objects again for further annotation usage
|
||||
geometry_objects = Geometry.objects.filter(id__in=geometry_objects_ids)
|
||||
|
||||
self._write_warning("=== Update parcels and districts ===")
|
||||
# Order geometries by size to process smaller once at first
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 19.08.21
|
||||
|
||||
"""
|
||||
from django.core.management import BaseCommand
|
||||
|
||||
from intervention.models import Intervention
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Performs test on collisions using the identifier generation"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
identifiers = {}
|
||||
max_iterations = 100000
|
||||
try:
|
||||
collisions = 0
|
||||
len_ids = len(identifiers)
|
||||
while len_ids < max_iterations:
|
||||
tmp_intervention = Intervention()
|
||||
_id = tmp_intervention.generate_new_identifier()
|
||||
len_ids = len(identifiers)
|
||||
if _id not in identifiers:
|
||||
if len_ids % (max_iterations/5) == 0:
|
||||
print(len_ids)
|
||||
identifiers[_id] = None
|
||||
else:
|
||||
collisions += 1
|
||||
print("+++ Collision after {} identifiers +++".format(len_ids))
|
||||
|
||||
except KeyboardInterrupt:
|
||||
self._break_line()
|
||||
exit(-1)
|
||||
print(
|
||||
"\n{} collisions in {} identifiers; Collision rate {}%".format(
|
||||
collisions,
|
||||
len_ids,
|
||||
(collisions / len_ids)*100,
|
||||
)
|
||||
)
|
||||
|
||||
def _break_line(self):
|
||||
""" Simply prints a line break
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
self.stdout.write("\n")
|
||||
@@ -66,7 +66,6 @@ INSTALLED_APPS = [
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.gis',
|
||||
'django.contrib.humanize',
|
||||
'simple_sso.sso_server',
|
||||
'django_tables2',
|
||||
'bootstrap_modal_forms',
|
||||
'fontawesome_5',
|
||||
|
||||
@@ -5,6 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 31.01.22
|
||||
|
||||
"""
|
||||
from konova.sub_settings.django_settings import env
|
||||
|
||||
# MAPS
|
||||
DEFAULT_LAT = 50.00
|
||||
@@ -28,3 +29,6 @@ LANIS_ZOOM_LUT = {
|
||||
1000: 30,
|
||||
500: 31,
|
||||
}
|
||||
|
||||
MAP_PROXY_HOST_WHITELIST = env.list("MAP_PROXY_HOST_WHITELIST")
|
||||
i = 0
|
||||
@@ -16,3 +16,5 @@ OAUTH_CODE_VERIFIER = env("OAUTH_CODE_VERIFIER")
|
||||
|
||||
OAUTH_CLIENT_ID = env("OAUTH_CLIENT_ID")
|
||||
OAUTH_CLIENT_SECRET = env("OAUTH_CLIENT_SECRET")
|
||||
|
||||
PROPAGATION_SECRET = env("PROPAGATION_SECRET")
|
||||
|
||||
@@ -91,3 +91,6 @@ INTERVENTION_HAS_REVOCATIONS_TEMPLATE = _("This intervention has {} revocations"
|
||||
DATA_CHECKED_ON_TEMPLATE = _("Checked on {} by {}")
|
||||
DATA_CHECKED_PREVIOUSLY_TEMPLATE = _("Data has changed since last check on {} by {}")
|
||||
DATA_IS_UNCHECKED = _("Current data not checked yet")
|
||||
|
||||
# API TOKEN SETTINGS
|
||||
NEW_API_TOKEN_GENERATED = _("New token generated. Administrators need to validate.")
|
||||
@@ -1,78 +0,0 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 17.08.21
|
||||
|
||||
"""
|
||||
from collections import Iterable
|
||||
|
||||
import requests
|
||||
from user.models import User
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from konova.settings import SSO_SERVER_BASE, SSO_PUBLIC_KEY, PROXIES
|
||||
from konova.sub_settings.context_settings import BASE_TITLE_SHORT
|
||||
|
||||
|
||||
class Messenger:
|
||||
""" Used to send messages to the SSO server.
|
||||
|
||||
Messages can be seen by the user the next time they login on their SSO dashboard.
|
||||
Documentation for SSO Server-Client communication can be found here:
|
||||
https://git.naturschutz.rlp.de/SGD-Nord/arnova/wiki/Messages
|
||||
|
||||
"""
|
||||
server_url = "{}communication/message/".format(SSO_SERVER_BASE)
|
||||
|
||||
def __init__(self, users: Iterable, subject: str = None, body: str = None, type: str = None):
|
||||
self.users = users
|
||||
self.msg_subject = subject
|
||||
self.msg_body = body
|
||||
self.msg_type = type
|
||||
|
||||
def send(self):
|
||||
""" Sends a message
|
||||
|
||||
"""
|
||||
if self.msg_body is None or len(self.msg_body) == 0:
|
||||
raise AttributeError("No message body set")
|
||||
|
||||
headers = {
|
||||
"x-services-public-key": SSO_PUBLIC_KEY
|
||||
}
|
||||
for user in self.users:
|
||||
data = {
|
||||
"type": self.msg_type,
|
||||
"sender": BASE_TITLE_SHORT,
|
||||
"receiver": user.username,
|
||||
"subject": self.msg_subject,
|
||||
"body": self.msg_body,
|
||||
}
|
||||
requests.post(
|
||||
self.server_url,
|
||||
data=data,
|
||||
headers=headers,
|
||||
proxies=PROXIES
|
||||
)
|
||||
|
||||
def send_object_checked(self, obj_identifier: str, performing_user: User, detail_view_url: str = ""):
|
||||
""" Wraps sending of a message related to the checking of an object, like an intervention
|
||||
|
||||
Args:
|
||||
obj_identifier (str): The object's identifier (e.g. 'EIV-123'
|
||||
performing_user (User): The user who performed the checking
|
||||
detail_view_url (str): If a direct link to the object shall be added to the message, it can be provided here
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
self.msg_subject = _("{} checked").format(obj_identifier)
|
||||
if len(detail_view_url) > 0:
|
||||
detail_view_url = _('<a href="{}">Check it out</a>').format(detail_view_url)
|
||||
self.msg_body = _("{} has been checked successfully by user {}! {}").format(
|
||||
obj_identifier,
|
||||
performing_user.username,
|
||||
detail_view_url
|
||||
)
|
||||
self.send()
|
||||
@@ -11,6 +11,7 @@ from json import JSONDecodeError
|
||||
import requests
|
||||
|
||||
from konova.sub_settings import schneider_settings
|
||||
from konova.sub_settings.lanis_settings import DEFAULT_SRID
|
||||
from konova.sub_settings.proxy_settings import PROXIES
|
||||
|
||||
|
||||
@@ -34,6 +35,7 @@ class ParcelFetcher:
|
||||
if geom.area < buffer_threshold:
|
||||
# Fallback for malicious geometries which are way too small and would disappear on negative buffering
|
||||
geom = geometry.geom
|
||||
geom.transform(DEFAULT_SRID)
|
||||
self.geojson = geom.ewkt
|
||||
self.results = []
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ Contact: ksp-servicestelle@sgdnord.rlp.de
|
||||
Created on: 19.08.22
|
||||
|
||||
"""
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib.gis.geos import MultiPolygon
|
||||
from django.http import HttpResponse, HttpRequest
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
@@ -24,5 +24,13 @@ class LogoutView(View):
|
||||
Returns:
|
||||
A redirect
|
||||
"""
|
||||
user = request.user
|
||||
try:
|
||||
oauth_token = user.oauth_token
|
||||
if oauth_token:
|
||||
oauth_token.revoke()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
logout(request)
|
||||
return redirect(SSO_SERVER_BASE)
|
||||
|
||||
@@ -9,6 +9,7 @@ import json
|
||||
from json import JSONDecodeError
|
||||
|
||||
import requests
|
||||
import urllib3.util
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.http import JsonResponse, HttpRequest, HttpResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
@@ -17,6 +18,7 @@ from django.views import View
|
||||
|
||||
from requests.auth import HTTPDigestAuth
|
||||
|
||||
from konova.sub_settings.lanis_settings import MAP_PROXY_HOST_WHITELIST
|
||||
from konova.sub_settings.proxy_settings import PROXIES, GEOPORTAL_RLP_USER, GEOPORTAL_RLP_PASSWORD
|
||||
|
||||
|
||||
@@ -31,6 +33,13 @@ class BaseClientProxyView(View):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def _check_with_whitelist(self, url):
|
||||
parsed_url = urllib3.util.parse_url(url)
|
||||
parsed_url_host = parsed_url.host
|
||||
whitelist = set(MAP_PROXY_HOST_WHITELIST)
|
||||
is_allowed = parsed_url_host in whitelist
|
||||
return is_allowed
|
||||
|
||||
def perform_url_call(self, url, headers={}, auth=None):
|
||||
""" Generic proxied call
|
||||
|
||||
@@ -61,6 +70,11 @@ class ClientProxyParcelSearch(BaseClientProxyView):
|
||||
|
||||
def get(self, request: HttpRequest):
|
||||
url = request.META.get("QUERY_STRING")
|
||||
|
||||
is_url_allowed = self._check_with_whitelist(url)
|
||||
if not is_url_allowed:
|
||||
raise PermissionError(f"Proxied url '{url}' is not allowed!")
|
||||
|
||||
content, response_code = self.perform_url_call(url)
|
||||
return HttpResponse(content)
|
||||
|
||||
|
||||
@@ -115,10 +115,10 @@ class OAuthCallbackView(View):
|
||||
if status_code_invalid:
|
||||
raise RuntimeError(f"OAuth access token could not be fetched: {access_code_response.text}")
|
||||
|
||||
oauth_access_token = OAuthToken.from_access_token_response(access_code_response_body, received_on)
|
||||
oauth_access_token.save()
|
||||
user = oauth_access_token.update_and_get_user()
|
||||
user.oauth_replace_token(oauth_access_token)
|
||||
oauth_token = OAuthToken.from_access_token_response(access_code_response_body, received_on)
|
||||
oauth_token.save()
|
||||
user = oauth_token.update_and_get_user()
|
||||
user.oauth_replace_token(oauth_token)
|
||||
|
||||
login(request, user)
|
||||
return redirect("home")
|
||||
|
||||
Reference in New Issue
Block a user