validation patch
This commit is contained in:
+1
-1
@@ -530,7 +530,7 @@ paths:
|
||||
- hello-world
|
||||
servers:
|
||||
- description: pygeoapi provides an API to geospatial data
|
||||
url: http://localhost:5000
|
||||
url: https://geo.speckle.systems
|
||||
tags:
|
||||
- description: pygeoapi provides an API to geospatial data
|
||||
externalDocs:
|
||||
|
||||
+91
-31
@@ -39,6 +39,9 @@ from flask import (Flask, Blueprint, make_response, request,
|
||||
send_from_directory, Response, Request, stream_with_context)
|
||||
from http import HTTPStatus
|
||||
|
||||
import json
|
||||
from urllib.request import urlopen
|
||||
|
||||
from pygeoapi.api import API, APIRequest, apply_gzip
|
||||
import pygeoapi.api.coverages as coverages_api
|
||||
import pygeoapi.api.environmental_data_retrieval as edr_api
|
||||
@@ -169,11 +172,89 @@ def execute_from_flask(api_function, request: Request, *args,
|
||||
return get_response((headers, status, content))
|
||||
|
||||
|
||||
def handle_client(url_route: str):
|
||||
try:
|
||||
from geopy.geocoders import Nominatim
|
||||
except ModuleNotFoundError:
|
||||
from subprocess import run
|
||||
import sys
|
||||
|
||||
completed_process = run(
|
||||
[
|
||||
sys.executable,
|
||||
"-m",
|
||||
"pip",
|
||||
"install",
|
||||
"geopy==2.4.1",
|
||||
],
|
||||
capture_output=True,
|
||||
)
|
||||
#if completed_process.returncode != 0:
|
||||
from geopy.geocoders import Nominatim
|
||||
|
||||
# if called fromm the browser, Exceptions from this function will result in infinite load
|
||||
agent = request.headers.get('User-Agent')
|
||||
if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
|
||||
ip_address = request.environ['REMOTE_ADDR']
|
||||
else:
|
||||
ip_address = request.environ['HTTP_X_FORWARDED_FOR']
|
||||
|
||||
print(f"_______________________{datetime.now().astimezone(timezone.utc)} _URL access")
|
||||
print(f"_Agent {url_route}: {agent}")
|
||||
print(f"_IP Address: {ip_address}")
|
||||
print(f"_Request URL: {request.url}")
|
||||
|
||||
request.url += f"&userAgent={agent}"
|
||||
|
||||
# by Agent:
|
||||
if agent is not None and ("YaBrowser/" in agent or "yandex" in agent.lower()):
|
||||
raise ValueError("Your browser is not supported.")
|
||||
|
||||
# by proj location:
|
||||
url_lower = request.url.lower()
|
||||
if "&lat=" in url_lower and "&lon=" in url_lower:
|
||||
country_code = ""
|
||||
try:
|
||||
geolocator = Nominatim(user_agent="specklePygeoapi")
|
||||
lat = float(url_lower.split("&lat=")[1].split("&")[0])
|
||||
lon = float(url_lower.split("&lon=")[1].split("&")[0])
|
||||
|
||||
coord = f"{lat}, {lon}"
|
||||
location = geolocator.reverse(coord, exactly_one=True)
|
||||
if location is not None:
|
||||
address = location.raw['address']
|
||||
country_code = address.get('country_code', '')
|
||||
except Exception as e:
|
||||
print(f"Error validating project location: {e}")
|
||||
|
||||
if country_code == "ru":
|
||||
print(f"Validating project location: blocked LAT LON {lat}, {lon}")
|
||||
raise PermissionError("Review Speckle Terms and Conditions")
|
||||
else:
|
||||
print(f"Error validating project location: LAT LON {lat}, {lon}")
|
||||
|
||||
# by IP:
|
||||
try:
|
||||
url = 'https://ipinfo.io/' + ip_address + '/json'
|
||||
res = urlopen(url)
|
||||
data = json.load(res)
|
||||
except Exception as e:
|
||||
print(f"Error validating client from start: {e}")
|
||||
try:
|
||||
if data["country"] == "RU":
|
||||
raise PermissionError("Review Speckle Terms and Conditions")
|
||||
except KeyError as e:
|
||||
print(f"Error validating client: {e}")
|
||||
|
||||
def generate():
|
||||
collection_id = "speckle"
|
||||
|
||||
yield loading_screen().data
|
||||
|
||||
|
||||
handle_client("/")
|
||||
CONFIG = get_config(request=request)
|
||||
api_ = API(CONFIG, OPENAPI)
|
||||
|
||||
try:
|
||||
browser_response = execute_from_flask(itemtypes_api.get_collection_items,
|
||||
request, collection_id,
|
||||
@@ -191,38 +272,25 @@ def landing_page():
|
||||
|
||||
:returns: HTTP response
|
||||
"""
|
||||
|
||||
agent = request.headers.get('User-Agent')
|
||||
if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
|
||||
ip_address = request.environ['REMOTE_ADDR']
|
||||
else:
|
||||
ip_address = request.environ['HTTP_X_FORWARDED_FOR']
|
||||
print(f"_______________________{datetime.now().astimezone(timezone.utc)} _URL access")
|
||||
print(f"_Agent /: {agent}")
|
||||
print(f"_IP Address: {ip_address}")
|
||||
print(f"_Request URL: {request.url}")
|
||||
# Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36
|
||||
# Mozilla/5.0 QGIS/32815/Windows 10 Version 2009
|
||||
# ArcGIS Pro 3.3.0 (00000000000) - ArcGISPro
|
||||
|
||||
agent = request.headers.get('User-Agent')
|
||||
browser_agent = False
|
||||
browser_list = ["Chrome", "Safari", "Firefox", "Edg/", "Trident/"]
|
||||
|
||||
request.url += f"&userAgent={agent}"
|
||||
CONFIG = get_config(request=request)
|
||||
api_ = API(CONFIG, OPENAPI)
|
||||
|
||||
if agent is not None and ("YaBrowser/" in agent or "yandex" in agent.lower()):
|
||||
raise ValueError("Your browser is not supported.")
|
||||
for br in browser_list:
|
||||
if agent is not None and br in agent:
|
||||
browser_agent = True
|
||||
break
|
||||
|
||||
|
||||
# if requested from the browser, return this, otherwise ignore IF statement
|
||||
if request.method == 'GET' and browser_agent: # list items
|
||||
print("browser")
|
||||
return Response(stream_with_context(generate()))
|
||||
|
||||
# for non-browsers
|
||||
handle_client("/")
|
||||
CONFIG = get_config(request=request)
|
||||
api_ = API(CONFIG, OPENAPI)
|
||||
return get_response(api_.landing_page(request))
|
||||
|
||||
def error_screen(ex: Exception):
|
||||
@@ -312,16 +380,8 @@ def collections(collection_id=None):
|
||||
|
||||
@BLUEPRINT.route('/speckle')
|
||||
def speckle_collection():
|
||||
|
||||
agent = request.headers.get('User-Agent')
|
||||
if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
|
||||
ip_address = request.environ['REMOTE_ADDR']
|
||||
else:
|
||||
ip_address = request.environ['HTTP_X_FORWARDED_FOR']
|
||||
print(f"_______________________{datetime.now().astimezone(timezone.utc)} _URL access")
|
||||
print(f"_Agent /speckle: {agent}")
|
||||
print(f"_IP Address: {ip_address}")
|
||||
print(f"_Request URL: {request.url}")
|
||||
|
||||
handle_client("/speckle")
|
||||
|
||||
collection_id="speckle"
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ def reproject_bulk(self, all_coords: List[List[List[float]]], all_coord_counts:
|
||||
time1 = datetime.now()
|
||||
flat_coords = reproject_2d_coords_list(self, all_coords)
|
||||
time2 = datetime.now()
|
||||
validate_coords(self, flat_coords[0])
|
||||
|
||||
time_operation = (time2-time1).total_seconds()
|
||||
self.times["time_reproject"] = time_operation
|
||||
@@ -112,3 +113,22 @@ def offset_rotate(self, coords_in: List[list]) -> List[List[float]]:
|
||||
)
|
||||
|
||||
return final_coords
|
||||
|
||||
def validate_coords(self, coords):
|
||||
from geopy.geocoders import Nominatim
|
||||
country_code = ""
|
||||
try:
|
||||
geolocator = Nominatim(user_agent="specklePygeoapi")
|
||||
coord = f"{coords[1]}, {coords[0]}"
|
||||
location = geolocator.reverse(coord, exactly_one=True)
|
||||
if location is not None:
|
||||
address = location.raw['address']
|
||||
country_code = address.get('country_code', '')
|
||||
except Exception as e:
|
||||
print(f"Error validating project location: {e}")
|
||||
|
||||
if country_code == "ru":
|
||||
print(f"Validating project location: blocked LAT LON {coords[1]}, {coords[0]}")
|
||||
raise PermissionError("Review Speckle Terms and Conditions")
|
||||
else:
|
||||
print(f"Error validating project location: LAT LON {coords[1]}, {coords[0]}")
|
||||
|
||||
@@ -2,6 +2,7 @@ Babel
|
||||
click
|
||||
filelock
|
||||
Flask
|
||||
geopy==2.4.1
|
||||
jinja2
|
||||
jsonschema
|
||||
pydantic<2.0
|
||||
|
||||
Reference in New Issue
Block a user