Skip to content
Open
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: 6 additions & 4 deletions geonode/thumbs/tests/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def test_datasets_locations_dataset(self):
locations, bbox = thumbnails._datasets_locations(dataset)

self.assertFalse(bbox, "Expected BBOX not to be calculated")
self.assertEqual(locations, [[settings.OGC_SERVER["default"]["LOCATION"], [dataset.alternate], []]])
self.assertEqual(locations, [[settings.OGC_SERVER["default"]["LOCATION"], [dataset.alternate], [], {}]])

def test_datasets_locations_dataset_default_bbox(self):
expected_bbox = [-8238681.374829309, -8220320.783295829, 4969844.0930337105, 4984363.884452854, "EPSG:3857"]
Expand All @@ -211,7 +211,7 @@ def test_datasets_locations_dataset_default_bbox(self):

self.assertEqual(bbox[-1].upper(), "EPSG:3857", "Expected calculated BBOX CRS to be EPSG:3857")
self.assertEqual(bbox, expected_bbox, "Expected calculated BBOX to match pre-converted one.")
self.assertEqual(locations, [[settings.OGC_SERVER["default"]["LOCATION"], [dataset.alternate], []]])
self.assertEqual(locations, [[settings.OGC_SERVER["default"]["LOCATION"], [dataset.alternate], [], {}]])

def test_datasets_locations_dataset_bbox(self):
dataset = Dataset.objects.get(title="theaters_nyc")
Expand All @@ -222,7 +222,7 @@ def test_datasets_locations_dataset_bbox(self):
self.assertEqual(
bbox[-1].lower(), dataset.bbox[-1].lower(), "Expected calculated BBOX's CRS to match dataset's"
)
self.assertEqual(locations, [[settings.OGC_SERVER["default"]["LOCATION"], [dataset.alternate], []]])
self.assertEqual(locations, [[settings.OGC_SERVER["default"]["LOCATION"], [dataset.alternate], [], {}]])

def test_datasets_locations_simple_map(self):
dataset = Dataset.objects.get(title="theaters_nyc")
Expand All @@ -243,6 +243,7 @@ def test_datasets_locations_simple_map(self):
settings.OGC_SERVER["default"]["LOCATION"],
[dataset.alternate, "geonode:Meteorite_Landings_from_NASA_Open_Data_Portal1"],
["theaters_nyc", "test_style"],
{},
]
],
)
Expand All @@ -258,7 +259,7 @@ def test_datasets_locations_simple_map_default_bbox(self):
self.assertEqual(bbox[-1].upper(), "EPSG:3857", "Expected calculated BBOX CRS to be EPSG:3857")
self.assertEqual(bbox, expected_bbox, "Expected calculated BBOX to match pre-converted one.")
self.assertEqual(
locations, [[settings.OGC_SERVER["default"]["LOCATION"], [dataset.alternate], ["theaters_nyc"]]]
locations, [[settings.OGC_SERVER["default"]["LOCATION"], [dataset.alternate], ["theaters_nyc"], {}]]
)

def test_datasets_locations_composition_map_default_bbox(self):
Expand All @@ -271,6 +272,7 @@ def test_datasets_locations_composition_map_default_bbox(self):
"rt_geologia.dbg_risorse_minerarie",
],
[],
{},
]
]

Expand Down
22 changes: 20 additions & 2 deletions geonode/thumbs/thumbnails.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def create_thumbnail(
# --- fetch WMS datasets ---
partial_thumbs = []

for ogc_server, datasets, _styles in locations:
for ogc_server, datasets, _styles, auth_info in locations:
if isinstance(instance, Map):
styles = []
if len(datasets) == len(_styles):
Expand All @@ -160,6 +160,7 @@ def create_thumbnail(
width=width,
height=height,
instance=instance,
auth_info=auth_info,
)
)
except Exception as e:
Expand Down Expand Up @@ -248,6 +249,17 @@ def _generate_thumbnail_name(instance: Union[Dataset, Map, Document, GeoApp, Res
return file_name


def _get_auth_info(dataset: "Dataset") -> dict:
"""Gets authentication info for a dataset if it's a remote service requiring auth."""
auth_info = {}
if dataset.remote_service and dataset.remote_service.needs_authentication:
auth_info = {
"username": dataset.remote_service.username,
"password": dataset.remote_service.get_password(),
}
return auth_info


def _datasets_locations(
instance: Union[Dataset, Map], compute_bbox: bool = False, target_crs: str = "EPSG:3857"
) -> Tuple[List[List], List]:
Expand All @@ -270,7 +282,9 @@ def _datasets_locations(
locations = []
bbox = []
if isinstance(instance, Dataset):
locations.append([instance.ows_url or ogc_server_settings.LOCATION, [instance.alternate], []])
# Check if dataset has remote service with authentication
auth_info = _get_auth_info(instance)
locations.append([instance.ows_url or ogc_server_settings.LOCATION, [instance.alternate], [], auth_info])
if compute_bbox:
if instance.ll_bbox_polygon:
bbox = bbox_utils.clean_bbox(instance.ll_bbox, target_crs)
Expand Down Expand Up @@ -308,6 +322,8 @@ def _datasets_locations(
continue

if dataset.subtype in ["tileStore", "remote"]:
# Check if remote service requires authentication
auth_info = _get_auth_info(dataset)
# limit number of locations, ensuring dataset order
if len(locations) and locations[-1][0] == dataset.remote_service.service_url:
# if previous dataset's location is the same as the current one - append current dataset there
Expand All @@ -321,6 +337,7 @@ def _datasets_locations(
dataset.remote_service.service_url,
[dataset.alternate],
[map_dataset_style] if map_dataset_style else [],
auth_info,
]
)
else:
Expand All @@ -337,6 +354,7 @@ def _datasets_locations(
settings.OGC_SERVER["default"]["LOCATION"],
[dataset.alternate],
[map_dataset_style] if map_dataset_style else [],
{},
]
)

Expand Down
19 changes: 9 additions & 10 deletions geonode/thumbs/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ def get_map(
max_retries: int = 3,
retry_delay: int = 1,
instance=None,
auth_info: dict = None,
):
"""
Function fetching an image from OGC server.
Expand All @@ -164,6 +165,7 @@ def get_map(
:param height: height of the returned image
:param max_retries: maximum number of retries before skipping retrieval
:param retry_delay: number of seconds waited between retries
:param auth_info: optional dict with 'username' and 'password' for remote service authentication
:returns: retrieved image
"""
from geonode.geoserver.helpers import ogc_server_settings
Expand Down Expand Up @@ -201,16 +203,13 @@ def get_map(
else:
headers["Authorization"] = f"Bearer {additional_kwargs['access_token']}"

if instance and instance.subtype == "remote" and instance.remote_typename:
from geonode.services.models import Service

service = Service.objects.filter(name=instance.remote_typename, username__isnull=False, password__isnull=False)
if service.exists():
service = service.first()
encoded_credentials = base64.b64encode(
f"{service.username}:{service.get_password()}".encode("UTF-8")
).decode("ascii")
headers["Authorization"] = f"Basic {encoded_credentials}"
# Check if auth_info is provided (for remote services with authentication)
if auth_info and auth_info.get("username") and auth_info.get("password"):
# Use provided authentication credentials for remote service
encoded_credentials = base64.b64encode(
f"{auth_info['username']}:{auth_info['password']}".encode("UTF-8")
).decode("ascii")
headers["Authorization"] = f"Basic {encoded_credentials}"

image = None
for retry in range(max_retries):
Expand Down
Loading