From c4bd604e1aa453cd9c6b718792e156e8bdf86e3b Mon Sep 17 00:00:00 2001 From: afabiani Date: Wed, 14 Sep 2022 10:02:03 +0200 Subject: [PATCH 001/137] Bump to version 4.0.2 dev 0 --- geonode/__init__.py | 2 +- requirements.txt | 4 ++-- setup.cfg | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/geonode/__init__.py b/geonode/__init__.py index e47da639957..851e0aef2b9 100644 --- a/geonode/__init__.py +++ b/geonode/__init__.py @@ -19,7 +19,7 @@ import os -__version__ = (4, 0, 1, 'final', 0) +__version__ = (4, 0, 2, 'dev', 0) default_app_config = "geonode.apps.AppConfig" diff --git a/requirements.txt b/requirements.txt index fa0900184cb..beeff261b00 100644 --- a/requirements.txt +++ b/requirements.txt @@ -86,8 +86,8 @@ pinax-notifications==6.0.0 pinax-ratings==4.0.0 # GeoNode org maintained apps. -django-geonode-mapstore-client==4.0.4 -# -e git+https://github.com/GeoNode/geonode-mapstore-client.git@4.0.x#egg=django_geonode_mapstore_client +# django-geonode-mapstore-client==4.0.4 +-e git+https://github.com/GeoNode/geonode-mapstore-client.git@4.0.x#egg=django_geonode_mapstore_client geonode-avatar==5.0.8 geonode-oauth-toolkit==2.2.2 geonode-user-messages==2.0.2 diff --git a/setup.cfg b/setup.cfg index ee315fb0a7f..08fdb0bf6b1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -112,8 +112,8 @@ install_requires = pinax-ratings==4.0.0 # GeoNode org maintained apps. - django-geonode-mapstore-client==4.0.4 - # django-geonode-mapstore-client>=4.0.0 + # django-geonode-mapstore-client==4.0.4 + django-geonode-mapstore-client>=4.0.4 geonode-avatar==5.0.8 geonode-oauth-toolkit==2.2.2 geonode-user-messages==2.0.2 From 40fae5b3240ddf5b033688ce1891d7e7f1cfc304 Mon Sep 17 00:00:00 2001 From: Emanuele Tajariol Date: Mon, 19 Sep 2022 10:29:55 +0200 Subject: [PATCH 002/137] #10024 Wrong default style when creating layer (#10025) --- geonode/geoserver/helpers.py | 52 +++++++++++++++++++++--------------- geonode/geoserver/tasks.py | 40 +++++++++++++++++++++++---- 2 files changed, 65 insertions(+), 27 deletions(-) diff --git a/geonode/geoserver/helpers.py b/geonode/geoserver/helpers.py index 02f68bd49a8..d27ca3e5f32 100755 --- a/geonode/geoserver/helpers.py +++ b/geonode/geoserver/helpers.py @@ -1132,7 +1132,7 @@ def set_attributes_from_geoserver(layer, overwrite=False): ) -def get_dataset(layer, gs_catalog): +def get_dataset(layer, gs_catalog: Catalog): gs_catalog.reset() gs_dataset = None try: @@ -1151,24 +1151,27 @@ def get_dataset(layer, gs_catalog): return gs_dataset -def clean_styles(layer, gs_catalog): +def clean_styles(layer, gs_catalog: Catalog): try: # Cleanup Styles without a Workspace gs_catalog.reset() gs_dataset = get_dataset(layer, gs_catalog) - gs_catalog.delete( - gs_catalog.get_style( - name=gs_dataset.default_style.name, - workspace=None, - recursive=True), - purge=True, - recurse=False) - except Exception: - tb = traceback.format_exc() - logger.debug(tb) + logger.debug(f'clean_styles: Retrieving style "{gs_dataset.default_style.name}" for cleanup') + style = gs_catalog.get_style( + name=gs_dataset.default_style.name, + workspace=None, + recursive=True) + if style: + gs_catalog.delete(style, purge=True, recurse=False) + logger.debug(f'clean_styles: Style removed: {gs_dataset.default_style.name}') + else: + logger.debug(f'clean_styles: Style does not exist: {gs_dataset.default_style.name}') + except Exception as e: + logger.warning(f'Could not clean style for layer {layer.name}', exc_info=e) + logger.debug(f'Could not clean style for layer {layer.name} - STACK INFO', stack_info=True) -def set_styles(layer, gs_catalog): +def set_styles(layer, gs_catalog: Catalog): style_set = [] gs_dataset = get_dataset(layer, gs_catalog) if gs_dataset: @@ -1178,18 +1181,21 @@ def set_styles(layer, gs_catalog): layer.default_style, _gs_default_style = save_style(default_style, layer) try: if default_style.name != _gs_default_style.name or default_style.workspace != _gs_default_style.workspace: + logger.debug(f'set_style: Setting default style "{_gs_default_style.name}" for layer "{layer.name}') + gs_dataset.default_style = _gs_default_style gs_catalog.save(gs_dataset) if default_style.name not in DEFAULT_STYLE_NAME: - gs_catalog.delete( - gs_catalog.get_style( - name=default_style.name, - workspace=None, - recursive=True), - purge=True, - recurse=False) + logger.debug(f'set_style: Retrieving no-workspace default style "{default_style.name}" for deletion') + style_to_delete = gs_catalog.get_style(name=default_style.name, workspace=None, recursive=True) + if style_to_delete: + gs_catalog.delete(style_to_delete, purge=True, recurse=False) + logger.debug(f'set_style: No-ws default style deleted: {default_style.name}') + else: + logger.debug(f'set_style: No-ws default style does not exist: {default_style.name}') except Exception as e: - logger.exception(e) + logger.error(f'Error setting default style "{_gs_default_style.name}" for layer "{layer.name}', exc_info=e) + style_set.append(layer.default_style) try: @@ -1218,7 +1224,7 @@ def set_styles(layer, gs_catalog): layer.refresh_from_db() # Legend links - logger.debug(" -- Resource Links[Legend link]...") + logger.debug(f" -- Resource Links[Legend link] for layer {layer.name}...") try: from geonode.base.models import Link dataset_legends = Link.objects.filter(resource=layer.resourcebase_ptr, name='Legend') @@ -1257,11 +1263,13 @@ def save_style(gs_style, layer): sld_body = copy.copy(gs_style.sld_body) _gs_style = None if not gs_style.workspace: + logger.debug(f'save_style: Copying style "{sld_name}" to "{layer.workspace}:{layer.name}') _gs_style = gs_catalog.create_style( layer.name, sld_body, raw=True, overwrite=True, workspace=layer.workspace) else: + logger.debug(f'save_style: Retrieving style "{layer.workspace}:{sld_name}" for layer "{layer.workspace}:{layer.name}') _gs_style = gs_catalog.get_style( name=sld_name, workspace=layer.workspace diff --git a/geonode/geoserver/tasks.py b/geonode/geoserver/tasks.py index 4b4fb8118e1..a0c8b8f7c9f 100644 --- a/geonode/geoserver/tasks.py +++ b/geonode/geoserver/tasks.py @@ -16,6 +16,7 @@ # along with this program. If not, see . # ######################################################################### +import logging import os from django.conf import settings @@ -46,6 +47,8 @@ logger = get_task_logger(__name__) +log_lock = logging.getLogger("geonode_lock_handler") + @app.task( bind=True, @@ -65,12 +68,16 @@ def geoserver_update_datasets(self, *args, **kwargs): Runs update layers. """ lock_id = f'{self.request.id}' + log_lock.debug(f"geoserver_update_datasets: Creating lock {lock_id}") with AcquireLock(lock_id) as lock: + log_lock.debug(f"geoserver_update_datasets: Acquiring lock {lock_id}") if lock.acquire() is True: + log_lock.debug(f"geoserver_update_datasets: Acquired lock {lock_id}") try: return gs_slurp(*args, **kwargs) finally: lock.release() + log_lock.debug(f"geoserver_update_datasets: Released lock {lock_id}") @app.task( @@ -100,9 +107,12 @@ def geoserver_set_style( logger.debug(f"Dataset id {instance_id} does not exist yet!") raise - lock_id = f'{self.request.id}' + lock_id = f'{self.request.id}' if self.request.id else instance.name + log_lock.debug(f"geoserver_set_style: Creating lock {lock_id} for {instance.name}") with AcquireLock(lock_id) as lock: + log_lock.debug(f"geoserver_set_style: Acquiring lock {lock_id} for {instance.name}") if lock.acquire() is True: + log_lock.debug(f"geoserver_set_style: Acquired lock {lock_id} for {instance.name}") try: sld = open(base_file, "rb").read() set_dataset_style( @@ -114,6 +124,7 @@ def geoserver_set_style( logger.exception(e) finally: lock.release() + log_lock.debug(f"geoserver_set_style: Released lock {lock_id} for {instance.name}") @app.task( @@ -146,9 +157,12 @@ def geoserver_create_style( logger.debug(f"Dataset id {instance_id} does not exist yet!") raise - lock_id = f'{self.request.id}' + lock_id = f'{self.request.id}' if self.request.id else instance.name + log_lock.debug(f"geoserver_create_style: Creating lock {lock_id} for {instance.name}") with AcquireLock(lock_id) as lock: - if lock.acquire() is True and instance: + log_lock.debug(f"geoserver_create_style: Acquiring lock {lock_id} for {instance.name}") + if lock.acquire() is True: + log_lock.debug(f"geoserver_create_style: Acquired lock {lock_id} for {instance.name}") try: f = None if sld_file and os.path.exists(sld_file) and os.access(sld_file, os.R_OK): @@ -194,6 +208,7 @@ def geoserver_create_style( geoserver_automatic_default_style_set.send_robust(sender=instance, instance=instance) finally: lock.release() + log_lock.debug(f"geoserver_create_style: Released lock {lock_id} for {instance.name}") @app.task( @@ -216,9 +231,19 @@ def geoserver_post_save_datasets( """ Runs update layers. """ - lock_id = f'{self.request.id}' + instance = None + try: + instance = Dataset.objects.get(id=instance_id) + except Dataset.DoesNotExist: + logger.debug(f"Dataset id {instance_id} does not exist yet!") + raise + + lock_id = f'{self.request.id}' if self.request.id else instance.name + log_lock.debug(f"geoserver_post_save_datasets: Creating lock {lock_id} for {instance_id}") with AcquireLock(lock_id) as lock: + log_lock.debug(f"geoserver_post_save_datasets: Acquiring lock {lock_id} for {instance_id}") if lock.acquire() is True: + log_lock.debug(f"geoserver_post_save_datasets: Acquired lock {lock_id} for {instance_id}") try: sync_instance_with_geoserver(instance_id, *args, **kwargs) @@ -227,6 +252,7 @@ def geoserver_post_save_datasets( call_command('update_index') finally: lock.release() + log_lock.debug(f"geoserver_post_save_datasets: Releasing lock {lock_id} for {instance_id}") @app.task( @@ -253,9 +279,12 @@ def geoserver_create_thumbnail(self, instance_id, overwrite=True, check_bbox=Tru logger.error(f"Resource id {instance_id} does not exist yet!") raise - lock_id = f'{self.request.id}' + lock_id = f'{self.request.id}' if self.request.id else instance.name + log_lock.debug(f"geoserver_create_thumbnail: Creating lock {lock_id} for {instance.name}") with AcquireLock(lock_id) as lock: + log_lock.debug(f"geoserver_create_thumbnail: Acquiring lock {lock_id} for {instance.name}") if lock.acquire() is True: + log_lock.debug(f"geoserver_create_thumbnail: Acquired lock {lock_id} for {instance.name}") try: instance.set_processing_state(enumerations.STATE_RUNNING) try: @@ -268,6 +297,7 @@ def geoserver_create_thumbnail(self, instance_id, overwrite=True, check_bbox=Tru instance.set_processing_state(enumerations.STATE_PROCESSED) finally: lock.release() + log_lock.debug(f"geoserver_create_thumbnail: Released lock {lock_id} for {instance.name}") @app.task( From 6c546dd187792b155d6d841af708ef749602e75f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 11:31:18 +0200 Subject: [PATCH 003/137] Bump boto3 from 1.24.70 to 1.24.75 (#10031) (#10032) Bumps [boto3](https://github.com/boto/boto3) from 1.24.70 to 1.24.75. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/boto3/compare/1.24.70...1.24.75) --- updated-dependencies: - dependency-name: boto3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index beeff261b00..a0d56776d41 100644 --- a/requirements.txt +++ b/requirements.txt @@ -110,7 +110,7 @@ django-storages==1.13.1 dropbox==11.34.0 google-cloud-storage==2.5.0 google-cloud-core==2.3.2 -boto3==1.24.70 +boto3==1.24.75 # Django Caches python-memcached<=1.59 From 5f5419312ca4a46211bbd222633c49ed323ef311 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 11:31:41 +0200 Subject: [PATCH 004/137] Bump smart-open from 6.1.0 to 6.2.0 (#10030) (#10033) Bumps [smart-open](https://github.com/piskvorky/smart_open) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/piskvorky/smart_open/releases) - [Changelog](https://github.com/RaRe-Technologies/smart_open/blob/develop/CHANGELOG.md) - [Commits](https://github.com/piskvorky/smart_open/compare/v6.1.0...v6.2.0) --- updated-dependencies: - dependency-name: smart-open dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a0d56776d41..d1a04491c5b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,7 +24,7 @@ jsonschema==4.16.0 zipstream-new==1.1.8 schema==0.7.5 rdflib==6.1.1 -smart_open==6.1.0 +smart_open==6.2.0 # Django Apps django-allauth==0.51.0 From 15f328b58d4eeea3840ae3042937dceff74398d7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 11:32:01 +0200 Subject: [PATCH 005/137] Bump drf-spectacular from 0.23.1 to 0.24.0 (#10029) (#10034) Bumps [drf-spectacular](https://github.com/tfranzel/drf-spectacular) from 0.23.1 to 0.24.0. - [Release notes](https://github.com/tfranzel/drf-spectacular/releases) - [Changelog](https://github.com/tfranzel/drf-spectacular/blob/master/CHANGELOG.rst) - [Commits](https://github.com/tfranzel/drf-spectacular/compare/0.23.1...0.24.0) --- updated-dependencies: - dependency-name: drf-spectacular dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d1a04491c5b..d26eda59726 100644 --- a/requirements.txt +++ b/requirements.txt @@ -78,7 +78,7 @@ djangorestframework-gis==1.0 djangorestframework-guardian==0.3.0 drf-extensions==0.7.1 drf-writable-nested==0.7.0 -drf-spectacular==0.23.1 +drf-spectacular==0.24.0 dynamic-rest==2.1.2 Markdown==3.4.1 From ae30c2947ff47e49ebf34044218bfbe2dec1b70f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 11:32:20 +0200 Subject: [PATCH 006/137] Update idna requirement from <2.11,>=2.5 to >=2.5,<3.5 (#10028) (#10036) Updates the requirements on [idna](https://github.com/kjd/idna) to permit the latest version. - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst) - [Commits](https://github.com/kjd/idna/compare/v2.5...v3.4) --- updated-dependencies: - dependency-name: idna dependency-type: direct:production ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d26eda59726..13750720eff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,7 @@ amqp==5.1.1 beautifulsoup4==4.11.1 httplib2<0.20.5 hyperlink==21.0.0 -idna>=2.5,<2.11 +idna>=2.5,<3.5 urllib3==1.26.12 Paver==1.3.4 python-slugify==6.1.2 From 9739f7803991b2e37fff74d43a9fed7c27c6577d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 11:32:39 +0200 Subject: [PATCH 007/137] Bump pyjwt from 2.4.0 to 2.5.0 (#10027) (#10037) Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 2.4.0 to 2.5.0. - [Release notes](https://github.com/jpadilla/pyjwt/releases) - [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst) - [Commits](https://github.com/jpadilla/pyjwt/compare/2.4.0...2.5.0) --- updated-dependencies: - dependency-name: pyjwt dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alessio Fabiani Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alessio Fabiani --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 13750720eff..c0a4cb4571a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -48,7 +48,7 @@ django-widget-tweaks==1.4.12 django-sequences==2.7 oauthlib==3.2.1 pyopenssl==22.0.0 -pyjwt==2.4.0 +pyjwt==2.5.0 # geopython dependencies pyproj<3.5.0 From 0330a9074db216898fc4a18fb136772899f3b499 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 11:33:07 +0200 Subject: [PATCH 008/137] [Dependencies] Align setup.cfg with requirements.txt (#10038) (#10044) Co-authored-by: Alessio Fabiani --- setup.cfg | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/setup.cfg b/setup.cfg index 08fdb0bf6b1..e7d6fc6d1b2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -35,7 +35,7 @@ install_requires = beautifulsoup4==4.11.1 httplib2<0.20.5 hyperlink==21.0.0 - idna>=2.5,<2.11 + idna>=2.5,<3.5 urllib3==1.26.12 Paver==1.3.4 python-slugify==6.1.2 @@ -50,7 +50,7 @@ install_requires = zipstream-new==1.1.8 schema==0.7.5 rdflib==6.1.1 - smart_open==6.1.0 + smart_open==6.2.0 # Django Apps django-allauth==0.51.0 @@ -74,7 +74,7 @@ install_requires = django-sequences==2.7 oauthlib==3.2.1 pyopenssl==22.0.0 - pyjwt==2.4.0 + pyjwt==2.5.0 # geopython dependencies pyproj<3.5.0 @@ -104,7 +104,7 @@ install_requires = djangorestframework-guardian==0.3.0 drf-extensions==0.7.1 drf-writable-nested==0.7.0 - drf-spectacular==0.23.1 + drf-spectacular==0.24.0 dynamic-rest==2.1.2 Markdown==3.4.1 @@ -136,7 +136,7 @@ install_requires = dropbox==11.34.0 google-cloud-storage==2.5.0 google-cloud-core==2.3.2 - boto3==1.24.70 + boto3==1.24.75 # Django Caches python-memcached<=1.59 From 3211ab15acad8837bebe346e717d190b9d9a944d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 11:33:32 +0200 Subject: [PATCH 009/137] add installation type to issue template (#10042) (#10043) Co-authored-by: Giovanni Allegri --- .github/ISSUE_TEMPLATE/report_issue.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/report_issue.md b/.github/ISSUE_TEMPLATE/report_issue.md index 43da5c11481..4295d375315 100644 --- a/.github/ISSUE_TEMPLATE/report_issue.md +++ b/.github/ISSUE_TEMPLATE/report_issue.md @@ -22,6 +22,7 @@ assignees: '' ## Specifications - GeoNode version: - - Installation method (manual, GeoNode Docker, SPCGeoNode Docker): + - Installation type (vanilla, geonode-project): + - Installation method (manual, docker): - Platform: - Additional details: From 423ecc2d57d36ffffa79e5c1ce3ea702dc934387 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Sep 2022 15:08:18 +0200 Subject: [PATCH 010/137] [Fixes #10040] Remove auto-generated thumbnail for documents (#10045) (#10052) * -[Fixes #10040] Remove auto-generated thumbnail for documents * - add migration to clean available thumbs * - fix migration * - modify functionality Co-authored-by: NAGGINDA MARTHA --- .../0036_clean_document_thumbnails.py | 33 +++++++++++ geonode/documents/models.py | 13 ---- geonode/documents/tasks.py | 59 ++++--------------- 3 files changed, 45 insertions(+), 60 deletions(-) create mode 100644 geonode/documents/migrations/0036_clean_document_thumbnails.py diff --git a/geonode/documents/migrations/0036_clean_document_thumbnails.py b/geonode/documents/migrations/0036_clean_document_thumbnails.py new file mode 100644 index 00000000000..edfd6847a66 --- /dev/null +++ b/geonode/documents/migrations/0036_clean_document_thumbnails.py @@ -0,0 +1,33 @@ +import logging + +from django.db import migrations + +from ..models import Document + +logger = logging.getLogger(__name__) + + +def set_null_to_non_image_docs_thumbnails(apps, _): + "Sets thumbnail_url to null for documents which are not images" + try: + # update thumbnail urls + for document in Document.objects.all(): + if not document.is_image: + document.thumbnail_url=None + document.save() + # Remove thumbnail links + link_model = apps.get_model('base', 'Link') + link_model.objects.filter(resource__thumbnail_url__isnull=True, name='Thumbnail').delete() + except Exception as e: + logger.exception(e) + + +class Migration(migrations.Migration): + + dependencies = [ + ('documents', '0033_remove_document_doc_type'), + ] + + operations = [ + migrations.RunPython(set_null_to_non_image_docs_thumbnails, migrations.RunPython.noop), + ] diff --git a/geonode/documents/models.py b/geonode/documents/models.py index b9c20121f38..938d736efd8 100644 --- a/geonode/documents/models.py +++ b/geonode/documents/models.py @@ -23,7 +23,6 @@ from django.conf import settings from django.db import models from django.urls import reverse -from django.contrib.staticfiles import finders from django.utils.functional import classproperty from django.utils.translation import ugettext_lazy as _ from django.contrib.contenttypes.models import ContentType @@ -101,18 +100,6 @@ def name_long(self): else: return f'{self.title} ({self.id})' - def find_placeholder(self): - placeholder = 'documents/{0}-placeholder.png' - if finders.find(placeholder.format(self.extension), False): - return finders.find(placeholder.format(self.extension), False) - elif self.is_audio: - return finders.find(placeholder.format('audio'), False) - elif self.is_image: - return finders.find(placeholder.format('image'), False) - elif self.is_video: - return finders.find(placeholder.format('video'), False) - return finders.find(placeholder.format('generic'), False) - @property def href(self): if self.doc_url: diff --git a/geonode/documents/tasks.py b/geonode/documents/tasks.py index e91a6ca30b1..1cd21e6bb74 100644 --- a/geonode/documents/tasks.py +++ b/geonode/documents/tasks.py @@ -16,18 +16,14 @@ # along with this program. If not, see . # ######################################################################### -import os - from celery.utils.log import get_task_logger from geonode.celery_app import app from geonode.storage.manager import storage_manager +from ..base.models import ResourceBase from .models import Document -from .renderers import ( - render_document, - generate_thumbnail_content, - ConversionError) +from .renderers import (generate_thumbnail_content) logger = get_task_logger(__name__) @@ -56,60 +52,29 @@ def create_document_thumbnail(self, object_id): logger.error(f"Document #{object_id} does not exist.") raise - image_path = None image_file = None + thumbnail_content = None if document.is_image: dname = storage_manager.path(document.files[0]) if storage_manager.exists(dname): image_file = storage_manager.open(dname, 'rb') - elif document.is_video or document.is_audio: - image_file = open(document.find_placeholder(), 'rb') - elif document.is_file: - dname = storage_manager.path(document.files[0]) - try: - document_location = storage_manager.path(dname) - except NotImplementedError as e: - logger.debug(e) - - document_location = storage_manager.url(dname) - try: - image_path = render_document(document_location) - if image_path is not None: - try: - image_file = open(image_path, 'rb') - except Exception as e: - logger.debug(f"Failed to render document #{object_id}: {e}") - else: - logger.debug(f"Failed to render document #{object_id}") - except ConversionError as e: - logger.debug(f"Could not convert document #{object_id}: {e}.") - except NotImplementedError as e: - logger.debug(f"Failed to render document #{object_id}: {e}") - - thumbnail_content = None - try: try: thumbnail_content = generate_thumbnail_content(image_file) except Exception as e: - logger.debug(f"Could not generate thumbnail, falling back to 'placeholder': {e}") - thumbnail_content = generate_thumbnail_content(document.find_placeholder()) - except Exception as e: - logger.error(f"Could not generate thumbnail: {e}") - return - finally: - if image_file is not None: - image_file.close() - - if image_path is not None: - os.remove(image_path) + logger.debug(f"Could not generate thumbnail, setting thumbnail_url to None: {e}") + finally: + if image_file is not None: + image_file.close() if not thumbnail_content: logger.warning(f"Thumbnail for document #{object_id} empty.") - filename = f'document-{document.uuid}-thumb.png' - document.save_thumbnail(filename, thumbnail_content) - logger.debug(f"Thumbnail for document #{object_id} created.") + ResourceBase.objects.filter(id=document.id).update(thumbnail_url=None) + else: + filename = f'document-{document.uuid}-thumb.png' + document.save_thumbnail(filename, thumbnail_content) + logger.debug(f"Thumbnail for document #{object_id} created.") @app.task( From ad788e838afefb071b38c69c69db00dd9f2ff4de Mon Sep 17 00:00:00 2001 From: afabiani Date: Wed, 28 Sep 2022 10:24:17 +0200 Subject: [PATCH 011/137] [CLA] Add "edsonflavio" to .clabot (cherry picked from commit 7ead70b47e9535727f89f14159264c9792752f46) --- .clabot | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.clabot b/.clabot index d2622dfb710..0ce286b3718 100644 --- a/.clabot +++ b/.clabot @@ -64,6 +64,7 @@ "mikesname", "DavidQuartz", "jkariukidev", - "mwallschlaeger" + "mwallschlaeger", + "edsonflavio" ] } From dbdf2f8d52c4795b489f58cbafe63f923810ba9b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 28 Sep 2022 10:27:59 +0200 Subject: [PATCH 012/137] Bump pyopenssl from 22.0.0 to 22.1.0 (#10049) (#10059) Bumps [pyopenssl](https://github.com/pyca/pyopenssl) from 22.0.0 to 22.1.0. - [Release notes](https://github.com/pyca/pyopenssl/releases) - [Changelog](https://github.com/pyca/pyopenssl/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/pyopenssl/compare/22.0.0...22.1.0) --- updated-dependencies: - dependency-name: pyopenssl dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alessio Fabiani Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alessio Fabiani --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c0a4cb4571a..64a1cc33195 100644 --- a/requirements.txt +++ b/requirements.txt @@ -47,7 +47,7 @@ django-uuid-upload-path==1.0.0 django-widget-tweaks==1.4.12 django-sequences==2.7 oauthlib==3.2.1 -pyopenssl==22.0.0 +pyopenssl==22.1.0 pyjwt==2.5.0 # geopython dependencies From 9ab5d53d2dcd9ab8140a972ed96b47384a1ed347 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 28 Sep 2022 10:28:26 +0200 Subject: [PATCH 013/137] Bump boto3 from 1.24.75 to 1.24.80 (#10050) (#10058) Bumps [boto3](https://github.com/boto/boto3) from 1.24.75 to 1.24.80. - [Release notes](https://github.com/boto/boto3/releases) - [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/boto3/compare/1.24.75...1.24.80) --- updated-dependencies: - dependency-name: boto3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 64a1cc33195..4c85ca4ce27 100644 --- a/requirements.txt +++ b/requirements.txt @@ -110,7 +110,7 @@ django-storages==1.13.1 dropbox==11.34.0 google-cloud-storage==2.5.0 google-cloud-core==2.3.2 -boto3==1.24.75 +boto3==1.24.80 # Django Caches python-memcached<=1.59 From fdec79af265a0586c4ff7aa0b852796b77057276 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 28 Sep 2022 10:29:00 +0200 Subject: [PATCH 014/137] Update setuptools requirement from <65.4.0,>=59.1.1 to >=59.1.1,<65.5.0 (#10047) (#10054) Updates the requirements on [setuptools](https://github.com/pypa/setuptools) to permit the latest version. - [Release notes](https://github.com/pypa/setuptools/releases) - [Changelog](https://github.com/pypa/setuptools/blob/main/CHANGES.rst) - [Commits](https://github.com/pypa/setuptools/compare/v59.1.1...v65.4.0) --- updated-dependencies: - dependency-name: setuptools dependency-type: direct:production ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4c85ca4ce27..5a7ebe0c6ff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -155,7 +155,7 @@ pytest-bdd==6.0.1 splinter==0.18.1 pytest-splinter==3.3.2 pytest-django==4.5.2 -setuptools>=59.1.1,<65.4.0 +setuptools>=59.1.1,<65.5.0 pip==22.2.2 Twisted==22.8.0 pixelmatch==0.3.0 From 2fdb24fc13df564fb61a05a006565b673c1789b1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 28 Sep 2022 10:29:25 +0200 Subject: [PATCH 015/137] Bump drf-spectacular from 0.24.0 to 0.24.1 (#10051) (#10053) Bumps [drf-spectacular](https://github.com/tfranzel/drf-spectacular) from 0.24.0 to 0.24.1. - [Release notes](https://github.com/tfranzel/drf-spectacular/releases) - [Changelog](https://github.com/tfranzel/drf-spectacular/blob/master/CHANGELOG.rst) - [Commits](https://github.com/tfranzel/drf-spectacular/compare/0.24.0...0.24.1) --- updated-dependencies: - dependency-name: drf-spectacular dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alessio Fabiani Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alessio Fabiani --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5a7ebe0c6ff..6a792c9ef45 100644 --- a/requirements.txt +++ b/requirements.txt @@ -78,7 +78,7 @@ djangorestframework-gis==1.0 djangorestframework-guardian==0.3.0 drf-extensions==0.7.1 drf-writable-nested==0.7.0 -drf-spectacular==0.24.0 +drf-spectacular==0.24.1 dynamic-rest==2.1.2 Markdown==3.4.1 From eac7b940cdeaaaac2d71ba43211f2de489408654 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 28 Sep 2022 10:29:59 +0200 Subject: [PATCH 016/137] [Dependencies] Align setup.cfg with requirements.txt (#10061) (#10064) * [Dependencies] Align setup.cfg with requirements.txt * Revert "Bump djangorestframework from 3.12.0 to 3.14.0" Co-authored-by: Alessio Fabiani --- setup.cfg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.cfg b/setup.cfg index e7d6fc6d1b2..d79b82cab6c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -73,7 +73,7 @@ install_requires = django-widget-tweaks==1.4.12 django-sequences==2.7 oauthlib==3.2.1 - pyopenssl==22.0.0 + pyopenssl==22.1.0 pyjwt==2.5.0 # geopython dependencies @@ -104,7 +104,7 @@ install_requires = djangorestframework-guardian==0.3.0 drf-extensions==0.7.1 drf-writable-nested==0.7.0 - drf-spectacular==0.24.0 + drf-spectacular==0.24.1 dynamic-rest==2.1.2 Markdown==3.4.1 @@ -136,7 +136,7 @@ install_requires = dropbox==11.34.0 google-cloud-storage==2.5.0 google-cloud-core==2.3.2 - boto3==1.24.75 + boto3==1.24.80 # Django Caches python-memcached<=1.59 @@ -181,7 +181,7 @@ install_requires = splinter==0.18.1 pytest-splinter==3.3.2 pytest-django==4.5.2 - setuptools>=59.1.1,<65.4.0 + setuptools>=59.1.1,<65.5.0 pip==22.2.2 Twisted==22.8.0 pixelmatch==0.3.0 From b7836dd435ace600acad015fce627c7f9f57a2b1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 29 Sep 2022 13:52:36 +0200 Subject: [PATCH 017/137] [Fixes #10041] Review the thumbnail scaling process (#10046) (#10069) * -[Fixes #10040] Remove auto-generated thumbnail for documents * - update thumbnail pixels * - add tests * - fix-tests * - fix-tests Co-authored-by: NAGGINDA MARTHA --- geonode/base/models.py | 3 +- geonode/documents/renderers.py | 118 -------------------------- geonode/documents/tasks.py | 13 ++- geonode/documents/tests.py | 38 +++++++++ geonode/documents/tests/data/text.txt | 1 + geonode/settings.py | 2 +- 6 files changed, 51 insertions(+), 124 deletions(-) delete mode 100644 geonode/documents/renderers.py create mode 100644 geonode/documents/tests/data/text.txt diff --git a/geonode/base/models.py b/geonode/base/models.py index 0915bd78717..fd619e89b07 100644 --- a/geonode/base/models.py +++ b/geonode/base/models.py @@ -1741,8 +1741,7 @@ def save_thumbnail(self, filename, image): url = storage_manager.url(upload_path) try: # Optimize the Thumbnail size and resolution - _default_thumb_size = getattr( - settings, 'THUMBNAIL_GENERATOR_DEFAULT_SIZE', {'width': 240, 'height': 200}) + _default_thumb_size = settings.THUMBNAIL_SIZE im = Image.open(storage_manager.open(actual_name)) im.thumbnail( (_default_thumb_size['width'], _default_thumb_size['height']), diff --git a/geonode/documents/renderers.py b/geonode/documents/renderers.py deleted file mode 100644 index dda0fc3e736..00000000000 --- a/geonode/documents/renderers.py +++ /dev/null @@ -1,118 +0,0 @@ -######################################################################### -# -# Copyright (C) 2017 OSGeo -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -######################################################################### - -import io -import os -import subprocess -import traceback -import tempfile - -from django.conf import settings -from threading import Timer -from mimetypes import guess_type -from urllib.request import pathname2url - - -class ConversionError(Exception): - """Raise when conversion was unsuccessful.""" - pass - - -class MissingPILError(Exception): - """Raise when could not import PIL package.""" - pass - - -def guess_mimetype(document_path): - """Guess mime type for a file in local filesystem. - - Return string containing valid mime type. - """ - document_url = pathname2url(document_path) - return guess_type(document_url)[0] - - -def render_document(document_path, extension="png"): - """Render document using `unconv` converter. - - Package `unoconv` has to be installed and available on system - path. Return `NamedTemporaryFile` instance. - """ - - # workaround: https://github.com/dagwieers/unoconv/issues/167 - # first convert a document to PDF and continue - dispose_input = False - if extension != "pdf" and guess_mimetype(document_path) != 'application/pdf': - document_path = render_document(document_path, extension="pdf") - dispose_input = True - - # spawn subprocess and render the document - output_path = None - if settings.UNOCONV_ENABLE: - timeout = None - _, output_path = tempfile.mkstemp(suffix=f".{extension}") - try: - unoconv = subprocess.Popen( - [settings.UNOCONV_EXECUTABLE, "-v", "-e", "PageRange=1-2", - "-f", extension, "-o", output_path, document_path], - stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) - timeout = Timer(settings.UNOCONV_TIMEOUT, unoconv.kill) - timeout.start() - stdout, stderr = unoconv.communicate() - except Exception as e: - traceback.print_exc() - raise ConversionError(str(e)) - finally: - if timeout: - timeout.cancel() - if dispose_input and document_path is not None: - os.remove(document_path) - else: - raise NotImplementedError("unoconv is disabled. Set 'UNOCONV_ENABLE' to enable.") - - return output_path - - -def generate_thumbnail_content(image_path, size=(200, 150)): - """Generate thumbnail content from an image file. - - Return the entire content of the image file. - """ - - try: - from PIL import Image, ImageOps - except ImportError: - raise MissingPILError() - - try: - image = Image.open(image_path) - source_width, source_height = image.size - target_width, target_height = size - - if source_width != target_width or source_width != target_height: - image = ImageOps.fit(image, size, Image.ANTIALIAS) - - with io.BytesIO() as output: - image.save(output, format='PNG') - content = output.getvalue() - output.close() - return content - except Exception as e: - raise e diff --git a/geonode/documents/tasks.py b/geonode/documents/tasks.py index 1cd21e6bb74..d9968e8bbb9 100644 --- a/geonode/documents/tasks.py +++ b/geonode/documents/tasks.py @@ -16,6 +16,10 @@ # along with this program. If not, see . # ######################################################################### +import io + +from PIL import Image + from celery.utils.log import get_task_logger from geonode.celery_app import app @@ -23,7 +27,6 @@ from ..base.models import ResourceBase from .models import Document -from .renderers import (generate_thumbnail_content) logger = get_task_logger(__name__) @@ -61,9 +64,13 @@ def create_document_thumbnail(self, object_id): image_file = storage_manager.open(dname, 'rb') try: - thumbnail_content = generate_thumbnail_content(image_file) + image = Image.open(image_file) + with io.BytesIO() as output: + image.save(output, format='PNG') + thumbnail_content = output.getvalue() + output.close() except Exception as e: - logger.debug(f"Could not generate thumbnail, setting thumbnail_url to None: {e}") + logger.debug(f"Could not generate thumbnail: {e}") finally: if image_file is not None: image_file.close() diff --git a/geonode/documents/tests.py b/geonode/documents/tests.py index 9674da4d8a5..f5311351710 100644 --- a/geonode/documents/tests.py +++ b/geonode/documents/tests.py @@ -31,6 +31,7 @@ from io import BytesIO from unittest.mock import patch +from urllib.parse import urlparse from django.urls import reverse from django.conf import settings @@ -95,6 +96,7 @@ def tearDownClass(cls): def setUp(self): super().setUp() create_models('map') + self.project_root = os.path.abspath(os.path.dirname(__file__)) self.imgfile = io.BytesIO( b'GIF87a\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00ccc,\x00' b'\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;') @@ -266,6 +268,42 @@ def test_replace_document(self): # Remove document d.delete() + def test_non_image_documents_thumbnail(self): + self.client.login(username='admin', password='admin') + try: + with open(os.path.join(f"{self.project_root}", "tests/data/text.txt"), "rb") as f: + data = { + 'title': "Non img File Doc", + 'doc_file': f, + 'extension': 'txt' + } + self.client.post(reverse('document_upload'), data=data) + d = Document.objects.get(title='Non img File Doc') + self.assertIsNone(d.thumbnail_url) + finally: + Document.objects.filter(title='Non img File Doc').delete() + + def test_image_documents_thumbnail(self): + self.client.login(username='admin', password='admin') + try: + with open(os.path.join(f"{self.project_root}", "tests/data/img.gif"), "rb") as f: + data = { + 'title': "img File Doc", + 'doc_file': f, + 'extension': 'gif', + } + with self.settings(THUMBNAIL_SIZE={'width': 400, 'height': 200}): + self.client.post(reverse('document_upload'), data=data) + d = Document.objects.get(title='img File Doc') + self.assertIsNotNone(d.thumbnail_url) + thumb_file = os.path.join( + settings.MEDIA_ROOT, f"thumbs/{os.path.basename(urlparse(d.thumbnail_url).path)}" + ) + file = Image.open(thumb_file) + self.assertEqual(file.size, (400, 200)) + finally: + Document.objects.filter(title='img File Doc').delete() + def test_upload_document_form_size_limit(self): form_data = { 'title': 'GeoNode Map', diff --git a/geonode/documents/tests/data/text.txt b/geonode/documents/tests/data/text.txt new file mode 100644 index 00000000000..2a02d41ce21 --- /dev/null +++ b/geonode/documents/tests/data/text.txt @@ -0,0 +1 @@ +TEST diff --git a/geonode/settings.py b/geonode/settings.py index a695558f362..ded3d6e80b8 100644 --- a/geonode/settings.py +++ b/geonode/settings.py @@ -1997,7 +1997,7 @@ def get_geonode_catalogue_service(): 'THUMBNAIL_GENERATOR', 'geonode.thumbs.thumbnails.create_gs_thumbnail_geonode') THUMBNAIL_SIZE = { - 'width': int(os.environ.get('THUMBNAIL_GENERATOR_DEFAULT_SIZE_WIDTH', 240)), + 'width': int(os.environ.get('THUMBNAIL_GENERATOR_DEFAULT_SIZE_WIDTH', 500)), 'height': int(os.environ.get('THUMBNAIL_GENERATOR_DEFAULT_SIZE_HEIGHT', 200)) } From 5a53e2a41af890d114a3cfd9ae3501e1ee7be7a1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 29 Sep 2022 14:22:48 +0200 Subject: [PATCH 018/137] [Fixes #10066][Depencendies] Security audit and checks (#10067) (#10072) * [Fixes #10066][Depencendies] Security audit and checks * -SNYK security fix Co-authored-by: Alessio Fabiani --- requirements.txt | 5 +++++ setup.cfg | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/requirements.txt b/requirements.txt index 6a792c9ef45..fe73b0415af 100644 --- a/requirements.txt +++ b/requirements.txt @@ -164,3 +164,8 @@ flaky==3.7.0 selenium>=4.1.0,<5.0.0 selenium-requests==2.0.0 webdriver_manager==3.8.3 + +# Security and audit +mistune==2.0.3 +protobuf==4.21.6 +mako==1.2.3 diff --git a/setup.cfg b/setup.cfg index d79b82cab6c..0e90037af19 100644 --- a/setup.cfg +++ b/setup.cfg @@ -191,6 +191,11 @@ install_requires = selenium-requests==2.0.0 webdriver_manager==3.8.3 + # Security and audit + mistune==2.0.3 + protobuf==4.21.6 + mako==1.2.3 + [options.packages.find] exclude = tests From 4391987da08535c216c17644c39b1f577ad846a7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 10:10:12 +0200 Subject: [PATCH 019/137] [Fixes #10055] Modify Metadata form with permissions check (#10057) (#10076) * -[Fixes #10055] Modify Metadata form with permissions check * - check user in form * - update tests * - add tests Co-authored-by: Giovanni Allegri Co-authored-by: NAGGINDA MARTHA Co-authored-by: Giovanni Allegri --- geonode/base/forms.py | 7 ++++- geonode/geoapps/tests.py | 2 +- geonode/layers/tests.py | 56 ++++++++++++++++++++++++++++++++++++++++ geonode/maps/tests.py | 2 +- 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/geonode/base/forms.py b/geonode/base/forms.py index d2bc3b4b12b..5c241b1562b 100644 --- a/geonode/base/forms.py +++ b/geonode/base/forms.py @@ -484,7 +484,9 @@ def __init__(self, *args, **kwargs): self.user = kwargs.pop('user', None) super().__init__(*args, **kwargs) self.fields['regions'].choices = get_tree_data() - + self.can_change_perms = self.user and self.user.has_perm( + 'change_resourcebase_permissions', self.instance.get_self_resource() + ) if self.instance and self.instance.id and self.instance.metadata.exists(): self.fields['extra_metadata'].initial = [x.metadata for x in self.instance.metadata.all()] @@ -501,6 +503,9 @@ def __init__(self, *args, **kwargs): 'data-container': 'body', 'data-html': 'true'}) + if field in ['poc', 'owner'] and not self.can_change_perms: + self.fields[field].disabled = True + def disable_keywords_widget_for_non_superuser(self, user): if settings.FREETEXT_KEYWORDS_READONLY and not user.is_superuser: self['keywords'].field.disabled = True diff --git a/geonode/geoapps/tests.py b/geonode/geoapps/tests.py index 290a25e66c8..8a1cfa54f67 100644 --- a/geonode/geoapps/tests.py +++ b/geonode/geoapps/tests.py @@ -136,7 +136,7 @@ def test_resource_form_is_valid_extra_metadata(self): "date_type": "creation", "language": "eng", "extra_metadata": '[{"id": 1, "filter_header": "object", "field_name": "object", "field_label": "object", "field_value": "object"}]' - }) + }, user=self.user) self.assertTrue(form.is_valid()) def test_geoapp_category_is_correctly_assigned_in_metadata_upload(self): diff --git a/geonode/layers/tests.py b/geonode/layers/tests.py index 293e9f662cb..479d06113a2 100644 --- a/geonode/layers/tests.py +++ b/geonode/layers/tests.py @@ -1877,6 +1877,62 @@ def test_resource_form_is_invalid_extra_metadata_not_json_format(self): expected = {"success": False, "errors": ["extra_metadata: The value provided for the Extra metadata field is not a valid JSON"]} self.assertDictEqual(expected, response.json()) + def test_change_owner_in_metadata(self): + try: + test_user = get_user_model().objects.create_user( + username='non_auth', + email="non_auth@geonode.org", + password='password') + norman = get_user_model().objects.get(username='norman') + dataset = Dataset.objects.first() + data = { + "resource-title": "geoapp_title", + "resource-date": "2022-01-24 16:38 pm", + "resource-date_type": "creation", + "resource-language": "eng", + 'dataset_attribute_set-TOTAL_FORMS': 0, + 'dataset_attribute_set-INITIAL_FORMS': 0 + } + perm_spec = { + "users": { + "non_auth": [ + 'change_resourcebase_metadata', + 'change_resourcebase', + ], + "norman": [ + 'change_resourcebase_metadata', + 'change_resourcebase_permissions' + ], + } + } + self.assertTrue(dataset.set_permissions(perm_spec)) + self.assertFalse(test_user.has_perm('change_resourcebase_permissions', dataset.get_self_resource())) + + url = reverse("dataset_metadata", args=(dataset.alternate,)) + # post as non-authorised user + self.client.login(username="non_auth", password="password") + data["resource-owner"] = test_user.id + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 200) + self.assertNotEqual(dataset.owner, test_user) + # post as admin + self.client.login(username="admin", password="admin") + response = self.client.post(url, data=data) + dataset.refresh_from_db() + self.assertEqual(response.status_code, 200) + self.assertEqual(dataset.owner, test_user) + # post as an authorised user + self.client.login(username="norman", password="norman") + self.assertTrue(norman.has_perm('change_resourcebase_permissions', dataset.get_self_resource())) + data["resource-owner"] = norman.id + response = self.client.post(url, data=data) + dataset.refresh_from_db() + self.assertEqual(response.status_code, 200) + self.assertEqual(dataset.owner, norman) + finally: + get_user_model().objects.filter(username='non_auth').delete + Dataset.objects.filter(name='dataset_name').delete() + @override_settings(EXTRA_METADATA_SCHEMA={"key": "value"}) def test_resource_form_is_invalid_extra_metadata_not_schema_in_settings(self): self.client.login(username="admin", password="admin") diff --git a/geonode/maps/tests.py b/geonode/maps/tests.py index f2447307956..2a0d48c1138 100644 --- a/geonode/maps/tests.py +++ b/geonode/maps/tests.py @@ -710,7 +710,7 @@ def test_resource_form_is_invalid_extra_metadata_invalids_schema_entry(self): self.assertIn(expected, response.json()['errors'][0]) def test_resource_form_is_valid_extra_metadata(self): - form = self.sut(data={ + form = self.sut(user=self.user, data={ "owner": self.map.owner.id, "title": "map_title", "date": "2022-01-24 16:38 pm", From 9e9513305ab6804df5a4f45630d930a97e5cf353 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 4 Oct 2022 15:34:27 +0200 Subject: [PATCH 020/137] [Fixes #10070] Let the resource manager handle also raw sld (#10071) (#10095) * [Fixes #10070] Let the resource manager handle also raw sld * [Fixes #10070] Let the resource manager handle also raw sld * [Fixes #10070] Let the resource manager handle also raw sld Co-authored-by: mattiagiupponi <51856725+mattiagiupponi@users.noreply.github.com> --- geonode/geoserver/helpers.py | 15 ++++------- geonode/geoserver/tasks.py | 9 ++++++- geonode/geoserver/tests/test_tasks.py | 39 ++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/geonode/geoserver/helpers.py b/geonode/geoserver/helpers.py index d27ca3e5f32..ba235b0dce6 100755 --- a/geonode/geoserver/helpers.py +++ b/geonode/geoserver/helpers.py @@ -407,17 +407,12 @@ def set_dataset_style(saved_dataset, title, sld, base_file=None): except Exception as e: logger.exception(e) else: - style = gs_catalog.get_style(saved_dataset.name, workspace=saved_dataset.workspace) or \ - gs_catalog.get_style(saved_dataset.name) try: - if not style: - style = gs_catalog.create_style( - saved_dataset.name, sld, - overwrite=True, raw=True, - workspace=saved_dataset.workspace) - elif sld: - style.style_format = _extract_style_version_from_sld(sld) - style.update_body(sld) + _sld_format = _extract_style_version_from_sld(sld) + style = gs_catalog.create_style( + saved_dataset.name, sld, + overwrite=True, raw=True, style_format=_sld_format, + workspace=saved_dataset.workspace) except Exception as e: logger.exception(e) diff --git a/geonode/geoserver/tasks.py b/geonode/geoserver/tasks.py index a0c8b8f7c9f..f109002a04d 100644 --- a/geonode/geoserver/tasks.py +++ b/geonode/geoserver/tasks.py @@ -114,12 +114,19 @@ def geoserver_set_style( if lock.acquire() is True: log_lock.debug(f"geoserver_set_style: Acquired lock {lock_id} for {instance.name}") try: - sld = open(base_file, "rb").read() + sld = None + if os.path.exists(base_file): + sld = open(base_file, "rb").read() + else: + sld = base_file + base_file = None + set_dataset_style( instance, instance.alternate, sld, base_file=base_file) + except Exception as e: logger.exception(e) finally: diff --git a/geonode/geoserver/tests/test_tasks.py b/geonode/geoserver/tests/test_tasks.py index 9b84df07798..a091a541328 100644 --- a/geonode/geoserver/tests/test_tasks.py +++ b/geonode/geoserver/tests/test_tasks.py @@ -1,7 +1,7 @@ from unittest.mock import create_autospec, patch from geonode.base.populate_test_data import all_public, create_models, remove_models -from geonode.geoserver.tasks import geoserver_create_style +from geonode.geoserver.tasks import geoserver_create_style, geoserver_set_style from geonode.geoserver.signals import geoserver_automatic_default_style_set from geonode.layers.models import Dataset from geonode.layers.populate_datasets_data import create_dataset_data @@ -54,3 +54,40 @@ def test_geoserver_style_visual_mode_automatically_without_sld_file(self): geoserver_automatic_default_style_set.connect(handler) geoserver_create_style(dataset.id, dataset.name, sld_file=None, tempdir=None) handler.assert_called_once_with(signal=geoserver_automatic_default_style_set, sender=dataset, instance=dataset) + + @patch("geonode.geoserver.tasks.set_dataset_style") + def test_geoserver_set_style_with_real_file(self, mocked_set_dataset_style): + dataset = Dataset.objects.first() + sld_file = "geonode/base/fixtures/test_sld.sld" + geoserver_set_style( + instance_id=dataset.id, + base_file=sld_file + ) + mocked_set_dataset_style.assert_called_once() + + args_list = mocked_set_dataset_style.call_args_list[0].args + kwargs_list = mocked_set_dataset_style.call_args_list[0].kwargs + self.assertEqual(args_list[0].id, dataset.id) + self.assertEqual(args_list[1], dataset.alternate) + self.assertIsInstance(args_list[2], bytes) + + self.assertDictEqual({"base_file": sld_file}, kwargs_list) + + @patch("geonode.geoserver.tasks.set_dataset_style") + def test_geoserver_set_style_with_xml(self, mocked_set_dataset_style): + dataset = Dataset.objects.first() + + with open("geonode/base/fixtures/test_sld.sld", 'r+') as _file: + geoserver_set_style( + instance_id=dataset.id, + base_file=_file.read() + ) + mocked_set_dataset_style.assert_called_once() + + args_list = mocked_set_dataset_style.call_args_list[0].args + kwargs_list = mocked_set_dataset_style.call_args_list[0].kwargs + self.assertEqual(args_list[0].id, dataset.id) + self.assertEqual(args_list[1], dataset.alternate) + self.assertIsInstance(args_list[2], str) + + self.assertDictEqual({"base_file": None}, kwargs_list) From a3cf8b2118c35751b6b5ae15eb9782e861d89ca4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 10 Oct 2022 09:29:08 +0200 Subject: [PATCH 021/137] [Fixes #10113] Data retriver keep kmz files even if is unzipped (#10114) (#10115) * [Fixes #10113] Data retriever keeps kmz files even if are unzipped Co-authored-by: mattiagiupponi <51856725+mattiagiupponi@users.noreply.github.com> --- geonode/storage/data_retriever.py | 2 +- geonode/storage/tests.py | 21 +++++++++++++++++++++ geonode/storage/tests/data/Italy.kmz | Bin 0 -> 20402 bytes 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 geonode/storage/tests/data/Italy.kmz diff --git a/geonode/storage/data_retriever.py b/geonode/storage/data_retriever.py index fa20b8a7d51..c9dcb0aa85a 100644 --- a/geonode/storage/data_retriever.py +++ b/geonode/storage/data_retriever.py @@ -202,7 +202,7 @@ def _unzip(self, zip_name: str) -> Mapping: the_zip = zipfile.ZipFile(zip_file, allowZip64=True) the_zip.extractall(self.temporary_folder) available_choices = get_allowed_extensions() - not_main_files = ['xml', 'sld', 'zip'] + not_main_files = ['xml', 'sld', 'zip', 'kmz'] base_file_choices = [x for x in available_choices if x not in not_main_files] for _file in Path(self.temporary_folder).iterdir(): if any([_file.name.endswith(_ext) for _ext in base_file_choices]): diff --git a/geonode/storage/tests.py b/geonode/storage/tests.py index 68ce413b4bb..853aaf06f0a 100644 --- a/geonode/storage/tests.py +++ b/geonode/storage/tests.py @@ -19,6 +19,7 @@ import io import os import shutil +from django.test import override_settings import gisdata from unittest.mock import patch @@ -584,6 +585,26 @@ def test_zip_file_should_correctly_recognize_main_extension_with_csv(self): _files = storage_manager.get_retrieved_paths() self.assertTrue("example.csv" in _files.get("base_file")) + @override_settings(SUPPORTED_DATASET_FILE_TYPES=[{ + "id": "kmz", + "label": "kmz", + "format": "vector", + "ext": ["kmz"] + }, { + "id": "kml", + "label": "kml", + "format": "vector", + "ext": ["kml"] + }]) + def test_zip_file_should_correctly_recognize_main_extension_with_kmz(self): + # reinitiate the storage manager with the zip file + storage_manager = self.sut(remote_files={"base_file": os.path.join(f"{self.project_root}", "tests/data/Italy.kmz")}) + storage_manager.clone_remote_files() + + self.assertIsNotNone(storage_manager.data_retriever.temporary_folder) + _files = storage_manager.get_retrieved_paths() + self.assertTrue("doc.kml" in _files.get("base_file"), msg=f"files available: {_files}") + def test_zip_file_should_correctly_recognize_main_extension_with_shp(self): # zipping files storage_manager = self.sut(remote_files=self.local_files_paths) diff --git a/geonode/storage/tests/data/Italy.kmz b/geonode/storage/tests/data/Italy.kmz new file mode 100644 index 0000000000000000000000000000000000000000..66688fd6798a64ca432844fcaea4c6d4a74d4cf5 GIT binary patch literal 20402 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 Date: Mon, 10 Oct 2022 12:13:39 +0200 Subject: [PATCH 022/137] -[Fixes #10104] Sort resource APIs with created date (#10105) (#10122) Co-authored-by: Alessio Fabiani Co-authored-by: NAGGINDA MARTHA Co-authored-by: Alessio Fabiani --- geonode/base/api/serializers.py | 2 +- geonode/base/api/views.py | 2 +- geonode/documents/api/views.py | 2 +- geonode/geoapps/api/views.py | 2 +- geonode/layers/api/views.py | 2 +- geonode/maps/api/views.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/geonode/base/api/serializers.py b/geonode/base/api/serializers.py index 229ab9c0c48..714709a2949 100644 --- a/geonode/base/api/serializers.py +++ b/geonode/base/api/serializers.py @@ -412,7 +412,7 @@ def to_representation(self, instance): Q(output_params__output__uuid=_resource.uuid) | Q(geonode_resource=_resource)) ) - ).order_by('-last_updated') + ).order_by('-created') for execution in executions: data.append({ diff --git a/geonode/base/api/views.py b/geonode/base/api/views.py index a2fac993e55..b45b16e1e22 100644 --- a/geonode/base/api/views.py +++ b/geonode/base/api/views.py @@ -313,7 +313,7 @@ class ResourceBaseViewSet(DynamicModelViewSet): DynamicFilterBackend, DynamicSortingFilter, DynamicSearchFilter, ExtentFilter, ResourceBasePermissionsFilter, FavoriteFilter ] - queryset = ResourceBase.objects.all().order_by('-last_updated') + queryset = ResourceBase.objects.all().order_by('-created') serializer_class = ResourceBaseSerializer pagination_class = GeoNodeApiPagination diff --git a/geonode/documents/api/views.py b/geonode/documents/api/views.py index 3e733b8c53d..5121fab1912 100644 --- a/geonode/documents/api/views.py +++ b/geonode/documents/api/views.py @@ -53,7 +53,7 @@ class DocumentViewSet(DynamicModelViewSet): DynamicFilterBackend, DynamicSortingFilter, DynamicSearchFilter, ExtentFilter, DocumentPermissionsFilter ] - queryset = Document.objects.all().order_by('-last_updated') + queryset = Document.objects.all().order_by('-created') serializer_class = DocumentSerializer pagination_class = GeoNodeApiPagination diff --git a/geonode/geoapps/api/views.py b/geonode/geoapps/api/views.py index a47bb51f0c0..6dc0595f0ec 100644 --- a/geonode/geoapps/api/views.py +++ b/geonode/geoapps/api/views.py @@ -47,6 +47,6 @@ class GeoAppViewSet(DynamicModelViewSet): DynamicFilterBackend, DynamicSortingFilter, DynamicSearchFilter, ExtentFilter, GeoAppPermissionsFilter ] - queryset = GeoApp.objects.all().order_by('-last_updated') + queryset = GeoApp.objects.all().order_by('-created') serializer_class = GeoAppSerializer pagination_class = GeoNodeApiPagination diff --git a/geonode/layers/api/views.py b/geonode/layers/api/views.py index be83b328d29..3cfc5eb9e56 100644 --- a/geonode/layers/api/views.py +++ b/geonode/layers/api/views.py @@ -63,7 +63,7 @@ class DatasetViewSet(DynamicModelViewSet): ExtentFilter, DatasetPermissionsFilter, ] - queryset = Dataset.objects.all().order_by("-last_updated") + queryset = Dataset.objects.all().order_by('-created') serializer_class = DatasetSerializer pagination_class = GeoNodeApiPagination diff --git a/geonode/maps/api/views.py b/geonode/maps/api/views.py index ac1c88f3741..ca33839ed34 100644 --- a/geonode/maps/api/views.py +++ b/geonode/maps/api/views.py @@ -62,7 +62,7 @@ class MapViewSet(DynamicModelViewSet): ExtentFilter, MapPermissionsFilter, ] - queryset = Map.objects.all().order_by('-last_updated') + queryset = Map.objects.all().order_by('-created') serializer_class = MapSerializer pagination_class = GeoNodeApiPagination From 82c2bc6bb82d29a602fee7e4c7fb42832233531c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 10 Oct 2022 12:14:00 +0200 Subject: [PATCH 023/137] [Fixes #10075] Improvements to the upload time step UI (#10094) (#10111) * -[Fixes #10075] Improvements to the upload time step UI * clarify why user is inside this step Co-authored-by: Giovanni Allegri Co-authored-by: Alessio Fabiani Co-authored-by: NAGGINDA MARTHA Co-authored-by: Giovanni Allegri Co-authored-by: Alessio Fabiani --- geonode/static/geonode/js/upload/time.js | 9 + .../templates/upload/dataset_upload_base.html | 3 +- .../templates/upload/dataset_upload_time.html | 319 +++++++++--------- 3 files changed, 171 insertions(+), 160 deletions(-) diff --git a/geonode/static/geonode/js/upload/time.js b/geonode/static/geonode/js/upload/time.js index 30e86c3657d..bdd55c79b6f 100644 --- a/geonode/static/geonode/js/upload/time.js +++ b/geonode/static/geonode/js/upload/time.js @@ -235,6 +235,7 @@ define(['upload/upload', $(function () { $("#next").on('click', doTime); + const settingsForm = document.getElementById("settings"); $("#DISCRETE_INTERVAL,#CONTINUOUS_INTERVAL").on('change',function(ev) { $("#precision").show(); @@ -245,7 +246,15 @@ define(['upload/upload', }); $('#time-series-toggle-choice').on('change',function(ev) { + // show time form and advamced options + if (settingsForm.style.display !== "none"){ + settingsForm.style.display = "none"; + } + else{ + settingsForm.style.display = "block"; + } if(ev.target.value === 'on' && ev.target.checked) { + if($('#existing').val()) { $('input:radio[id="existing"]').prop("checked", true); $('#existing').trigger("click"); diff --git a/geonode/upload/templates/upload/dataset_upload_base.html b/geonode/upload/templates/upload/dataset_upload_base.html index 582a8d6da2e..1f5b4f37fb2 100644 --- a/geonode/upload/templates/upload/dataset_upload_base.html +++ b/geonode/upload/templates/upload/dataset_upload_base.html @@ -13,8 +13,7 @@ {% block body_outer %}
{% block body %}{% endblock body %} diff --git a/geonode/upload/templates/upload/dataset_upload_time.html b/geonode/upload/templates/upload/dataset_upload_time.html index 814864b321d..c950ebaf4a1 100644 --- a/geonode/upload/templates/upload/dataset_upload_time.html +++ b/geonode/upload/templates/upload/dataset_upload_time.html @@ -6,18 +6,29 @@ {% block body_class %}data data-list upload{% endblock %} -{% block title %} {% trans "Upload Dataset Step: Time" %} - {{ block.super }} {% endblock %} +{% block title %} {% trans "Time series configuration" %} - {{ block.super }} {% endblock %} +{% block page_title %}{% trans "Time series configuration" %}{% endblock page_title %} {% block head %} {{ block.super }} {% endblock %} {% block body %} -
-

{% trans "Inspect data for " %} "{{ dataset_name }}"

- +
+
+ {% trans "Date time fields were detected inside" %} "{{ dataset_name }}". {% trans "Do you want to configure it as a time series dataset?" %} + +

{% blocktrans %}Toggling this selector allows you to configure (or not) this data as a time series; in this case you will also have to select an attribute + to drive the time dimension. +

+ If GeoNode is not able to parse any of the values for the selected attribute red markers will appear to highlight the problems. +

+ More information is provided at the bottom of the page in the "Additional Help" sections. + {% endblocktrans %} +

+
+
- {% csrf_token %}
@@ -25,20 +36,11 @@

{% trans "Inspect data for " %} "{{ dataset_name }}"

{% trans "Configure as Time-Series" %}

- -

{% blocktrans %}Toggling this selector allows you to configure (or not) this data as a time series; in this case you will also have to select an attribute - to drive the time dimension. -

- If GeoNode is not able to parse any of the values for the selected attribute red markers will appear to highlight the problems. -

- More information is provided at the bottom of the page in the "Additional Help" sections. - {% endblocktrans %}

-
- -