diff --git a/geonode/geoserver/helpers.py b/geonode/geoserver/helpers.py index 3a4efff86c8..7c9ae977b37 100755 --- a/geonode/geoserver/helpers.py +++ b/geonode/geoserver/helpers.py @@ -66,6 +66,7 @@ from geonode.layers.models import Layer, Attribute, Style from geonode.security.views import _perms_info_json from geonode.utils import set_attributes +from geonode.security.utils import set_geowebcache_invalidate_cache import xml.etree.ElementTree as ET from django.utils.module_loading import import_string @@ -345,6 +346,7 @@ def set_layer_style(saved_layer, title, sld, base_file=None): layer.default_style = style cat.save(layer) saved_layer.default_style = save_style(style) + set_geowebcache_invalidate_cache(saved_layer.alternate) except Exception as e: logger.exception(e) else: @@ -360,6 +362,7 @@ def set_layer_style(saved_layer, title, sld, base_file=None): layer.default_style = style cat.save(layer) saved_layer.default_style = save_style(style) + set_geowebcache_invalidate_cache(saved_layer.alternate) except Exception as e: logger.exception(e) diff --git a/geonode/layers/templates/layers/layer_detail.html b/geonode/layers/templates/layers/layer_detail.html index 5bd4e9a6e74..6a43a0ad3f7 100644 --- a/geonode/layers/templates/layers/layer_detail.html +++ b/geonode/layers/templates/layers/layer_detail.html @@ -655,6 +655,16 @@

{% trans "Styles" %}

{% endif %} + {% if OGC_SERVER.default.BACKEND == 'geonode.geoserver' %} + {% if "change_resourcebase" in perms_list %} +
  • +

    {% trans "Clear the Server Cache of this layer" %}

    +

    {% trans "Click the button below to wipe the tile-cache of this layer." %}

    + {% trans "Empty Tiled-Layer Cache" %} +
  • + {% endif %} + {% endif %} + {% if GEONODE_SECURITY_ENABLED %} {% if "change_resourcebase_permissions" in perms_list %}
  • diff --git a/geonode/security/tests.py b/geonode/security/tests.py index 57ad464c612..64774215fff 100644 --- a/geonode/security/tests.py +++ b/geonode/security/tests.py @@ -299,9 +299,6 @@ def test_perms_info(self): 'change_resourcebase', layer.get_self_resource())) - # TODO Much more to do here once jj0hns0n understands the ACL system - # better - # Test with a Map object # TODO diff --git a/geonode/security/urls.py b/geonode/security/urls.py index 54ad3aa100c..757dc42825b 100644 --- a/geonode/security/urls.py +++ b/geonode/security/urls.py @@ -29,4 +29,6 @@ views.set_bulk_permissions, name='bulk_permissions'), url(r'^request-permissions/?$', views.request_permissions, name='request_permissions'), + url(r'^invalidate_tiledlayer_cache/?$', + views.invalidate_tiledlayer_cache, name='invalidate_tiledlayer_cache'), ] diff --git a/geonode/security/utils.py b/geonode/security/utils.py index 5d7b59c4be9..8eaeeea482e 100644 --- a/geonode/security/utils.py +++ b/geonode/security/utils.py @@ -283,6 +283,33 @@ def set_geofence_invalidate_cache(): logger.debug(tb) +@on_ogc_backend(geoserver.BACKEND_PACKAGE) +def set_geowebcache_invalidate_cache(layer_alternate): + """invalidate GeoWebCache Cache Rules""" + try: + url = settings.OGC_SERVER['default']['LOCATION'] + user = settings.OGC_SERVER['default']['USER'] + passwd = settings.OGC_SERVER['default']['PASSWORD'] + # Check first that the rules does not exist already + """ + curl -v -u admin:geoserver \ + -H "Content-type: text/xml" \ + -d "{layer_alternate}" \ + http://localhost:8080/geoserver/gwc/rest/masstruncate + """ + headers = {'Content-type': 'text/xml'} + payload = "%s" % layer_alternate + r = requests.post(url + 'gwc/rest/masstruncate', + headers=headers, + data=payload, + auth=HTTPBasicAuth(user, passwd)) + if (r.status_code < 200 or r.status_code > 201): + logger.warning("Could not Truncate GWC Cache for Layer '%s'." % layer_alternate) + except Exception: + tb = traceback.format_exc() + logger.debug(tb) + + @on_ogc_backend(geoserver.BACKEND_PACKAGE) def set_geofence_all(instance): """assign access permissions to all users diff --git a/geonode/security/views.py b/geonode/security/views.py index ad927523c79..2ca1cd06c2f 100644 --- a/geonode/security/views.py +++ b/geonode/security/views.py @@ -113,8 +113,31 @@ def resource_permissions(request, resource_id): @require_POST -def set_bulk_permissions(request): +def invalidate_tiledlayer_cache(request): + from .utils import set_geowebcache_invalidate_cache + uuid = request.POST['uuid'] + resource = get_object_or_404(ResourceBase, uuid=uuid) + can_change_data = request.user.has_perm( + 'change_resourcebase', + resource) + layer = Layer.objects.get(id=resource.id) + if layer and can_change_data: + set_geowebcache_invalidate_cache(layer.alternate) + return HttpResponse( + json.dumps({'success': 'ok', 'message': 'GeoWebCache Tiled Layer Emptied!'}), + status=200, + content_type='text/plain' + ) + else: + return HttpResponse( + json.dumps({'success': 'false', 'message': 'You cannot modify this resource!'}), + status=200, + content_type='text/plain' + ) + +@require_POST +def set_bulk_permissions(request): permission_spec = json.loads(request.POST.get('permissions', None)) resource_ids = request.POST.getlist('resources', []) if permission_spec is not None: diff --git a/geonode/templates/_permissions_form_js.html b/geonode/templates/_permissions_form_js.html index 5028853c491..2c06012124a 100644 --- a/geonode/templates/_permissions_form_js.html +++ b/geonode/templates/_permissions_form_js.html @@ -74,7 +74,6 @@ }; $(function() { - $('#permissions-body').ready(function(){ {% if resource %} $.ajax( @@ -294,7 +293,6 @@ return group.name; } - var perms_submit = function() { var form = $(this); var action = form.attr("action"); @@ -339,9 +337,46 @@ }); {% if resource %} - $("#permission_form").submit(perms_submit); + $("#permission_form").submit(perms_submit); {% endif %} + + $("#tiledlayer_refresh").click(function(){ + $.ajax( + { + type: "POST", + url: "{% url 'invalidate_tiledlayer_cache' %}", + dataType: 'json', + data: { uuid: "{{ resource.uuid }}" }, + success: function(data) { + $("#modal_perms").modal("hide"); + message = data; + title = ""; + body = message.message; + if (message.success) { + title = "OK"; + } else { + title = "Warning"; + } + $("#_permissions_feedbacks").find('.modal-title').text(title); + $("#_permissions_feedbacks").find('.modal-body').text(body); + $("#_permissions_feedbacks").modal("show"); + }, + cache: false + } + ).fail(function (jqXHR, textStatus, error) { + // Handle error here + $("#modal_perms").modal("hide"); + message = JSON.parse(jqXHR.responseText); + body = message.message; + title = "Error"; + $("#_permissions_feedbacks").find('.modal-title').text(title); + $("#_permissions_feedbacks").find('.modal-body').text(body); + $("#_permissions_feedbacks").modal("show"); + }); + return false; + }); + $("#_bulk_permissions").on('hidden.bs.modal', function (e) { $('#bulk_perms_message').addClass("hidden"); }); diff --git a/geonode/tests/integration.py b/geonode/tests/integration.py index 1cf76d261d1..2c3debe7727 100644 --- a/geonode/tests/integration.py +++ b/geonode/tests/integration.py @@ -165,6 +165,24 @@ def test_layer_upload(self): user=norman, overwrite=True, ) + + # Test that layer owner can wipe GWC Cache + if check_ogc_backend(geoserver.BACKEND_PACKAGE): + from geonode.security.utils import set_geowebcache_invalidate_cache + set_geowebcache_invalidate_cache(saved_layer.alternate) + + url = settings.OGC_SERVER['default']['LOCATION'] + user = settings.OGC_SERVER['default']['USER'] + passwd = settings.OGC_SERVER['default']['PASSWORD'] + + import requests + from requests.auth import HTTPBasicAuth + r = requests.get(url + 'gwc/rest/seed/%s.json' % saved_layer.alternate, + auth=HTTPBasicAuth(user, passwd)) + self.assertEquals(r.status_code, 200) + o = json.loads(r.text) + self.assertTrue('long-array-array' in o) + self.assertTrue(len(o['long-array-array']) > 0) try: saved_layer.set_default_permissions() url = reverse('layer_metadata', args=[saved_layer.service_typename])