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
9 changes: 5 additions & 4 deletions geonode/catalogue/backends/pycsw_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,11 @@ def _csw_local_dispatch(self, keywords=None, start=0, limit=10, bbox=None, ident
HTTP-less CSW
"""

mdict = dict(settings.PYCSW["CONFIGURATION"], **CONFIGURATION)
if "server" in settings.PYCSW["CONFIGURATION"]:
# override server system defaults with user specified directives
mdict["server"].update(settings.PYCSW["CONFIGURATION"]["server"])
mdict = dict(CONFIGURATION, **settings.PYCSW["CONFIGURATION"])
# if "server" in settings.PYCSW["CONFIGURATION"]:
# # override server system defaults with user specified directives
# # When swapping parameters from dict(), this if statement becomes useless
# mdict["server"].update(settings.PYCSW["CONFIGURATION"]["server"])
Comment on lines +127 to +131
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current implementation performs a shallow merge, which causes the server dictionary to be completely replaced by the one in settings.PYCSW. This leads to a regression where default values defined in CONFIGURATION["server"] (such as domainquerytype) are lost if they are not explicitly redefined in the user settings.

Furthermore, the original code (now commented out) had a bug where it mutated the global CONFIGURATION constant because dict() only creates a shallow copy, and update() modifies the dictionary in place.

It is recommended to remove the commented-out code and use a merge strategy that preserves nested defaults and avoids mutating global constants.

Suggested change
mdict = dict(CONFIGURATION, **settings.PYCSW["CONFIGURATION"])
# if "server" in settings.PYCSW["CONFIGURATION"]:
# # override server system defaults with user specified directives
# # When swapping parameters from dict(), this if statement becomes useless
# mdict["server"].update(settings.PYCSW["CONFIGURATION"]["server"])
mdict = dict(CONFIGURATION, **settings.PYCSW["CONFIGURATION"])
if "server" in settings.PYCSW["CONFIGURATION"]:
mdict["server"] = dict(CONFIGURATION.get("server", {}), **settings.PYCSW["CONFIGURATION"]["server"])


# fake HTTP environment variable
os.environ["QUERY_STRING"] = ""
Expand Down
2 changes: 1 addition & 1 deletion geonode/catalogue/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def csw_global_dispatch(request, dataset_filter=None, config_updater=None):
if settings.CATALOGUE["default"]["ENGINE"] != "geonode.catalogue.backends.pycsw_local":
return HttpResponseRedirect(settings.CATALOGUE["default"]["URL"])

mdict = dict(settings.PYCSW["CONFIGURATION"], **CONFIGURATION)
mdict = dict(CONFIGURATION, **settings.PYCSW["CONFIGURATION"])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This shallow merge will cause the server dictionary from settings.PYCSW to completely overwrite the defaults in CONFIGURATION. Additionally, since dict() creates a shallow copy, any subsequent modifications to nested dictionaries in mdict (for example, by config_updater on line 50) will inadvertently mutate the global CONFIGURATION object. It is safer to create a new dictionary for the nested server configuration to ensure defaults are preserved and the global state remains immutable.

Suggested change
mdict = dict(CONFIGURATION, **settings.PYCSW["CONFIGURATION"])
mdict = dict(CONFIGURATION, **settings.PYCSW["CONFIGURATION"])
if "server" in settings.PYCSW["CONFIGURATION"]:
mdict["server"] = dict(CONFIGURATION.get("server", {}), **settings.PYCSW["CONFIGURATION"]["server"])

mdict = config_updater(mdict) if config_updater else mdict

access_token = None
Expand Down
Loading