def map_embed(request, mapid=None, template='maps/map_embed.html'): try: map_obj = _resolve_map(request, mapid, 'base.view_resourcebase', _PERMISSION_MSG_VIEW) except PermissionDenied: return HttpResponse(MSG_NOT_ALLOWED, status=403) except Exception: raise Http404(MSG_NOT_FOUND) if not map_obj: raise Http404(MSG_NOT_FOUND) access_token = None if request and request.user: 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 context_dict = { 'access_token': access_token, 'resource': map_obj, } register_event(request, EventType.EVENT_VIEW, map_obj) return render(request, template, context=context_dict)
def dataset_detail(request, layername, template='datasets/dataset_detail.html'): try: layer = _resolve_dataset(request, layername, 'base.view_resourcebase', _PERMISSION_MSG_VIEW) except PermissionDenied: return HttpResponse(_("Not allowed"), status=403) except Exception: raise Http404(_("Not found")) if not layer: raise Http404(_("Not found")) # Update count for popularity ranking, # but do not includes admins or resource owners layer.view_count_up(request.user) access_token = None if request and request.user: 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 context_dict = { 'access_token': access_token, 'resource': layer, } register_event(request, 'view', layer) return TemplateResponse(request, template, context=context_dict)
def geoapp_edit(request, geoappid, template='apps/app_edit.html'): """ The view that returns the app composer opened to the app with the given app ID. """ try: geoapp_obj = _resolve_geoapp( request, geoappid, 'base.view_resourcebase', _PERMISSION_MSG_VIEW) except PermissionDenied: return HttpResponse(_("Not allowed"), status=403) except Exception: raise Http404(_("Not found")) if not geoapp_obj: raise Http404(_("Not found")) # Call this first in order to be sure "perms_list" is correct permissions_json = _perms_info_json(geoapp_obj) perms_list = list( geoapp_obj.get_self_resource().get_user_perms(request.user) .union(geoapp_obj.get_user_perms(request.user)) ) group = None if geoapp_obj.group: try: group = GroupProfile.objects.get(slug=geoapp_obj.group.name) except GroupProfile.DoesNotExist: group = None access_token = None if request and request.user: 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 _data = GeoAppData.objects.filter(resource__id=geoappid).first() _config = _data.blob if _data else {} _ctx = { 'appId': geoappid, 'appType': geoapp_obj.type, 'config': _config, 'user': request.user, 'access_token': access_token, 'resource': geoapp_obj, 'group': group, 'perms_list': perms_list, "permissions_json": permissions_json, 'preview': getattr( settings, 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY', 'mapstore') } return render(request, template, context=_ctx)
def test_outh_token(self): user = '******' _user = get_user_model().objects.get(username=user) token = get_or_create_token(_user) auth_header = f'Bearer {token}' list_url = reverse('api_dispatch_list', kwargs={ 'api_name': 'api', 'resource_name': 'datasets' }) with self.settings(SESSION_EXPIRED_CONTROL_ENABLED=False, DELAYED_SECURITY_SIGNALS=False): # all public resp = self.api_client.get(list_url) self.assertValidJSONResponse(resp) self.assertGreaterEqual(len(self.deserialize(resp)['objects']), 7) perm_spec = { "users": { "admin": ['view_resourcebase'] }, "groups": {} } layer = Dataset.objects.all()[0] layer.set_permissions(perm_spec) resp = self.api_client.get(list_url) self.assertGreaterEqual(len(self.deserialize(resp)['objects']), 7) resp = self.api_client.get(list_url, authentication=auth_header) self.assertGreaterEqual(len(self.deserialize(resp)['objects']), 7) layer.is_published = False layer.save()
def test_inbox_renders(self): logged_in = self.client.login( username=self.first_user.username, password=self.user_password) self.assertTrue(logged_in) session = self.client.session session['access_token'] = get_or_create_token(self.first_user) session.save() response = self.client.get(reverse("messages_inbox")) self.assertTemplateUsed(response, "user_messages/inbox.html") self.assertEqual(response.status_code, 200)
def setUp(self): super(DataTypeResourceTests, self).setUp() self.user = get_user_model().objects.get(username="******") self.list_url = reverse('api_dispatch_list', kwargs={ 'api_name': 'api', 'resource_name': 'datatype' }) all_public() self.token = get_or_create_token(self.user) self.auth_header = f'Bearer {self.token}'
def setUp(self): super(LayerResourceTests, self).setUp() self.user = get_user_model().objects.get(username="******") self.list_url = reverse('api_dispatch_list', kwargs={ 'api_name': 'api', 'resource_name': 'layers' }) all_public() self.token = get_or_create_token(self.user) self.auth_header = 'Bearer {}'.format(self.token)
def test_the_api_should_return_all_datasets_with_metadata_false(self): list_url = reverse('api_dispatch_list', kwargs={ 'api_name': 'api', 'resource_name': 'datasets' }) user = get_user_model().objects.get(username="******") token = get_or_create_token(user) auth_header = f'Bearer {token}' resp = self.api_client.get(list_url, authentication=auth_header) self.assertValidJSONResponse(resp) self.assertEqual(8, resp.json()["meta"]["total_count"])
def setUp(self): super(OAuthApiTests, self).setUp() self.user = '******' self.passwd = 'admin' self._user = get_user_model().objects.get(username=self.user) self.token = get_or_create_token(self._user) self.auth_header = f'Bearer {self.token}' self.list_url = reverse('api_dispatch_list', kwargs={ 'api_name': 'api', 'resource_name': 'layers' }) all_public() self.perm_spec = {"users": {}, "groups": {}}
def setUp(self): super(OAuthApiTests, self).setUp() self.user = '******' self.passwd = 'admin' self._user = get_user_model().objects.get(username=self.user) self.token = get_or_create_token(self._user) self.auth_header = 'Bearer {}'.format(self.token) self.list_url = reverse( 'api_dispatch_list', kwargs={ 'api_name': 'api', 'resource_name': 'layers'}) all_public() self.perm_spec = {"users": {}, "groups": {}}
def profile_detail(request, username): profile = get_object_or_404(get_user_model(), Q(is_active=True), username=username) # combined queryset from each model content type access_token = None if request and request.user: 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 return render(request, "people/profile_detail.html", { 'access_token': access_token, "profile": profile, })
def do_login(sender, user, request, **kwargs): """ Take action on user login. Generate a new user access_token to be shared with GeoServer, and store it into the request.session """ if user and user.is_authenticated: token = None try: token = get_or_create_token(user) except Exception: u = uuid1() token = u.hex tb = traceback.format_exc() logger.debug(tb) set_session_token(request.session, token)
def do_login(sender, user, request, **kwargs): """ Take action on user login. Generate a new user access_token to be shared with GeoServer, and store it into the request.session """ if user and user.is_authenticated(): token = None try: token = get_or_create_token(user) except BaseException: u = uuid1() token = u.hex tb = traceback.format_exc() logger.debug(tb) set_session_token(request.session, token)
def new_geoapp(request, template='apps/app_new.html'): access_token = None if request and request.user: 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 if request.method == 'GET': _ctx = { 'user': request.user, 'access_token': access_token, } return render(request, template, context=_ctx) return HttpResponseRedirect(hookset.geoapp_list_url())
def _get_topomap_sheets( topomap: PublishedTopoMapIndexSheetLayer) -> typing.List: geoserver_admin_user = get_user_model().objects.get( username=settings.OGC_SERVER_DEFAULT_USER) access_token = get_or_create_token(geoserver_admin_user) published_sheets = topomap.get_published_sheets( use_public_wfs_url=False, geoserver_access_token=access_token) sheets_info = [] for sheet_index in published_sheets: sheet_paths = utils.find_sheet(topomap.series, topomap.version, sheet_index) if sheet_paths is not None: sheets_info.append({ 'index': sheet_index, 'paper_sizes': sheet_paths.keys() }) sheets_info = sorted(sheets_info, key=lambda x: x['index']) return sheets_info
def do_login(sender, user, request, **kwargs): """ Take action on user login. Generate a new user access_token to be shared with GeoServer, and store it into the request.session """ if user and user.is_authenticated: token = None try: token = get_or_create_token(user) except Exception: u = uuid1() token = u.hex tb = traceback.format_exc() logger.debug(tb) set_session_token(request.session, token) if groups_settings.AUTO_ASSIGN_REGISTERED_MEMBERS_TO_REGISTERED_MEMBERS_GROUP_AT == 'login': _add_user_to_registered_members(user)
def do_login(sender, user, request, **kwargs): """ Take action on user login. Generate a new user access_token to be shared with GeoServer, and store it into the request.session """ if user and user.is_authenticated(): token = None try: token = get_or_create_token(user) except BaseException: u = uuid1() token = u.hex tb = traceback.format_exc() logger.debug(tb) set_session_token(request.session, token) from geonode.groups.conf import settings as groups_settings if groups_settings.AUTO_ASSIGN_REGISTERED_MEMBERS_TO_REGISTERED_MEMBERS_GROUP_NAME: group_name = groups_settings.REGISTERED_MEMBERS_GROUP_NAME groupprofile = GroupProfile.objects.filter(slug=group_name).first() if groupprofile and not groupprofile.user_is_member(user): groupprofile.join(user)
def construct_wms_url( ogc_server_location: str, layers: List, bbox: List, wms_version: str = settings.OGC_SERVER["default"].get( "WMS_VERSION", "1.1.0"), mime_type: str = "image/png", styles: str = None, width: int = 240, height: int = 200, ) -> str: """ Method constructing a GetMap URL to the OGC server. :param ogc_server_location: OGC server URL :param layers: layers which should be fetched from the OGC server :param bbox: area's bounding box in format: [west, east, south, north, CRS] :param wms_version: WMS version of the query :param mime_type: mime type of the returned image :param styles: styles, which OGC server should use for rendering an image :param width: width of the returned image :param height: height of the returned image :return: GetMap URL """ # create GetMap query parameters params = { "service": "WMS", "version": wms_version, "request": "GetMap", "layers": ",".join(layers), "bbox": ",".join([str(bbox[0]), str(bbox[2]), str(bbox[1]), str(bbox[3])]), "crs": bbox[-1], "width": width, "height": height, "format": mime_type, "transparent": True, } if styles is not None: params["styles"] = styles # create GetMap request ogc_server_settings = OGC_Servers_Handler(settings.OGC_SERVER)["default"] if ogc_server_location is not None: thumbnail_url = ogc_server_location else: thumbnail_url = ogc_server_settings.LOCATION wms_endpoint = "" if thumbnail_url == ogc_server_settings.LOCATION: # add access token to requests to Geoserver (logic based on the previous implementation) username = ogc_server_settings.credentials.username user = get_user_model().objects.filter(username=username).first() if user: access_token = get_or_create_token(user) if access_token and not access_token.is_expired(): params["access_token"] = access_token.token # add WMS endpoint to requests to Geoserver wms_endpoint = getattr(ogc_server_settings, "WMS_ENDPOINT") or "ows" thumbnail_url = f"{thumbnail_url}{wms_endpoint}?{'&'.join(f'{key}={val}' for key, val in params.items())}" return thumbnail_url
def get_map( ogc_server_location: str, layers: List, bbox: List, wms_version: str = settings.OGC_SERVER["default"].get("WMS_VERSION", "1.1.1"), mime_type: str = "image/png", styles: List = None, width: int = 240, height: int = 200, max_retries: int = 3, retry_delay: int = 1, ): """ Function fetching an image from OGC server. For the requests to the configured OGC backend (ogc_server_settings.LOCATION) the function tries to generate an access_token and attach it to the URL. If access_token is not added ant the request is against Geoserver Basic Authentication is used instead. If image retrieval fails, function retries to fetch the image max_retries times, waiting retry_delay seconds between consecutive requests. :param ogc_server_location: OGC server URL :param layers: layers which should be fetched from the OGC server :param bbox: area's bounding box in format: [west, east, south, north, CRS] :param wms_version: WMS version of the query (default: 1.1.1) :param mime_type: mime type of the returned image :param styles: styles, which OGC server should use for rendering an image :param width: width of the returned image :param height: height of the returned image :param max_retries: maximum number of retries before skipping retrieval :param retry_delay: number of seconds waited between retries :returns: retrieved image """ ogc_server_settings = OGC_Servers_Handler(settings.OGC_SERVER)["default"] if ogc_server_location is not None: thumbnail_url = ogc_server_location else: thumbnail_url = ogc_server_settings.LOCATION if thumbnail_url.startswith(ogc_server_settings.PUBLIC_LOCATION): thumbnail_url = thumbnail_url.replace(ogc_server_settings.PUBLIC_LOCATION, ogc_server_settings.LOCATION) wms_endpoint = "" additional_kwargs = {} if thumbnail_url == ogc_server_settings.LOCATION: # add access token to requests to Geoserver (logic based on the previous implementation) username = ogc_server_settings.credentials.username user = get_user_model().objects.filter(username=username).first() if user: access_token = get_or_create_token(user) if access_token and not access_token.is_expired(): additional_kwargs['access_token'] = access_token.token # add WMS endpoint to requests to Geoserver wms_endpoint = getattr(ogc_server_settings, "WMS_ENDPOINT") or "ows" # prepare authorization for WMS service headers = {} if thumbnail_url.startswith(ogc_server_settings.LOCATION): if "access_token" not in additional_kwargs.keys(): # for the Geoserver backend, use Basic Auth, if access_token is not provided _user, _pwd = ogc_server_settings.credentials encoded_credentials = base64.b64encode(f"{_user}:{_pwd}".encode("UTF-8")).decode("ascii") headers["Authorization"] = f"Basic {encoded_credentials}" else: headers["Authorization"] = f"Bearer {additional_kwargs['access_token']}" wms = WebMapService( f"{thumbnail_url}{wms_endpoint}", version=wms_version, headers=headers) image = None for retry in range(max_retries): try: # fetch data image = wms.getmap( layers=layers, styles=styles, srs=bbox[-1] if bbox else None, bbox=[bbox[0], bbox[2], bbox[1], bbox[3]] if bbox else None, size=(width, height), format=mime_type, transparent=True, timeout=getattr(ogc_server_settings, "TIMEOUT", None), **additional_kwargs, ) # validate response if not image or "ServiceException" in str(image.read()): raise ThumbnailError( f"Fetching partial thumbnail from {thumbnail_url} failed with response: {str(image)}" ) except Exception as e: if retry + 1 >= max_retries: logger.exception(e) return time.sleep(retry_delay) continue else: break return image.read()
def geoapp_detail(request, geoappid, template='apps/app_detail.html'): """ The view that returns the app composer opened to the app with the given app ID. """ try: geoapp_obj = _resolve_geoapp(request, geoappid, 'base.view_resourcebase', _PERMISSION_MSG_VIEW) except PermissionDenied: return HttpResponse(_("Not allowed"), status=403) except Exception: raise Http404(_("Not found")) if not geoapp_obj: raise Http404(_("Not found")) # Add metadata_author or poc if missing geoapp_obj.add_missing_metadata_author_or_poc() # Update count for popularity ranking, # but do not includes admins or resource owners if request.user != geoapp_obj.owner and not request.user.is_superuser: GeoApp.objects.filter(id=geoapp_obj.id).update( popular_count=F('popular_count') + 1) _data = GeoAppData.objects.filter(resource__id=geoappid).first() _config = _data.blob if _data else {} # Call this first in order to be sure "perms_list" is correct permissions_json = _perms_info_json(geoapp_obj) perms_list = get_perms(request.user, geoapp_obj.get_self_resource()) + get_perms( request.user, geoapp_obj) group = None if geoapp_obj.group: try: group = GroupProfile.objects.get(slug=geoapp_obj.group.name) except GroupProfile.DoesNotExist: group = None access_token = None if request and request.user: 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 context_dict = { 'appId': geoappid, 'appType': geoapp_obj.type, 'config': _config, 'user': request.user, 'access_token': access_token, 'resource': geoapp_obj, 'group': group, 'perms_list': perms_list, 'permissions_json': permissions_json, 'preview': getattr(settings, 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY', 'mapstore'), 'crs': getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857') } if settings.SOCIAL_ORIGINS: context_dict["social_links"] = build_social_links(request, geoapp_obj) register_event(request, EventType.EVENT_VIEW, request.path) return render(request, template, context=context_dict)
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): # 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') # 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 = list(_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', 'version': wms_version, 'request': 'GetMap', 'layers': layers, 'format': wms_format, # '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. _p = "&".join("%s=%s" % item for item in params.items()) import posixpath thumbnail_remote_url = posixpath.join( ogc_server_settings.PUBLIC_LOCATION, wms_endpoint) + "?" + _p 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)
def document_detail(request, docid): """ The view that show details of each document """ document = None try: document = _resolve_document(request, docid, 'base.view_resourcebase', _PERMISSION_MSG_VIEW) except Http404: return HttpResponse(loader.render_to_string('404.html', context={}, request=request), status=404) except PermissionDenied: return HttpResponse(loader.render_to_string( '401.html', context={ 'error_message': _("You are not allowed to view this document.") }, request=request), status=403) if document is None: return HttpResponse('An unknown error has occured.', content_type="text/plain", status=401) else: permission_manager = ManageResourceOwnerPermissions(document) permission_manager.set_owner_permissions_according_to_workflow() # Add metadata_author or poc if missing document.add_missing_metadata_author_or_poc() related = get_related_resources(document) # Update count for popularity ranking, # but do not includes admins or resource owners if request.user != document.owner and not request.user.is_superuser: Document.objects.filter(id=document.id).update( popular_count=F('popular_count') + 1) metadata = document.link_set.metadata().filter( name__in=settings.DOWNLOAD_FORMATS_METADATA) # Call this first in order to be sure "perms_list" is correct permissions_json = _perms_info_json(document) perms_list = get_perms(request.user, document.get_self_resource()) + get_perms( request.user, document) group = None if document.group: try: group = GroupProfile.objects.get(slug=document.group.name) except ObjectDoesNotExist: group = None access_token = None if request and request.user: 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 context_dict = { 'access_token': access_token, 'resource': document, 'perms_list': perms_list, 'permissions_json': permissions_json, 'group': group, 'metadata': metadata, 'imgtypes': IMGTYPES, 'related': related } if settings.SOCIAL_ORIGINS: context_dict["social_links"] = build_social_links( request, document) if getattr(settings, 'EXIF_ENABLED', False): try: from geonode.documents.exif.utils import exif_extract_dict exif = exif_extract_dict(document) if exif: context_dict['exif_data'] = exif except Exception: logger.error("Exif extraction failed.") if request.user.is_authenticated: if getattr(settings, 'FAVORITE_ENABLED', False): from geonode.favorite.utils import get_favorite_info context_dict["favorite_info"] = get_favorite_info( request.user, document) register_event(request, EventType.EVENT_VIEW, document) return render(request, "documents/document_detail.html", context=context_dict)
def map_detail(request, mapid, template='maps/map_detail.html'): ''' The view that show details of each map ''' map_obj = _resolve_map(request, mapid, 'base.view_resourcebase', _PERMISSION_MSG_VIEW) permission_manager = ManageResourceOwnerPermissions(map_obj) permission_manager.set_owner_permissions_according_to_workflow() # Add metadata_author or poc if missing map_obj.add_missing_metadata_author_or_poc() # Update count for popularity ranking, # but do not includes admins or resource owners if request.user != map_obj.owner and not request.user.is_superuser: Map.objects.filter(id=map_obj.id).update( popular_count=F('popular_count') + 1) config = map_obj.viewer_json(request) register_event(request, EventType.EVENT_VIEW, map_obj.title) config = json.dumps(config) layers = MapLayer.objects.filter(map=map_obj.id) links = map_obj.link_set.download() # Call this first in order to be sure "perms_list" is correct permissions_json = _perms_info_json(map_obj) perms_list = get_perms(request.user, map_obj.get_self_resource()) + get_perms( request.user, map_obj) group = None if map_obj.group: try: group = GroupProfile.objects.get(slug=map_obj.group.name) except GroupProfile.DoesNotExist: group = None access_token = None if request and request.user: 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 context_dict = { 'access_token': access_token, 'config': config, 'resource': map_obj, 'group': group, 'layers': layers, 'perms_list': perms_list, 'permissions_json': permissions_json, "documents": get_related_documents(map_obj), 'links': links, 'preview': getattr(settings, 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY', 'mapstore'), 'crs': getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857') } if settings.SOCIAL_ORIGINS: context_dict["social_links"] = build_social_links(request, map_obj) if request.user.is_authenticated: if getattr(settings, 'FAVORITE_ENABLED', False): from geonode.favorite.utils import get_favorite_info context_dict["favorite_info"] = get_favorite_info( request.user, map_obj) register_event(request, EventType.EVENT_VIEW, request.path) return render(request, template, context=context_dict)
def csw_global_dispatch(request, layer_filter=None, config_updater=None): """pycsw wrapper""" # this view should only operate if pycsw_local is the backend # else, redirect to the URL of the non-pycsw_local backend if settings.CATALOGUE['default'][ 'ENGINE'] != 'geonode.catalogue.backends.pycsw_local': return HttpResponseRedirect(settings.CATALOGUE['default']['URL']) mdict = dict(settings.PYCSW['CONFIGURATION'], **CONFIGURATION) mdict = config_updater(mdict) if config_updater else mdict access_token = None 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 = f'{request.build_absolute_uri()}' query_string = f"{request.META['QUERY_STRING']}" env = request.META.copy() 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 = f'{absolute_uri}&access_token={access_token.token}' query_string = f'{query_string}&access_token={access_token.token}' env.update({ 'local.app_root': os.path.dirname(__file__), 'REQUEST_URI': absolute_uri, 'QUERY_STRING': query_string }) # Save original filter before doing anything mdict_filter = mdict['repository']['filter'] try: # Filter out Layers not accessible to the User authorized_ids = [] if request.user: profiles = get_user_model().objects.filter( username=str(request.user)) else: profiles = get_user_model().objects.filter( username="******") if profiles: authorized = list( get_objects_for_user(profiles[0], 'base.view_resourcebase').values('id')) layers = ResourceBase.objects.filter( id__in=[d['id'] for d in authorized]) if layer_filter and layers: layers = layer_filter(layers) if layers: authorized_ids = [d.id for d in layers] if len(authorized_ids) > 0: authorized_layers = "(" + (", ".join( str(e) for e in authorized_ids)) + ")" authorized_layers_filter = "id IN " + authorized_layers mdict['repository']['filter'] += " AND " + authorized_layers_filter if request.user and request.user.is_authenticated: mdict['repository'][ 'filter'] = f"({mdict['repository']['filter']}) OR ({authorized_layers_filter})" else: authorized_layers_filter = "id = -9999" mdict['repository']['filter'] += " AND " + authorized_layers_filter # Filter out Documents and Maps if 'ALTERNATES_ONLY' in settings.CATALOGUE[ 'default'] and settings.CATALOGUE['default']['ALTERNATES_ONLY']: mdict['repository']['filter'] += " AND alternate IS NOT NULL" # Filter out Layers belonging to specific Groups is_admin = False if request.user: is_admin = request.user.is_superuser if request.user else False if not is_admin and settings.GROUP_PRIVATE_RESOURCES: groups_ids = [] if request.user and request.user.is_authenticated: for group in request.user.groups.all(): groups_ids.append(group.id) group_list_all = [] try: group_list_all = request.user.group_list_all().values( 'group') except Exception: pass for group in group_list_all: if isinstance(group, dict): if 'group' in group: groups_ids.append(group['group']) else: groups_ids.append(group.id) public_groups = GroupProfile.objects.exclude( access="private").values('group') for group in public_groups: if isinstance(group, dict): if 'group' in group: groups_ids.append(group['group']) else: groups_ids.append(group.id) if len(groups_ids) > 0: groups = "(" + (", ".join(str(e) for e in groups_ids)) + ")" groups_filter = "(group_id IS NULL OR group_id IN " + groups + ")" mdict['repository']['filter'] += " AND " + groups_filter else: groups_filter = "group_id IS NULL" mdict['repository']['filter'] += " AND " + groups_filter csw = server.Csw(mdict, env, version='2.0.2') content = csw.dispatch_wsgi() # pycsw 2.0 has an API break: # - pycsw < 2.0: content = xml_response # - pycsw >= 2.0: content = [http_status_code, content] # deal with the API break if isinstance(content, list): # pycsw 2.0+ content = content[1] finally: # Restore original filter before doing anything mdict['repository']['filter'] = mdict_filter return HttpResponse(content, content_type=csw.contenttype)
def document_detail(request, docid): """ The view that show details of each document """ try: document = _resolve_document(request, docid, 'base.view_resourcebase', _PERMISSION_MSG_VIEW) except PermissionDenied: return HttpResponse(_("Not allowed"), status=403) except Exception: raise Http404(_("Not found")) if not document: raise Http404(_("Not found")) permission_manager = ManageResourceOwnerPermissions(document) permission_manager.set_owner_permissions_according_to_workflow() # Add metadata_author or poc if missing document.add_missing_metadata_author_or_poc() related = get_related_resources(document) # Update count for popularity ranking, # but do not includes admins or resource owners if request.user != document.owner and not request.user.is_superuser: Document.objects.filter(id=document.id).update( popular_count=F('popular_count') + 1) metadata = document.link_set.metadata().filter( name__in=settings.DOWNLOAD_FORMATS_METADATA) # Call this first in order to be sure "perms_list" is correct permissions_json = _perms_info_json(document) perms_list = list(document.get_self_resource().get_user_perms( request.user).union(document.get_user_perms(request.user))) group = None if document.group: try: group = GroupProfile.objects.get(slug=document.group.name) except ObjectDoesNotExist: group = None access_token = None if request and request.user: 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 AUDIOTYPES = [_e for _e, _t in DOCUMENT_TYPE_MAP.items() if _t == 'audio'] IMGTYPES = [_e for _e, _t in DOCUMENT_TYPE_MAP.items() if _t == 'image'] VIDEOTYPES = [_e for _e, _t in DOCUMENT_TYPE_MAP.items() if _t == 'video'] context_dict = { 'access_token': access_token, 'resource': document, 'perms_list': perms_list, 'permissions_json': permissions_json, 'group': group, 'metadata': metadata, 'audiotypes': AUDIOTYPES, 'imgtypes': IMGTYPES, 'videotypes': VIDEOTYPES, 'mimetypemap': DOCUMENT_MIMETYPE_MAP, 'related': related } if settings.SOCIAL_ORIGINS: context_dict["social_links"] = build_social_links(request, document) if getattr(settings, 'EXIF_ENABLED', False): try: from geonode.documents.exif.utils import exif_extract_dict exif = exif_extract_dict(document) if exif: context_dict['exif_data'] = exif except Exception: logger.debug("Exif extraction failed.") if request.user.is_authenticated: if getattr(settings, 'FAVORITE_ENABLED', False): from geonode.favorite.utils import get_favorite_info context_dict["favorite_info"] = get_favorite_info( request.user, document) register_event(request, EventType.EVENT_VIEW, document) return render(request, "documents/document_detail.html", context=context_dict)
def geoapp_edit(request, geoappid, template='apps/app_edit.html'): """ The view that returns the app composer opened to the app with the given app ID. """ try: geoapp_obj = _resolve_geoapp(request, geoappid, 'base.view_resourcebase', _PERMISSION_MSG_VIEW) except PermissionDenied: return HttpResponse(_("Not allowed"), status=403) except Exception: raise Http404(_("Not found")) if not geoapp_obj: raise Http404(_("Not found")) # Call this first in order to be sure "perms_list" is correct permissions_json = _perms_info_json(geoapp_obj) perms_list = list(geoapp_obj.get_self_resource().get_user_perms( request.user).union(geoapp_obj.get_user_perms(request.user))) group = None if geoapp_obj.group: try: group = GroupProfile.objects.get(slug=geoapp_obj.group.name) except GroupProfile.DoesNotExist: group = None r = geoapp_obj if request.method in ('POST', 'PATCH', 'PUT'): r = resource_manager.update(geoapp_obj.uuid, instance=geoapp_obj, notify=True) resource_manager.set_permissions( geoapp_obj.uuid, instance=geoapp_obj, permissions=ast.literal_eval(permissions_json)) resource_manager.set_thumbnail(geoapp_obj.uuid, instance=geoapp_obj, overwrite=False) access_token = None if request and request.user: 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 _config = json.dumps(r.blob) _ctx = { 'appId': geoappid, 'appType': geoapp_obj.resource_type, 'config': _config, 'user': request.user, 'access_token': access_token, 'resource': geoapp_obj, 'group': group, 'perms_list': perms_list, "permissions_json": permissions_json, 'preview': getattr(settings, 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY', 'mapstore') } return render(request, template, context=_ctx)
def csw_global_dispatch(request): """pycsw wrapper""" # this view should only operate if pycsw_local is the backend # else, redirect to the URL of the non-pycsw_local backend if settings.CATALOGUE['default']['ENGINE'] != 'geonode.catalogue.backends.pycsw_local': return HttpResponseRedirect(settings.CATALOGUE['default']['URL']) mdict = dict(settings.PYCSW['CONFIGURATION'], **CONFIGURATION) access_token = None 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 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.update({'local.app_root': os.path.dirname(__file__), 'REQUEST_URI': absolute_uri, 'QUERY_STRING': query_string}) # Save original filter before doing anything mdict_filter = mdict['repository']['filter'] try: # Filter out Layers not accessible to the User authorized_ids = [] if request.user: profiles = Profile.objects.filter(username=str(request.user)) else: profiles = Profile.objects.filter(username="******") if profiles: authorized = list( get_objects_for_user( profiles[0], 'base.view_resourcebase').values('id')) layers = ResourceBase.objects.filter( id__in=[d['id'] for d in authorized]) if layers: authorized_ids = [d['id'] for d in authorized] if len(authorized_ids) > 0: authorized_layers = "(" + (", ".join(str(e) for e in authorized_ids)) + ")" authorized_layers_filter = "id IN " + authorized_layers mdict['repository']['filter'] += " AND " + authorized_layers_filter if request.user and request.user.is_authenticated(): mdict['repository']['filter'] = "({}) OR ({})".format(mdict['repository']['filter'], authorized_layers_filter) else: authorized_layers_filter = "id = -9999" mdict['repository']['filter'] += " AND " + authorized_layers_filter # Filter out Documents and Maps if 'ALTERNATES_ONLY' in settings.CATALOGUE['default'] and settings.CATALOGUE['default']['ALTERNATES_ONLY']: mdict['repository']['filter'] += " AND alternate IS NOT NULL" # Filter out Layers belonging to specific Groups is_admin = False if request.user: is_admin = request.user.is_superuser if request.user else False if not is_admin and settings.GROUP_PRIVATE_RESOURCES: groups_ids = [] if request.user and request.user.is_authenticated(): for group in request.user.groups.all(): groups_ids.append(group.id) group_list_all = [] try: group_list_all = request.user.group_list_all().values('group') except BaseException: pass for group in group_list_all: if isinstance(group, dict): if 'group' in group: groups_ids.append(group['group']) else: groups_ids.append(group.id) public_groups = GroupProfile.objects.exclude( access="private").values('group') for group in public_groups: if isinstance(group, dict): if 'group' in group: groups_ids.append(group['group']) else: groups_ids.append(group.id) if len(groups_ids) > 0: groups = "(" + (", ".join(str(e) for e in groups_ids)) + ")" groups_filter = "(group_id IS NULL OR group_id IN " + groups + ")" mdict['repository']['filter'] += " AND " + groups_filter else: groups_filter = "group_id IS NULL" mdict['repository']['filter'] += " AND " + groups_filter csw = server.Csw(mdict, env, version='2.0.2') content = csw.dispatch_wsgi() # pycsw 2.0 has an API break: # pycsw < 2.0: content = xml_response # pycsw >= 2.0: content = [http_status_code, content] # deal with the API break if isinstance(content, list): # pycsw 2.0+ content = content[1] spaces = {'csw': 'http://www.opengis.net/cat/csw/2.0.2', 'dc': 'http://purl.org/dc/elements/1.1/', 'dct': 'http://purl.org/dc/terms/', 'gmd': 'http://www.isotc211.org/2005/gmd', 'gml': 'http://www.opengis.net/gml', 'ows': 'http://www.opengis.net/ows', 'xs': 'http://www.w3.org/2001/XMLSchema', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance', 'ogc': 'http://www.opengis.net/ogc', 'gco': 'http://www.isotc211.org/2005/gco', 'gmi': 'http://www.isotc211.org/2005/gmi'} for prefix, uri in spaces.iteritems(): ET.register_namespace(prefix, uri) if access_token and not access_token.is_expired(): tree = ET.fromstring(content) for online_resource in tree.findall( '*//gmd:CI_OnlineResource', spaces): try: linkage = online_resource.find('gmd:linkage', spaces) for url in linkage.findall('gmd:URL', spaces): if url.text: if '?' not in url.text: url.text += "?" else: url.text += "&" url.text += ("access_token=%s" % (access_token.token)) url.set('updated', 'yes') except BaseException: pass content = ET.tostring(tree, encoding='utf8', method='xml') finally: # Restore original filter before doing anything mdict['repository']['filter'] = mdict_filter return HttpResponse(content, content_type=csw.contenttype)
def get_headers(request, url, raw_url, allowed_hosts=[]): headers = {} cookies = None csrftoken = None if settings.SESSION_COOKIE_NAME in request.COOKIES and is_safe_url( url=raw_url, host=url.hostname): cookies = request.META["HTTP_COOKIE"] for cook in request.COOKIES: name = str(cook) value = request.COOKIES.get(name) if name == 'csrftoken': csrftoken = value cook = "%s=%s" % (name, value) cookies = cook if not cookies else (cookies + '; ' + cook) csrftoken = get_token(request) if not csrftoken else csrftoken if csrftoken: headers['X-Requested-With'] = "XMLHttpRequest" headers['X-CSRFToken'] = csrftoken cook = "%s=%s" % ('csrftoken', csrftoken) cookies = cook if not cookies else (cookies + '; ' + cook) if cookies: if 'JSESSIONID' in request.session and request.session['JSESSIONID']: cookies = cookies + '; JSESSIONID=' + \ request.session['JSESSIONID'] headers['Cookie'] = cookies if request.method in ("POST", "PUT") and "CONTENT_TYPE" in request.META: headers["Content-Type"] = request.META["CONTENT_TYPE"] access_token = None site_url = urlsplit(settings.SITEURL) allowed_hosts += [url.hostname] # We want to convert HTTP_AUTH into a Beraer Token only when hitting the local GeoServer if site_url.hostname in allowed_hosts: # we give precedence to obtained from Aithorization headers if 'HTTP_AUTHORIZATION' in request.META: auth_header = request.META.get( 'HTTP_AUTHORIZATION', request.META.get('HTTP_AUTHORIZATION2')) if auth_header: headers['Authorization'] = auth_header access_token = get_token_from_auth_header( auth_header, create_if_not_exists=True) # otherwise we check if a session is active elif request and request.user.is_authenticated: access_token = get_token_object_from_session(request.session) # we extend the token in case the session is active but the token expired if access_token and access_token.is_expired(): extend_token(access_token) else: access_token = get_or_create_token(request.user) if access_token: headers['Authorization'] = 'Bearer %s' % access_token pragma = "no-cache" referer = request.META[ "HTTP_REFERER"] if "HTTP_REFERER" in request.META else \ "{scheme}://{netloc}/".format(scheme=site_url.scheme, netloc=site_url.netloc) encoding = request.META[ "HTTP_ACCEPT_ENCODING"] if "HTTP_ACCEPT_ENCODING" in request.META else "gzip" headers.update({ "Pragma": pragma, "Referer": referer, "Accept-encoding": encoding, }) return (headers, access_token)
def get_capabilities(request, layerid=None, user=None, mapid=None, category=None, tolerant=False): """ Compile a GetCapabilities document containing public layers filtered by layer, user, map, or category """ rootdoc = None layers = None cap_name = ' Capabilities - ' if layerid is not None: layer_obj = Layer.objects.get(id=layerid) cap_name += layer_obj.title layers = Layer.objects.filter(id=layerid) elif user is not None: layers = Layer.objects.filter(owner__username=user) cap_name += user elif category is not None: layers = Layer.objects.filter(category__identifier=category) cap_name += category elif mapid is not None: map_obj = Map.objects.get(id=mapid) cap_name += map_obj.title alternates = [] for layer in map_obj.layers: if layer.local: alternates.append(layer.name) layers = Layer.objects.filter(alternate__in=alternates) for layer in layers: if request.user.has_perm('view_resourcebase', layer.get_self_resource()): 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, access_token=access_token, tolerant=tolerant) if layercap: # 1st one, seed with real GetCapabilities doc try: namespaces = {'wms': 'http://www.opengis.net/wms', 'xlink': 'http://www.w3.org/1999/xlink', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'} layercap = etree.fromstring(layercap) rootdoc = etree.ElementTree(layercap) format_online_resource(workspace, layername, rootdoc, namespaces) service_name = rootdoc.find('.//wms:Service/wms:Name', namespaces) if service_name: service_name.text = cap_name rootdoc = rootdoc.find('.//wms:Capability/wms:Layer/wms:Layer', namespaces) except Exception as e: import traceback traceback.print_exc() logger.error( "Error occurred creating GetCapabilities for %s: %s" % (layer.typename, str(e))) rootdoc = None if not layercap or not rootdoc: # Get the required info from layer model # TODO: store time dimension on DB also tpl = get_template("geoserver/layer.xml") ctx = { 'layer': layer, 'geoserver_public_url': ogc_server_settings.public_url, 'catalogue_url': settings.CATALOGUE['default']['URL'], } gc_str = tpl.render(ctx) gc_str = gc_str.encode("utf-8", "replace") layerelem = etree.XML(gc_str) rootdoc = etree.ElementTree(layerelem) except Exception as e: import traceback traceback.print_exc() logger.error( "Error occurred creating GetCapabilities for %s:%s" % (layer.typename, str(e))) rootdoc = None if rootdoc is not None: capabilities = etree.tostring( rootdoc, xml_declaration=True, encoding='UTF-8', pretty_print=True) return HttpResponse(capabilities, content_type="text/xml") return HttpResponse(status=200)
def csw_global_dispatch(request): """pycsw wrapper""" # this view should only operate if pycsw_local is the backend # else, redirect to the URL of the non-pycsw_local backend if settings.CATALOGUE['default']['ENGINE'] != 'geonode.catalogue.backends.pycsw_local': return HttpResponseRedirect(settings.CATALOGUE['default']['URL']) mdict = dict(settings.PYCSW['CONFIGURATION'], **CONFIGURATION) access_token = None 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 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.update({'local.app_root': os.path.dirname(__file__), 'REQUEST_URI': absolute_uri, 'QUERY_STRING': query_string}) # Save original filter before doing anything mdict_filter = mdict['repository']['filter'] try: # Filter out Layers not accessible to the User authorized_ids = [] if request.user: profiles = Profile.objects.filter(username=str(request.user)) else: profiles = Profile.objects.filter(username="******") if profiles: authorized = list( get_objects_for_user( profiles[0], 'base.view_resourcebase').values('id')) layers = ResourceBase.objects.filter( id__in=[d['id'] for d in authorized]) if layers: authorized_ids = [d['id'] for d in authorized] if len(authorized_ids) > 0: authorized_layers = "(" + (", ".join(str(e) for e in authorized_ids)) + ")" authorized_layers_filter = "id IN " + authorized_layers mdict['repository']['filter'] += " AND " + authorized_layers_filter if request.user and request.user.is_authenticated: mdict['repository']['filter'] = "({}) OR ({})".format(mdict['repository']['filter'], authorized_layers_filter) else: authorized_layers_filter = "id = -9999" mdict['repository']['filter'] += " AND " + authorized_layers_filter # Filter out Documents and Maps if 'ALTERNATES_ONLY' in settings.CATALOGUE['default'] and settings.CATALOGUE['default']['ALTERNATES_ONLY']: mdict['repository']['filter'] += " AND alternate IS NOT NULL" # Filter out Layers belonging to specific Groups is_admin = False if request.user: is_admin = request.user.is_superuser if request.user else False if not is_admin and settings.GROUP_PRIVATE_RESOURCES: groups_ids = [] if request.user and request.user.is_authenticated: for group in request.user.groups.all(): groups_ids.append(group.id) group_list_all = [] try: group_list_all = request.user.group_list_all().values('group') except BaseException: pass for group in group_list_all: if isinstance(group, dict): if 'group' in group: groups_ids.append(group['group']) else: groups_ids.append(group.id) public_groups = GroupProfile.objects.exclude( access="private").values('group') for group in public_groups: if isinstance(group, dict): if 'group' in group: groups_ids.append(group['group']) else: groups_ids.append(group.id) if len(groups_ids) > 0: groups = "(" + (", ".join(str(e) for e in groups_ids)) + ")" groups_filter = "(group_id IS NULL OR group_id IN " + groups + ")" mdict['repository']['filter'] += " AND " + groups_filter else: groups_filter = "group_id IS NULL" mdict['repository']['filter'] += " AND " + groups_filter csw = server.Csw(mdict, env, version='2.0.2') content = csw.dispatch_wsgi() # pycsw 2.0 has an API break: # pycsw < 2.0: content = xml_response # pycsw >= 2.0: content = [http_status_code, content] # deal with the API break if isinstance(content, list): # pycsw 2.0+ content = content[1] spaces = {'csw': 'http://www.opengis.net/cat/csw/2.0.2', 'dc': 'http://purl.org/dc/elements/1.1/', 'dct': 'http://purl.org/dc/terms/', 'gmd': 'http://www.isotc211.org/2005/gmd', 'gml': 'http://www.opengis.net/gml', 'ows': 'http://www.opengis.net/ows', 'xs': 'http://www.w3.org/2001/XMLSchema', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance', 'ogc': 'http://www.opengis.net/ogc', 'gco': 'http://www.isotc211.org/2005/gco', 'gmi': 'http://www.isotc211.org/2005/gmi'} for prefix, uri in spaces.items(): ET.register_namespace(prefix, uri) if access_token and not access_token.is_expired(): tree = dlxml.fromstring(content) for online_resource in tree.findall( '*//gmd:CI_OnlineResource', spaces): try: linkage = online_resource.find('gmd:linkage', spaces) for url in linkage.findall('gmd:URL', spaces): if url.text: if '?' not in url.text: url.text += "?" else: url.text += "&" url.text += ("access_token=%s" % (access_token.token)) url.set('updated', 'yes') except BaseException: pass content = ET.tostring(tree, encoding='utf8', method='xml') finally: # Restore original filter before doing anything mdict['repository']['filter'] = mdict_filter return HttpResponse(content, content_type=csw.contenttype)
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): # 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') # 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 = list(_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', 'version': wms_version, 'request': 'GetMap', 'layers': layers, 'format': wms_format, # '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. _p = "&".join("%s=%s" % item for item in params.items()) import posixpath thumbnail_remote_url = posixpath.join(ogc_server_settings.PUBLIC_LOCATION, wms_endpoint) + "?" + _p 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)
def get_capabilities(request, layerid=None, user=None, mapid=None, category=None, tolerant=False): """ Compile a GetCapabilities document containing public layers filtered by layer, user, map, or category """ rootdoc = None layers = None cap_name = ' Capabilities - ' if layerid is not None: layer_obj = Layer.objects.get(id=layerid) cap_name += layer_obj.title layers = Layer.objects.filter(id=layerid) elif user is not None: layers = Layer.objects.filter(owner__username=user) cap_name += user elif category is not None: layers = Layer.objects.filter(category__identifier=category) cap_name += category elif mapid is not None: map_obj = Map.objects.get(id=mapid) cap_name += map_obj.title alternates = [] for layer in map_obj.layers: if layer.local: alternates.append(layer.name) layers = Layer.objects.filter(alternate__in=alternates) for layer in layers: if request.user.has_perm('view_resourcebase', layer.get_self_resource()): 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, access_token=access_token, tolerant=tolerant) if layercap: # 1st one, seed with real GetCapabilities doc try: namespaces = { 'wms': 'http://www.opengis.net/wms', 'xlink': 'http://www.w3.org/1999/xlink', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance' } layercap = dlxml.fromstring(layercap) rootdoc = etree.ElementTree(layercap) format_online_resource(workspace, layername, rootdoc, namespaces) service_name = rootdoc.find('.//wms:Service/wms:Name', namespaces) if service_name: service_name.text = cap_name rootdoc = rootdoc.find( './/wms:Capability/wms:Layer/wms:Layer', namespaces) except Exception as e: import traceback traceback.print_exc() logger.error( "Error occurred creating GetCapabilities for %s: %s" % (layer.typename, str(e))) rootdoc = None if not layercap or not rootdoc: # Get the required info from layer model # TODO: store time dimension on DB also tpl = get_template("geoserver/layer.xml") ctx = { 'layer': layer, 'geoserver_public_url': ogc_server_settings.public_url, 'catalogue_url': settings.CATALOGUE['default']['URL'], } gc_str = tpl.render(ctx) gc_str = gc_str.encode("utf-8", "replace") layerelem = etree.XML(gc_str) rootdoc = etree.ElementTree(layerelem) except Exception as e: import traceback traceback.print_exc() logger.error( "Error occurred creating GetCapabilities for %s:%s" % (layer.typename, str(e))) rootdoc = None if rootdoc is not None: capabilities = etree.tostring(rootdoc, xml_declaration=True, encoding='UTF-8', pretty_print=True) return HttpResponse(capabilities, content_type="text/xml") return HttpResponse(status=200)
def dataset_download(request, layername): try: dataset = _resolve_dataset( request, layername, 'base.download_resourcebase', _PERMISSION_MSG_GENERIC) except Exception as e: raise Http404(Exception(_("Not found"), e)) if not settings.USE_GEOSERVER: # if GeoServer is not used, we redirect to the proxy download return HttpResponseRedirect(reverse('download', args=[dataset.id])) download_format = request.GET.get('export_format') if download_format and not wps_format_is_supported(download_format, dataset.subtype): logger.error("The format provided is not valid for the selected resource") return JsonResponse({"error": "The format provided is not valid for the selected resource"}, status=500) _format = 'application/zip' if dataset.is_vector() else 'image/tiff' # getting default payload tpl = get_template("geoserver/dataset_download.xml") ctx = { "alternate": dataset.alternate, "download_format": download_format or _format } # applying context for the payload payload = tpl.render(ctx) # init of Client client = HttpClient() headers = { "Content-type": "application/xml", "Accept": "application/xml" } # defining the URL needed fr the download url = f"{settings.OGC_SERVER['default']['LOCATION']}ows?service=WPS&version=1.0.0&REQUEST=Execute" if not request.user.is_anonymous: # define access token for the user access_token = get_or_create_token(request.user) url += f"&access_token={access_token}" # request to geoserver response, content = client.request( url=url, data=payload, method="post", headers=headers ) if response.status_code != 200: logger.error(f"Download dataset exception: error during call with GeoServer: {response.content}") return JsonResponse( {"error": f"Download dataset exception: error during call with GeoServer: {response.content}"}, status=500 ) # error handling namespaces = {"ows": "http://www.opengis.net/ows/1.1", "wps": "http://www.opengis.net/wps/1.0.0"} response_type = response.headers.get('Content-Type') if response_type == 'text/xml': # parsing XML for get exception content = ET.fromstring(response.text) exc = content.find('*//ows:Exception', namespaces=namespaces) or content.find('ows:Exception', namespaces=namespaces) if exc: exc_text = exc.find('ows:ExceptionText', namespaces=namespaces) logger.error(f"{exc.attrib.get('exceptionCode')} {exc_text.text}") return JsonResponse({"error": f"{exc.attrib.get('exceptionCode')}: {exc_text.text}"}, status=500) return_response = fetch_response_headers( HttpResponse( content=response.content, status=response.status_code, content_type=download_format ), response.headers) return_response.headers['Content-Type'] = download_format or _format return return_response