From c7713102df6027e7f2f597e2ad636e4eddaeb326 Mon Sep 17 00:00:00 2001 From: Steve Hillier Date: Tue, 6 Jul 2021 15:50:22 -0700 Subject: [PATCH 001/693] reduce API docs to a simplified set of endpoints * wells list and well details, and public files for wells * aquifers list and aquifer details, and aquifer documentation * registries list --- app/backend/aquifers/views.py | 17 +++++---------- app/backend/gwells/views/api.py | 11 +++++++--- app/backend/registries/urls.py | 3 ++- app/backend/registries/views.py | 37 ++++++++++----------------------- app/backend/wells/views.py | 27 +++++++----------------- 5 files changed, 33 insertions(+), 62 deletions(-) diff --git a/app/backend/aquifers/views.py b/app/backend/aquifers/views.py index ce5d5e9ce7..622b8e7cbe 100644 --- a/app/backend/aquifers/views.py +++ b/app/backend/aquifers/views.py @@ -343,7 +343,7 @@ class AquiferNameList(ListAPIView): serializer_class = serializers.AquiferSerializerBasic model = Aquifer pagination_class = None - + swagger_schema = None filter_backends = (filters.SearchFilter,) ordering = ('aquifer_id',) search_fields = ( @@ -513,16 +513,9 @@ def delete(self, request, aquifer_id, **kwargs): @swagger_auto_schema( - operation_description=( - 'Get GeoJSON (see https://tools.ietf.org/html/rfc7946) dump of aquifers.'), - method='get', - manual_parameters=GEO_JSON_PARAMS, - responses={ - 302: openapi.Response(GEO_JSON_302_MESSAGE), - 200: openapi.Response( - 'GeoJSON data for aquifers.', - get_geojson_schema(AQUIFER_PROPERTIES, 'Polygon')) - }) + method="GET", + auto_schema=None +) @api_view(['GET']) def aquifer_geojson_v1(request, **kwargs): realtime = request.GET.get('realtime') in ('True', 'true') @@ -557,7 +550,7 @@ def aquifer_geojson_v1(request, **kwargs): 'api/v1/gis/aquifers.json') return HttpResponseRedirect(url) - +@swagger_auto_schema(method='GET', auto_schema=None) @api_view(['GET']) @cache_page(60*15) def aquifer_geojson_simplified_v1(request, **kwargs): diff --git a/app/backend/gwells/views/api.py b/app/backend/gwells/views/api.py index 31bd3e3e2c..6d21c12cc1 100644 --- a/app/backend/gwells/views/api.py +++ b/app/backend/gwells/views/api.py @@ -1,7 +1,7 @@ import requests import geojson from geojson import Feature, FeatureCollection, Point - +from drf_yasg.utils import swagger_auto_schema from rest_framework.response import Response from rest_framework.views import APIView from django.http import JsonResponse, HttpResponse @@ -44,6 +44,8 @@ def get(self, request, **kwargs): class AnalyticsConfig(APIView): """ serves analytics config """ + swagger_schema = None + def get(self, request, **kwargs): config = { "enable_google_analytics": get_env_variable("ENABLE_GOOGLE_ANALYTICS") == "True" @@ -53,7 +55,9 @@ def get(self, request, **kwargs): class InsideBC(APIView): """ Check if a given point is inside BC """ - + + swagger_schema = None + def get(self, request, **kwargs): latitude = request.query_params.get('latitude') longitude = request.query_params.get('longitude') @@ -65,7 +69,8 @@ def get(self, request, **kwargs): class DataBCGeocoder(APIView): """ Looks up address using DataBC's geocoder """ - + swagger_schema = None + def get(self, request, **kwargs): query = kwargs['query'] diff --git a/app/backend/registries/urls.py b/app/backend/registries/urls.py index e2c1c7aaa3..f967412d06 100644 --- a/app/backend/registries/urls.py +++ b/app/backend/registries/urls.py @@ -36,6 +36,7 @@ license=openapi.License(name="Open Government License - British Columbia", url="https://www2.gov.bc.ca/gov/content?id=A519A56BC2BF44E4A008B33FCF527F61"), ), + url='https://apps.nrs.gov.bc.ca/gwells/', public=False, permission_classes=(permissions.RegistriesEditOrReadOnly,) ) @@ -128,6 +129,6 @@ name='city-list-installers'), # Swagger documentation endpoint - url(r'^api/$', schema_view.with_ui('redoc', cache_timeout=None), name='api-docs'), + url(r'^api/$', schema_view.with_ui('swagger', cache_timeout=None), name='api-docs'), ] diff --git a/app/backend/registries/views.py b/app/backend/registries/views.py index 57036e7dac..8856f78f00 100644 --- a/app/backend/registries/views.py +++ b/app/backend/registries/views.py @@ -324,7 +324,6 @@ class PersonListView(RevisionMixin, AuditCreateMixin, ListCreateAPIView): permission_classes = (RegistriesEditOrReadOnly,) serializer_class = PersonAdminSerializer pagination_class = APILimitOffsetPagination - # Allow searching on name fields, names of related companies, etc. filter_backends = (restfilters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter) @@ -577,6 +576,7 @@ class OrganizationNameListView(ListAPIView): .select_related('province_state') pagination_class = None lookup_field = 'organization_guid' + swagger_schema = None def get_queryset(self): return self.queryset.filter(expiry_date__gt=timezone.now()) @@ -769,6 +769,7 @@ class PersonNameSearch(ListAPIView): serializer_class = PersonNameSerializer pagination_class = None lookup_field = 'person_guid' + swagger_schema = None ordering = ('surname',) @@ -780,29 +781,13 @@ def get_queryset(self): class ListFiles(APIView): """ - List documents associated with an aquifer - - get: list files found for the aquifer identified in the uri - """ - - @swagger_auto_schema(responses={200: openapi.Response('OK', - openapi.Schema(type=openapi.TYPE_OBJECT, properties={ - 'public': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema( - type=openapi.TYPE_OBJECT, - properties={ - 'url': openapi.Schema(type=openapi.TYPE_STRING), - 'name': openapi.Schema(type=openapi.TYPE_STRING) - } - )), - 'private': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema( - type=openapi.TYPE_OBJECT, - properties={ - 'url': openapi.Schema(type=openapi.TYPE_STRING), - 'name': openapi.Schema(type=openapi.TYPE_STRING) - } - )) - }) - )}) + List documents associated with a person in the Registry + + get: list files found for the person identified in the uri + """ + + swagger_schema = None + def get(self, request, person_guid, **kwargs): user_is_staff = self.request.user.groups.filter( Q(name=REGISTRIES_EDIT_ROLE) | Q(name=REGISTRIES_VIEWER_ROLE)).exists() @@ -825,8 +810,8 @@ class PreSignedDocumentKey(APIView): queryset = Person.objects.all() permission_classes = (RegistriesEditPermissions,) + swagger_schema = None - @swagger_auto_schema(auto_schema=None) def get(self, request, person_guid, **kwargs): person = get_object_or_404(self.queryset, pk=person_guid) client = MinioClient( @@ -852,8 +837,8 @@ class DeleteDrillerDocument(APIView): queryset = Person.objects.all() permission_classes = (RegistriesEditPermissions,) + swagger_schema = None - @swagger_auto_schema(auto_schema=None) def delete(self, request, person_guid, **kwargs): person = get_object_or_404(self.queryset, pk=person_guid) client = MinioClient( diff --git a/app/backend/wells/views.py b/app/backend/wells/views.py index 7122c3e91e..d860020d2d 100644 --- a/app/backend/wells/views.py +++ b/app/backend/wells/views.py @@ -269,6 +269,7 @@ class WellTagSearchAPIView(ListAPIView): pagination_class = None serializer_class = WellTagSearchSerializer lookup_field = 'well_tag_number' + swagger_schema = None filter_backends = (filters.SearchFilter, filters.OrderingFilter) ordering_fields = ('well_tag_number',) @@ -318,6 +319,7 @@ class WellLocationListAPIViewV1(ListAPIView): permission_classes = (WellsEditOrReadOnly,) model = Well serializer_class = WellLocationSerializerV1 + swagger_schema = None # Allow searching on name fields, names of related companies, etc. filter_backends = (WellListFilterBackend, BoundingBoxFilterBackend, @@ -631,15 +633,8 @@ def get(self, request, well_id, **kwargs): @swagger_auto_schema( - operation_description=('Get GeoJSON (see https://tools.ietf.org/html/rfc7946) dump of wells.'), - method='get', - manual_parameters=GEO_JSON_PARAMS, - responses={ - 302: openapi.Response(GEO_JSON_302_MESSAGE), - 200: openapi.Response( - 'GeoJSON data for well.', - get_geojson_schema(WELL_PROPERTIES, 'Point')) - } + method="GET", + auto_schema=None ) @api_view(['GET']) def well_geojson(request, **kwargs): @@ -710,16 +705,8 @@ def well_geojson(request, **kwargs): @swagger_auto_schema( - operation_description=('Get GeoJSON (see https://tools.ietf.org/html/rfc7946) dump of well ' - 'lithology.'), - method='get', - manual_parameters=GEO_JSON_PARAMS, - responses={ - 302: openapi.Response(GEO_JSON_302_MESSAGE), - 200: openapi.Response( - 'GeoJSON data for well lithology.', - get_geojson_schema(LITHOLOGY_PROPERTIES, 'Point')) - } + method="GET", + auto_schema=None ) @api_view(['GET']) def lithology_geojson(request, **kwargs): @@ -751,7 +738,7 @@ def lithology_geojson(request, **kwargs): 'api/v1/gis/lithology.json') return HttpResponseRedirect(url) - +@swagger_auto_schema(method='GET', auto_schema=None) @api_view(['GET']) def well_licensing(request, **kwargs): tag = request.GET.get('well_tag_number') From a88685cba3546340dcfbc2a6c2f8a6799ff45c53 Mon Sep 17 00:00:00 2001 From: Steve Hillier Date: Thu, 22 Jul 2021 12:15:59 -0700 Subject: [PATCH 002/693] unquote object names to remove plus signs --- app/backend/gwells/documents.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/backend/gwells/documents.py b/app/backend/gwells/documents.py index d183a34898..898a03ad25 100644 --- a/app/backend/gwells/documents.py +++ b/app/backend/gwells/documents.py @@ -16,7 +16,7 @@ import logging from datetime import timedelta from django.urls import reverse -from urllib.parse import quote +from urllib.parse import quote, unquote_plus from minio import Minio from gwells.settings.base import get_env_variable @@ -111,7 +111,7 @@ def create_url(self, obj, host, bucket_name, private=False): return 'https://{}/{}/{}'.format( host, quote(obj.bucket_name), - quote(obj.object_name) + quote(unquote_plus(obj.object_name)) ) def create_url_list(self, objects, host, bucket_name, private=False): @@ -122,7 +122,7 @@ def create_url_list(self, objects, host, bucket_name, private=False): 'url': self.create_url(document, host, bucket_name, private), # split on last occurrence of '/' and return last item (supports any or no prefixes) - 'name': document.object_name.rsplit('/', 1)[-1] + 'name': unquote_plus(document.object_name).rsplit('/', 1)[-1] }, objects) ) return urls From fe36fd79c1981c489fd1db548c7468acbf98fff5 Mon Sep 17 00:00:00 2001 From: Steve Hillier Date: Thu, 22 Jul 2021 15:45:59 -0700 Subject: [PATCH 003/693] add test for s3 filename unquote --- app/backend/gwells/tests/test_documents.py | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 app/backend/gwells/tests/test_documents.py diff --git a/app/backend/gwells/tests/test_documents.py b/app/backend/gwells/tests/test_documents.py new file mode 100644 index 0000000000..6cf24db9be --- /dev/null +++ b/app/backend/gwells/tests/test_documents.py @@ -0,0 +1,32 @@ +from django.test import TestCase +from gwells.documents import MinioClient + + +class DocumentsTestCase(TestCase): + + def test_document_url_with_space(self): + minio_client = MinioClient(disable_private=True) + + test_document = { + "bucket_name": "test_bucket", + "object_name": "test key" + } + + test_url = minio_client.create_url(test_document, "example.com", test_document.get("bucket_name")) + + self.assertEqual(test_url, "https://example.com/test_bucket/test key") + + def test_document_url_with_plus(self): + minio_client = MinioClient(disable_private=True) + + test_document = { + "bucket_name": "test_bucket", + + # if this was a real plus in the filename it should be %2B in the listing. + # spaces get encoded into + (so in this test case, this object_name originally had a space). + "object_name": "test+key" + } + + test_url = minio_client.create_url(test_document, "example.com", test_document.get("bucket_name")) + + self.assertEqual(test_url, "https://example.com/test_bucket/test key") From f16204f605f0a59165b2189f0cf7ada778c1d632 Mon Sep 17 00:00:00 2001 From: Steve Hillier Date: Thu, 22 Jul 2021 16:22:58 -0700 Subject: [PATCH 004/693] update test (basic mock file objects) --- app/backend/gwells/tests/test_documents.py | 33 +++++++++++----------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/app/backend/gwells/tests/test_documents.py b/app/backend/gwells/tests/test_documents.py index 6cf24db9be..b466cd7927 100644 --- a/app/backend/gwells/tests/test_documents.py +++ b/app/backend/gwells/tests/test_documents.py @@ -1,32 +1,33 @@ from django.test import TestCase +from urllib.parse import quote from gwells.documents import MinioClient +class MockObject(): + def __init__(self, bucket_name, object_name): + self.bucket_name = bucket_name + self.object_name = object_name + class DocumentsTestCase(TestCase): def test_document_url_with_space(self): + """ test creating a URL from an object with a space in the object key""" minio_client = MinioClient(disable_private=True) - test_document = { - "bucket_name": "test_bucket", - "object_name": "test key" - } - - test_url = minio_client.create_url(test_document, "example.com", test_document.get("bucket_name")) + test_document = MockObject("test_bucket", "test key") + test_url = minio_client.create_url(test_document, "example.com", test_document.bucket_name) - self.assertEqual(test_url, "https://example.com/test_bucket/test key") + self.assertEqual(test_url, quote("https://example.com/test_bucket/test key")) def test_document_url_with_plus(self): + """ test creating a URL from and object key containing a plus sign """ minio_client = MinioClient(disable_private=True) - test_document = { - "bucket_name": "test_bucket", - - # if this was a real plus in the filename it should be %2B in the listing. - # spaces get encoded into + (so in this test case, this object_name originally had a space). - "object_name": "test+key" - } + # use a key that contains a plus. + # if this was a real plus in the filename it should be %2B in the listing. + # spaces get encoded into + (so in this test case, this object_name originally had a space). + test_document = MockObject("test_bucket", "test+key") - test_url = minio_client.create_url(test_document, "example.com", test_document.get("bucket_name")) + test_url = minio_client.create_url(test_document, "example.com", test_document.bucket_name) - self.assertEqual(test_url, "https://example.com/test_bucket/test key") + self.assertEqual(test_url, quote("https://example.com/test_bucket/test key")) From aacd7e84fe2a7b38b9e107fe19c34a3bdb8ff484 Mon Sep 17 00:00:00 2001 From: Steve Hillier Date: Thu, 22 Jul 2021 16:24:44 -0700 Subject: [PATCH 005/693] add another test case --- app/backend/gwells/tests/test_documents.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/app/backend/gwells/tests/test_documents.py b/app/backend/gwells/tests/test_documents.py index b466cd7927..c396e2133c 100644 --- a/app/backend/gwells/tests/test_documents.py +++ b/app/backend/gwells/tests/test_documents.py @@ -20,7 +20,7 @@ def test_document_url_with_space(self): self.assertEqual(test_url, quote("https://example.com/test_bucket/test key")) def test_document_url_with_plus(self): - """ test creating a URL from and object key containing a plus sign """ + """ test creating a URL from an object key containing a plus sign """ minio_client = MinioClient(disable_private=True) # use a key that contains a plus. @@ -31,3 +31,17 @@ def test_document_url_with_plus(self): test_url = minio_client.create_url(test_document, "example.com", test_document.bucket_name) self.assertEqual(test_url, quote("https://example.com/test_bucket/test key")) + + + def test_document_url_with_encoded_plus(self): + """ test creating a URL from and object key containing an encoded plus sign + e.g., the original filename contained a plus. + """ + minio_client = MinioClient(disable_private=True) + + # use a key that contains an encoded plus (e.g. ). + test_document = MockObject("test_bucket", "test%2Bkey") + + test_url = minio_client.create_url(test_document, "example.com", test_document.bucket_name) + + self.assertEqual(test_url, quote("https://example.com/test_bucket/test+key")) From bd0346731a1b0465742e09c42b4d27ea4366fa00 Mon Sep 17 00:00:00 2001 From: Steve Hillier Date: Thu, 22 Jul 2021 16:34:53 -0700 Subject: [PATCH 006/693] use unquote_plus before generating presigned URLs --- app/backend/gwells/documents.py | 2 +- app/backend/gwells/tests/test_documents.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/backend/gwells/documents.py b/app/backend/gwells/documents.py index 898a03ad25..6b7605a796 100644 --- a/app/backend/gwells/documents.py +++ b/app/backend/gwells/documents.py @@ -92,7 +92,7 @@ def get_private_file(self, object_name: str, bucket_name): """ Generates a link to a private document with name "object_name" (name includes prefixes) """ return self.private_client.presigned_get_object( bucket_name, - object_name, + quote(unquote_plus(object_name)), expires=timedelta(minutes=12)) def create_url(self, obj, host, bucket_name, private=False): diff --git a/app/backend/gwells/tests/test_documents.py b/app/backend/gwells/tests/test_documents.py index c396e2133c..38adb79101 100644 --- a/app/backend/gwells/tests/test_documents.py +++ b/app/backend/gwells/tests/test_documents.py @@ -17,7 +17,7 @@ def test_document_url_with_space(self): test_document = MockObject("test_bucket", "test key") test_url = minio_client.create_url(test_document, "example.com", test_document.bucket_name) - self.assertEqual(test_url, quote("https://example.com/test_bucket/test key")) + self.assertEqual(test_url, "https://example.com/" + quote("test_bucket/test key")) def test_document_url_with_plus(self): """ test creating a URL from an object key containing a plus sign """ @@ -30,7 +30,7 @@ def test_document_url_with_plus(self): test_url = minio_client.create_url(test_document, "example.com", test_document.bucket_name) - self.assertEqual(test_url, quote("https://example.com/test_bucket/test key")) + self.assertEqual(test_url, "https://example.com/" + quote("test_bucket/test key")) def test_document_url_with_encoded_plus(self): @@ -44,4 +44,4 @@ def test_document_url_with_encoded_plus(self): test_url = minio_client.create_url(test_document, "example.com", test_document.bucket_name) - self.assertEqual(test_url, quote("https://example.com/test_bucket/test+key")) + self.assertEqual(test_url, "https://example.com/" + quote("test_bucket/test+key")) From 0c03effbfce8fe389c2521655fe83710a71d0dad Mon Sep 17 00:00:00 2001 From: Steve Hillier Date: Thu, 22 Jul 2021 17:18:24 -0700 Subject: [PATCH 007/693] remove extra `quote` call and add API test --- app/backend/gwells/documents.py | 2 +- tests/api-tests/wells_v2_api_tests.json | 30 ++++++------------------- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/app/backend/gwells/documents.py b/app/backend/gwells/documents.py index 6b7605a796..76eb90fcb8 100644 --- a/app/backend/gwells/documents.py +++ b/app/backend/gwells/documents.py @@ -92,7 +92,7 @@ def get_private_file(self, object_name: str, bucket_name): """ Generates a link to a private document with name "object_name" (name includes prefixes) """ return self.private_client.presigned_get_object( bucket_name, - quote(unquote_plus(object_name)), + unquote_plus(object_name), expires=timedelta(minutes=12)) def create_url(self, obj, host, bucket_name, private=False): diff --git a/tests/api-tests/wells_v2_api_tests.json b/tests/api-tests/wells_v2_api_tests.json index c9877246c6..840cf183f2 100644 --- a/tests/api-tests/wells_v2_api_tests.json +++ b/tests/api-tests/wells_v2_api_tests.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "e27c4a75-c9e6-4a49-b020-ca0fe3322f7f", + "_postman_id": "a73e4387-79dd-4ef9-95de-5e26ae7b0a7f", "name": "GWELLS Well API v2", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, @@ -14,7 +14,6 @@ { "listen": "test", "script": { - "id": "46c51db8-8a25-45d5-941f-f55f682ab9b6", "type": "text/javascript", "exec": [ "var jsonData = pm.response.json()", @@ -85,8 +84,7 @@ }, "response": [] } - ], - "protocolProfileBehavior": {} + ] }, { "name": "Wells", @@ -97,7 +95,6 @@ { "listen": "test", "script": { - "id": "20837dbe-0390-4709-b8dc-4ac3b22153f4", "exec": [ "var jsonData = pm.response.json()", "", @@ -145,7 +142,6 @@ { "listen": "test", "script": { - "id": "7a45223c-da07-49be-adc9-95919a90e263", "exec": [ "var jsonData = pm.response.json();", "", @@ -205,7 +201,6 @@ { "listen": "test", "script": { - "id": "ebc2262c-3d93-4e5f-aa48-4904501c525a", "exec": [ "var jsonData = pm.response.json()", "", @@ -248,7 +243,6 @@ { "listen": "test", "script": { - "id": "768133b0-7dd6-4197-97ca-ddca5cb1743f", "exec": [ "var jsonData = pm.response.json()", "", @@ -260,6 +254,7 @@ " var jsonData = pm.response.json()", " pm.expect(jsonData.url).to.not.eql(null)", " pm.expect(jsonData.url).to.include(\"X-Amz-Signature\")", + " pm.expect(jsonData.url).to.include(\"file with space.pdf\")", "})", "" ], @@ -269,7 +264,6 @@ { "listen": "prerequest", "script": { - "id": "4d7ea87d-32ab-4696-9176-b041b6673698", "exec": [ "" ], @@ -286,7 +280,7 @@ } ], "url": { - "raw": "{{base_url}}/api/v2/wells/{{well_tag_number}}/presigned_put_url?filename=file.pdf", + "raw": "{{base_url}}/api/v2/wells/{{well_tag_number}}/presigned_put_url?filename=file with space.pdf", "host": [ "{{base_url}}" ], @@ -300,7 +294,7 @@ "query": [ { "key": "filename", - "value": "file.pdf" + "value": "file with space.pdf" } ] } @@ -313,7 +307,6 @@ { "listen": "test", "script": { - "id": "768133b0-7dd6-4197-97ca-ddca5cb1743f", "exec": [ "var jsonData = pm.response.json()", "", @@ -333,7 +326,6 @@ { "listen": "prerequest", "script": { - "id": "4d7ea87d-32ab-4696-9176-b041b6673698", "exec": [ "" ], @@ -371,7 +363,6 @@ { "listen": "test", "script": { - "id": "8f3aa783-2831-40f6-a4f9-3ccf241c44aa", "exec": [ "var jsonData = pm.response.json()", "pm.environment.set(\"aquifer_id\", jsonData.aquifer_id);", @@ -423,7 +414,6 @@ { "listen": "test", "script": { - "id": "7a45223c-da07-49be-adc9-95919a90e263", "exec": [ "var jsonData = pm.response.json();\r", "var aquifer_id = pm.environment.get('aquifer_id')\r", @@ -498,7 +488,6 @@ { "listen": "test", "script": { - "id": "8f3aa783-2831-40f6-a4f9-3ccf241c44aa", "exec": [ "var jsonData = pm.response.json()", "pm.environment.set(\"aquifer2_id\", jsonData.aquifer_id);", @@ -550,7 +539,6 @@ { "listen": "test", "script": { - "id": "7a45223c-da07-49be-adc9-95919a90e263", "exec": [ "var jsonData = pm.response.json();\r", "\r", @@ -605,7 +593,6 @@ { "listen": "test", "script": { - "id": "768133b0-7dd6-4197-97ca-ddca5cb1743f", "exec": [ "var jsonData = pm.response.json()", "var aquifer_id = pm.environment.get('aquifer_id')", @@ -658,7 +645,6 @@ { "listen": "prerequest", "script": { - "id": "4d7ea87d-32ab-4696-9176-b041b6673698", "exec": [ "" ], @@ -690,9 +676,7 @@ }, "response": [] } - ], - "protocolProfileBehavior": {} + ] } - ], - "protocolProfileBehavior": {} + ] } \ No newline at end of file From 67f8509811df7d649e16fd079102675a3bd2720c Mon Sep 17 00:00:00 2001 From: Steve Hillier Date: Fri, 23 Jul 2021 09:43:39 -0700 Subject: [PATCH 008/693] update test to use encoded url --- tests/api-tests/wells_v2_api_tests.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api-tests/wells_v2_api_tests.json b/tests/api-tests/wells_v2_api_tests.json index 840cf183f2..917b6e3043 100644 --- a/tests/api-tests/wells_v2_api_tests.json +++ b/tests/api-tests/wells_v2_api_tests.json @@ -254,7 +254,7 @@ " var jsonData = pm.response.json()", " pm.expect(jsonData.url).to.not.eql(null)", " pm.expect(jsonData.url).to.include(\"X-Amz-Signature\")", - " pm.expect(jsonData.url).to.include(\"file with space.pdf\")", + " pm.expect(jsonData.url).to.include(\"file%20with%20space.pdf\")", "})", "" ], From 115a6b5205ff1fe5f4e8e97bbe257afe0a00714f Mon Sep 17 00:00:00 2001 From: Steve Hillier Date: Wed, 4 Aug 2021 15:11:48 -0700 Subject: [PATCH 009/693] order lithology by start/end --- .../wells/migrations/0135_auto_20210804_2205.py | 17 +++++++++++++++++ app/backend/wells/models.py | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 app/backend/wells/migrations/0135_auto_20210804_2205.py diff --git a/app/backend/wells/migrations/0135_auto_20210804_2205.py b/app/backend/wells/migrations/0135_auto_20210804_2205.py new file mode 100644 index 0000000000..7b60505a8c --- /dev/null +++ b/app/backend/wells/migrations/0135_auto_20210804_2205.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.24 on 2021-08-04 22:05 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('wells', '0134_alter_well_export_views_water_1545_v2'), + ] + + operations = [ + migrations.AlterModelOptions( + name='lithologydescription', + options={'ordering': ['start', 'end']}, + ) + ] diff --git a/app/backend/wells/models.py b/app/backend/wells/models.py index 3dfa6277a8..6935a8a4a0 100644 --- a/app/backend/wells/models.py +++ b/app/backend/wells/models.py @@ -2093,7 +2093,7 @@ class LithologyDescription(AuditModel): class Meta: db_table = 'lithology_description' - ordering = ["lithology_sequence_number"] + ordering = ["start", "end"] db_table_comment = ('Describes the different lithologic qualities, characteristics, and materials found ' 'at different depths while drilling.') From 3851d286c99d0d648432c568d525cbcf65d1484e Mon Sep 17 00:00:00 2001 From: Lolanda Emerson <103149911+LolandaE@users.noreply.github.com> Date: Fri, 8 Apr 2022 11:05:21 -0700 Subject: [PATCH 010/693] Update issue templates --- .github/ISSUE_TEMPLATE/bug.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug.md diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 0000000000..68a5e9934c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,24 @@ +--- +name: Bug +about: An undesirable behaviour that needs correction +title: '' +labels: Bug +assignees: '' + +--- + +**Describe the Bug** +A clear and concise description of what the bug is. + +**Expected Behaviour** +A clear and concise description of what you expected to happen. + +**Actual Behaviour** +A clear and concise description of what you expected to happen. + +** Steps To Reproduce** +Steps to reproduce the behaviour: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error From c7d6791017e354c576716c5244df907ae6d2f863 Mon Sep 17 00:00:00 2001 From: Lolanda Emerson <103149911+LolandaE@users.noreply.github.com> Date: Fri, 8 Apr 2022 12:02:55 -0700 Subject: [PATCH 011/693] Update issue templates --- .github/ISSUE_TEMPLATE/task.md | 20 ++++++++++++++++++++ .github/ISSUE_TEMPLATE/user-story.md | 18 ++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/task.md create mode 100644 .github/ISSUE_TEMPLATE/user-story.md diff --git a/.github/ISSUE_TEMPLATE/task.md b/.github/ISSUE_TEMPLATE/task.md new file mode 100644 index 0000000000..becc961f72 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/task.md @@ -0,0 +1,20 @@ +--- +name: Task +about: Any work that does not directly impact the user +title: '' +labels: Task +assignees: '' + +--- + +**Describe the task** +A clear and concise description of what the task is. + +**Acceptance Criteria** +- [ ] first +- [ ] second +- [ ] third + +**Additional context** +- Add any other context about the task here. +- Or here diff --git a/.github/ISSUE_TEMPLATE/user-story.md b/.github/ISSUE_TEMPLATE/user-story.md new file mode 100644 index 0000000000..a5b06661d0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/user-story.md @@ -0,0 +1,18 @@ +--- +name: User Story +about: This template is to be used when describing a feature from the user's perspective +title: '' +labels: User Story +assignees: '' + +--- + +**As a** *(User Type/Persona)* **I want** *(Feature/enhancement)* **So That** *(Value, why is this wanted, what is the user trying to accomplish)* + +**Additional Context** +- enter text here +- enter text here + +**Acceptance Criteria** +- [ ] Given (Context), When (action carried out), Then (expected outcome) +- [ ] Given (Context), When (action carried out), Then (expected outcome) From 4902b644f55fc72b99f100345aa19a1ec7309ea9 Mon Sep 17 00:00:00 2001 From: Lolanda Emerson <103149911+LolandaE@users.noreply.github.com> Date: Mon, 2 May 2022 08:53:16 -0700 Subject: [PATCH 012/693] Update issue templates (#1822) --- .github/ISSUE_TEMPLATE/spike.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/spike.md diff --git a/.github/ISSUE_TEMPLATE/spike.md b/.github/ISSUE_TEMPLATE/spike.md new file mode 100644 index 0000000000..05e435a846 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/spike.md @@ -0,0 +1,26 @@ +--- +name: Spike +about: Research options prior to development work +title: '' +labels: Spike +assignees: '' + +--- + +**Problem Description** +**In order to** (achieve some goal), (a system or persona) **needs to** (some action). + +**Solution Needs** +- Enter the non-negotiables of the solution (what are the needs vs. what are the wants) + +**Timebox** +- How much effort are we committing to this research? + +**Outcome** +Details describing the outcome of the research +- Was it successful? What direction should the work go? +- Was it unsuccessful? Discuss next steps with team + +**Additional Context** +- enter text here +- enter text here From 123433292791dace49934ceb5bdfd6eb00d7f66f Mon Sep 17 00:00:00 2001 From: Norris Ng <103449568+norrisng-bc@users.noreply.github.com> Date: Tue, 7 Jun 2022 15:41:10 -0700 Subject: [PATCH 013/693] Update README local install instructions --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9943f51db5..d2d852d394 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,13 @@ If a new field(s) are needed for export, this export_databc.py has raw sql queri ### Running the GWELLS application locally -[Clone the GWELLS repository](https://help.github.com/en/articles/cloning-a-repository) and run the application with [Docker](https://store.docker.com/search?type=edition&offering=community): +[Clone the GWELLS repository](https://help.github.com/en/articles/cloning-a-repository), and build the [Docker](https://store.docker.com/search?type=edition&offering=community) image for the backend: +```sh +cd gwells/openshift/docker/backend +docker build . --tag=gwells/backend +``` + +Then, run the application with Docker: ```sh cd gwells docker-compose up From 366fd79b257c9026b8f1d7468dc4b1b10dd9d0bc Mon Sep 17 00:00:00 2001 From: Norris Ng <103449568+norrisng-bc@users.noreply.github.com> Date: Wed, 8 Jun 2022 12:46:53 -0700 Subject: [PATCH 014/693] Tweak Dockerfile to download from non-HTTPS url instead --- openshift/docker/backend/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openshift/docker/backend/Dockerfile b/openshift/docker/backend/Dockerfile index e7da3f325c..443d372ba1 100644 --- a/openshift/docker/backend/Dockerfile +++ b/openshift/docker/backend/Dockerfile @@ -10,7 +10,7 @@ USER root # Install and configure GEOS # -RUN cd /tmp && wget https://download.osgeo.org/geos/geos-3.7.1.tar.bz2 && \ +RUN cd /tmp && wget http://download.osgeo.org/geos/geos-3.7.1.tar.bz2 && \ tar xjf geos-3.7.1.tar.bz2 && \ cd geos-3.7.1/ && \ ./configure --prefix=/usr/local && \ @@ -24,8 +24,8 @@ RUN cd /tmp && wget https://download.osgeo.org/geos/geos-3.7.1.tar.bz2 && \ # Install and configure PROJ.4 # -RUN cd /tmp && wget https://download.osgeo.org/proj/proj-5.2.0.tar.gz && \ - wget https://download.osgeo.org/proj/proj-datumgrid-north-america-1.1.tar.gz && \ +RUN cd /tmp && wget http://download.osgeo.org/proj/proj-5.2.0.tar.gz && \ + wget http://download.osgeo.org/proj/proj-datumgrid-north-america-1.1.tar.gz && \ tar xzf proj-5.2.0.tar.gz && \ cd proj-5.2.0/nad && \ tar xzf ../../proj-datumgrid-north-america-1.1.tar.gz && \ From fd26aad268ed85aa2088a236ea84d7bb76fa4e06 Mon Sep 17 00:00:00 2001 From: Norris Ng <103449568+norrisng-bc@users.noreply.github.com> Date: Wed, 8 Jun 2022 13:04:42 -0700 Subject: [PATCH 015/693] Dockerfile: add comment explaining use of non-HTTPS url --- openshift/docker/backend/Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openshift/docker/backend/Dockerfile b/openshift/docker/backend/Dockerfile index 443d372ba1..ecb072bbdd 100644 --- a/openshift/docker/backend/Dockerfile +++ b/openshift/docker/backend/Dockerfile @@ -9,6 +9,8 @@ USER root # External libraries required by Python GIS extensions (e.g. GeoDjango, GeoAlchemy) # Install and configure GEOS # +# Note: HTTPS will result in certificate errors, hence the downgrade to HTTP here +# RUN cd /tmp && wget http://download.osgeo.org/geos/geos-3.7.1.tar.bz2 && \ tar xjf geos-3.7.1.tar.bz2 && \ @@ -23,6 +25,8 @@ RUN cd /tmp && wget http://download.osgeo.org/geos/geos-3.7.1.tar.bz2 && \ # Install and configure PROJ.4 # +# Note: HTTPS will result in certificate errors, hence the downgrade to HTTP here +# RUN cd /tmp && wget http://download.osgeo.org/proj/proj-5.2.0.tar.gz && \ wget http://download.osgeo.org/proj/proj-datumgrid-north-america-1.1.tar.gz && \ From 3f810e80c17a754da6d61ecc7aa47ab9accc1437 Mon Sep 17 00:00:00 2001 From: Christopher Walsh Date: Mon, 20 Jun 2022 11:53:42 -0700 Subject: [PATCH 016/693] Removed duplicate output for alternative specs --- app/frontend/src/wells/views/WellDetail.vue | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/frontend/src/wells/views/WellDetail.vue b/app/frontend/src/wells/views/WellDetail.vue index 40bdac25b3..067391a5d9 100644 --- a/app/frontend/src/wells/views/WellDetail.vue +++ b/app/frontend/src/wells/views/WellDetail.vue @@ -470,9 +470,6 @@ Licensed under the Apache License, Version 2.0 (the "License");

{{ well.comments ? well.comments : 'No comments submitted' }}

-

- Alternative Specs Submitted: {{ well.alternative_specs_submitted | nullBooleanToYesNo }} -

From ff1ad4becd5fb6b615385a43ea35af6c698bcc48 Mon Sep 17 00:00:00 2001 From: Christopher-walsh22 <106549296+Christopher-walsh22@users.noreply.github.com> Date: Fri, 22 Jul 2022 09:10:46 -0700 Subject: [PATCH 017/693] Added Markup-Escape to comply with sonarcloud alerts (#1851) Approved and Completed --- app/backend/gwells/middleware.py | 2 ++ app/backend/requirements.txt | 1 + 2 files changed, 3 insertions(+) diff --git a/app/backend/gwells/middleware.py b/app/backend/gwells/middleware.py index e8b28090f9..2512bb2a11 100644 --- a/app/backend/gwells/middleware.py +++ b/app/backend/gwells/middleware.py @@ -6,6 +6,7 @@ from django.http import HttpResponseBadRequest from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponse +from markupsafe import Markup from gwells.settings.base import get_env_variable @@ -40,5 +41,6 @@ def process_request(self, request, **kwargs): elif _method.upper() == 'DELETE': self.delete(request) else: + _method = Markup.escape(_method) message = 'Unsupported _method: ' + _method return HttpResponse(message, status=500) diff --git a/app/backend/requirements.txt b/app/backend/requirements.txt index 4d92a9e92f..acd9dcc0cb 100644 --- a/app/backend/requirements.txt +++ b/app/backend/requirements.txt @@ -26,3 +26,4 @@ deepdiff>=4 urllib3>=1.24,<1.25 djangorestframework-csv==2.1.0 geojson==2.4.1 +MarkupSafe>=2.0.1 \ No newline at end of file From 0a50ffdb553d3a782ef721006bab35cc7eebcf87 Mon Sep 17 00:00:00 2001 From: dmitri-korin-bcps <108112696+dmitri-korin-bcps@users.noreply.github.com> Date: Fri, 29 Jul 2022 15:38:17 -0700 Subject: [PATCH 018/693] Fix GWELLS Jenkins pipeline issues (#1858) * Use fixed version of setuptools * Revert commit breaking the unit test * Show build status * Add time to finish build * Output more logging info * Try test with minimum pod count * Correct syntax * Set pod number to match the expected by pipeline * Only adjust replica count for the current version * Refactor checking build status --- Jenkinsfile.ocp4 | 11 +++++++++++ app/.s2i/bin/assemble | 2 +- app/frontend/src/wells/views/WellDetail.vue | 3 +++ openshift/ocp4/backend.dc.json | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile.ocp4 b/Jenkinsfile.ocp4 index a439988395..125f3e3950 100644 --- a/Jenkinsfile.ocp4 +++ b/Jenkinsfile.ocp4 @@ -126,6 +126,7 @@ def unitTestDjango (String stageName, String envProject, String envSuffix) { } } } + echo "Running Django unit tests" def ocoutput = openshift.exec( @@ -653,6 +654,16 @@ pipeline { echo "Build Started: ${newBuildSelector.names()}" newBuildSelector.logs("-f") echo "Build Ended: ${newBuildSelector.names()}" + + def buildStatus = "" + timeout(1) { + waitUntil { + buildStatus = newBuildSelector.object().status.phase + echo "Build Status: ${buildStatus}" + return buildStatus != "Running" + } + } + if (newBuildSelector.object().status.phase != "Complete") { error("Build ${newBuildSelector.names()} has failed!") } diff --git a/app/.s2i/bin/assemble b/app/.s2i/bin/assemble index d3b05a5141..2bbe97a8ba 100644 --- a/app/.s2i/bin/assemble +++ b/app/.s2i/bin/assemble @@ -30,7 +30,7 @@ mv /tmp/src/* ./ if [[ ! -z "$UPGRADE_PIP_TO_LATEST" || ! -z "$ENABLE_PIPENV" ]]; then echo "---> Upgrading pip to latest version ..." - pip install -U pip setuptools wheel + pip install -U pip setuptools==57.4.0 wheel fi cd backend diff --git a/app/frontend/src/wells/views/WellDetail.vue b/app/frontend/src/wells/views/WellDetail.vue index 067391a5d9..40bdac25b3 100644 --- a/app/frontend/src/wells/views/WellDetail.vue +++ b/app/frontend/src/wells/views/WellDetail.vue @@ -470,6 +470,9 @@ Licensed under the Apache License, Version 2.0 (the "License");

{{ well.comments ? well.comments : 'No comments submitted' }}

+

+ Alternative Specs Submitted: {{ well.alternative_specs_submitted | nullBooleanToYesNo }} +

diff --git a/openshift/ocp4/backend.dc.json b/openshift/ocp4/backend.dc.json index a5af8c97fa..e60ed9c35b 100644 --- a/openshift/ocp4/backend.dc.json +++ b/openshift/ocp4/backend.dc.json @@ -240,7 +240,7 @@ "type": "ConfigChange" } ], - "replicas": 1, + "replicas": 2, "test": false, "selector": { "name": "gwells${NAME_SUFFIX}" From 2c0aaf73d9534e230daac45f9ab9070a3936d1f0 Mon Sep 17 00:00:00 2001 From: JulianForeman Date: Fri, 12 Aug 2022 12:51:56 -0700 Subject: [PATCH 019/693] Edited test to match expected frontend behaviour. --- app/frontend/src/wells/views/WellDetail.vue | 3 --- .../specs/wells/__snapshots__/WellDetail.spec.js.snap | 9 --------- 2 files changed, 12 deletions(-) diff --git a/app/frontend/src/wells/views/WellDetail.vue b/app/frontend/src/wells/views/WellDetail.vue index 40bdac25b3..067391a5d9 100644 --- a/app/frontend/src/wells/views/WellDetail.vue +++ b/app/frontend/src/wells/views/WellDetail.vue @@ -470,9 +470,6 @@ Licensed under the Apache License, Version 2.0 (the "License");

{{ well.comments ? well.comments : 'No comments submitted' }}

-

- Alternative Specs Submitted: {{ well.alternative_specs_submitted | nullBooleanToYesNo }} -

diff --git a/app/frontend/tests/unit/specs/wells/__snapshots__/WellDetail.spec.js.snap b/app/frontend/tests/unit/specs/wells/__snapshots__/WellDetail.spec.js.snap index e83fd5ff61..fe95b8fb7b 100644 --- a/app/frontend/tests/unit/specs/wells/__snapshots__/WellDetail.spec.js.snap +++ b/app/frontend/tests/unit/specs/wells/__snapshots__/WellDetail.spec.js.snap @@ -1766,15 +1766,6 @@ exports[`WellDetail.vue should match snapshot 1`] = `

-

- - Alternative Specs Submitted: - - - -

Date: Fri, 12 Aug 2022 16:24:09 -0700 Subject: [PATCH 020/693] Updated Wellview Snapshot --- .../tests/unit/specs/wells/__snapshots__/WellDetail.spec.js.snap | 1 - 1 file changed, 1 deletion(-) diff --git a/app/frontend/tests/unit/specs/wells/__snapshots__/WellDetail.spec.js.snap b/app/frontend/tests/unit/specs/wells/__snapshots__/WellDetail.spec.js.snap index fe95b8fb7b..1896b34289 100644 --- a/app/frontend/tests/unit/specs/wells/__snapshots__/WellDetail.spec.js.snap +++ b/app/frontend/tests/unit/specs/wells/__snapshots__/WellDetail.spec.js.snap @@ -1765,7 +1765,6 @@ exports[`WellDetail.vue should match snapshot 1`] = ` No comments submitted

-
Date: Tue, 6 Sep 2022 14:26:01 -0700 Subject: [PATCH 021/693] Correct url lookup (#1866) --- app/backend/submissions/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/backend/submissions/views.py b/app/backend/submissions/views.py index de0e61f712..08c5b12e0a 100644 --- a/app/backend/submissions/views.py +++ b/app/backend/submissions/views.py @@ -416,7 +416,7 @@ def get(self, request, **kwargs): root = urljoin('/', app_root, 'api/v2/') for item in activity_codes.data: if item['code'] not in ('LEGACY'): - item['path'] = reverse(item['code'], request=request)[len(root):] + item['path'] = reverse(item['code'], kwargs={'version': 'v2'})[len(root):] options["province_codes"] = province_codes.data options["activity_types"] = activity_codes.data From 18acbeca85100c68f4ef0e541d8f255faaf7c35d Mon Sep 17 00:00:00 2001 From: JulianForeman Date: Thu, 15 Sep 2022 17:16:09 -0700 Subject: [PATCH 022/693] Changed assemble file permissions to allow jenkins build job to run --- app/.s2i/bin/assemble | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 app/.s2i/bin/assemble diff --git a/app/.s2i/bin/assemble b/app/.s2i/bin/assemble old mode 100644 new mode 100755 From 37fa1b891227fc4636f48909ea327ad278058bf1 Mon Sep 17 00:00:00 2001 From: JulianForeman Date: Tue, 27 Sep 2022 16:40:29 -0700 Subject: [PATCH 023/693] Changing setup tools version so assemble doesn't fail installing GDAL --- app/.s2i/bin/assemble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/.s2i/bin/assemble b/app/.s2i/bin/assemble index d3b05a5141..6be42655f3 100755 --- a/app/.s2i/bin/assemble +++ b/app/.s2i/bin/assemble @@ -30,7 +30,7 @@ mv /tmp/src/* ./ if [[ ! -z "$UPGRADE_PIP_TO_LATEST" || ! -z "$ENABLE_PIPENV" ]]; then echo "---> Upgrading pip to latest version ..." - pip install -U pip setuptools wheel + pip install -U pip setuptools<58 wheel fi cd backend From 736817d32f4ca838b6d03780d83b7d338a439058 Mon Sep 17 00:00:00 2001 From: JulianForeman Date: Tue, 27 Sep 2022 16:47:48 -0700 Subject: [PATCH 024/693] Weird merge fix --- app/.s2i/bin/assemble | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/.s2i/bin/assemble b/app/.s2i/bin/assemble index eafea3f21c..6be42655f3 100755 --- a/app/.s2i/bin/assemble +++ b/app/.s2i/bin/assemble @@ -30,11 +30,7 @@ mv /tmp/src/* ./ if [[ ! -z "$UPGRADE_PIP_TO_LATEST" || ! -z "$ENABLE_PIPENV" ]]; then echo "---> Upgrading pip to latest version ..." -<<<<<<< HEAD pip install -U pip setuptools<58 wheel -======= - pip install -U pip setuptools==57.4.0 wheel ->>>>>>> 0203a363defc9b1962835626ecdd1e3fc1283f04 fi cd backend From 130594f44a67f165f77fc4ef1ecf60a482190a1d Mon Sep 17 00:00:00 2001 From: JulianForeman Date: Tue, 27 Sep 2022 16:52:29 -0700 Subject: [PATCH 025/693] Attempting to fix assemble setuptools version --- app/.s2i/bin/assemble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/.s2i/bin/assemble b/app/.s2i/bin/assemble index 6be42655f3..a981179c29 100755 --- a/app/.s2i/bin/assemble +++ b/app/.s2i/bin/assemble @@ -30,7 +30,7 @@ mv /tmp/src/* ./ if [[ ! -z "$UPGRADE_PIP_TO_LATEST" || ! -z "$ENABLE_PIPENV" ]]; then echo "---> Upgrading pip to latest version ..." - pip install -U pip setuptools<58 wheel + pip install -U pip setuptools<=57.4.0 wheel fi cd backend From 1a9c36819c41a133d273f6e1143f3f0929c4fd6d Mon Sep 17 00:00:00 2001 From: JulianForeman Date: Tue, 27 Sep 2022 16:55:48 -0700 Subject: [PATCH 026/693] Reverting changes to test --- app/.s2i/bin/assemble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/.s2i/bin/assemble b/app/.s2i/bin/assemble index a981179c29..2bbe97a8ba 100755 --- a/app/.s2i/bin/assemble +++ b/app/.s2i/bin/assemble @@ -30,7 +30,7 @@ mv /tmp/src/* ./ if [[ ! -z "$UPGRADE_PIP_TO_LATEST" || ! -z "$ENABLE_PIPENV" ]]; then echo "---> Upgrading pip to latest version ..." - pip install -U pip setuptools<=57.4.0 wheel + pip install -U pip setuptools==57.4.0 wheel fi cd backend From 278ebae12adfcb033b9306913d3db5bde515d248 Mon Sep 17 00:00:00 2001 From: Lolanda Emerson <103149911+LolandaE@users.noreply.github.com> Date: Wed, 12 Oct 2022 15:27:22 -0700 Subject: [PATCH 027/693] Update issue templates (#1876) --- .github/ISSUE_TEMPLATE/bug.md | 2 +- .github/ISSUE_TEMPLATE/task.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 68a5e9934c..804f8c7c60 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -2,7 +2,7 @@ name: Bug about: An undesirable behaviour that needs correction title: '' -labels: Bug +labels: '' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/task.md b/.github/ISSUE_TEMPLATE/task.md index becc961f72..526d466248 100644 --- a/.github/ISSUE_TEMPLATE/task.md +++ b/.github/ISSUE_TEMPLATE/task.md @@ -10,6 +10,9 @@ assignees: '' **Describe the task** A clear and concise description of what the task is. +**Purpose** +The reason why this task is needed and/or what value it adds. + **Acceptance Criteria** - [ ] first - [ ] second From 53142431bcae4b5ded2cde749f82f56c3b0905bf Mon Sep 17 00:00:00 2001 From: Christopher-walsh22 <106549296+Christopher-walsh22@users.noreply.github.com> Date: Thu, 13 Oct 2022 12:30:18 -0700 Subject: [PATCH 028/693] Updated ReadMe for local setup (#1880) Updated instructions for local setup of Min.IO Specified version of Min.IO in docker file to match version used in staging environment. --- README.md | 5 +++++ openshift/docker/minio/Dockerfile | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d2d852d394..770a0fc39f 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,11 @@ cd gwells docker-compose up ``` +For gwells to interact with your local instance of Min.IO add the appropriate settings to your local machines HOSTS file: +``` +127.0.0.1 minio-public +``` + Visit the following links to browse the API and frontend applications: * Django REST API development server: http://localhost:8000/gwells/api/ diff --git a/openshift/docker/minio/Dockerfile b/openshift/docker/minio/Dockerfile index b63259c3e4..b487adbde8 100644 --- a/openshift/docker/minio/Dockerfile +++ b/openshift/docker/minio/Dockerfile @@ -1,4 +1,4 @@ -FROM minio/minio:latest +FROM minio/minio:RELEASE.2020-11-25T22-36-25Z COPY ./minio-entrypoint.sh / ENTRYPOINT /minio-entrypoint.sh \ No newline at end of file From a0118848a85bf96b499ee1030b94e5ba54a3c0aa Mon Sep 17 00:00:00 2001 From: Christopher-walsh22 <106549296+Christopher-walsh22@users.noreply.github.com> Date: Tue, 18 Oct 2022 12:14:09 -0700 Subject: [PATCH 029/693] Add debug output (#1881) * Updated ReadMe for local setup Updated instructions for local setup of Min.IO Specified version of Min.IO in docker file to match version used in staging environment. * Adding debug output Adding debug out for investigation into ticket# 1812 * Revert "Updated ReadMe for local setup" This reverts commit e3b644a762e8eb0f7bbb9001e5d352f822c1a125. * Changed exception handling Changing exception output to conform to code scan --- app/backend/gwells/documents.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/backend/gwells/documents.py b/app/backend/gwells/documents.py index 76eb90fcb8..df4dc7b79c 100644 --- a/app/backend/gwells/documents.py +++ b/app/backend/gwells/documents.py @@ -183,9 +183,9 @@ def get_documents(self, document_id: int, resource='well', include_private=False self.public_client.list_objects( public_bucket, prefix=prefix, recursive=True), self.public_host, public_bucket) - except: + except Exception: logger.error( - "Could not retrieve files from public file server") + "Could not retrieve files from public file server", exc_info=True) objects['public'] = pub_objects From e591dd8e4e678033bfa23de6f7b9be0c7c6d68a8 Mon Sep 17 00:00:00 2001 From: dmitri-korin-bcps <108112696+dmitri-korin-bcps@users.noreply.github.com> Date: Tue, 18 Oct 2022 16:19:46 -0700 Subject: [PATCH 030/693] set-up-daily-build-for-gwells-product (#1883) * Set up trigger for daily build * Post-build notification * Run post build on any agent * Relocate agent assignment * Scope post event * Set post event to run on master * Run post event on build node * Simulate build failure for testing * Simulate fixed build * Check build cause * Using getCanonicalName need approval, replacing it * Convert buildCause to environment variable --- Jenkinsfile.ocp4 | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile.ocp4 b/Jenkinsfile.ocp4 index 125f3e3950..c902e8e3c7 100644 --- a/Jenkinsfile.ocp4 +++ b/Jenkinsfile.ocp4 @@ -545,6 +545,9 @@ def dbBackup (String envProject, String envSuffix) { } pipeline { + triggers { + cron(env.BRANCH_NAME == 'PR-1800' ? '0 7 * * 1-5' : '') + } options { timestamps() ansiColor('xterm') @@ -1114,7 +1117,13 @@ pipeline { agent none when { beforeInput true - expression { env.CHANGE_TARGET == 'master' } + expression { + def buildCause = currentBuild.rawBuild.getCauses().collect { + it.getClass().getName().tokenize('.').last() + } + echo "Build Cause: ${buildCause}" + env.CHANGE_TARGET == 'master' && buildCause.toString() != '[TimerTrigger$TimerTriggerCause]' + } } input { message "Deploy to production?" @@ -1130,7 +1139,13 @@ pipeline { agent { label 'deploy' } when { beforeAgent true - expression { env.CHANGE_TARGET == 'master' } + expression { + def buildCause = currentBuild.rawBuild.getCauses().collect { + it.getClass().getName().tokenize('.').last() + } + echo "Build Cause: ${buildCause}" + env.CHANGE_TARGET == 'master' && buildCause.toString() != '[TimerTrigger$TimerTriggerCause]' + } } steps { script { @@ -1417,4 +1432,14 @@ pipeline { } } } + post { + always { + node('build') { + step([$class: 'Mailer', + notifyEveryUnstableBuild: true, + recipients: "dmitri.korin@gov.bc.ca,Julian.Foreman@gov.bc.ca,Christopher.Walsh@gov.bc.ca,Norris.Ng@gov.bc.ca", + sendToIndividuals: true]) + } + } + } } From c1029426cd7ef24bd9eba7ddc4ae370fd51f1a55 Mon Sep 17 00:00:00 2001 From: Christopher-walsh22 <106549296+Christopher-walsh22@users.noreply.github.com> Date: Thu, 20 Oct 2022 14:59:15 -0700 Subject: [PATCH 031/693] Resolving error from sonar Cloud code scan (#1886) * Recreating error from sonar Cloud Logging error was previously flagged from sonar cloud. Recreating issue. * Adding debug output adding debug output to conform with sonar cloud recommendations, while showing stack trace --- app/backend/gwells/documents.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/backend/gwells/documents.py b/app/backend/gwells/documents.py index df4dc7b79c..26e6d783fb 100644 --- a/app/backend/gwells/documents.py +++ b/app/backend/gwells/documents.py @@ -183,9 +183,9 @@ def get_documents(self, document_id: int, resource='well', include_private=False self.public_client.list_objects( public_bucket, prefix=prefix, recursive=True), self.public_host, public_bucket) - except Exception: + except Exception as e: logger.error( - "Could not retrieve files from public file server", exc_info=True) + "Could not retrieve files from public file server", exc_info=e) objects['public'] = pub_objects From 97bbed41d4d96e080ad619f4358446e41bdcc68e Mon Sep 17 00:00:00 2001 From: Christopher-walsh22 <106549296+Christopher-walsh22@users.noreply.github.com> Date: Mon, 24 Oct 2022 11:56:06 -0700 Subject: [PATCH 032/693] Additional info logger and error logger output (#1887) * Recreating error from sonar Cloud Logging error was previously flagged from sonar cloud. Recreating issue. * Adding debug output adding debug output * Additional Output Adding info logger output to call for retrieving documents Adding additional error logging for failing call to object storage --- app/backend/gwells/documents.py | 2 +- app/backend/wells/views.py | 28 +++++++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/app/backend/gwells/documents.py b/app/backend/gwells/documents.py index 26e6d783fb..521c5cd025 100644 --- a/app/backend/gwells/documents.py +++ b/app/backend/gwells/documents.py @@ -161,7 +161,7 @@ def format_object_name(self, object_name: str, document_id: int, resource='well' def get_documents(self, document_id: int, resource='well', include_private=False): """Retrieves a list of available documents for a well or aquifer""" - + logger.info('Get Documents for: document_id:%s, resource: %s, include_private: %s ', document_id, resource, include_private) # prefix well tag numbers with a 6 digit "folder" id # e.g. WTA 23456 goes into prefix 020000/ prefix = self.get_prefix(document_id, resource) diff --git a/app/backend/wells/views.py b/app/backend/wells/views.py index d860020d2d..821c655a0e 100644 --- a/app/backend/wells/views.py +++ b/app/backend/wells/views.py @@ -196,23 +196,25 @@ class ListFiles(APIView): @swagger_auto_schema(responses={200: openapi.Response('OK', LIST_FILES_OK)}) def get(self, request, tag, **kwargs): + try: + well = get_object_or_404(Well, pk=tag) - well = get_object_or_404(Well, pk=tag) - - if well.well_publication_status\ - .well_publication_status_code == 'Unpublished': - if not self.request.user.groups.filter(name=WELLS_EDIT_ROLE).exists(): - return HttpResponseNotFound() - - user_is_staff = self.request.user.groups.filter( - name=WELLS_VIEWER_ROLE).exists() + if well.well_publication_status\ + .well_publication_status_code == 'Unpublished': + if not self.request.user.groups.filter(name=WELLS_EDIT_ROLE).exists(): + return HttpResponseNotFound() - client = MinioClient( - request=request, disable_private=(not user_is_staff)) + user_is_staff = self.request.user.groups.filter( + name=WELLS_VIEWER_ROLE).exists() - documents = client.get_documents( - int(tag), resource="well", include_private=user_is_staff) + client = MinioClient( + request=request, disable_private=(not user_is_staff)) + documents = client.get_documents( + int(tag), resource="well", include_private=user_is_staff) + except Exception as e: + logger.error( + "Get documents failed at call", exc_info=e) return Response(documents) From 7c88fe74e5fb3ee60457274cc3110a11c224fcc6 Mon Sep 17 00:00:00 2001 From: Lolanda Emerson <103149911+LolandaE@users.noreply.github.com> Date: Mon, 31 Oct 2022 11:55:14 -0700 Subject: [PATCH 033/693] Update issue templates (#1888) --- .github/ISSUE_TEMPLATE/bug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 804f8c7c60..8f53470ab5 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -14,7 +14,7 @@ A clear and concise description of what the bug is. A clear and concise description of what you expected to happen. **Actual Behaviour** -A clear and concise description of what you expected to happen. +A clear and concise description of what actually happens. ** Steps To Reproduce** Steps to reproduce the behaviour: From efe5fd92ce682f035403c88ea18f69d4c336298d Mon Sep 17 00:00:00 2001 From: Christopher-walsh22 <106549296+Christopher-walsh22@users.noreply.github.com> Date: Tue, 1 Nov 2022 15:48:50 -0700 Subject: [PATCH 034/693] Error logging to pass unit tests (#1890) * Recreating error from sonar Cloud Logging error was previously flagged from sonar cloud. Recreating issue. * Adding debug output adding debug output * Additional Output Adding info logger output to call for retrieving documents Adding additional error logging for failing call to object storage * Comply with unit tests Previous version failed Django Unit tests. Updating to meet requirements * Remove try except Undoing changes that were failing unit tests. --- app/backend/wells/views.py | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/app/backend/wells/views.py b/app/backend/wells/views.py index 821c655a0e..21516b371c 100644 --- a/app/backend/wells/views.py +++ b/app/backend/wells/views.py @@ -196,28 +196,24 @@ class ListFiles(APIView): @swagger_auto_schema(responses={200: openapi.Response('OK', LIST_FILES_OK)}) def get(self, request, tag, **kwargs): - try: - well = get_object_or_404(Well, pk=tag) + well = get_object_or_404(Well, pk=tag) + + if well.well_publication_status\ + .well_publication_status_code == 'Unpublished': + if not self.request.user.groups.filter(name=WELLS_EDIT_ROLE).exists(): + return HttpResponseNotFound() - if well.well_publication_status\ - .well_publication_status_code == 'Unpublished': - if not self.request.user.groups.filter(name=WELLS_EDIT_ROLE).exists(): - return HttpResponseNotFound() + user_is_staff = self.request.user.groups.filter( + name=WELLS_VIEWER_ROLE).exists() - user_is_staff = self.request.user.groups.filter( - name=WELLS_VIEWER_ROLE).exists() + client = MinioClient( + request=request, disable_private=(not user_is_staff)) - client = MinioClient( - request=request, disable_private=(not user_is_staff)) + documents = client.get_documents( + int(tag), resource="well", include_private=user_is_staff) - documents = client.get_documents( - int(tag), resource="well", include_private=user_is_staff) - except Exception as e: - logger.error( - "Get documents failed at call", exc_info=e) return Response(documents) - class WellListAPIViewV1(ListAPIView): """List and create wells From 403306c24b9cbb4954537c883dfd44334f967bbb Mon Sep 17 00:00:00 2001 From: Norris Ng <103449568+norrisng-bc@users.noreply.github.com> Date: Mon, 14 Nov 2022 16:52:38 -0800 Subject: [PATCH 035/693] Add new column for Silver Keycloak ID --- .../0008_profile_silver_keycloak_id.py | 28 +++++++++++++++++++ app/backend/gwells/models/__init__.py | 1 + 2 files changed, 29 insertions(+) create mode 100644 app/backend/gwells/migrations/0008_profile_silver_keycloak_id.py diff --git a/app/backend/gwells/migrations/0008_profile_silver_keycloak_id.py b/app/backend/gwells/migrations/0008_profile_silver_keycloak_id.py new file mode 100644 index 0000000000..5b98925ce0 --- /dev/null +++ b/app/backend/gwells/migrations/0008_profile_silver_keycloak_id.py @@ -0,0 +1,28 @@ +# Generated by Django 2.2.28 on 2022-11-08 01:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('gwells', '0007_create_postgis_ftw_schema_20200501_2146'), + ] + + operations = [ + migrations.AddField( + model_name='profile', + name='silver_keycloak_id', + field=models.CharField(blank=True, max_length=150, null=True, unique=True), + ), + migrations.RunSQL( + ''' + UPDATE profile + SET silver_keycloak_id = auth_user.username + FROM auth_user + WHERE auth_user.id = profile.user_id; + ''', + # Column is dropped on reversal anyway, so no need to do anything + reverse_sql='' + ), + ] diff --git a/app/backend/gwells/models/__init__.py b/app/backend/gwells/models/__init__.py index 2eb5583fba..6f7fc12b9b 100644 --- a/app/backend/gwells/models/__init__.py +++ b/app/backend/gwells/models/__init__.py @@ -44,6 +44,7 @@ class Profile(models.Model, DBComments): primary_key=True, default=uuid.uuid4, editable=False) username = models.CharField(max_length=100, blank=True, null=True) name = models.CharField(max_length=100, blank=True, null=True) + silver_keycloak_id = models.CharField(max_length=150, unique=True, blank=True, null=True) db_table_comment = ('Additional user information that cannot be stored on the django auth_user table.') From 5f98e08dd5961ae55945be849fa2189aebbe845b Mon Sep 17 00:00:00 2001 From: Norris Ng <103449568+norrisng-bc@users.noreply.github.com> Date: Mon, 14 Nov 2022 16:57:45 -0800 Subject: [PATCH 036/693] Handle Gold JWT differences --- app/backend/gwells/authentication.py | 51 ++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/app/backend/gwells/authentication.py b/app/backend/gwells/authentication.py index 35484ea556..e40a805f7e 100644 --- a/app/backend/gwells/authentication.py +++ b/app/backend/gwells/authentication.py @@ -20,6 +20,7 @@ from gwells.models import Profile from gwells.roles import roles_to_groups +KEYCLOAK_GOLD_REALM_URL = 'loginproxy.gov.bc.ca/auth/realms/standard' class JwtOidcAuthentication(JSONWebTokenAuthentication): """ @@ -46,10 +47,18 @@ def authenticate_credentials(self, payload): 'email': 'email', 'family_name': 'last_name' } - payload_profile_mapping = { - 'preferred_username': 'username', - 'name': 'name' - } + + if self.is_gold_shared_realm(payload): + payload_profile_mapping = { + 'preferred_username': 'username', + 'name': 'name' + } + else: + payload_profile_mapping = { + 'sub': 'silver_keycloak_id', + 'preferred_username': 'username', + 'name': 'name' + } # We map auth_time to user.last_login ; this is true depending on your point of view. It's the # last time the user logged into sso, which may not co-incide with the last time the user # logged into gwells. @@ -57,6 +66,13 @@ def authenticate_credentials(self, payload): if auth_time: auth_time = datetime.fromtimestamp(auth_time, tz=timezone.utc) + # NOTE: We assume that as part of the user migration process (yet to be provided/announced by the SSO team), + # we'll be overwriting the User.username field (in the auth_user table) with the GUID. + # The Silver Keycloak ID is preserved under Profile.silver_keycloak_id. + # If we've switched over to Gold but haven't done this, + # we'll end up with duplicate users whenever we call get_or_create(). + # (one with the GUID as the username, the other with the Keycloak ID) + # # Get or create a user with the keycloak ID. try: user, update = User.objects.get_or_create(username=username) @@ -94,6 +110,14 @@ def authenticate_credentials(self, payload): if source == 'preferred_username': value = value.upper() # Uppercase to match existing data setattr(profile, target, value) + # Manually combining IDP/username allows us to preserve the existing table structure meant for Silver + if self.is_gold_shared_realm(payload): + identity_provider = payload.get('identity_provider') + if identity_provider == 'idir': + username = payload.get('idir_username') + else: + username = payload.get('bceid_username') + setattr(profile, 'username', f'{username}@{identity_provider}'.upper()) if not profile.name and profile.username: # When the name of the user isn't available, fallback to the username profile.name = profile.username @@ -103,7 +127,10 @@ def authenticate_credentials(self, payload): # Get the roles supplied by Keycloak for this user. try: - roles = payload.get('realm_access').get('roles') + if self.is_gold_shared_realm(payload): + roles = payload.get('client_roles') + else: + roles = payload.get('realm_access').get('roles') except: raise exceptions.AuthenticationFailed('Failed to retrieve roles') @@ -112,8 +139,18 @@ def authenticate_credentials(self, payload): return user + @staticmethod + def is_gold_shared_realm(payload): + return payload.get('iss').endswith(KEYCLOAK_GOLD_REALM_URL) + @staticmethod def known_sso_authority(payload): preferred_username = payload.get('preferred_username') - return 'idir\\' in preferred_username or 'bceid\\' in preferred_username\ - or preferred_username == 'testuser' + + if payload.get('iss').endswith(KEYCLOAK_GOLD_REALM_URL): + identity_provider = payload.get('identity_provider') + return 'idir' in identity_provider or 'bceid' in identity_provider\ + or preferred_username == 'testuser' + else: + return 'idir\\' in preferred_username or 'bceid\\' in preferred_username\ + or preferred_username == 'testuser' From 69e33d17dbb9d2dbc8f022246e5e4c410792f8dc Mon Sep 17 00:00:00 2001 From: Christopher-walsh22 <106549296+Christopher-walsh22@users.noreply.github.com> Date: Tue, 15 Nov 2022 10:44:19 -0800 Subject: [PATCH 037/693] Reload documents if unable to retrieve list (#1892) If documents fail to load attempt to load files again. This will happen 4 more times if unsuccessful. --- app/frontend/src/wells/components/Documents.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/frontend/src/wells/components/Documents.vue b/app/frontend/src/wells/components/Documents.vue index ed9bf37dd4..94dfcf0f07 100644 --- a/app/frontend/src/wells/components/Documents.vue +++ b/app/frontend/src/wells/components/Documents.vue @@ -62,6 +62,7 @@ diff --git a/app/frontend/src/registry/components/people/OrganizationEdit.vue b/app/frontend/src/registry/components/people/OrganizationEdit.vue index 93c42e414b..85dad955ea 100644 --- a/app/frontend/src/registry/components/people/OrganizationEdit.vue +++ b/app/frontend/src/registry/components/people/OrganizationEdit.vue @@ -304,7 +304,7 @@ diff --git a/app/frontend/src/registry/components/people/PersonAdd.vue b/app/frontend/src/registry/components/people/PersonAdd.vue index 96e73add25..9010ee7813 100644 --- a/app/frontend/src/registry/components/people/PersonAdd.vue +++ b/app/frontend/src/registry/components/people/PersonAdd.vue @@ -379,7 +379,7 @@ export default { this.setPrivate(value) } }, - ...mapGetters([ + ...mapGetters('registriesStore', [ 'loading', 'error' ]), diff --git a/app/frontend/src/registry/components/people/PersonDetail.vue b/app/frontend/src/registry/components/people/PersonDetail.vue index f8454940d8..b376d3a7b2 100644 --- a/app/frontend/src/registry/components/people/PersonDetail.vue +++ b/app/frontend/src/registry/components/people/PersonDetail.vue @@ -536,12 +536,14 @@ export default { } return notes }, - ...mapGetters([ - 'loading', - 'user', + ...mapGetters('registriesStore', [ 'error', 'currentDriller', - 'drillers', + 'searchResponse', + 'loading', + ]), + ...mapGetters([ + 'user', 'userRoles' ]), ...mapState('documentState', [ @@ -558,9 +560,16 @@ export default { 'fileUploadSuccess', 'fileUploadFail' ]), + ...mapActions('registriesStore', [ + FETCH_DRILLER, + FETCH_DRILLER_OPTIONS + ]), ...mapMutations('documentState', [ 'setFiles' ]), + ...mapMutations('registriesStore', [ + SET_DRILLER + ]), show (key) { return ((key === 'PUMP' && this.pumpApplication) || (key === 'DRILL' && this.drillApplication)) }, @@ -573,7 +582,7 @@ export default { return null }, updateRecord () { - this.$store.dispatch(FETCH_DRILLER, this.$route.params.person_guid) + this.FETCH_DRILLER(this.$route.params.person_guid) // update changeHistory when company is updated if (this.currentDriller && this.$refs.changeHistory) { this.$refs.changeHistory.update() @@ -647,20 +656,20 @@ export default { created () { if (this.currentDriller.person_guid !== this.$route.params.person_guid) { // reset the currentDriller object if another driller was previously loaded - this.$store.commit(SET_DRILLER, {}) - if (this.drillers && this.drillers.results && this.drillers.results.length) { + this[SET_DRILLER]({}) + if (this.searchResponse && this.searchResponse.results && this.searchResponse.results.length) { // use basic info (name etc) from driller list while complete record is being fetched from API - const driller = this.drillers.results.find((item) => { + const driller = this.searchResponse.results.find((item) => { return item.person_guid === this.$route.params.person_guid }) if (driller) { - this.$store.commit(SET_DRILLER, driller) + this[SET_DRILLER](driller) } } } // always fetch up to date record from API when page loads this.updateRecord() - this.$store.dispatch(FETCH_DRILLER_OPTIONS) + this.FETCH_DRILLER_OPTIONS() } } diff --git a/app/frontend/src/registry/components/people/PersonEdit.vue b/app/frontend/src/registry/components/people/PersonEdit.vue index 40c2399ca1..ab162439ff 100644 --- a/app/frontend/src/registry/components/people/PersonEdit.vue +++ b/app/frontend/src/registry/components/people/PersonEdit.vue @@ -212,7 +212,7 @@ export default { contact_email: (this.fieldErrors.contact_email && this.fieldErrors.contact_email.length) ? false : null } }, - ...mapGetters([ + ...mapGetters('registriesStore', [ 'error', 'currentDriller' ]) diff --git a/app/frontend/src/registry/components/people/PersonNotes.vue b/app/frontend/src/registry/components/people/PersonNotes.vue index d9e4c0d775..431152735e 100644 --- a/app/frontend/src/registry/components/people/PersonNotes.vue +++ b/app/frontend/src/registry/components/people/PersonNotes.vue @@ -92,7 +92,13 @@ export default { } return [] }, - ...mapGetters(['currentDriller', 'userRoles']) + ...mapGetters([ + 'userRoles' + ]), + ...mapGetters('registriesStore', [ + 'currentDriller' + ]), + }, methods: { noteSubmit () { diff --git a/app/frontend/src/registry/components/search/RegistryMap.vue b/app/frontend/src/registry/components/search/RegistryMap.vue new file mode 100644 index 0000000000..df059a3b2f --- /dev/null +++ b/app/frontend/src/registry/components/search/RegistryMap.vue @@ -0,0 +1,313 @@ +/* + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + + + + diff --git a/app/frontend/src/registry/components/search/SearchHome.vue b/app/frontend/src/registry/components/search/SearchHome.vue index 931303bdf9..dff88d5c84 100644 --- a/app/frontend/src/registry/components/search/SearchHome.vue +++ b/app/frontend/src/registry/components/search/SearchHome.vue @@ -53,91 +53,114 @@ -
- - - - - - Well Driller - Well Pump Installer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+ + + +
+ Use the search form below to locate registered well drillers and pump installers. + The map can be used to narrow down search results by geographic area. + (The map will only show wells drillers and pump installers that have known geographic positions and are in BC.) + Registered well drillers and pump installers that do not have known geographic locations or are not in BC + can be located using the search form below. +
+ + + + + + Well Driller + Well Pump Installer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+
Download everyone in registry
-
    + @@ -146,7 +169,7 @@
    - @@ -78,6 +82,7 @@ - From 368f6be6ebd2515646344becf2bf7ad6ec6015a6 Mon Sep 17 00:00:00 2001 From: David <62899351+davidclaveau@users.noreply.github.com> Date: Thu, 2 Nov 2023 17:47:05 -0700 Subject: [PATCH 302/693] fix to doc upload, allow deletion from edit --- .../components/SubmissionForm/Documents.vue | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/app/frontend/src/submissions/components/SubmissionForm/Documents.vue b/app/frontend/src/submissions/components/SubmissionForm/Documents.vue index d736cf37e2..3c934da3cf 100644 --- a/app/frontend/src/submissions/components/SubmissionForm/Documents.vue +++ b/app/frontend/src/submissions/components/SubmissionForm/Documents.vue @@ -25,7 +25,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
    - @@ -166,7 +166,7 @@ import { mapGetters, mapState, mapMutations } from 'vuex' import { omit } from 'lodash' import inputBindingsMixin from '@/common/inputBindingsMixin.js' -// import ApiService from '@/common/services/ApiService.js' +import ApiService from '@/common/services/ApiService.js' import BackToTopLink from '@/common/components/BackToTopLink.vue' import { WELL_TAGS } from '@/common/constants.js' @@ -245,22 +245,30 @@ export default { } }, computedAttachments () { - return [...this.attachmentsData] + return JSON.stringify(this.attachmentsData); }, }, watch: { computedAttachments: { deep: true, handler: function (newAttachments, oldAttachments) { - if (newAttachments[0].file) { - newAttachments.forEach((newAttachment, index) => { + let jsonNewAttachments = JSON.parse(newAttachments), + jsonOldAttachments = JSON.parse(oldAttachments); + + // We have at least one new attachment + if (jsonNewAttachments[0].file) { + jsonNewAttachments.forEach((newAttachment, index) => { + + // Add the new attachment const newFile = newAttachment.file; if (newAttachment.file_name) { const uploadName = newAttachment.file_name.replace(/^WTN\s\d+_/,''); - const modifiedFile = new File([newFile], uploadName, { type: newFile.type }); - this.files = [modifiedFile]; - this.privateDocument = false; + const newFileAdded = new File([newFile], uploadName, { type: newFile.type }); + this.files[index] = newFileAdded; } + + // TODO: add prive doc logic + this.privateDocument = false; }); } }, @@ -281,8 +289,17 @@ export default { 'setPrivate', 'removeFile' ]), - handleFileDelete() { - alert('Delete Action!'); + handleFileDelete(value, e) { + e.preventDefault() + let tag = this.form.well && isNaN(this.form.well) ? this.form.well.well_tag_number : this.form.well + let encodedFileName = encodeURIComponent(value) + + //TODO: add private file deletion/logic + ApiService.deleteFile(`wells/${tag}/delete_document?filename=${encodedFileName}&private=false}`) + .then(() => { + console.log('File deleted') + this.$emit('fetchFiles') + }) }, setFileName(index) { try { @@ -359,7 +376,7 @@ export default { attachmentIsEmpty (attachment) { const fieldsToTest = omit(attachment, 'length_required') return Object.values(fieldsToTest).every((x) => !x) - } + }, } } From 12a185706d5250acbec5a12f5f454e31c6bda4a6 Mon Sep 17 00:00:00 2001 From: LocalNewsTV <62873746+LocalNewsTV@users.noreply.github.com> Date: Fri, 3 Nov 2023 08:49:19 -0700 Subject: [PATCH 303/693] code cleanup, change header names for clarity, fix public list bug --- app/backend/gwells/documents.py | 2 +- .../components/SubmissionForm/Documents.vue | 10 +++++----- app/frontend/src/wells/components/Documents.vue | 12 +++++------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/app/backend/gwells/documents.py b/app/backend/gwells/documents.py index f6c26de5c5..d5f68ab1f6 100644 --- a/app/backend/gwells/documents.py +++ b/app/backend/gwells/documents.py @@ -127,7 +127,7 @@ def create_url_list(self, objects, host, bucket_name, private=False): "well_number": self.extract_well_number(document.object_name), "date_of_action": self.extract_date_of_action(document.object_name), "well_label": self.extract_well_label(document.object_name), - "private": private + "document_status": private }, objects) ) return urls diff --git a/app/frontend/src/submissions/components/SubmissionForm/Documents.vue b/app/frontend/src/submissions/components/SubmissionForm/Documents.vue index 3c934da3cf..c3a6ae8ed6 100644 --- a/app/frontend/src/submissions/components/SubmissionForm/Documents.vue +++ b/app/frontend/src/submissions/components/SubmissionForm/Documents.vue @@ -27,9 +27,9 @@ Licensed under the Apache License, Version 2.0 (the "License");