Skip to content

Commit

Permalink
- Make sure we use "basic.auth" whenever we check for 'access_token'
Browse files Browse the repository at this point in the history
  • Loading branch information
afabiani committed Mar 18, 2019
1 parent 81471d1 commit b4686d7
Show file tree
Hide file tree
Showing 8 changed files with 221 additions and 167 deletions.
24 changes: 13 additions & 11 deletions geonode/catalogue/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from geonode.catalogue.backends.pycsw_local import CONFIGURATION
from geonode.base.models import ResourceBase
from geonode.layers.models import Layer
from geonode.base.auth import get_or_create_token
from geonode.base.models import ContactRole, SpatialRepresentationType
from geonode.people.models import Profile
from geonode.groups.models import GroupProfile
Expand All @@ -50,24 +51,25 @@ def csw_global_dispatch(request):
mdict = dict(settings.PYCSW['CONFIGURATION'], **CONFIGURATION)

access_token = None
if request and 'access_token' in request.session:
access_token = request.session['access_token']
if request and request.user:
access_token = get_or_create_token(request.user)
if access_token and access_token.is_expired():
access_token = None

absolute_uri = ('%s' % request.build_absolute_uri())
query_string = ('%s' % request.META['QUERY_STRING'])
env = request.META.copy()

if access_token and 'access_token' not in query_string:
absolute_uri = ('%s&access_token=%s' % (absolute_uri, access_token))
query_string = ('%s&access_token=%s' % (query_string, access_token))
if access_token and not access_token.is_expired():
env.update({'access_token': access_token.token})
if 'access_token' not in query_string:
absolute_uri = ('%s&access_token=%s' % (absolute_uri, access_token.token))
query_string = ('%s&access_token=%s' % (query_string, access_token.token))

env = request.META.copy()
env.update({'local.app_root': os.path.dirname(__file__),
'REQUEST_URI': absolute_uri,
'QUERY_STRING': query_string})

if access_token:
env.update({'access_token': access_token})

# Save original filter before doing anything
mdict_filter = mdict['repository']['filter']

Expand Down Expand Up @@ -170,7 +172,7 @@ def csw_global_dispatch(request):
for prefix, uri in spaces.iteritems():
ET.register_namespace(prefix, uri)

if access_token:
if access_token and not access_token.is_expired():
tree = ET.fromstring(content)
for online_resource in tree.findall(
'*//gmd:CI_OnlineResource', spaces):
Expand All @@ -182,7 +184,7 @@ def csw_global_dispatch(request):
url.text += "?"
else:
url.text += "&"
url.text += ("access_token=%s" % (access_token))
url.text += ("access_token=%s" % (access_token.token))
url.set('updated', 'yes')
except BaseException:
pass
Expand Down
94 changes: 90 additions & 4 deletions geonode/geoserver/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@
from owslib.wcs import WebCoverageService
from owslib.wms import WebMapService
from geonode import GeoNodeException
from geonode.layers.enumerations import LAYER_ATTRIBUTE_NUMERIC_DATA_TYPES
from geonode.base.auth import get_or_create_token
from geonode.utils import http_client
from geonode.layers.models import Layer, Attribute, Style
from geonode.layers.enumerations import LAYER_ATTRIBUTE_NUMERIC_DATA_TYPES
from geonode.security.views import _perms_info_json
from geonode.utils import set_attributes, http_client
from geonode.security.utils import set_geowebcache_invalidate_cache
import xml.etree.ElementTree as ET
from django.utils.module_loading import import_string
Expand Down Expand Up @@ -801,6 +802,89 @@ def get_stores(store_type=None):
return store_list


def set_attributes(
layer,
attribute_map,
overwrite=False,
attribute_stats=None):
""" *layer*: a geonode.layers.models.Layer instance
*attribute_map*: a list of 2-lists specifying attribute names and types,
example: [ ['id', 'Integer'], ... ]
*overwrite*: replace existing attributes with new values if name/type matches.
*attribute_stats*: dictionary of return values from get_attribute_statistics(),
of the form to get values by referencing attribute_stats[<layer_name>][<field_name>].
"""
# we need 3 more items; description, attribute_label, and display_order
attribute_map_dict = {
'field': 0,
'ftype': 1,
'description': 2,
'label': 3,
'display_order': 4,
}
for attribute in attribute_map:
attribute.extend((None, None, 0))

attributes = layer.attribute_set.all()
# Delete existing attributes if they no longer exist in an updated layer
for la in attributes:
lafound = False
for attribute in attribute_map:
field, ftype, description, label, display_order = attribute
if field == la.attribute:
lafound = True
# store description and attribute_label in attribute_map
attribute[attribute_map_dict['description']] = la.description
attribute[attribute_map_dict['label']] = la.attribute_label
attribute[attribute_map_dict['display_order']
] = la.display_order
if overwrite or not lafound:
logger.debug(
"Going to delete [%s] for [%s]",
la.attribute,
layer.name.encode('utf-8'))
la.delete()

# Add new layer attributes if they don't already exist
if attribute_map is not None:
iter = len(Attribute.objects.filter(layer=layer)) + 1
for attribute in attribute_map:
field, ftype, description, label, display_order = attribute
if field is not None:
la, created = Attribute.objects.get_or_create(
layer=layer, attribute=field, attribute_type=ftype,
description=description, attribute_label=label,
display_order=display_order)
if created:
if (not attribute_stats or layer.name not in attribute_stats or
field not in attribute_stats[layer.name]):
result = None
else:
result = attribute_stats[layer.name][field]

if result is not None:
logger.debug("Generating layer attribute statistics")
la.count = result['Count']
la.min = result['Min']
la.max = result['Max']
la.average = result['Average']
la.median = result['Median']
la.stddev = result['StandardDeviation']
la.sum = result['Sum']
la.unique_values = result['unique_values']
la.last_stats_updated = datetime.datetime.now(timezone.get_current_timezone())
la.visible = ftype.find("gml:") != 0
la.display_order = iter
la.save()
iter += 1
logger.debug(
"Created [%s] attribute for [%s]",
field,
layer.name.encode('utf-8'))
else:
logger.debug("No attributes found")


def set_attributes_from_geoserver(layer, overwrite=False):
"""
Retrieve layer attribute names & types from Geoserver,
Expand Down Expand Up @@ -1842,8 +1926,10 @@ def decimal_encode(bbox):
# 'TIME': '-99999999999-01-01T00:00:00.0Z/99999999999-01-01T00:00:00.0Z'
}

if request and 'access_token' in request.session:
params['access_token'] = request.session['access_token']
if request and request.user:
access_token = get_or_create_token(request.user)
if access_token and not access_token.is_expired():
params['access_token'] = access_token.token

_p = "&".join("%s=%s" % item for item in params.items())

Expand Down
8 changes: 4 additions & 4 deletions geonode/geoserver/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
from guardian.shortcuts import get_objects_for_user
from .utils import requests_retry
from geonode.base.models import ResourceBase
from geonode.base.auth import get_or_create_token
from geonode.layers.forms import LayerStyleUploadForm
from geonode.layers.models import Layer, Style
from geonode.layers.views import _resolve_layer, _PERMISSION_MSG_MODIFY
Expand Down Expand Up @@ -833,12 +834,11 @@ def get_capabilities(request, layerid=None, user=None,
for layer in layers:
if request.user.has_perm('view_resourcebase',
layer.get_self_resource()):
access_token = None
if request and 'access_token' in request.session:
access_token = request.session['access_token']
access_token = get_or_create_token(request.user)
if access_token and not access_token.is_expired():
access_token = access_token.token
else:
access_token = None

try:
workspace, layername = layer.alternate.split(":") if ":" in layer.alternate else (None, layer.alternate)
layercap = get_layer_capabilities(layer,
Expand Down
98 changes: 77 additions & 21 deletions geonode/layers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
import glob
import sys
import logging
import tarfile

from geonode.maps.models import Map
from osgeo import gdal, osr
from zipfile import ZipFile, is_zipfile
from datetime import datetime

# Django functionality
from django.contrib.auth import get_user_model
Expand All @@ -42,23 +44,31 @@
from django.db.models import Q

# Geonode functionality
from geonode.maps.models import Map
from geonode.base.auth import get_or_create_token
from geonode import GeoNodeException, geoserver, qgis_server
from geonode.people.utils import get_valid_user
from geonode.layers.models import Layer, UploadSession, LayerFile
from geonode.base.models import Link, SpatialRepresentationType, \
TopicCategory, Region, License, ResourceBase
from geonode.layers.models import shp_exts, csv_exts, vec_exts, cov_exts
from geonode.layers.metadata import set_metadata
from geonode.utils import (http_client, check_ogc_backend,
unzip_file, extract_tarfile)
from ..geoserver.helpers import (ogc_server_settings,
_prepare_thumbnail_body_from_opts)

import tarfile

from zipfile import ZipFile, is_zipfile

from datetime import datetime
from geonode.utils import (http_client,
check_ogc_backend,
unzip_file,
extract_tarfile,
bbox_to_projection)

if check_ogc_backend(geoserver.BACKEND_PACKAGE):
# FIXME: The post service providing the map_status object
# should be moved to geonode.geoserver.
from geonode.geoserver.helpers import ogc_server_settings

# Use the http_client with one that knows the username
# and password for GeoServer's management user.
from geonode.geoserver.helpers import _prepare_thumbnail_body_from_opts
elif check_ogc_backend(qgis_server.BACKEND_PACKAGE):
from geonode.qgis_server.helpers import ogc_server_settings

logger = logging.getLogger('geonode.layers.utils')

Expand Down Expand Up @@ -958,10 +968,12 @@ def create_thumbnail(instance, thumbnail_remote_url, thumbnail_create_url=None,
if 'ServiceException' in image or \
resp.status_code < 200 or resp.status_code > 299:
msg = 'Unable to obtain thumbnail: %s' % image
raise Exception(msg)
except BaseException:
import traceback
logger.debug(traceback.format_exc())
logger.error(msg)

# Replace error message with None.
image = None
except BaseException as e:
logger.exception(e)

# Replace error message with None.
image = None
Expand All @@ -986,29 +998,53 @@ def create_thumbnail(instance, thumbnail_remote_url, thumbnail_create_url=None,
else:
msg = 'Unable to obtain thumbnail for: %s' % instance
logger.error(msg)
# raise Exception(msg)


# this is the original implementation of create_gs_thumbnail()
def create_gs_thumbnail_geonode(instance, overwrite=False, check_bbox=False):
"""
Create a thumbnail with a GeoServer request.
"""
layers = None
bbox = None # x0, x1, y0, y1
local_layers = []
local_bboxes = []
if isinstance(instance, Map):
local_layers = []
# a map could be empty!
if not instance.layers:
return
for layer in instance.layers:
if layer.local:
local_layers.append(layer.name)
# Compute Bounds
_l = Layer.objects.get(alternate=layer.name)
wgs84_bbox = bbox_to_projection(_l.bbox)
local_bboxes.append(wgs84_bbox)
layers = ",".join(local_layers).encode('utf-8')
else:
layers = instance.alternate.encode('utf-8')

wms_endpoint = getattr(ogc_server_settings, "WMS_ENDPOINT") or 'ows'
wms_version = getattr(ogc_server_settings, "WMS_VERSION") or '1.1.1'
wms_format = getattr(ogc_server_settings, "WMS_FORMAT") or 'image/png8'
# Compute Bounds
_l = Layer.objects.get(alternate=layers)
wgs84_bbox = bbox_to_projection(_l.bbox)
local_bboxes.append(wgs84_bbox)

if local_bboxes:
for _bbox in local_bboxes:
if bbox is None:
bbox = _bbox
else:
if bbox[0] > _bbox[0]:
bbox[0] = _bbox[0]
if bbox[1] < _bbox[1]:
bbox[1] = _bbox[1]
if bbox[2] > _bbox[2]:
bbox[2] = _bbox[2]
if bbox[3] < _bbox[3]:
bbox[3] = _bbox[3]

wms_endpoint = getattr(ogc_server_settings, 'WMS_ENDPOINT') or 'ows'
wms_version = getattr(ogc_server_settings, 'WMS_VERSION') or '1.1.1'
wms_format = getattr(ogc_server_settings, 'WMS_FORMAT') or 'image/png8'

params = {
'service': 'WMS',
Expand All @@ -1019,6 +1055,25 @@ def create_gs_thumbnail_geonode(instance, overwrite=False, check_bbox=False):
# 'TIME': '-99999999999-01-01T00:00:00.0Z/99999999999-01-01T00:00:00.0Z'
}

if bbox:
params['bbox'] = "%s,%s,%s,%s" % (bbox[0], bbox[2], bbox[1], bbox[3])
params['crs'] = 'EPSG:4326'
params['width'] = 240
params['height'] = 180

user = None
try:
username = ogc_server_settings.credentials.username
user = get_user_model().objects.get(username=username)
except BaseException as e:
logger.exception(e)

access_token = None
if user:
access_token = get_or_create_token(user)
if access_token and not access_token.is_expired():
params['access_token'] = access_token.token

# Avoid using urllib.urlencode here because it breaks the url.
# commas and slashes in values get encoded and then cause trouble
# with the WMS parser.
Expand All @@ -1031,6 +1086,7 @@ def create_gs_thumbnail_geonode(instance, overwrite=False, check_bbox=False):
thumbnail_create_url = posixpath.join(
ogc_server_settings.LOCATION,
wms_endpoint) + "?" + _p

create_thumbnail(instance, thumbnail_remote_url, thumbnail_create_url,
overwrite=overwrite, check_bbox=check_bbox)

Expand Down

0 comments on commit b4686d7

Please sign in to comment.