Skip to content

Commit 8129352

Browse files
authored
[Backport 5.0.x] [Fixes #13913] Disable default sync dataset download (#14092)
1 parent 0cf6d20 commit 8129352

5 files changed

Lines changed: 31 additions & 142 deletions

File tree

geonode/base/api/serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ def get_attribute(self, instance):
367367
download_urls.append({"url": obj.download_url, "ajax_safe": obj.is_ajax_safe, "default": False})
368368

369369
if asset:
370-
download_urls.append({"url": asset_url, "ajax_safe": True, "default": False if download_urls else True})
370+
download_urls.append({"url": asset_url, "ajax_safe": True, "default": False})
371371

372372
return download_urls
373373
else:

geonode/base/api/tests.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2885,9 +2885,7 @@ def test_base_resources_return_download_links_for_datasets(self):
28852885
Ensure we can access the Resource Base list.
28862886
"""
28872887
_dataset = Dataset.objects.first()
2888-
expected_payload = [
2889-
{"url": reverse("dataset_download", args=[_dataset.alternate]), "ajax_safe": True, "default": True}
2890-
]
2888+
expected_payload = []
28912889

28922890
# From resource base API
28932891
json = self._get_for_object(_dataset, "base-resources-detail")

geonode/layers/api/tests.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -682,19 +682,14 @@ def test_download_api(self):
682682
response = self.client.get(url)
683683
self.assertTrue(response.status_code == 200)
684684
data = response.json()["dataset"]
685-
download_url_data = data["download_urls"][0]
686-
download_url = reverse("dataset_download", args=[dataset.alternate])
687-
self.assertEqual(download_url_data["default"], True)
688-
self.assertEqual(download_url_data["ajax_safe"], True)
689-
self.assertEqual(download_url_data["url"], download_url)
685+
self.assertEqual(data["download_urls"], [])
690686

691687
link = Link(link_type="original", url="https://myoriginal.org", resource=dataset)
692688
link.save()
693689

694690
response = self.client.get(url)
695691
data = response.json()["dataset"]
696692
download_url_data = data["download_urls"][0]
697-
download_url = reverse("dataset_download", args=[dataset.alternate])
698693
self.assertEqual(download_url_data["default"], True)
699694
self.assertEqual(download_url_data["ajax_safe"], False)
700695
self.assertEqual(download_url_data["url"], "https://myoriginal.org")

geonode/layers/download_handler.py

Lines changed: 4 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,11 @@
1818
#########################################################################
1919

2020
import logging
21-
import xml.etree.ElementTree as ET
2221

23-
from django.http import Http404, HttpResponse, HttpResponseRedirect, JsonResponse
24-
from django.template.loader import get_template
25-
from django.urls import reverse
22+
from django.http import Http404
2623
from django.utils.translation import gettext_lazy as _
2724
from django.conf import settings
28-
from geonode.base.auth import get_or_create_token
29-
from geonode.geoserver.helpers import wps_format_is_supported
3025
from geonode.layers.views import _resolve_dataset
31-
from geonode.proxy.views import fetch_response_headers
32-
from geonode.utils import HttpClient
3326

3427
logger = logging.getLogger("geonode.layers.download_handler")
3528

@@ -51,11 +44,7 @@ def get_download_response(self):
5144
Basic method. Should return the Response object
5245
that allow the resource download
5346
"""
54-
resource = self.get_resource()
55-
if not resource:
56-
raise Http404("Resource requested is not available")
57-
response = self.process_dowload(resource)
58-
return response
47+
raise Http404("Direct download for the requested resource is not supported")
5948

6049
@property
6150
def is_link_resource(self):
@@ -82,7 +71,7 @@ def download_url(self):
8271
if self.is_link_resource:
8372
return resource.link_set.filter(resource=resource.get_self_resource(), link_type="original").first().url
8473

85-
return reverse("dataset_download", args=[resource.alternate])
74+
return None
8675

8776
def get_resource(self):
8877
"""
@@ -99,70 +88,4 @@ def get_resource(self):
9988
except Exception as e:
10089
logger.debug(e)
10190

102-
return self._resource
103-
104-
def process_dowload(self, resource=None):
105-
"""
106-
Generate the response object
107-
"""
108-
if not resource:
109-
resource = self.get_resource()
110-
if not settings.USE_GEOSERVER:
111-
# if GeoServer is not used, we redirect to the proxy download
112-
return HttpResponseRedirect(reverse("download", args=[resource.id]))
113-
114-
download_format = self.request.GET.get("export_format")
115-
116-
if download_format and not wps_format_is_supported(download_format, resource.subtype):
117-
logger.error("The format provided is not valid for the selected resource")
118-
return JsonResponse({"error": "The format provided is not valid for the selected resource"}, status=500)
119-
120-
_format = "application/zip" if resource.is_vector() else "image/tiff"
121-
# getting default payload
122-
tpl = get_template("geoserver/dataset_download.xml")
123-
ctx = {"alternate": resource.alternate, "download_format": download_format or _format}
124-
# applying context for the payload
125-
payload = tpl.render(ctx)
126-
127-
# init of Client
128-
client = HttpClient()
129-
130-
headers = {"Content-type": "application/xml", "Accept": "application/xml"}
131-
132-
# defining the URL needed fr the download
133-
url = f"{settings.OGC_SERVER['default']['LOCATION']}ows?service=WPS&version=1.0.0&REQUEST=Execute"
134-
if not self.request.user.is_anonymous:
135-
# define access token for the user
136-
access_token = get_or_create_token(self.request.user)
137-
url += f"&access_token={access_token}"
138-
139-
# request to geoserver
140-
response, content = client.request(url=url, data=payload, method="post", headers=headers)
141-
142-
if not response or response.status_code != 200:
143-
logger.error(f"Download dataset exception: error during call with GeoServer: {content}")
144-
return JsonResponse(
145-
{"error": "Download dataset exception: error during call with GeoServer"},
146-
status=500,
147-
)
148-
149-
# error handling
150-
namespaces = {"ows": "http://www.opengis.net/ows/1.1", "wps": "http://www.opengis.net/wps/1.0.0"}
151-
response_type = response.headers.get("Content-Type")
152-
if response_type == "text/xml":
153-
# parsing XML for get exception
154-
content = ET.fromstring(response.text)
155-
exc = content.find("*//ows:Exception", namespaces=namespaces) or content.find(
156-
"ows:Exception", namespaces=namespaces
157-
)
158-
if exc:
159-
exc_text = exc.find("ows:ExceptionText", namespaces=namespaces)
160-
logger.error(f"{exc.attrib.get('exceptionCode')} {exc_text.text}")
161-
return JsonResponse({"error": f"{exc.attrib.get('exceptionCode')}: {exc_text.text}"}, status=500)
162-
163-
return_response = fetch_response_headers(
164-
HttpResponse(content=response.content, status=response.status_code, content_type=download_format),
165-
response.headers,
166-
)
167-
return_response.headers["Content-Type"] = download_format or _format
168-
return return_response
91+
return self._resource

geonode/layers/tests.py

Lines changed: 24 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -644,35 +644,26 @@ def test_dataset_download_not_found_for_non_existing_dataset(self):
644644
self.assertEqual(404, response.status_code)
645645

646646
@override_settings(USE_GEOSERVER=False)
647-
def test_dataset_download_redirect_to_proxy_url(self):
648-
# if settings.USE_GEOSERVER is false, the URL must be redirected
647+
def test_dataset_download_returns_404(self):
649648
self.client.login(username="admin", password="admin")
650649
dataset = Dataset.objects.first()
651650
url = reverse("dataset_download", args=[dataset.alternate])
652651
response = self.client.get(url)
653-
self.assertEqual(302, response.status_code)
654-
self.assertEqual(f"/download/{dataset.id}", response.url)
652+
self.assertEqual(404, response.status_code)
655653

656-
def test_dataset_download_invalid_wps_format(self):
657-
# if settings.USE_GEOSERVER is false, the URL must be redirected
654+
def test_dataset_download_invalid_format(self):
658655
self.client.login(username="admin", password="admin")
659656
dataset = Dataset.objects.first()
660657
url = reverse("dataset_download", args=[dataset.alternate])
661658
response = self.client.get(f"{url}?export_format=foo")
662-
self.assertEqual(500, response.status_code)
663-
self.assertDictEqual({"error": "The format provided is not valid for the selected resource"}, response.json())
659+
self.assertEqual(404, response.status_code)
664660

665-
@patch("geonode.layers.download_handler.HttpClient.request")
666-
def test_dataset_download_call_the_catalog_raise_error_for_no_200(self, mocked_catalog):
667-
_response = MagicMock(status_code=500, content="foo-bar")
668-
mocked_catalog.return_value = _response, "foo-bar"
669-
# if settings.USE_GEOSERVER is false, the URL must be redirected
661+
def test_dataset_download_no_geoserver_call(self):
670662
self.client.login(username="admin", password="admin")
671663
dataset = Dataset.objects.first()
672664
url = reverse("dataset_download", args=[dataset.alternate])
673665
response = self.client.get(url)
674-
self.assertEqual(500, response.status_code)
675-
self.assertDictEqual({"error": "Download dataset exception: error during call with GeoServer"}, response.json())
666+
self.assertEqual(404, response.status_code)
676667

677668
def test_dataset_download_call_the_catalog_raise_error_for_error_content(self):
678669
content = """<?xml version="1.0" encoding="UTF-8"?>
@@ -686,24 +677,23 @@ def test_dataset_download_call_the_catalog_raise_error_for_error_content(self):
686677
# if settings.USE_GEOSERVER is false, the URL must be redirected
687678
self.client.login(username="admin", password="admin")
688679
dataset = Dataset.objects.first()
689-
with patch("geonode.layers.download_handler.HttpClient.request") as mocked_catalog:
680+
with patch("geonode.utils.HttpClient.request") as mocked_catalog:
690681
mocked_catalog.return_value = _response, content
691682
url = reverse("dataset_download", args=[dataset.alternate])
692683
response = self.client.get(url)
693-
self.assertEqual(500, response.status_code)
694-
self.assertDictEqual({"error": "InvalidParameterValue: Foo Bar Exception"}, response.json())
684+
self.assertEqual(404, response.status_code)
695685

696-
def test_dataset_download_call_the_catalog_works(self):
686+
def test_dataset_download_call_the_catalog(self):
697687
# if settings.USE_GEOSERVER is false, the URL must be redirected
698688
_response = MagicMock(status_code=200, text="", headers={"Content-Type": ""}) # noqa
699689
self.client.login(username="admin", password="admin")
700690
dataset = Dataset.objects.first()
701691
layer = create_dataset(dataset.title, dataset.title, dataset.owner, "Point")
702-
with patch("geonode.layers.download_handler.HttpClient.request") as mocked_catalog:
692+
with patch("geonode.utils.HttpClient.request") as mocked_catalog:
703693
mocked_catalog.return_value = _response, ""
704694
url = reverse("dataset_download", args=[layer.alternate])
705695
response = self.client.get(url)
706-
self.assertTrue(response.status_code == 200)
696+
self.assertTrue(response.status_code == 404)
707697

708698
def test_dataset_download_call_the_catalog_not_work_without_download_resurcebase_perm(self):
709699
dataset = Dataset.objects.first()
@@ -713,55 +703,42 @@ def test_dataset_download_call_the_catalog_not_work_without_download_resurcebase
713703
response = self.client.get(url)
714704
self.assertEqual(404, response.status_code)
715705

716-
def test_dataset_download_call_the_catalog_work_anonymous(self):
717-
# if settings.USE_GEOSERVER is false, the URL must be redirected
706+
def test_dataset_download_anonymous(self):
718707
_response = MagicMock(status_code=200, text="", headers={"Content-Type": ""}) # noqa
719708
dataset = Dataset.objects.first()
720709
layer = create_dataset(dataset.title, dataset.title, dataset.owner, "Point")
721-
with patch("geonode.layers.download_handler.HttpClient.request") as mocked_catalog:
710+
with patch("geonode.utils.HttpClient.request") as mocked_catalog:
722711
mocked_catalog.return_value = _response, ""
723712
url = reverse("dataset_download", args=[layer.alternate])
724713
response = self.client.get(url)
725-
self.assertTrue(response.status_code == 200)
714+
self.assertTrue(response.status_code == 404)
726715

727716
@override_settings(USE_GEOSERVER=True)
728-
@patch("geonode.layers.download_handler.get_template")
729-
def test_dataset_download_call_the_catalog_work_for_raster(self, pathed_template):
717+
@patch("django.template.loader.get_template")
718+
def test_dataset_download_call_the_catalog_for_raster(self, pathed_template):
730719
# if settings.USE_GEOSERVER is false, the URL must be redirected
731720
_response = MagicMock(status_code=200, text="", headers={"Content-Type": ""}) # noqa
732721
dataset = Dataset.objects.filter(subtype="raster").first()
733722
layer = create_dataset(dataset.title, dataset.title, dataset.owner, "Point")
734723
Dataset.objects.filter(alternate=layer.alternate).update(subtype="raster")
735-
with patch("geonode.layers.download_handler.HttpClient.request") as mocked_catalog:
724+
with patch("geonode.utils.HttpClient.request") as mocked_catalog:
736725
mocked_catalog.return_value = _response, ""
737726
url = reverse("dataset_download", args=[layer.alternate])
738727
response = self.client.get(url)
739-
self.assertTrue(response.status_code == 200)
740-
"""
741-
Evaluate that the context used by the template contains the right mimetype for the resource
742-
"""
743-
self.assertTupleEqual(
744-
({"alternate": layer.alternate, "download_format": "image/tiff"},), pathed_template.mock_calls[1].args
745-
)
728+
self.assertTrue(response.status_code == 404)
746729

747730
@override_settings(USE_GEOSERVER=True)
748-
@patch("geonode.layers.download_handler.get_template")
749-
def test_dataset_download_call_the_catalog_work_for_vector(self, pathed_template):
731+
@patch("django.template.loader.get_template")
732+
def test_dataset_download_call_the_catalog_not_work_for_vector(self, pathed_template):
750733
# if settings.USE_GEOSERVER is false, the URL must be redirected
751734
_response = MagicMock(status_code=200, text="", headers={"Content-Type": ""}) # noqa
752735
dataset = Dataset.objects.filter(subtype="vector").first()
753736
layer = create_dataset(dataset.title, dataset.title, dataset.owner, "Point")
754-
with patch("geonode.layers.download_handler.HttpClient.request") as mocked_catalog:
737+
with patch("geonode.utils.HttpClient.request") as mocked_catalog:
755738
mocked_catalog.return_value = _response, ""
756739
url = reverse("dataset_download", args=[layer.alternate])
757740
response = self.client.get(url)
758-
self.assertTrue(response.status_code == 200)
759-
"""
760-
Evaluate that the context used by the template contains the right mimetype for the resource
761-
"""
762-
self.assertTupleEqual(
763-
({"alternate": layer.alternate, "download_format": "application/zip"},), pathed_template.mock_calls[1].args
764-
)
741+
self.assertTrue(response.status_code == 404)
765742

766743
@patch.object(Dataset, "get_choices", new_callable=PropertyMock)
767744
def test_supports_time_with_vector_time_subtype(self, mock_get_choices):
@@ -1327,8 +1304,8 @@ def setUp(self):
13271304
self.sut = DatasetDownloadHandler(request, self.dataset.alternate)
13281305

13291306
def test_download_url_without_original_link(self):
1330-
expected_url = reverse("dataset_download", args=[self.dataset.alternate])
1331-
self.assertEqual(expected_url, self.sut.download_url)
1307+
1308+
self.assertIsNone(self.sut.download_url)
13321309

13331310
def test_download_url_with_original_link(self):
13341311
Link.objects.update_or_create(
@@ -1347,10 +1324,6 @@ def test_download_url_with_original_link(self):
13471324
def test_get_resource_exists(self):
13481325
self.assertIsNotNone(self.sut.get_resource())
13491326

1350-
def test_process_dowload(self):
1351-
response = self.sut.get_download_response()
1352-
self.assertIsNotNone(response)
1353-
13541327

13551328
class DummyDownloadHandler(DatasetDownloadHandler):
13561329
def get_download_response(self):

0 commit comments

Comments
 (0)