diff --git a/docs/reference/developers/settings.txt b/docs/reference/developers/settings.txt
index bdb87addf58..cb75353f4be 100644
--- a/docs/reference/developers/settings.txt
+++ b/docs/reference/developers/settings.txt
@@ -155,9 +155,9 @@ Specific settings for map API providers (if they are not set those base maps wil
* BING_API_KEY set this variable to your BING Map Key value
-LAYER_PREVIEW_LIBRARY
----------------------
-Default: ``"leaflet"``
+GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY
+------------------------------------
+Default: ``"geoext"``
The library to use for display preview images of layers. The library choices are:
diff --git a/docs/tutorials/advanced/geonode_settings/settings.txt b/docs/tutorials/advanced/geonode_settings/settings.txt
index 66f46d7ddff..ba7be0c6914 100644
--- a/docs/tutorials/advanced/geonode_settings/settings.txt
+++ b/docs/tutorials/advanced/geonode_settings/settings.txt
@@ -151,9 +151,9 @@ Default::
A list of dictionaries that specify the default map layers.
-LAYER_PREVIEW_LIBRARY
----------------------
-Default: ``"leaflet"``
+GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY
+------------------------------------
+Default: ``"geoext"``
The library to use for display preview images of layers. The library choices are:
diff --git a/docs/tutorials/install_and_admin/setup_on_centos/install_geonode.txt b/docs/tutorials/install_and_admin/setup_on_centos/install_geonode.txt
index f2ae2debb08..57bdbb272de 100644
--- a/docs/tutorials/install_and_admin/setup_on_centos/install_geonode.txt
+++ b/docs/tutorials/install_and_admin/setup_on_centos/install_geonode.txt
@@ -232,7 +232,7 @@ The resulting configuration file should look like this:::
}
# Default preview library
- #LAYER_PREVIEW_LIBRARY = 'geoext'
+ # GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY = 'geoext'
.. _geonode_install_initialization:
diff --git a/geonode/api/api.py b/geonode/api/api.py
index 0a693ad7a61..c87070560bc 100644
--- a/geonode/api/api.py
+++ b/geonode/api/api.py
@@ -47,12 +47,10 @@
from geonode.base.models import Region
from geonode.base.models import HierarchicalKeyword
from geonode.base.models import ThesaurusKeywordLabel
-
from geonode.layers.models import Layer, Style
from geonode.maps.models import Map
from geonode.documents.models import Document
from geonode.groups.models import GroupProfile, GroupCategory
-from django.contrib.auth.models import Group
from django.core.serializers.json import DjangoJSONEncoder
from tastypie.serializers import Serializer
from tastypie import fields
@@ -61,6 +59,7 @@
from tastypie.utils import trailing_slash
from geonode.utils import check_ogc_backend
+from geonode.security.utils import get_visible_resources
FILTER_TYPES = {
'layer': Layer,
@@ -80,8 +79,13 @@ def get_resources_counts(self, options):
options['user'],
'base.view_resourcebase'
)
- if settings.RESOURCE_PUBLISHING:
- resources = resources.filter(Q(is_published=True) | Q(owner__username__iexact=str(options['user'])))
+
+ resources = get_visible_resources(
+ resources,
+ options['user'],
+ admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
+ unpublished_not_visible=settings.RESOURCE_PUBLISHING,
+ private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES)
if options['title_filter']:
resources = resources.filter(title__icontains=options['title_filter'])
@@ -248,95 +252,12 @@ def dehydrate_layers_count(self, bundle):
filter_set = bundle.obj.resourcebase_set.filter(id__in=obj_with_perms.values('id'))
if not settings.SKIP_PERMS_FILTER:
- is_admin = False
- is_manager = False
- if request.user:
- is_admin = request.user.is_superuser if request.user else False
- try:
- is_manager = request.user.groupmember_set.all().filter(role='manager').exists()
- except:
- is_manager = False
-
- # Get the list of objects the user has access to
- anonymous_group = None
- public_groups = GroupProfile.objects.exclude(access="private").values('group')
- groups = []
- group_list_all = []
- manager_groups = []
- try:
- group_list_all = request.user.group_list_all().values('group')
- except:
- pass
- try:
- manager_groups = Group.objects.filter(
- name__in=request.user.groupmember_set.filter(role="manager").values_list("group__slug", flat=True))
- except:
- pass
- try:
- anonymous_group = Group.objects.get(name='anonymous')
- if anonymous_group and anonymous_group not in groups:
- groups.append(anonymous_group)
- except:
- pass
-
- if settings.ADMIN_MODERATE_UPLOADS:
- if not is_admin:
- if is_manager:
- filter_set = filter_set.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- filter_set = filter_set.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- filter_set = filter_set.filter(Q(is_published=True))
-
- if settings.RESOURCE_PUBLISHING:
- if not is_admin:
- if is_manager:
- filter_set = filter_set.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(group__in=public_groups) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- filter_set = filter_set.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- filter_set = filter_set.filter(Q(is_published=True))
-
- if settings.GROUP_PRIVATE_RESOURCES:
- if is_admin:
- filter_set = filter_set
- elif request.user:
- filter_set = filter_set.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=public_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- if anonymous_group:
- filter_set = filter_set.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups) |
- Q(group=anonymous_group))
- else:
- filter_set = filter_set.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups))
+ filter_set = get_visible_resources(
+ filter_set,
+ request.user if request else None,
+ admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
+ unpublished_not_visible=settings.RESOURCE_PUBLISHING,
+ private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES)
return filter_set.distinct().count()
diff --git a/geonode/api/resourcebase_api.py b/geonode/api/resourcebase_api.py
index d28cf3facf9..77faf3e6dbd 100644
--- a/geonode/api/resourcebase_api.py
+++ b/geonode/api/resourcebase_api.py
@@ -41,7 +41,6 @@
from django.core.paginator import Paginator, InvalidPage
from django.http import Http404
from django.core.exceptions import ObjectDoesNotExist
-from django.contrib.auth.models import Group
from django.forms.models import model_to_dict
from tastypie.utils.mime import build_content_type
@@ -55,6 +54,7 @@
from geonode.people.models import Profile
from geonode.groups.models import GroupProfile
from geonode.utils import check_ogc_backend
+from geonode.security.utils import get_visible_resources
from .authorization import GeoNodeAuthorization, GeonodeApiKeyAuthentication
@@ -203,123 +203,21 @@ def apply_filters(self, request, applicable_filters):
return filtered
def filter_published(self, queryset, request):
- is_admin = False
- is_manager = False
- if request.user:
- is_admin = request.user.is_superuser if request.user else False
- try:
- is_manager = request.user.groupmember_set.all().filter(role='manager').exists()
- except:
- is_manager = False
-
- # Get the list of objects the user has access to
- anonymous_group = None
- public_groups = GroupProfile.objects.exclude(access="private").values('group')
- groups = []
- group_list_all = []
- manager_groups = []
- try:
- group_list_all = request.user.group_list_all().values('group')
- except:
- pass
- try:
- manager_groups = Group.objects.filter(
- name__in=request.user.groupmember_set.filter(role="manager").values_list("group__slug", flat=True))
- except:
- pass
- try:
- anonymous_group = Group.objects.get(name='anonymous')
- if anonymous_group and anonymous_group not in groups:
- groups.append(anonymous_group)
- except:
- pass
-
- filtered = queryset
- if settings.ADMIN_MODERATE_UPLOADS:
- if not is_admin:
- if is_manager:
- filtered = filtered.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- filtered = filtered.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- filtered = filtered.filter(Q(is_published=True))
-
- if settings.RESOURCE_PUBLISHING:
- if not is_admin:
- if is_manager:
- filtered = filtered.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(group__in=public_groups) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- filtered = filtered.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- filtered = filtered.filter(Q(is_published=True))
+ filter_set = get_visible_resources(
+ queryset,
+ request.user if request else None,
+ admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
+ unpublished_not_visible=settings.RESOURCE_PUBLISHING)
- return filtered
+ return filter_set
def filter_group(self, queryset, request):
- is_admin = False
- if request.user:
- is_admin = request.user.is_superuser if request.user else False
+ filter_set = get_visible_resources(
+ queryset,
+ request.user if request else None,
+ private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES)
- try:
- anonymous_group = Group.objects.get(name='anonymous')
- except BaseException:
- anonymous_group = None
-
- public_groups = GroupProfile.objects.exclude(access="private").values('group')
- if is_admin:
- filtered = queryset
- elif request.user:
- groups = request.user.groups.all()
- group_list_all = []
- try:
- group_list_all = request.user.group_list_all().values('group')
- except:
- pass
- if anonymous_group:
- filtered = queryset.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(group__in=public_groups) |
- Q(group=anonymous_group) |
- Q(owner__username__iexact=str(request.user)))
- else:
- filtered = queryset.filter(
- Q(group__isnull=True) |
- Q(group__in=group_list_all) |
- Q(group__in=public_groups) |
- Q(group__in=groups) |
- Q(owner__username__iexact=str(request.user)))
- else:
- if anonymous_group:
- filtered = queryset.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups) |
- Q(group=anonymous_group))
- else:
- filtered = queryset.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups))
- return filtered
+ return filter_set
def filter_h_keywords(self, queryset, keywords):
filtered = queryset
@@ -540,98 +438,16 @@ def get_search(self, request, **kwargs):
sqs = self.build_haystack_filters(request.GET)
if not settings.SKIP_PERMS_FILTER:
- is_admin = False
- is_manager = False
- if request.user:
- is_admin = request.user.is_superuser if request.user else False
- try:
- is_manager = request.user.groupmember_set.all().filter(role='manager').exists()
- except:
- is_manager = False
filter_set = get_objects_for_user(
request.user, 'base.view_resourcebase')
- # Get the list of objects the user has access to
- anonymous_group = None
- public_groups = GroupProfile.objects.exclude(access="private").values('group')
- groups = []
- group_list_all = []
- manager_groups = []
- try:
- group_list_all = request.user.group_list_all().values('group')
- except:
- pass
- try:
- manager_groups = Group.objects.filter(
- name__in=request.user.groupmember_set.filter(role="manager").values_list("group__slug", flat=True))
- except:
- pass
- try:
- anonymous_group = Group.objects.get(name='anonymous')
- if anonymous_group and anonymous_group not in groups:
- groups.append(anonymous_group)
- except:
- pass
-
- if settings.ADMIN_MODERATE_UPLOADS:
- if not is_admin:
- if is_manager:
- filter_set = filter_set.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- filter_set = filter_set.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- filter_set = filter_set.filter(Q(is_published=True))
-
- if settings.RESOURCE_PUBLISHING:
- if not is_admin:
- if is_manager:
- filter_set = filter_set.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(group__in=public_groups) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- filter_set = filter_set.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- filter_set = filter_set.filter(Q(is_published=True))
-
- if settings.GROUP_PRIVATE_RESOURCES:
- if is_admin:
- filter_set = filter_set
- elif request.user:
- filter_set = filter_set.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=public_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- if anonymous_group:
- filter_set = filter_set.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups) |
- Q(group=anonymous_group))
- else:
- filter_set = filter_set.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups))
+ filter_set = get_visible_resources(
+ filter_set,
+ request.user if request else None,
+ admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
+ unpublished_not_visible=settings.RESOURCE_PUBLISHING,
+ private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES)
filter_set_ids = filter_set.values_list('id')
# Do the query using the filterset and the query term. Facet the
diff --git a/geonode/base/autocomplete_light_registry.py b/geonode/base/autocomplete_light_registry.py
index 95ae0318ce7..4e29ca11257 100644
--- a/geonode/base/autocomplete_light_registry.py
+++ b/geonode/base/autocomplete_light_registry.py
@@ -24,8 +24,7 @@
from guardian.shortcuts import get_objects_for_user
from django.conf import settings
from django.db.models import Q
-from django.contrib.auth.models import Group
-from geonode.groups.models import GroupProfile
+from geonode.security.utils import get_visible_resources
from models import ResourceBase, Region, HierarchicalKeyword, ThesaurusKeywordLabel
@@ -41,92 +40,12 @@ def choices_for_request(self):
'base.view_resourcebase')
self.choices = self.choices.filter(id__in=permitted)
- is_admin = False
- is_manager = False
- if request.user:
- is_admin = request.user.is_superuser if request.user else False
- try:
- is_manager = request.user.groupmember_set.all().filter(role='manager').exists()
- except:
- is_manager = False
-
- # Get the list of objects the user has access to
- anonymous_group = None
- public_groups = GroupProfile.objects.exclude(access="private").values('group')
- groups = []
- group_list_all = []
- manager_groups = []
- try:
- group_list_all = request.user.group_list_all().values('group')
- except:
- pass
- try:
- manager_groups = Group.objects.filter(
- name__in=request.user.groupmember_set.filter(role="manager").values_list("group__slug", flat=True))
- except:
- pass
- try:
- anonymous_group = Group.objects.get(name='anonymous')
- if anonymous_group and anonymous_group not in groups:
- groups.append(anonymous_group)
- except:
- pass
-
- if settings.ADMIN_MODERATE_UPLOADS:
- if not is_admin:
- if is_manager:
- self.choices = self.choices.filter(
- Q(is_published=True) |
- Q(group__in=manager_groups) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- self.choices = self.choices.filter(
- Q(is_published=True) |
- Q(owner__username__iexact=str(request.user)))
- else:
- self.choices = self.choices.filter(Q(is_published=True))
-
- if settings.RESOURCE_PUBLISHING:
- if not is_admin:
- if is_manager:
- self.choices = self.choices.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(group__in=public_groups) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- self.choices = self.choices.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- self.choices = self.choices.filter(Q(is_published=True))
-
- if settings.GROUP_PRIVATE_RESOURCES:
- public_groups = GroupProfile.objects.exclude(access="private").values('group')
- if is_admin:
- self.choices = self.choices
- elif request.user:
- self.choices = self.choices.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=public_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- if anonymous_group:
- self.choices = self.choices.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups) |
- Q(group=anonymous_group))
- else:
- self.choices = self.choices.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups))
+ self.choices = get_visible_resources(
+ self.choices,
+ request.user if request else None,
+ admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
+ unpublished_not_visible=settings.RESOURCE_PUBLISHING,
+ private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES)
return super(ResourceBaseAutocomplete, self).choices_for_request()
diff --git a/geonode/base/management/commands/fixgeofencerules.py b/geonode/base/management/commands/fixgeofencerules.py
index 3b5e838ebc6..96f67a4aa60 100644
--- a/geonode/base/management/commands/fixgeofencerules.py
+++ b/geonode/base/management/commands/fixgeofencerules.py
@@ -24,7 +24,7 @@
from geonode.people.models import Profile
from geonode.layers.models import Layer
-from geonode.security import models
+from geonode.security import utils
class Command(BaseCommand):
@@ -42,7 +42,7 @@ def handle(self, *args, **options):
for index, layer in enumerate(layers):
print "[%s / %s] Setting default permissions to Layer [%s] ..." % ((index + 1), len(layers), layer.name)
try:
- models.set_geofence_all(layer)
+ utils.set_geofence_all(layer)
except:
print "[ERROR] Layer [%s] couldn't be updated" % (layer.name)
@@ -52,13 +52,13 @@ def handle(self, *args, **options):
print "[%s / %s] Setting owner permissions to Layer [%s] ..." \
% ((index + 1), len(protected_layers), layer.name)
try:
- perms = models.get_users_with_perms(layer)
+ perms = utils.get_users_with_perms(layer)
for profile in perms.keys():
print " - [%s / %s]" % (str(profile), layer.name)
geofence_user = str(profile)
if "AnonymousUser" in geofence_user:
geofence_user = None
- models.set_geofence_owner(
+ utils.set_geofence_owner(
layer, geofence_user,
view_perms=True,
download_perms=True
diff --git a/geonode/base/management/commands/set_all_layers_public.py b/geonode/base/management/commands/set_all_layers_public.py
index ba8a8eadb4c..b089d3a45b4 100644
--- a/geonode/base/management/commands/set_all_layers_public.py
+++ b/geonode/base/management/commands/set_all_layers_public.py
@@ -21,7 +21,7 @@
from django.conf import settings
from django.core.management.base import BaseCommand
from geonode.layers.models import Layer
-from geonode.security.models import set_geofence_all
+from geonode.security.utils import set_geofence_all
class Command(BaseCommand):
diff --git a/geonode/base/templatetags/base_tags.py b/geonode/base/templatetags/base_tags.py
index 2f3147dceab..4e0c373cbb2 100644
--- a/geonode/base/templatetags/base_tags.py
+++ b/geonode/base/templatetags/base_tags.py
@@ -24,7 +24,6 @@
from django.db.models import Q
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import get_user_model
-from django.contrib.auth.models import Group
from django.db.models import Count
from django.conf import settings
@@ -35,6 +34,7 @@
from geonode.documents.models import Document
from geonode.groups.models import GroupProfile
from geonode.base.models import HierarchicalKeyword
+from geonode.security.utils import get_visible_resources
register = template.Library()
@@ -56,15 +56,6 @@ def num_ratings(obj):
@register.assignment_tag(takes_context=True)
def facets(context):
request = context['request']
- is_admin = False
- is_manager = False
- if request.user:
- is_admin = request.user.is_superuser if request.user else False
- try:
- is_manager = request.user.groupmember_set.all().filter(role='manager').exists()
- except:
- is_manager = False
-
title_filter = request.GET.get('title__icontains', '')
extent_filter = request.GET.get('extent', None)
keywords_filter = request.GET.getlist('keywords__slug__in', None)
@@ -101,86 +92,12 @@ def facets(context):
if date_range_filter:
documents = documents.filter(date__range=date_range_filter.split(','))
- # Get the list of objects the user has access to
- anonymous_group = None
- public_groups = GroupProfile.objects.exclude(access="private").values('group')
- groups = []
- group_list_all = []
- manager_groups = []
- try:
- group_list_all = request.user.group_list_all().values('group')
- except:
- pass
- try:
- manager_groups = Group.objects.filter(
- name__in=request.user.groupmember_set.filter(role="manager").values_list("group__slug", flat=True))
- except:
- pass
- try:
- anonymous_group = Group.objects.get(name='anonymous')
- if anonymous_group and anonymous_group not in groups:
- groups.append(anonymous_group)
- except:
- pass
-
- if settings.ADMIN_MODERATE_UPLOADS:
- if not is_admin:
- if is_manager:
- documents = documents.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- documents = documents.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- documents = documents.filter(Q(is_published=True))
-
- if settings.RESOURCE_PUBLISHING:
- if not is_admin:
- if is_manager:
- documents = documents.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(group__in=public_groups) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- documents = documents.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- documents = documents.filter(Q(is_published=True))
-
- if settings.GROUP_PRIVATE_RESOURCES:
- if is_admin:
- pass
- elif request.user:
- documents = documents.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=public_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- if anonymous_group:
- documents = documents.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups) |
- Q(group=anonymous_group))
- else:
- documents = documents.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups))
+ documents = get_visible_resources(
+ documents,
+ request.user if request else None,
+ admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
+ unpublished_not_visible=settings.RESOURCE_PUBLISHING,
+ private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES)
if keywords_filter:
treeqs = HierarchicalKeyword.objects.none()
@@ -223,86 +140,12 @@ def facets(context):
if date_range_filter:
layers = layers.filter(date__range=date_range_filter.split(','))
- # Get the list of objects the user has access to
- anonymous_group = None
- public_groups = GroupProfile.objects.exclude(access="private").values('group')
- groups = []
- group_list_all = []
- manager_groups = []
- try:
- group_list_all = request.user.group_list_all().values('group')
- except:
- pass
- try:
- manager_groups = Group.objects.filter(
- name__in=request.user.groupmember_set.filter(role="manager").values_list("group__slug", flat=True))
- except:
- pass
- try:
- anonymous_group = Group.objects.get(name='anonymous')
- if anonymous_group and anonymous_group not in groups:
- groups.append(anonymous_group)
- except:
- pass
-
- if settings.ADMIN_MODERATE_UPLOADS:
- if not is_admin:
- if is_manager:
- layers = layers.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- layers = layers.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- layers = layers.filter(Q(is_published=True))
-
- if settings.RESOURCE_PUBLISHING:
- if not is_admin:
- if is_manager:
- layers = layers.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(group__in=public_groups) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- layers = layers.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- layers = layers.filter(Q(is_published=True))
-
- if settings.GROUP_PRIVATE_RESOURCES:
- if is_admin:
- pass
- elif request.user:
- layers = layers.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=public_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- if anonymous_group:
- layers = layers.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups) |
- Q(group=anonymous_group))
- else:
- layers = layers.filter(
- Q(group__isnull=True) |
- Q(group__in=public_groups))
+ layers = get_visible_resources(
+ layers,
+ request.user if request else None,
+ admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
+ unpublished_not_visible=settings.RESOURCE_PUBLISHING,
+ private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES)
if extent_filter:
bbox = extent_filter.split(
@@ -375,119 +218,18 @@ def facets(context):
maps = maps.filter(date__range=date_range_filter.split(','))
documents = documents.filter(date__range=date_range_filter.split(','))
- # Get the list of objects the user has access to
- anonymous_group = None
- public_groups = GroupProfile.objects.exclude(access="private").values('group')
- groups = []
- group_list_all = []
- manager_groups = []
- try:
- group_list_all = request.user.group_list_all().values('group')
- except:
- pass
- try:
- manager_groups = Group.objects.filter(
- name__in=request.user.groupmember_set.filter(role="manager").values_list("group__slug", flat=True))
- except:
- pass
- try:
- anonymous_group = Group.objects.get(name='anonymous')
- if anonymous_group and anonymous_group not in groups:
- groups.append(anonymous_group)
- except:
- pass
-
- if settings.ADMIN_MODERATE_UPLOADS:
- if not is_admin:
- if is_manager:
- maps = maps.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- documents = documents.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- maps = maps.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- documents = documents.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- maps = maps.filter(Q(is_published=True))
- documents = documents.filter(Q(is_published=True))
-
- if settings.RESOURCE_PUBLISHING:
- if not is_admin:
- if is_manager:
- maps = maps.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(group__in=public_groups) |
- Q(owner__username__iexact=str(request.user)))
- documents = documents.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=group_list_all) |
- Q(group__in=public_groups) |
- Q(owner__username__iexact=str(request.user)))
- elif request.user:
- maps = maps.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- documents = documents.filter(
- Q(is_published=True) |
- Q(group__in=groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- maps = maps.filter(Q(is_published=True))
- documents = documents.filter(Q(is_published=True))
-
- if settings.GROUP_PRIVATE_RESOURCES:
- if is_admin:
- pass
- elif request.user:
- maps = maps.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=public_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- documents = documents.filter(
- Q(group__isnull=True) |
- Q(group__in=groups) |
- Q(group__in=manager_groups) |
- Q(group__in=public_groups) |
- Q(group__in=group_list_all) |
- Q(owner__username__iexact=str(request.user)))
- else:
- if anonymous_group:
- maps = maps.filter(
- Q(group__isnull=True) |
- Q(group=anonymous_group))
- documents = documents.filter(
- Q(group__isnull=True) |
- Q(group=anonymous_group))
- else:
- maps = maps.filter(Q(group__isnull=True))
- documents = documents.filter(Q(group__isnull=True))
+ maps = get_visible_resources(
+ maps,
+ request.user if request else None,
+ admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
+ unpublished_not_visible=settings.RESOURCE_PUBLISHING,
+ private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES)
+ documents = get_visible_resources(
+ documents,
+ request.user if request else None,
+ admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
+ unpublished_not_visible=settings.RESOURCE_PUBLISHING,
+ private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES)
if extent_filter:
bbox = extent_filter.split(
diff --git a/geonode/client/__init__.py b/geonode/client/__init__.py
new file mode 100644
index 00000000000..a0f3a990243
--- /dev/null
+++ b/geonode/client/__init__.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+#
+# Copyright (C) 2018 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 .
+#
+#########################################################################
+from pkgutil import extend_path
+
+
+default_app_config = "geonode.client.apps.AppConfig"
+__path__ = extend_path(__path__, __name__) # noqa
diff --git a/geonode/client/apps.py b/geonode/client/apps.py
new file mode 100644
index 00000000000..6615a4099b4
--- /dev/null
+++ b/geonode/client/apps.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+#
+# Copyright (C) 2018 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 .
+#
+#########################################################################
+from django.apps import AppConfig as BaseAppConfig
+from django.utils.translation import ugettext_lazy as _
+
+
+class AppConfig(BaseAppConfig):
+
+ name = "geonode.client"
+ label = "geonode_client"
+ verbose_name = _("GeoNode Client Library")
diff --git a/geonode/client/conf.py b/geonode/client/conf.py
new file mode 100644
index 00000000000..1d19edef180
--- /dev/null
+++ b/geonode/client/conf.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+#
+# Copyright (C) 2018 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 importlib
+
+from django.conf import settings # noqa
+from django.core.exceptions import ImproperlyConfigured
+
+from appconf import AppConf
+
+
+def load_path_attr(path):
+ i = path.rfind(".")
+ module, attr = path[:i], path[i + 1:]
+ try:
+ mod = importlib.import_module(module)
+ except ImportError as e:
+ raise ImproperlyConfigured("Error importing {0}: '{1}'".format(module, e))
+ try:
+ attr = getattr(mod, attr)
+ except AttributeError:
+ raise ImproperlyConfigured("Module '{0}' does not define a '{1}'".format(module, attr))
+ return attr
+
+
+def is_installed(package):
+ try:
+ __import__(package)
+ return True
+ except ImportError:
+ return False
+
+
+class GeoNodeClientAppConf(AppConf):
+
+ LAYER_PREVIEW_LIBRARY = 'geoext'
+ HOOKSET = "geonode.client.hooksets.GeoExtHookSet"
+
+ def configure_hookset(self, value):
+ return load_path_attr(value)()
+
+ class Meta:
+ prefix = "geonode_client"
diff --git a/geonode/client/hooks.py b/geonode/client/hooks.py
new file mode 100644
index 00000000000..e042f0a606f
--- /dev/null
+++ b/geonode/client/hooks.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+#
+# Copyright (C) 2018 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 .
+#
+#########################################################################
+from .conf import settings
+
+
+class HookProxy(object):
+
+ def __getattr__(self, attr):
+ return getattr(settings.GEONODE_CLIENT_HOOKSET, attr)
+
+
+hookset = HookProxy()
diff --git a/geonode/client/hooksets.py b/geonode/client/hooksets.py
new file mode 100644
index 00000000000..22abd2fc773
--- /dev/null
+++ b/geonode/client/hooksets.py
@@ -0,0 +1,160 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+#
+# Copyright (C) 2018 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 .
+#
+#########################################################################
+
+
+class GeoExtHookSet(object):
+
+ # Layers
+ def layer_detail_template(self, context=None):
+ return 'geoext/layers/layer_geoext_map.html'
+
+ def layer_new_template(self, context=None):
+ return 'geoext/layers/layer_geoext_map.html'
+
+ def layer_view_template(self, context=None):
+ return 'geoext/layers/layer_geoext_map.html'
+
+ def layer_edit_template(self, context=None):
+ return 'geoext/layers/layer_geoext_map.html'
+
+ def layer_update_template(self, context=None):
+ return 'geoext/layers/layer_geoext_map.html'
+
+ def layer_embed_template(self, context=None):
+ return 'geoext/layers/layer_geoext_map.html'
+
+ def layer_download_template(self, context=None):
+ return 'geoext/layers/layer_geoext_map.html'
+
+ # Maps
+ def map_detail_template(self, context=None):
+ return 'geoext/maps/map_include.html'
+
+ def map_new_template(self, context=None):
+ return 'geoext/maps/map_geoexplorer.js'
+
+ def map_view_template(self, context=None):
+ return 'geoext/maps/map_geoexplorer.js'
+
+ def map_edit_template(self, context=None):
+ return 'geoext/maps/map_geoexplorer.js'
+
+ def map_update_template(self, context=None):
+ return 'geoext/maps/map_geoexplorer.js'
+
+ def map_embed_template(self, context=None):
+ return 'geoext/maps/map_geoexplorer.js'
+
+ def map_download_template(self, context=None):
+ return 'geoext/maps/map_geoexplorer.js'
+
+
+class LeafletHookSet(object):
+
+ # Layers
+ def layer_detail_template(self, context=None):
+ return 'leaflet/layers/layer_leaflet_map.html'
+
+ def layer_new_template(self, context=None):
+ return 'leaflet/layers/layer_leaflet_map.html'
+
+ def layer_view_template(self, context=None):
+ return 'leaflet/layers/layer_leaflet_map.html'
+
+ def layer_edit_template(self, context=None):
+ return 'leaflet/layers/layer_leaflet_map.html'
+
+ def layer_update_template(self, context=None):
+ return 'leaflet/layers/layer_leaflet_map.html'
+
+ def layer_embed_template(self, context=None):
+ return 'leaflet/layers/layer_leaflet_map.html'
+
+ def layer_download_template(self, context=None):
+ return 'leaflet/layers/layer_leaflet_map.html'
+
+ # Maps
+ def map_detail_template(self, context=None):
+ return 'leaflet/maps/map_view.html'
+
+ def map_new_template(self, context=None):
+ return 'leaflet/maps/map_view.html'
+
+ def map_view_template(self, context=None):
+ return 'leaflet/maps/map_view.html'
+
+ def map_edit_template(self, context=None):
+ return 'leaflet/maps/map_edit.html'
+
+ def map_update_template(self, context=None):
+ return 'leaflet/maps/map_edit.html'
+
+ def map_embed_template(self, context=None):
+ return 'leaflet/maps/map_detail.html'
+
+ def map_download_template(self, context=None):
+ return 'leaflet/maps/map_embed.html'
+
+
+class ReactHookSet(object):
+
+ # Layers
+ def layer_detail_template(self, context=None):
+ return 'geonode-client/layer_map.html'
+
+ def layer_new_template(self, context=None):
+ return 'geonode-client/layer_map.html'
+
+ def layer_view_template(self, context=None):
+ return 'geonode-client/layer_map.html'
+
+ def layer_edit_template(self, context=None):
+ return 'geonode-client/layer_map.html'
+
+ def layer_update_template(self, context=None):
+ return 'geonode-client/layer_map.html'
+
+ def layer_embed_template(self, context=None):
+ return 'geonode-client/layer_map.html'
+
+ def layer_download_template(self, context=None):
+ return 'geonode-client/layer_map.html'
+
+ # Maps
+ def map_detail_template(self, context=None):
+ return 'geonode-client/map_detail.html'
+
+ def map_new_template(self, context=None):
+ return 'geonode-client/map_new.html'
+
+ def map_view_template(self, context=None):
+ return 'geonode-client/map_view.html'
+
+ def map_edit_template(self, context=None):
+ return 'geonode-client/edit_map.html'
+
+ def map_update_template(self, context=None):
+ return 'geonode-client/edit_map.html'
+
+ def map_embed_template(self, context=None):
+ return 'geonode-client/map_view.html'
+
+ def map_download_template(self, context=None):
+ return 'geonode-client/map_view.html'
diff --git a/geonode/templates/geonode/app_header.html b/geonode/client/templates/geoext/app_header.html
similarity index 100%
rename from geonode/templates/geonode/app_header.html
rename to geonode/client/templates/geoext/app_header.html
diff --git a/geonode/templates/geonode/ext_header.html b/geonode/client/templates/geoext/ext_header.html
similarity index 100%
rename from geonode/templates/geonode/ext_header.html
rename to geonode/client/templates/geoext/ext_header.html
diff --git a/geonode/templates/geonode/geo_header.html b/geonode/client/templates/geoext/geo_header.html
similarity index 100%
rename from geonode/templates/geonode/geo_header.html
rename to geonode/client/templates/geoext/geo_header.html
diff --git a/geonode/templates/geonode/geo_header_debug.html b/geonode/client/templates/geoext/geo_header_debug.html
similarity index 100%
rename from geonode/templates/geonode/geo_header_debug.html
rename to geonode/client/templates/geoext/geo_header_debug.html
diff --git a/geonode/templates/geonode/geo_header_mini.html b/geonode/client/templates/geoext/geo_header_mini.html
similarity index 100%
rename from geonode/templates/geonode/geo_header_mini.html
rename to geonode/client/templates/geoext/geo_header_mini.html
diff --git a/geonode/layers/templates/layers/layer_geoext_map.html b/geonode/client/templates/geoext/layers/layer_geoext_map.html
similarity index 98%
rename from geonode/layers/templates/layers/layer_geoext_map.html
rename to geonode/client/templates/geoext/layers/layer_geoext_map.html
index 9c24bc93ac7..44680a9ca5a 100644
--- a/geonode/layers/templates/layers/layer_geoext_map.html
+++ b/geonode/client/templates/geoext/layers/layer_geoext_map.html
@@ -1,6 +1,6 @@
-{% include "geonode/ext_header.html" %}
-{% include "geonode/app_header.html" %}
-{% include "geonode/geo_header.html" %}
+{% include "geoext/ext_header.html" %}
+{% include "geoext/app_header.html" %}
+{% include "geoext/geo_header.html" %}
diff --git a/geonode/layers/templates/layers/layer_geoext_map_mini.html b/geonode/client/templates/geoext/layers/layer_geoext_map_mini.html
similarity index 98%
rename from geonode/layers/templates/layers/layer_geoext_map_mini.html
rename to geonode/client/templates/geoext/layers/layer_geoext_map_mini.html
index 0034a8ca638..64e832c98b2 100644
--- a/geonode/layers/templates/layers/layer_geoext_map_mini.html
+++ b/geonode/client/templates/geoext/layers/layer_geoext_map_mini.html
@@ -1,6 +1,6 @@
-{% include "geonode/ext_header.html" %}
-{% include "geonode/app_header.html" %}
-{% include "geonode/geo_header_mini.html" %}
+{% include "geoexet/ext_header.html" %}
+{% include "geoexet/app_header.html" %}
+{% include "geoexet/geo_header_mini.html" %}
diff --git a/geonode/maps/templates/maps/map_geoexplorer.js b/geonode/client/templates/geoext/maps/map_geoexplorer.js
similarity index 98%
rename from geonode/maps/templates/maps/map_geoexplorer.js
rename to geonode/client/templates/geoext/maps/map_geoexplorer.js
index fd843ae27ae..9c7327c3a72 100644
--- a/geonode/maps/templates/maps/map_geoexplorer.js
+++ b/geonode/client/templates/geoext/maps/map_geoexplorer.js
@@ -1,5 +1,5 @@
-{% include 'geonode/ext_header.html' %}
-{% include 'geonode/geo_header.html' %}
+{% include 'geoext/ext_header.html' %}
+{% include 'geoext/geo_header.html' %}
diff --git a/geonode/maps/templates/maps/map_include.html b/geonode/client/templates/geoext/maps/map_include.html
similarity index 98%
rename from geonode/maps/templates/maps/map_include.html
rename to geonode/client/templates/geoext/maps/map_include.html
index 7a5e08391a9..26286a68e74 100644
--- a/geonode/maps/templates/maps/map_include.html
+++ b/geonode/client/templates/geoext/maps/map_include.html
@@ -1,6 +1,6 @@
-{% include "geonode/ext_header.html" %}
-{% include "geonode/app_header.html" %}
-{% include "geonode/geo_header.html" %}
+{% include "geoext/ext_header.html" %}
+{% include "geoext/app_header.html" %}
+{% include "geoext/geo_header.html" %}
diff --git a/geonode/maps/templates/maps/map_sdk.js b/geonode/client/templates/geoext/maps/map_sdk.js
similarity index 94%
rename from geonode/maps/templates/maps/map_sdk.js
rename to geonode/client/templates/geoext/maps/map_sdk.js
index 2e7b549f7df..068f1fc75d0 100644
--- a/geonode/maps/templates/maps/map_sdk.js
+++ b/geonode/client/templates/geoext/maps/map_sdk.js
@@ -1,5 +1,5 @@
-{% include 'geonode/ext_header.html' %}
-{% include 'geonode/sdk_header.html' %}
+{% include 'geoext/ext_header.html' %}
+{% include 'geoext/sdk_header.html' %}
- {% if preview == 'geoext' %}
- {% include 'maps/map_geoexplorer.js' %}
- {% elif preview == 'react' %}
- {% include 'geonode-client/edit_map.html' %}
- {% else %}
- {% include 'maps/map_geoexplorer.js' %}
- {% endif %}
-
+ {% get_map_edit %}
{{ block.super }}
{% endblock %}
diff --git a/geonode/maps/templates/maps/map_embed.html b/geonode/maps/templates/maps/map_embed.html
index 6e87239daea..12d2b083f08 100644
--- a/geonode/maps/templates/maps/map_embed.html
+++ b/geonode/maps/templates/maps/map_embed.html
@@ -1,9 +1,9 @@
{% load i18n %}
{% block head %}
- {% include "geonode/ext_header.html" %}
- {% include "geonode/app_header.html" %}
- {% include "geonode/geo_header.html" %}
+ {% include "geoext/ext_header.html" %}
+ {% include "geoext/app_header.html" %}
+ {% include "geoext/geo_header.html" %}
diff --git a/geonode/maps/templates/maps/map_metadata.html b/geonode/maps/templates/maps/map_metadata.html
index 74f0803eb54..7e2ecd0bde2 100644
--- a/geonode/maps/templates/maps/map_metadata.html
+++ b/geonode/maps/templates/maps/map_metadata.html
@@ -9,7 +9,7 @@
{% block title %}{{ map.title }} — {{ block.super }}{% endblock %}
{% block head %}
- {% include "maps/map_ol2.html" %}
+ {% include "ol/maps/map_ol2.html" %}
{{ block.super }}
{% endblock head %}
diff --git a/geonode/maps/templates/maps/map_new.html b/geonode/maps/templates/maps/map_new.html
index 46d1aea130b..8f744971e97 100644
--- a/geonode/maps/templates/maps/map_new.html
+++ b/geonode/maps/templates/maps/map_new.html
@@ -2,6 +2,7 @@
{% load i18n %}
{% load base_tags %}
+{% load client_lib_tags %}
{% block title %} {% trans "New Map" %} - {{ block.super }} {% endblock %}
{% block head %}
@@ -12,14 +13,7 @@
}
- {% if preview == 'geoext' %}
- {% include 'maps/map_geoexplorer.js' %}
- {% elif preview == 'react' %}
- {% include 'geonode-client/map_new.html' %}
- {% else %}
- {% include 'maps/map_geoexplorer.js' %}
- {% endif %}
-
+ {% get_map_new %}
{{ block.super }}
{% endblock %}
diff --git a/geonode/maps/templates/maps/map_view.html b/geonode/maps/templates/maps/map_view.html
index 5c4ad9a91c5..426b6e4d3b0 100644
--- a/geonode/maps/templates/maps/map_view.html
+++ b/geonode/maps/templates/maps/map_view.html
@@ -2,6 +2,7 @@
{% load i18n %}
{% load base_tags %}
+{% load client_lib_tags %}
{% block title %} {% trans "Map" %} - {{ block.super }} {% endblock %}
@@ -13,13 +14,7 @@
}
- {% if preview == 'geoext' %}
- {% include 'maps/map_geoexplorer.js' %}
- {% elif preview == 'react' %}
- {% include 'geonode-client/map_view.html' %}
- {% else %}
- {% include 'maps/map_geoexplorer.js' %}
- {% endif %}
+ {% get_map_view %}
{{ block.super }}
{% endblock %}
{% block footer %}{% endblock %}
diff --git a/geonode/maps/views.py b/geonode/maps/views.py
index 01e2be3e392..79c07b6ca2b 100644
--- a/geonode/maps/views.py
+++ b/geonode/maps/views.py
@@ -165,8 +165,8 @@ def map_detail(request, mapid, snapshot=None, template='maps/map_detail.html'):
context_dict["preview"] = getattr(
settings,
- 'LAYER_PREVIEW_LIBRARY',
- '')
+ 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY',
+ 'geoext')
context_dict["crs"] = getattr(
settings,
'DEFAULT_MAP_CRS',
@@ -335,7 +335,7 @@ def map_metadata(request, mapid, template='maps/map_metadata.html'):
"author_form": author_form,
"category_form": category_form,
"layers": layers,
- "preview": getattr(settings, 'LAYER_PREVIEW_LIBRARY', 'leaflet'),
+ "preview": getattr(settings, 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY', 'geoext'),
"crs": getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913'),
"metadata_author_groups": metadata_author_groups,
"GROUP_MANDATORY_RESOURCES": getattr(settings, 'GROUP_MANDATORY_RESOURCES', False),
@@ -421,7 +421,7 @@ def map_embed(
def map_embed_widget(request, mapid,
- template='leaflet_maps/map_embed_widget.html'):
+ template='leaflet/maps/map_embed_widget.html'):
"""Display code snippet for embedding widget.
:param request: The request from the frontend.
@@ -544,8 +544,8 @@ def map_view(request, mapid, snapshot=None, layer_name=None, template='maps/map_
'map': map_obj,
'preview': getattr(
settings,
- 'LAYER_PREVIEW_LIBRARY',
- '')
+ 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY',
+ 'geoext')
}))
@@ -653,8 +653,8 @@ def map_edit(request, mapid, snapshot=None, template='maps/map_edit.html'):
'map': map_obj,
'preview': getattr(
settings,
- 'LAYER_PREVIEW_LIBRARY',
- '')
+ 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY',
+ 'geoext')
}))
@@ -690,8 +690,8 @@ def new_map(request, template='maps/map_new.html'):
}
context_dict["preview"] = getattr(
settings,
- 'LAYER_PREVIEW_LIBRARY',
- '')
+ 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY',
+ 'geoext')
if isinstance(config, HttpResponse):
return config
else:
diff --git a/geonode/messaging/consumer.py b/geonode/messaging/consumer.py
index 995daacc049..b0882afddac 100644
--- a/geonode/messaging/consumer.py
+++ b/geonode/messaging/consumer.py
@@ -21,10 +21,10 @@
import logging
import time
-from django.conf import settings
+# from django.conf import settings
from kombu.mixins import ConsumerMixin
from geonode.geoserver.signals import geoserver_post_save_local
-from geonode.security.views import send_email_consumer, send_email_owner_on_view
+from geonode.security.views import send_email_consumer # , send_email_owner_on_view
# from geonode.social.signals import notification_post_save_resource2
from geonode.layers.views import layer_view_counter
from geonode.layers.models import Layer
@@ -144,12 +144,13 @@ def on_consume_ready(self, connection, channel, consumers, **kwargs):
def on_layer_viewer(self, body, message):
# logger.debug("on_layer_viewer: RECEIVED MSG - body: %r" % (body,))
viewer = body.get("viewer")
- owner_layer = body.get("owner_layer")
+ # owner_layer = body.get("owner_layer")
layer_id = body.get("layer_id")
layer_view_counter(layer_id, viewer)
- if settings.EMAIL_ENABLE:
- send_email_owner_on_view(owner_layer, viewer, layer_id)
+ # TODO Disabled for now. This should be handeld through Notifications
+ # if settings.EMAIL_ENABLE:
+ # send_email_owner_on_view(owner_layer, viewer, layer_id)
message.ack()
logger.info("on_layer_viewer: finished")
self._check_message_limit()
diff --git a/geonode/people/admin.py b/geonode/people/admin.py
index 26f6cacb379..c14e118df3a 100644
--- a/geonode/people/admin.py
+++ b/geonode/people/admin.py
@@ -70,7 +70,7 @@ class ProfileAdmin(admin.ModelAdmin):
form = ProfileChangeForm
add_form = ProfileCreationForm
change_password_form = AdminPasswordChangeForm
- list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
+ list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_active')
list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups')
search_fields = ('username', 'first_name', 'last_name', 'email')
ordering = ('username',)
diff --git a/geonode/qgis_server/helpers.py b/geonode/qgis_server/helpers.py
index 84f24675fcf..20104ba4190 100644
--- a/geonode/qgis_server/helpers.py
+++ b/geonode/qgis_server/helpers.py
@@ -92,10 +92,10 @@ def validate_django_settings():
raise ImproperlyConfigured(
'QGIS_SERVER_CONFIG setting should be configured.')
- if not settings.LAYER_PREVIEW_LIBRARY == 'leaflet':
+ if not settings.GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY == 'leaflet':
raise ImproperlyConfigured(
'QGIS Server at the moment only works with '
- 'LAYER_PREVIEW_LIBRARY = leaflet.')
+ 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY = leaflet.')
# Check OGC Server settings
default_ogc_backend = settings.OGC_SERVER['default']
diff --git a/geonode/security/models.py b/geonode/security/models.py
index fdc0768261e..7350c0356c1 100644
--- a/geonode/security/models.py
+++ b/geonode/security/models.py
@@ -17,32 +17,20 @@
# along with this program. If not, see .
#
#########################################################################
-from geonode import geoserver
-from geonode.decorators import on_ogc_backend
-from lxml import etree
-
-try:
- import json
-except ImportError:
- from django.utils import simplejson as json
import logging
-import traceback
-import requests
-
-from requests.auth import HTTPBasicAuth
+from django.conf import settings
from django.contrib.auth import get_user_model
-
-from django.contrib.contenttypes.models import ContentType
-from django.contrib.auth import login
-from django.contrib.auth.models import Group, Permission
+from django.contrib.auth.models import Group
from geonode.groups.models import GroupProfile
-from django.core.exceptions import ObjectDoesNotExist
-from django.conf import settings
-from guardian.utils import get_user_obj_perms_model
from guardian.shortcuts import assign_perm, get_groups_with_perms
-from ..services.enumerations import CASCADED
+from .utils import (get_users_with_perms,
+ set_geofence_all,
+ set_geofence_owner,
+ set_geofence_group,
+ set_owner_permissions,
+ remove_object_permissions)
logger = logging.getLogger("geonode.security.models")
@@ -65,36 +53,6 @@
"GEOFENCE_SECURITY_ENABLED", False)
-def get_users_with_perms(obj):
- """
- Override of the Guardian get_users_with_perms
- """
- ctype = ContentType.objects.get_for_model(obj)
- permissions = {}
- PERMISSIONS_TO_FETCH = ADMIN_PERMISSIONS + LAYER_ADMIN_PERMISSIONS
-
- for perm in Permission.objects.filter(codename__in=PERMISSIONS_TO_FETCH, content_type_id=ctype.id):
- permissions[perm.id] = perm.codename
-
- user_model = get_user_obj_perms_model(obj)
- users_with_perms = user_model.objects.filter(object_pk=obj.pk,
- content_type_id=ctype.id,
- permission_id__in=permissions).values('user_id', 'permission_id')
-
- users = {}
- for item in users_with_perms:
- if item['user_id'] in users:
- users[item['user_id']].append(permissions[item['permission_id']])
- else:
- users[item['user_id']] = [permissions[item['permission_id']], ]
-
- profiles = {}
- for profile in get_user_model().objects.filter(id__in=users.keys()):
- profiles[profile] = users[profile.id]
-
- return profiles
-
-
class PermissionLevelError(Exception):
pass
@@ -269,391 +227,3 @@ def set_permissions(self, perm_spec):
assign_perm(perm, group, self.layer)
else:
assign_perm(perm, group, self.get_self_resource())
-
-
-def get_geofence_rules_count():
- """invalidate GeoFence 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 -X GET -u admin:geoserver \
- http://:/geoserver/geofence/rest/rules/count.json
- """
- headers = {'Content-type': 'application/json'}
- r = requests.get(url + 'geofence/rest/rules/count.json',
- headers=headers,
- auth=HTTPBasicAuth(user, passwd))
- if (r.status_code < 200 or r.status_code > 201):
- logger.warning("Could not retrieve GeoFence Rules count.")
-
- rules_objs = json.loads(r.text)
- rules_count = rules_objs['count']
- return int(rules_count)
- except:
- tb = traceback.format_exc()
- logger.debug(tb)
- return -1
-
-
-@on_ogc_backend(geoserver.BACKEND_PACKAGE)
-def set_geofence_invalidate_cache():
- """invalidate GeoFence Cache Rules"""
- if GEOFENCE_SECURITY_ENABLED:
- 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 -X GET -u admin:geoserver \
- http://:/geoserver/rest/ruleCache/invalidate
- """
- r = requests.put(url + 'rest/ruleCache/invalidate',
- auth=HTTPBasicAuth(user, passwd))
-
- if (r.status_code < 200 or r.status_code > 201):
- logger.warning("Could not Invalidate GeoFence Rules.")
- except Exception:
- tb = traceback.format_exc()
- logger.debug(tb)
- raise
-
-
-@on_ogc_backend(geoserver.BACKEND_PACKAGE)
-def set_geofence_all(instance):
- """assign access permissions to all users
-
- This method is only relevant to Layer instances that have their
- underlying data managed by geoserver, meaning:
-
- * layers that are not associated with a Service
- * layers that are associated with a Service that is being CASCADED through
- geoserver
-
- """
-
- resource = instance.get_self_resource()
- logger.debug("Inside set_geofence_all for instance {}".format(instance))
- try:
- workspace = _get_layer_workspace(resource.layer)
- logger.debug("going to work in workspace {!r}".format(workspace))
- except (ObjectDoesNotExist, AttributeError, RuntimeError):
- # This is either not a layer (if raised AttributeError) or it is
- # a layer that is not manageable by geofence (if raised
- # RuntimeError) so we have nothing to do
- return
- 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 -X GET -u admin:geoserver -H "Content-Type: application/json" \
- http://:/geoserver/geofence/rest/rules.json?layer=
- """
- headers = {'Content-type': 'application/json'}
- r = requests.get(url + 'geofence/rest/rules.json?layer=' + resource.layer.name,
- headers=headers,
- auth=HTTPBasicAuth(user, passwd))
-
- rules_already_present = False
- if (r.status_code < 200 or r.status_code > 201):
- logger.warning("Could not GET GeoServer Rules for Layer " + str(resource.layer.name))
- else:
- try:
- rules_objs = json.loads(r.text)
- rules_count = rules_objs['count']
- rules = rules_objs['rules']
- if rules_count > 1:
- for rule in rules:
- if rule['userName'] is None and rule['access'] == 'ALLOW':
- rules_already_present = True
- except Exception:
- logger.debug("Response [{}] : {}".format(r.status_code, r.text))
- raise
-
- # Create GeoFence Rules for ANONYMOUS to the Layer
- """
- curl -X POST -u admin:geoserver -H "Content-Type: text/xml" -d \
- "geonode{layer}ALLOW" \
- http://:/geoserver/geofence/rest/rules
- """
- rules_count = get_geofence_rules_count()
- headers = {'Content-type': 'application/xml'}
- payload = _get_geofence_payload(
- layer=resource.layer.name,
- workspace=workspace,
- access="ALLOW"
- )
-
- if not rules_already_present:
- response = requests.post(
- url + 'geofence/rest/rules',
- headers=headers,
- data=payload,
- auth=HTTPBasicAuth(user, passwd)
- )
- if response.status_code not in (200, 201):
- logger.debug(
- "Response {!r} : {}".format(r.status_code, r.text))
- raise RuntimeError("Could not ADD GeoServer ANONYMOUS Rule "
- "for Layer {}".format(resource.layer.name))
- except Exception:
- tb = traceback.format_exc()
- logger.debug(tb)
- raise
- finally:
- set_geofence_invalidate_cache()
-
-
-@on_ogc_backend(geoserver.BACKEND_PACKAGE)
-def set_geofence_owner(instance, username=None, view_perms=False, download_perms=False):
- """Assign access permissions to owner user
-
- This function uses the geoserver REST API in order to contact geofence.
- The request performs a similar function to the one in the following cURL
- snippet:
-
- curl -X POST -u {admin_user}:{admin_password} \
- -H "Content-Type: text/xml" \
- -d "{user}geonode \
- {layer}ALLOW" \
- http://:/geoserver/geofence/rest/rules
-
- """
-
- resource = instance.get_self_resource()
- try:
- workspace = _get_layer_workspace(resource.layer)
- except (ObjectDoesNotExist, AttributeError, RuntimeError):
- # resource is either not a layer (if raised AttributeError) or
- # a layer that is not manageable by geofence (if raised
- # RuntimeError) so we have nothing to do
- pass
- else:
- services = (
- (["WMS", "GWC"] if view_perms else []) +
- (["WFS", "WCS", "WPS"] if download_perms else [])
- )
- try:
- for service in services:
- _update_geofence_rule(
- layer=resource.layer.name,
- workspace=workspace,
- service=service,
- user=username
- )
- except Exception:
- tb = traceback.format_exc()
- logger.debug(tb)
- raise
- finally:
- set_geofence_invalidate_cache()
-
-
-@on_ogc_backend(geoserver.BACKEND_PACKAGE)
-def set_geofence_group(instance, groupname, view_perms=False,
- download_perms=False):
- """assign access permissions to owner group"""
- resource = instance.get_self_resource()
- try:
- workspace = _get_layer_workspace(resource.layer)
- except (ObjectDoesNotExist, AttributeError, RuntimeError):
- # resource is either not a layer (if raised AttributeError) or
- # a layer that is not manageable by geofence (if raised
- # RuntimeError) so we have nothing to do
- pass
- else:
- if groupname:
- services = (
- (["WMS", "GWC"] if view_perms else []) +
- (["WFS", "WCS", "WPS"] if download_perms else [])
- )
- try:
- for service in services:
- _update_geofence_rule(
- layer=resource.layer.name,
- workspace=workspace,
- group=groupname,
- service=service
- )
- except Exception:
- tb = traceback.format_exc()
- logger.debug(tb)
- raise
- finally:
- set_geofence_invalidate_cache()
-
-
-def set_owner_permissions(resource):
- """assign all admin permissions to the owner"""
- if resource.polymorphic_ctype:
- # Set the GeoFence Owner Rule
- if resource.polymorphic_ctype.name == 'layer':
- # Assign GeoFence Layer Access to Owner
- geofence_user = str(resource.owner)
- if "AnonymousUser" in geofence_user:
- geofence_user = None
- if GEOFENCE_SECURITY_ENABLED:
- set_geofence_owner(resource, username=geofence_user)
- for perm in LAYER_ADMIN_PERMISSIONS:
- assign_perm(perm, resource.owner, resource.layer)
-
- for perm in ADMIN_PERMISSIONS:
- assign_perm(perm, resource.owner, resource.get_self_resource())
-
-
-def remove_object_permissions(instance):
- """Remove object permissions on given resource.
-
- If is a layer removes the layer specific permissions then the
- resourcebase permissions
-
- """
-
- from guardian.models import UserObjectPermission, GroupObjectPermission
- resource = instance.get_self_resource()
- if hasattr(resource, "layer"):
- try:
- UserObjectPermission.objects.filter(
- content_type=ContentType.objects.get_for_model(resource.layer),
- object_pk=instance.id
- ).delete()
- GroupObjectPermission.objects.filter(
- content_type=ContentType.objects.get_for_model(resource.layer),
- object_pk=instance.id
- ).delete()
- if GEOFENCE_SECURITY_ENABLED:
- # Scan GeoFence Rules associated to the Layer
- """
- curl -u admin:geoserver
- http://:/geoserver/geofence/rest/rules.json?workspace=geonode&layer={layer}
- """
- url = settings.OGC_SERVER['default']['LOCATION']
- user = settings.OGC_SERVER['default']['USER']
- passwd = settings.OGC_SERVER['default']['PASSWORD']
- headers = {'Content-type': 'application/json'}
- workspace = _get_layer_workspace(resource.layer)
- r = requests.get(
- "{}geofence/rest/rules.json?workspace={}&layer={}".format(
- url, workspace, resource.layer.name),
- headers=headers,
- auth=HTTPBasicAuth(user, passwd)
- )
- if (r.status_code >= 200):
- gs_rules = r.json()
- r_ids = []
- if gs_rules and gs_rules['rules']:
- for r in gs_rules['rules']:
- if r['layer'] and r['layer'] == resource.layer.name:
- r_ids.append(r['id'])
-
- # Delete GeoFence Rules associated to the Layer
- # curl -X DELETE -u admin:geoserver http://:/geoserver/geofence/rest/rules/id/{r_id}
- for i, r_id in enumerate(r_ids):
- r = requests.delete(url + 'geofence/rest/rules/id/' + str(r_id),
- headers=headers,
- auth=HTTPBasicAuth(user, passwd))
- if (r.status_code < 200 or r.status_code > 201):
- msg = "Could not DELETE GeoServer Rule for Layer "
- msg = msg + str(resource.layer.name)
- e = Exception(msg)
- logger.debug("Response [{}] : {}".format(r.status_code, r.text))
- raise e
- except (ObjectDoesNotExist, RuntimeError):
- pass # This layer is not manageable by geofence
- except Exception:
- tb = traceback.format_exc()
- logger.debug(tb)
- raise
- finally:
- set_geofence_invalidate_cache()
-
- UserObjectPermission.objects.filter(content_type=ContentType.objects.get_for_model(resource),
- object_pk=instance.id).delete()
- GroupObjectPermission.objects.filter(content_type=ContentType.objects.get_for_model(resource),
- object_pk=instance.id).delete()
-
-
-# Logic to login a user automatically when it has successfully
-# activated an account:
-def autologin(sender, **kwargs):
- user = kwargs['user']
- request = kwargs['request']
- # Manually setting the default user backed to avoid the
- # 'User' object has no attribute 'backend' error
- user.backend = 'django.contrib.auth.backends.ModelBackend'
- # This login function does not need password.
- login(request, user)
-
-# FIXME(Ariel): Replace this signal with the one from django-user-accounts
-# user_activated.connect(autologin)
-
-
-def _get_layer_workspace(layer):
- """Get the workspace where the input layer belongs"""
- default_workspace = getattr(settings, "DEFAULT_WORKSPACE", "geonode")
- try:
- if layer.service.method == CASCADED:
- workspace = getattr(
- settings, "CASCADE_WORKSPACE", default_workspace)
- else:
- raise RuntimeError("Layer is not cascaded")
- except AttributeError: # layer does not have a service
- workspace = default_workspace
- return workspace
-
-
-def _get_geofence_payload(layer, workspace, access, user=None, group=None,
- service=None):
- rules_count = get_geofence_rules_count()
- root_el = etree.Element("Rule")
- if user is not None:
- username_el = etree.SubElement(root_el, "userName")
- username_el.text = user
- priority_el = etree.SubElement(root_el, "priority")
- priority_el.text = str(rules_count - 1)
- if group is not None:
- role_el = etree.SubElement(root_el, "roleName")
- role_el.text = "ROLE_{}".format(group.upper())
- workspace_el = etree.SubElement(root_el, "workspace")
- workspace_el.text = workspace
- layer_el = etree.SubElement(root_el, "layer")
- layer_el.text = layer
- access_el = etree.SubElement(root_el, "access")
- access_el.text = access
- if service is not None:
- service_el = etree.SubElement(root_el, "service")
- service_el.text = service
- return etree.tostring(root_el)
-
-
-def _update_geofence_rule(layer, workspace, service, user=None, group=None):
- payload = _get_geofence_payload(
- layer=layer,
- workspace=workspace,
- access="ALLOW",
- user=user,
- group=group,
- service=service
- )
- logger.debug("request data: {}".format(payload))
- response = requests.post(
- "{base_url}geofence/rest/rules".format(
- base_url=settings.OGC_SERVER['default']['LOCATION']),
- data=payload,
- headers={
- 'Content-type': 'application/xml'
- },
- auth=HTTPBasicAuth(
- username=settings.OGC_SERVER['default']['USER'],
- password=settings.OGC_SERVER['default']['PASSWORD']
- )
- )
- if response.status_code not in (200, 201):
- msg = ("Could not ADD GeoServer User {!r} Rule for "
- "Layer {!r}".format(user, layer))
- raise RuntimeError(msg)
diff --git a/geonode/security/utils.py b/geonode/security/utils.py
new file mode 100644
index 00000000000..cf35630a96e
--- /dev/null
+++ b/geonode/security/utils.py
@@ -0,0 +1,548 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+#
+# Copyright (C) 2018 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 .
+#
+#########################################################################
+from geonode import geoserver
+from geonode.decorators import on_ogc_backend
+from lxml import etree
+
+try:
+ import json
+except ImportError:
+ from django.utils import simplejson as json
+import logging
+import traceback
+import requests
+import models
+
+from requests.auth import HTTPBasicAuth
+from django.conf import settings
+from django.db.models import Q
+from django.contrib.auth import get_user_model
+from django.contrib.contenttypes.models import ContentType
+# from django.contrib.auth import login
+from django.contrib.auth.models import Group, Permission
+from django.core.exceptions import ObjectDoesNotExist
+from guardian.utils import get_user_obj_perms_model
+from guardian.shortcuts import assign_perm
+from geonode.groups.models import GroupProfile
+from ..services.enumerations import CASCADED
+
+logger = logging.getLogger("geonode.security.utils")
+
+
+def get_visible_resources(queryset,
+ user,
+ admin_approval_required=False,
+ unpublished_not_visible=False,
+ private_groups_not_visibile=False):
+ is_admin = False
+ is_manager = False
+ if user:
+ is_admin = user.is_superuser if user else False
+ try:
+ is_manager = user.groupmember_set.all().filter(role='manager').exists()
+ except:
+ is_manager = False
+
+ # Get the list of objects the user has access to
+ anonymous_group = None
+ public_groups = GroupProfile.objects.exclude(access="private").values('group')
+ groups = []
+ group_list_all = []
+ manager_groups = []
+ try:
+ group_list_all = user.group_list_all().values('group')
+ except:
+ pass
+ try:
+ manager_groups = Group.objects.filter(
+ name__in=user.groupmember_set.filter(role="manager").values_list("group__slug", flat=True))
+ except:
+ pass
+ try:
+ anonymous_group = Group.objects.get(name='anonymous')
+ if anonymous_group and anonymous_group not in groups:
+ groups.append(anonymous_group)
+ except:
+ pass
+
+ filter_set = queryset
+
+ if admin_approval_required:
+ if not is_admin:
+ if is_manager:
+ filter_set = filter_set.filter(
+ Q(is_published=True) |
+ Q(group__in=groups) |
+ Q(group__in=manager_groups) |
+ Q(group__in=group_list_all) |
+ Q(group__in=public_groups) |
+ Q(owner__username__iexact=str(user)))
+ elif user:
+ filter_set = filter_set.filter(
+ Q(is_published=True) |
+ Q(group__in=groups) |
+ Q(group__in=group_list_all) |
+ Q(group__in=public_groups) |
+ Q(owner__username__iexact=str(user)))
+ else:
+ filter_set = filter_set.filter(
+ Q(is_published=True) |
+ Q(group__in=public_groups) |
+ Q(group__in=groups))
+
+ if unpublished_not_visible:
+ if not is_admin:
+ if user:
+ filter_set = filter_set.exclude(
+ Q(is_published=False) & ~(
+ Q(owner__username__iexact=str(user)) | Q(group__in=group_list_all)))
+ else:
+ filter_set = filter_set.exclude(is_published=False)
+
+ if private_groups_not_visibile:
+ if not is_admin:
+ private_groups = GroupProfile.objects.filter(access="private").values('group')
+ if user:
+ filter_set = filter_set.exclude(
+ Q(group__in=private_groups) & ~(
+ Q(owner__username__iexact=str(user)) | Q(group__in=group_list_all)))
+ else:
+ filter_set = filter_set.exclude(group__in=private_groups)
+
+ return filter_set
+
+
+def get_users_with_perms(obj):
+ """
+ Override of the Guardian get_users_with_perms
+ """
+ ctype = ContentType.objects.get_for_model(obj)
+ permissions = {}
+ PERMISSIONS_TO_FETCH = models.ADMIN_PERMISSIONS + models.LAYER_ADMIN_PERMISSIONS
+
+ for perm in Permission.objects.filter(codename__in=PERMISSIONS_TO_FETCH, content_type_id=ctype.id):
+ permissions[perm.id] = perm.codename
+
+ user_model = get_user_obj_perms_model(obj)
+ users_with_perms = user_model.objects.filter(object_pk=obj.pk,
+ content_type_id=ctype.id,
+ permission_id__in=permissions).values('user_id', 'permission_id')
+
+ users = {}
+ for item in users_with_perms:
+ if item['user_id'] in users:
+ users[item['user_id']].append(permissions[item['permission_id']])
+ else:
+ users[item['user_id']] = [permissions[item['permission_id']], ]
+
+ profiles = {}
+ for profile in get_user_model().objects.filter(id__in=users.keys()):
+ profiles[profile] = users[profile.id]
+
+ return profiles
+
+
+@on_ogc_backend(geoserver.BACKEND_PACKAGE)
+def get_geofence_rules_count():
+ """invalidate GeoFence 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 -X GET -u admin:geoserver \
+ http://:/geoserver/geofence/rest/rules/count.json
+ """
+ headers = {'Content-type': 'application/json'}
+ r = requests.get(url + 'geofence/rest/rules/count.json',
+ headers=headers,
+ auth=HTTPBasicAuth(user, passwd))
+ if (r.status_code < 200 or r.status_code > 201):
+ logger.warning("Could not retrieve GeoFence Rules count.")
+
+ rules_objs = json.loads(r.text)
+ rules_count = rules_objs['count']
+ return int(rules_count)
+ except:
+ tb = traceback.format_exc()
+ logger.debug(tb)
+ return -1
+
+
+@on_ogc_backend(geoserver.BACKEND_PACKAGE)
+def set_geofence_invalidate_cache():
+ """invalidate GeoFence Cache Rules"""
+ if models.GEOFENCE_SECURITY_ENABLED:
+ 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 -X GET -u admin:geoserver \
+ http://:/geoserver/rest/ruleCache/invalidate
+ """
+ r = requests.put(url + 'rest/ruleCache/invalidate',
+ auth=HTTPBasicAuth(user, passwd))
+
+ if (r.status_code < 200 or r.status_code > 201):
+ logger.warning("Could not Invalidate GeoFence Rules.")
+ except Exception:
+ tb = traceback.format_exc()
+ logger.debug(tb)
+ raise
+
+
+@on_ogc_backend(geoserver.BACKEND_PACKAGE)
+def set_geofence_all(instance):
+ """assign access permissions to all users
+
+ This method is only relevant to Layer instances that have their
+ underlying data managed by geoserver, meaning:
+
+ * layers that are not associated with a Service
+ * layers that are associated with a Service that is being CASCADED through
+ geoserver
+
+ """
+
+ resource = instance.get_self_resource()
+ logger.debug("Inside set_geofence_all for instance {}".format(instance))
+ try:
+ workspace = _get_layer_workspace(resource.layer)
+ logger.debug("going to work in workspace {!r}".format(workspace))
+ except (ObjectDoesNotExist, AttributeError, RuntimeError):
+ # This is either not a layer (if raised AttributeError) or it is
+ # a layer that is not manageable by geofence (if raised
+ # RuntimeError) so we have nothing to do
+ return
+ 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 -X GET -u admin:geoserver -H "Content-Type: application/json" \
+ http://:/geoserver/geofence/rest/rules.json?layer=
+ """
+ headers = {'Content-type': 'application/json'}
+ r = requests.get(url + 'geofence/rest/rules.json?layer=' + resource.layer.name,
+ headers=headers,
+ auth=HTTPBasicAuth(user, passwd))
+
+ rules_already_present = False
+ if (r.status_code < 200 or r.status_code > 201):
+ logger.warning("Could not GET GeoServer Rules for Layer " + str(resource.layer.name))
+ else:
+ try:
+ rules_objs = json.loads(r.text)
+ rules_count = rules_objs['count']
+ rules = rules_objs['rules']
+ if rules_count > 1:
+ for rule in rules:
+ if rule['userName'] is None and rule['access'] == 'ALLOW':
+ rules_already_present = True
+ except Exception:
+ logger.debug("Response [{}] : {}".format(r.status_code, r.text))
+ raise
+
+ # Create GeoFence Rules for ANONYMOUS to the Layer
+ """
+ curl -X POST -u admin:geoserver -H "Content-Type: text/xml" -d \
+ "geonode{layer}ALLOW" \
+ http://:/geoserver/geofence/rest/rules
+ """
+ rules_count = get_geofence_rules_count()
+ headers = {'Content-type': 'application/xml'}
+ payload = _get_geofence_payload(
+ layer=resource.layer.name,
+ workspace=workspace,
+ access="ALLOW"
+ )
+
+ if not rules_already_present:
+ response = requests.post(
+ url + 'geofence/rest/rules',
+ headers=headers,
+ data=payload,
+ auth=HTTPBasicAuth(user, passwd)
+ )
+ if response.status_code not in (200, 201):
+ logger.debug(
+ "Response {!r} : {}".format(r.status_code, r.text))
+ raise RuntimeError("Could not ADD GeoServer ANONYMOUS Rule "
+ "for Layer {}".format(resource.layer.name))
+ except Exception:
+ tb = traceback.format_exc()
+ logger.debug(tb)
+ raise
+ finally:
+ set_geofence_invalidate_cache()
+
+
+@on_ogc_backend(geoserver.BACKEND_PACKAGE)
+def set_geofence_owner(instance, username=None, view_perms=False, download_perms=False):
+ """Assign access permissions to owner user
+
+ This function uses the geoserver REST API in order to contact geofence.
+ The request performs a similar function to the one in the following cURL
+ snippet:
+
+ curl -X POST -u {admin_user}:{admin_password} \
+ -H "Content-Type: text/xml" \
+ -d "{user}geonode \
+ {layer}ALLOW" \
+ http://:/geoserver/geofence/rest/rules
+
+ """
+
+ resource = instance.get_self_resource()
+ try:
+ workspace = _get_layer_workspace(resource.layer)
+ except (ObjectDoesNotExist, AttributeError, RuntimeError):
+ # resource is either not a layer (if raised AttributeError) or
+ # a layer that is not manageable by geofence (if raised
+ # RuntimeError) so we have nothing to do
+ pass
+ else:
+ services = (
+ (["WMS", "GWC"] if view_perms else []) +
+ (["WFS", "WCS", "WPS"] if download_perms else [])
+ )
+ try:
+ for service in services:
+ _update_geofence_rule(
+ layer=resource.layer.name,
+ workspace=workspace,
+ service=service,
+ user=username
+ )
+ except Exception:
+ tb = traceback.format_exc()
+ logger.debug(tb)
+ raise
+ finally:
+ set_geofence_invalidate_cache()
+
+
+@on_ogc_backend(geoserver.BACKEND_PACKAGE)
+def set_geofence_group(instance, groupname, view_perms=False,
+ download_perms=False):
+ """assign access permissions to owner group"""
+ resource = instance.get_self_resource()
+ try:
+ workspace = _get_layer_workspace(resource.layer)
+ except (ObjectDoesNotExist, AttributeError, RuntimeError):
+ # resource is either not a layer (if raised AttributeError) or
+ # a layer that is not manageable by geofence (if raised
+ # RuntimeError) so we have nothing to do
+ pass
+ else:
+ if groupname:
+ services = (
+ (["WMS", "GWC"] if view_perms else []) +
+ (["WFS", "WCS", "WPS"] if download_perms else [])
+ )
+ try:
+ for service in services:
+ _update_geofence_rule(
+ layer=resource.layer.name,
+ workspace=workspace,
+ group=groupname,
+ service=service
+ )
+ except Exception:
+ tb = traceback.format_exc()
+ logger.debug(tb)
+ raise
+ finally:
+ set_geofence_invalidate_cache()
+
+
+def set_owner_permissions(resource):
+ """assign all admin permissions to the owner"""
+ if resource.polymorphic_ctype:
+ # Set the GeoFence Owner Rule
+ if resource.polymorphic_ctype.name == 'layer':
+ # Assign GeoFence Layer Access to Owner
+ geofence_user = str(resource.owner)
+ if "AnonymousUser" in geofence_user:
+ geofence_user = None
+ if models.GEOFENCE_SECURITY_ENABLED:
+ set_geofence_owner(resource, username=geofence_user)
+ for perm in models.LAYER_ADMIN_PERMISSIONS:
+ assign_perm(perm, resource.owner, resource.layer)
+
+ for perm in models.ADMIN_PERMISSIONS:
+ assign_perm(perm, resource.owner, resource.get_self_resource())
+
+
+def remove_object_permissions(instance):
+ """Remove object permissions on given resource.
+
+ If is a layer removes the layer specific permissions then the
+ resourcebase permissions
+
+ """
+
+ from guardian.models import UserObjectPermission, GroupObjectPermission
+ resource = instance.get_self_resource()
+ if hasattr(resource, "layer"):
+ try:
+ UserObjectPermission.objects.filter(
+ content_type=ContentType.objects.get_for_model(resource.layer),
+ object_pk=instance.id
+ ).delete()
+ GroupObjectPermission.objects.filter(
+ content_type=ContentType.objects.get_for_model(resource.layer),
+ object_pk=instance.id
+ ).delete()
+ if models.GEOFENCE_SECURITY_ENABLED:
+ # Scan GeoFence Rules associated to the Layer
+ """
+ curl -u admin:geoserver
+ http://:/geoserver/geofence/rest/rules.json?workspace=geonode&layer={layer}
+ """
+ url = settings.OGC_SERVER['default']['LOCATION']
+ user = settings.OGC_SERVER['default']['USER']
+ passwd = settings.OGC_SERVER['default']['PASSWORD']
+ headers = {'Content-type': 'application/json'}
+ workspace = _get_layer_workspace(resource.layer)
+ r = requests.get(
+ "{}geofence/rest/rules.json?workspace={}&layer={}".format(
+ url, workspace, resource.layer.name),
+ headers=headers,
+ auth=HTTPBasicAuth(user, passwd)
+ )
+ if (r.status_code >= 200):
+ gs_rules = r.json()
+ r_ids = []
+ if gs_rules and gs_rules['rules']:
+ for r in gs_rules['rules']:
+ if r['layer'] and r['layer'] == resource.layer.name:
+ r_ids.append(r['id'])
+
+ # Delete GeoFence Rules associated to the Layer
+ # curl -X DELETE -u admin:geoserver http://:/geoserver/geofence/rest/rules/id/{r_id}
+ for i, r_id in enumerate(r_ids):
+ r = requests.delete(url + 'geofence/rest/rules/id/' + str(r_id),
+ headers=headers,
+ auth=HTTPBasicAuth(user, passwd))
+ if (r.status_code < 200 or r.status_code > 201):
+ msg = "Could not DELETE GeoServer Rule for Layer "
+ msg = msg + str(resource.layer.name)
+ e = Exception(msg)
+ logger.debug("Response [{}] : {}".format(r.status_code, r.text))
+ raise e
+ except (ObjectDoesNotExist, RuntimeError):
+ pass # This layer is not manageable by geofence
+ except Exception:
+ tb = traceback.format_exc()
+ logger.debug(tb)
+ raise
+ finally:
+ set_geofence_invalidate_cache()
+
+ UserObjectPermission.objects.filter(content_type=ContentType.objects.get_for_model(resource),
+ object_pk=instance.id).delete()
+ GroupObjectPermission.objects.filter(content_type=ContentType.objects.get_for_model(resource),
+ object_pk=instance.id).delete()
+
+
+# # Logic to login a user automatically when it has successfully
+# # activated an account:
+# def autologin(sender, **kwargs):
+# user = kwargs['user']
+# request = kwargs['request']
+# # Manually setting the default user backed to avoid the
+# # 'User' object has no attribute 'backend' error
+# user.backend = 'django.contrib.auth.backends.ModelBackend'
+# # This login function does not need password.
+# login(request, user)
+#
+# # FIXME(Ariel): Replace this signal with the one from django-user-accounts
+# # user_activated.connect(autologin)
+
+
+def _get_layer_workspace(layer):
+ """Get the workspace where the input layer belongs"""
+ default_workspace = getattr(settings, "DEFAULT_WORKSPACE", "geonode")
+ try:
+ if layer.service.method == CASCADED:
+ workspace = getattr(
+ settings, "CASCADE_WORKSPACE", default_workspace)
+ else:
+ raise RuntimeError("Layer is not cascaded")
+ except AttributeError: # layer does not have a service
+ workspace = default_workspace
+ return workspace
+
+
+def _get_geofence_payload(layer, workspace, access, user=None, group=None,
+ service=None):
+ rules_count = get_geofence_rules_count()
+ root_el = etree.Element("Rule")
+ if user is not None:
+ username_el = etree.SubElement(root_el, "userName")
+ username_el.text = user
+ priority_el = etree.SubElement(root_el, "priority")
+ priority_el.text = str(rules_count - 1)
+ if group is not None:
+ role_el = etree.SubElement(root_el, "roleName")
+ role_el.text = "ROLE_{}".format(group.upper())
+ workspace_el = etree.SubElement(root_el, "workspace")
+ workspace_el.text = workspace
+ layer_el = etree.SubElement(root_el, "layer")
+ layer_el.text = layer
+ access_el = etree.SubElement(root_el, "access")
+ access_el.text = access
+ if service is not None:
+ service_el = etree.SubElement(root_el, "service")
+ service_el.text = service
+ return etree.tostring(root_el)
+
+
+def _update_geofence_rule(layer, workspace, service, user=None, group=None):
+ payload = _get_geofence_payload(
+ layer=layer,
+ workspace=workspace,
+ access="ALLOW",
+ user=user,
+ group=group,
+ service=service
+ )
+ logger.debug("request data: {}".format(payload))
+ response = requests.post(
+ "{base_url}geofence/rest/rules".format(
+ base_url=settings.OGC_SERVER['default']['LOCATION']),
+ data=payload,
+ headers={
+ 'Content-type': 'application/xml'
+ },
+ auth=HTTPBasicAuth(
+ username=settings.OGC_SERVER['default']['USER'],
+ password=settings.OGC_SERVER['default']['PASSWORD']
+ )
+ )
+ if response.status_code not in (200, 201):
+ msg = ("Could not ADD GeoServer User {!r} Rule for "
+ "Layer {!r}".format(user, layer))
+ raise RuntimeError(msg)
diff --git a/geonode/services/templates/services/service_detail.html b/geonode/services/templates/services/service_detail.html
index f225890562a..2b6451e2ab4 100644
--- a/geonode/services/templates/services/service_detail.html
+++ b/geonode/services/templates/services/service_detail.html
@@ -2,9 +2,7 @@
{% load i18n %}
{% load guardian_tags %}
{% block head %}
-{% include "geonode/ext_header.html" %}
-{% include "geonode/app_header.html" %}
-{% include "geonode/geo_header.html" %}
+
{{ block.super }}