Ejemplo n.º 1
0
def get():
    app.logger.info(f"GET Maps, actor={g.user}")

    actor = get_authn_username()
    return rest_common.get_publications(MAP_TYPE,
                                        actor,
                                        request_args=request.args)
Ejemplo n.º 2
0
def get():
    app.logger.info(f"GET Layers, user={g.user}")

    user = get_authn_username()
    return rest_common.get_publications(LAYER_TYPE,
                                        user,
                                        request_args=request.args)
Ejemplo n.º 3
0
def get(workspace):
    app.logger.info(f"GET Maps, user={g.user}")

    user = get_authn_username()
    return rest_common.get_publications(MAP_TYPE,
                                        user,
                                        request_args=request.args,
                                        workspace=workspace)
Ejemplo n.º 4
0
def get(workspace):
    app.logger.info(f"GET Layers, actor={g.user}")

    actor = get_authn_username()
    return rest_common.get_publications(LAYER_TYPE,
                                        actor,
                                        request_args=request.args,
                                        workspace=workspace)
Ejemplo n.º 5
0
def proxy(subpath):
    app.logger.info(
        f"{request.method} GeoServer proxy, user={g.user}, subpath={subpath}, url={request.url}, request.query_string={request.query_string.decode('UTF-8')}"
    )

    url = settings.LAYMAN_GS_URL + subpath + '?' + request.query_string.decode(
        'UTF-8')
    headers_req = {
        key.lower(): value
        for (key, value) in request.headers if key.lower() not in
        ['host',
         settings.LAYMAN_GS_AUTHN_HTTP_HEADER_ATTRIBUTE.lower()]
    }
    data = request.get_data()
    authn_username = authn.get_authn_username()
    if is_user_with_name(authn_username):
        headers_req[
            settings.LAYMAN_GS_AUTHN_HTTP_HEADER_ATTRIBUTE] = authn_username

    app.logger.info(
        f"{request.method} GeoServer proxy, headers_req={headers_req}, url={url}"
    )
    wfs_t_layers = set()
    if data is not None and len(data) > 0:
        try:
            wfs_t_attribs, wfs_t_layers = extract_attributes_and_layers_from_wfs_t(
                data)
            if wfs_t_attribs:
                ensure_wfs_t_attributes(wfs_t_attribs)
        except BaseException as err:
            app.logger.warning(
                f"WFS Proxy: error={err}, trace={traceback.format_exc()}")
    response = requests.request(method=request.method,
                                url=url,
                                data=data,
                                headers=headers_req,
                                cookies=request.cookies,
                                allow_redirects=False)

    if response.status_code == 200:
        for workspace, layername in wfs_t_layers:
            if authz.can_i_edit(LAYER_TYPE, workspace, layername):
                patch_after_feature_change(workspace, layername)

    excluded_headers = [
        'content-encoding', 'content-length', 'transfer-encoding', 'connection'
    ]
    headers = {
        key: value
        for (key, value) in response.headers.items()
        if key.lower() not in excluded_headers
    }

    final_response = Response(response.content, response.status_code, headers)
    return final_response
Ejemplo n.º 6
0
def delete_publications(
    user,
    publ_type,
    is_chain_ready_fn,
    abort_publication_fn,
    delete_publication_fn,
    method,
    url_path,
    publ_param,
):
    from layman import authn
    actor_name = authn.get_authn_username()
    whole_infos = get_publication_infos(user, publ_type, {
        'actor_name': actor_name,
        'access_type': 'write'
    })

    for (_, _, publication) in whole_infos.keys():
        redis.create_lock(user, publ_type, publication, method)
        try:
            abort_publication_fn(user, publication)
            delete_publication_fn(user, publication)
            if is_chain_ready_fn(user, publication):
                redis.unlock_publication(user, publ_type, publication)
        except Exception as exc:
            try:
                if is_chain_ready_fn(user, publication):
                    redis.unlock_publication(user, publ_type, publication)
            finally:
                redis.unlock_publication(user, publ_type, publication)
            raise exc

    infos = [{
        'name':
        info["name"],
        'title':
        info.get("title", None),
        'url':
        url_for(**{
            'endpoint': url_path,
            publ_param: name,
            'workspace': user
        }),
        'uuid':
        info["uuid"],
        'access_rights':
        info['access_rights'],
    } for (name, info) in whole_infos.items()]
    return jsonify(infos)
Ejemplo n.º 7
0
    def decorated_function(*args, **kwargs):
        # print(f"authorize ARGS {args} KWARGS {kwargs}")
        req_path = request.script_root + request.path
        (workspace, publication_type,
         publication_name) = parse_request_path(req_path)
        if publication_type is None or workspace or publication_name:
            raise Exception(
                f"Authorization module is unable to authorize path {req_path}")
        actor_name = authn.get_authn_username()
        if request.method.lower() == common.REQUEST_METHOD_GET:
            # pylint: disable=unused-variable
            @after_this_request
            def authorize_after_request_tmp(response):
                return authorize_after_multi_get_request(actor_name, response)

        return func(*args, **kwargs)
Ejemplo n.º 8
0
def reserve_username(username, adjust=False):
    current_username = authn.get_authn_username()
    if is_user_with_name(current_username):
        raise LaymanError(34, {'username': current_username})
    if adjust is not True:
        check_workspace_name(username)
        workspaces = get_workspaces()
        if username in workspaces:
            raise LaymanError(35)
        try:
            ensure_whole_user(username)
            claims = get_open_id_claims()
            _save_reservation(username, claims)
        except LaymanError as exc:
            delete_whole_user(username)
            raise exc
        return
    claims = get_open_id_claims()
    suggestions = [username] + get_username_suggestions_from_claims(claims)
    suggestions = [
        slugify(s) for s in suggestions if s is not None and len(s) > 0
    ]
    suggestions = to_safe_names(suggestions, 'user')
    workspaces = get_workspaces()
    username = None
    idx = 0
    while True:
        for suggestion in suggestions:
            if idx > 0:
                suggestion = f"{suggestion}{idx}"
            try:
                check_workspace_name(suggestion)
            except LaymanError as exc:
                if not (exc.code == 2 or exc.code == 35):
                    raise exc
            if suggestion in workspaces:
                continue
            try:
                ensure_whole_user(suggestion)
                username = suggestion
                _save_reservation(username, claims)
                break
            except LaymanError:
                delete_whole_user(suggestion)
        if username is not None:
            break
        idx += 1
Ejemplo n.º 9
0
def patch(workspace, layername):
    app.logger.info(f"PATCH Layer, actor={g.user}")

    info = util.get_complete_layer_info(cached=True)
    kwargs = {
        'title': info.get('title', info['name']) or '',
        'description': info.get('description', '') or '',
    }

    # FILE
    sent_file_streams = []
    sent_file_paths = []
    if 'file' in request.files:
        sent_file_streams = [
            f for f in request.files.getlist("file") if len(f.filename) > 0
        ]
    if len(sent_file_streams) == 0 and len(request.form.getlist('file')) > 0:
        sent_file_paths = [
            filename for filename in request.form.getlist('file')
            if len(filename) > 0
        ]
    input_files = fs_util.InputFiles(sent_streams=sent_file_streams,
                                     sent_paths=sent_file_paths)

    # CRS
    crs_id = None
    if len(input_files.raw_paths) > 0 and len(request.form.get('crs', '')) > 0:
        crs_id = request.form['crs']
        if crs_id not in settings.INPUT_SRS_LIST:
            raise LaymanError(2, {
                'parameter': 'crs',
                'supported_values': settings.INPUT_SRS_LIST
            })
    check_crs = crs_id is None

    # TITLE
    if len(request.form.get('title', '')) > 0:
        kwargs['title'] = request.form['title']

    # DESCRIPTION
    if len(request.form.get('description', '')) > 0:
        kwargs['description'] = request.form['description']

    # SLD
    style_file = None
    if 'style' in request.files and not request.files['style'].filename == '':
        style_file = request.files['style']
    elif 'sld' in request.files and not request.files['sld'].filename == '':
        style_file = request.files['sld']

    delete_from = None
    style_type = None
    if style_file:
        style_type = input_style.get_style_type_from_file_storage(style_file)
        kwargs['style_type'] = style_type
        kwargs['store_in_geoserver'] = style_type.store_in_geoserver
        delete_from = 'layman.layer.qgis.wms'
    if len(input_files.raw_paths) > 0:
        delete_from = 'layman.layer.filesystem.input_file'

    # FILE NAMES
    use_chunk_upload = bool(input_files.sent_paths)
    if delete_from == 'layman.layer.filesystem.input_file':
        if not (use_chunk_upload and input_files.is_one_archive):
            input_file.check_filenames(workspace,
                                       layername,
                                       input_files,
                                       check_crs,
                                       ignore_existing_files=True)
        # file checks
        if not use_chunk_upload:
            temp_dir = tempfile.mkdtemp(prefix="layman_")
            input_file.save_layer_files(workspace,
                                        layername,
                                        input_files,
                                        check_crs,
                                        output_dir=temp_dir)

    if input_files.raw_paths:
        file_type = input_file.get_file_type(
            input_files.raw_or_archived_main_file_path)
    else:
        file_type = layman_util.get_publication_info(workspace,
                                                     LAYER_TYPE,
                                                     layername,
                                                     context={
                                                         'keys': ['file']
                                                     })['file']['file_type']
    if style_type:
        style_type_for_check = style_type.code
    else:
        style_type_for_check = layman_util.get_publication_info(
            workspace, LAYER_TYPE, layername,
            context={'keys': ['style_type']})['style_type']
    if file_type == settings.FILE_TYPE_RASTER and style_type_for_check == 'qml':
        raise LaymanError(48,
                          f'Raster layers are not allowed to have QML style.')

    props_to_refresh = util.get_same_or_missing_prop_names(
        workspace, layername)
    kwargs['metadata_properties_to_refresh'] = props_to_refresh

    layer_result = {}

    if delete_from is not None:
        request_method = request.method.lower()
        deleted = util.delete_layer(workspace,
                                    layername,
                                    source=delete_from,
                                    http_method=request_method)
        if style_file is None:
            try:
                style_file = deleted['style']['file']
            except KeyError:
                pass
        style_type = input_style.get_style_type_from_file_storage(style_file)
        kwargs['style_type'] = style_type
        kwargs['store_in_geoserver'] = style_type.store_in_geoserver
        if style_file:
            input_style.save_layer_file(workspace, layername, style_file,
                                        style_type)

        kwargs.update({
            'crs_id': crs_id,
            'http_method': request_method,
            'metadata_properties_to_refresh': props_to_refresh,
        })

        if delete_from == 'layman.layer.filesystem.input_file':

            if use_chunk_upload:
                files_to_upload = input_chunk.save_layer_files_str(
                    workspace, layername, input_files, check_crs)
                layer_result.update({
                    'files_to_upload': files_to_upload,
                })
                kwargs.update({
                    'check_crs': check_crs,
                })
            else:
                shutil.move(
                    temp_dir,
                    input_file.get_layer_input_file_dir(workspace, layername))
    kwargs.update({'actor_name': authn.get_authn_username()})

    rest_util.setup_patch_access_rights(request.form, kwargs)
    util.pre_publication_action_check(
        workspace,
        layername,
        kwargs,
    )

    util.patch_layer(
        workspace, layername, kwargs, delete_from,
        'layman.layer.filesystem.input_chunk'
        if use_chunk_upload else delete_from)

    app.logger.info('PATCH Layer changes done')
    info = util.get_complete_layer_info(workspace, layername)
    info.update(layer_result)

    return jsonify(info), 200
Ejemplo n.º 10
0
def patch(workspace, layername):
    app.logger.info(f"PATCH Layer, user={g.user}")

    info = util.get_complete_layer_info(cached=True)
    kwargs = {
        'title': info.get('title', info['name']),
        'description': info.get('description', ''),
    }

    # FILE
    use_chunk_upload = False
    files = []
    if 'file' in request.files:
        files = [
            f for f in request.files.getlist("file")
            if len(f.filename) > 0
        ]
    if len(files) == 0 and len(request.form.getlist('file')) > 0:
        files = [
            filename for filename in request.form.getlist('file')
            if len(filename) > 0
        ]
        if len(files) > 0:
            use_chunk_upload = True

    # CRS
    crs_id = None
    if len(files) > 0 and len(request.form.get('crs', '')) > 0:
        crs_id = request.form['crs']
        if crs_id not in settings.INPUT_SRS_LIST:
            raise LaymanError(2, {'parameter': 'crs', 'supported_values': settings.INPUT_SRS_LIST})
    check_crs = crs_id is None

    # TITLE
    if len(request.form.get('title', '')) > 0:
        kwargs['title'] = request.form['title']

    # DESCRIPTION
    if len(request.form.get('description', '')) > 0:
        kwargs['description'] = request.form['description']

    # SLD
    style_file = None
    if 'style' in request.files and not request.files['style'].filename == '':
        style_file = request.files['style']
    elif 'sld' in request.files and not request.files['sld'].filename == '':
        style_file = request.files['sld']

    delete_from = None
    if style_file:
        style_type = input_style.get_style_type_from_file_storage(style_file)
        kwargs['style_type'] = style_type
        kwargs['store_in_geoserver'] = style_type.store_in_geoserver
        delete_from = 'layman.layer.qgis.wms'
    if len(files) > 0:
        delete_from = 'layman.layer.filesystem.input_file'

    # FILE NAMES
    if delete_from == 'layman.layer.filesystem.input_file':
        if use_chunk_upload:
            filenames = files
        else:
            filenames = [f.filename for f in files]
        input_file.check_filenames(workspace, layername, filenames,
                                   check_crs, ignore_existing_files=True)

    props_to_refresh = util.get_same_or_missing_prop_names(workspace, layername)
    kwargs['metadata_properties_to_refresh'] = props_to_refresh

    layer_result = {}

    if delete_from is not None:
        request_method = request.method.lower()
        deleted = util.delete_layer(workspace, layername, source=delete_from, http_method=request_method)
        if style_file is None:
            try:
                style_file = deleted['style']['file']
            except KeyError:
                pass
        style_type = input_style.get_style_type_from_file_storage(style_file)
        kwargs['style_type'] = style_type
        kwargs['store_in_geoserver'] = style_type.store_in_geoserver
        if style_file:
            input_style.save_layer_file(workspace, layername, style_file, style_type)

        kwargs.update({
            'crs_id': crs_id,
            'ensure_user': False,
            'http_method': request_method,
            'metadata_properties_to_refresh': props_to_refresh,
        })

        if delete_from == 'layman.layer.filesystem.input_file':

            if use_chunk_upload:
                files_to_upload = input_chunk.save_layer_files_str(
                    workspace, layername, files, check_crs)
                layer_result.update({
                    'files_to_upload': files_to_upload,
                })
                kwargs.update({
                    'check_crs': check_crs,
                })
            else:
                input_file.save_layer_files(
                    workspace, layername, files, check_crs)
    kwargs.update({'actor_name': authn.get_authn_username()})

    rest_util.setup_patch_access_rights(request.form, kwargs)
    util.pre_publication_action_check(workspace,
                                      layername,
                                      kwargs,
                                      )

    util.patch_layer(
        workspace,
        layername,
        kwargs,
        delete_from,
        'layman.layer.filesystem.input_chunk' if use_chunk_upload else delete_from
    )

    app.logger.info('PATCH Layer changes done')
    info = util.get_complete_layer_info(workspace, layername)
    info.update(layer_result)

    return jsonify(info), 200
Ejemplo n.º 11
0
def patch(workspace, mapname):
    app.logger.info(f"PATCH Map, user={g.user}")

    info = util.get_complete_map_info(cached=True)

    # FILE
    file = None
    file_json = {}
    if 'file' in request.files and not request.files['file'].filename == '':
        file = request.files["file"]
    if file is not None:
        file_json = util.check_file(file)

    # TITLE
    if len(request.form.get('title', '')) > 0:
        title = request.form['title']
    elif len(file_json.get('title', '')) > 0:
        title = file_json['title']
    else:
        title = info['title']

    # DESCRIPTION
    if len(request.form.get('description', '')) > 0:
        description = request.form['description']
    elif len(file_json.get('abstract', '')) > 0:
        description = file_json['abstract']
    else:
        description = info['description']

    props_to_refresh = util.get_same_or_missing_prop_names(workspace, mapname)
    metadata_properties_to_refresh = props_to_refresh
    if file is not None:
        thumbnail.delete_map(workspace, mapname)
        file = FileStorage(io.BytesIO(json.dumps(file_json).encode()),
                           file.filename)
        input_file.save_map_files(workspace, mapname, [file])

    file_changed = file is not None
    kwargs = {
        'title': title,
        'description': description,
        'file_changed': file_changed,
        'http_method': 'patch',
        'metadata_properties_to_refresh': metadata_properties_to_refresh,
        'actor_name': authn.get_authn_username(),
    }

    rest_util.setup_patch_access_rights(request.form, kwargs)
    util.pre_publication_action_check(
        workspace,
        mapname,
        kwargs,
    )

    util.patch_map(
        workspace, mapname, kwargs,
        'layman.map.filesystem.input_file' if file_changed else None)

    info = util.get_complete_map_info(workspace, mapname)

    return jsonify(info), 200
Ejemplo n.º 12
0
def can_i_edit(publ_type, workspace, publication_name):
    actor_name = authn.get_authn_username()
    return can_user_write_publication(actor_name, workspace, publ_type,
                                      publication_name)
Ejemplo n.º 13
0
def post(workspace):
    app.logger.info(f"POST Layers, user={g.user}")

    # FILE
    use_chunk_upload = False
    files = []
    if 'file' in request.files:
        files = [
            f for f in request.files.getlist("file")
            if len(f.filename) > 0
        ]
    if len(files) == 0 and len(request.form.getlist('file')) > 0:
        files = [
            filename for filename in request.form.getlist('file')
            if len(filename) > 0
        ]
        if len(files) > 0:
            use_chunk_upload = True
    if len(files) == 0:
        raise LaymanError(1, {'parameter': 'file'})

    # NAME
    unsafe_layername = request.form.get('name', '')
    if len(unsafe_layername) == 0:
        unsafe_layername = input_file.get_unsafe_layername(files)
    layername = util.to_safe_layer_name(unsafe_layername)
    util.check_layername(layername)
    info = util.get_layer_info(workspace, layername)
    if info:
        raise LaymanError(17, {'layername': layername})
    util.check_new_layername(workspace, layername)

    # CRS
    crs_id = None
    if len(request.form.get('crs', '')) > 0:
        crs_id = request.form['crs']
        if crs_id not in settings.INPUT_SRS_LIST:
            raise LaymanError(2, {'parameter': 'crs', 'supported_values': settings.INPUT_SRS_LIST})
    check_crs = crs_id is None

    # TITLE
    if len(request.form.get('title', '')) > 0:
        title = request.form['title']
    else:
        title = layername

    # DESCRIPTION
    description = request.form.get('description', '')

    # Style
    style_file = None
    if 'style' in request.files and not request.files['style'].filename == '':
        style_file = request.files['style']
    elif 'sld' in request.files and not request.files['sld'].filename == '':
        style_file = request.files['sld']
    style_type = input_style.get_style_type_from_file_storage(style_file)

    actor_name = authn.get_authn_username()

    task_options = {
        'crs_id': crs_id,
        'description': description,
        'title': title,
        'ensure_user': True,
        'check_crs': False,
        'actor_name': actor_name,
        'style_type': style_type,
        'store_in_geoserver': style_type.store_in_geoserver,
    }

    rest_common.setup_post_access_rights(request.form, task_options, actor_name)
    util.pre_publication_action_check(workspace,
                                      layername,
                                      task_options,
                                      )

    layerurl = url_for('rest_workspace_layer.get', layername=layername, workspace=workspace)

    layer_result = {
        'name': layername,
        'url': layerurl,
    }

    # FILE NAMES
    if use_chunk_upload:
        filenames = files
    else:
        filenames = [f.filename for f in files]
    input_file.check_filenames(workspace, layername, filenames, check_crs)

    redis_util.create_lock(workspace, LAYER_TYPE, layername, request.method)

    try:
        # register layer uuid
        uuid_str = uuid.assign_layer_uuid(workspace, layername)
        layer_result.update({
            'uuid': uuid_str,
        })
        task_options.update({'uuid': uuid_str, })

        # save files
        input_style.save_layer_file(workspace, layername, style_file, style_type)
        if use_chunk_upload:
            files_to_upload = input_chunk.save_layer_files_str(
                workspace, layername, files, check_crs)
            layer_result.update({
                'files_to_upload': files_to_upload,
            })
            task_options.update({
                'check_crs': check_crs,
            })
        else:
            input_file.save_layer_files(
                workspace, layername, files, check_crs)

        util.post_layer(
            workspace,
            layername,
            task_options,
            'layman.layer.filesystem.input_chunk' if use_chunk_upload else 'layman.layer.filesystem.input_file'
        )
    except Exception as exc:
        try:
            if util.is_layer_chain_ready(workspace, layername):
                redis_util.unlock_publication(workspace, LAYER_TYPE, layername)
        finally:
            redis_util.unlock_publication(workspace, LAYER_TYPE, layername)
        raise exc

    # app.logger.info('uploaded layer '+layername)
    return jsonify([layer_result]), 200
Ejemplo n.º 14
0
def proxy(subpath):
    app.logger.info(
        f"{request.method} GeoServer proxy, actor={g.user}, subpath={subpath}, url={request.url}, request.query_string={request.query_string.decode('UTF-8')}"
    )

    # adjust authentication headers
    url = settings.LAYMAN_GS_URL + subpath
    query_params_string = request.query_string.decode('UTF-8')
    headers_req = {
        key.lower(): value
        for (key, value) in request.headers if key.lower() not in
        ['host',
         settings.LAYMAN_GS_AUTHN_HTTP_HEADER_ATTRIBUTE.lower()]
    }
    data = request.get_data()
    authn_username = authn.get_authn_username()
    if is_user_with_name(authn_username):
        headers_req[
            settings.LAYMAN_GS_AUTHN_HTTP_HEADER_ATTRIBUTE] = authn_username

    # ensure layer attributes in case of WFS-T
    app.logger.info(
        f"{request.method} GeoServer proxy, headers_req={headers_req}, url={url}"
    )
    wfs_t_layers = set()
    if data is not None and len(data) > 0:
        try:
            wfs_t_attribs, wfs_t_layers = extract_attributes_and_layers_from_wfs_t(
                data)
            if wfs_t_attribs:
                ensure_wfs_t_attributes(wfs_t_attribs)
        except BaseException as err:
            app.logger.warning(
                f"WFS Proxy: error={err}, trace={traceback.format_exc()}")

    query_params = CaseInsensitiveDict(request.args.to_dict())

    # change CRS:84 to EPSG:4326 if one of SLD layers has native CRS EPSG:5514
    # otherwise layers are shifted by hundreds of meters, we are not sure about the reason
    if query_params.get('service') == 'WMS' and query_params.get('request') == 'GetMap'\
       and (query_params.get('crs') or query_params.get('srs')) == crs_def.CRS_84:
        layers = [
            layer.split(':') for layer in query_params.get('layers').split(',')
        ]
        url_workspace = extract_workspace_from_url(subpath)
        layers = [
            layer if len(layer) == 2 else [url_workspace] + layer
            for layer in layers
        ]
        fix_params = False
        for geoserver_workspace, layer in layers:
            workspace = gs_wms.get_layman_workspace(geoserver_workspace)
            publ_info = layman_util.get_publication_info(
                workspace, LAYER_TYPE, layer,
                {'keys': ['native_crs', 'style_type']})
            if publ_info and publ_info.get(
                    'native_crs') == crs_def.EPSG_5514 and publ_info.get(
                        'style_type') == 'sld':
                fix_params = True
                break

        if fix_params:
            if query_params.get('crs') == crs_def.CRS_84:
                param_key = 'crs'
                bbox = query_params['bbox'].split(',')
                bbox = [bbox[1], bbox[0], bbox[3], bbox[2]]
                query_params['bbox'] = ",".join(bbox)
            else:
                param_key = 'srs'

            query_params[param_key] = crs_def.EPSG_4326
            query_params_string = parse.urlencode(query_params)

    url += '?' + query_params_string

    app.logger.info(f"{request.method} GeoServer proxy, final_url={url}")

    response = requests.request(method=request.method,
                                url=url,
                                data=data,
                                headers=headers_req,
                                cookies=request.cookies,
                                allow_redirects=False)

    if response.status_code == 200:
        for workspace, layername in wfs_t_layers:
            file_info = layman_util.get_publication_info(
                workspace, LAYER_TYPE, layername, context={'keys':
                                                           ['file']})['file']
            if authz.can_i_edit(
                    LAYER_TYPE, workspace, layername
            ) and file_info['file_type'] == settings.FILE_TYPE_VECTOR:
                patch_after_feature_change(workspace, layername)

    excluded_headers = [
        'content-encoding', 'content-length', 'transfer-encoding', 'connection'
    ]
    headers = {
        key: value
        for (key, value) in response.headers.items()
        if key.lower() not in excluded_headers
    }

    final_response = Response(response.content, response.status_code, headers)
    return final_response
Ejemplo n.º 15
0
def post(workspace):
    app.logger.info(f"POST Maps, user={g.user}")

    # FILE
    if 'file' in request.files and not request.files['file'].filename == '':
        file = request.files["file"]
    else:
        raise LaymanError(1, {'parameter': 'file'})
    file_json = util.check_file(file)

    # NAME
    unsafe_mapname = request.form.get('name', '')
    if len(unsafe_mapname) == 0:
        unsafe_mapname = input_file.get_unsafe_mapname(file_json)
    mapname = util.to_safe_map_name(unsafe_mapname)
    util.check_mapname(mapname)
    info = util.get_map_info(workspace, mapname)
    if info:
        raise LaymanError(24, {'mapname': mapname})

    # TITLE
    if len(request.form.get('title', '')) > 0:
        title = request.form['title']
    elif len(file_json.get('title', '')) > 0:
        title = file_json['title']
    else:
        title = mapname

    # DESCRIPTION
    if len(request.form.get('description', '')) > 0:
        description = request.form['description']
    else:
        description = file_json.get('abstract', '')

    mapurl = url_for('rest_workspace_map.get',
                     mapname=mapname,
                     workspace=workspace)

    redis_util.create_lock(workspace, MAP_TYPE, mapname, request.method)

    try:
        map_result = {
            'name': mapname,
            'url': mapurl,
        }

        actor_name = authn.get_authn_username()

        kwargs = {
            'title': title,
            'description': description,
            'actor_name': actor_name
        }

        rest_common.setup_post_access_rights(request.form, kwargs, actor_name)
        util.pre_publication_action_check(
            workspace,
            mapname,
            kwargs,
        )
        # register map uuid
        uuid_str = uuid.assign_map_uuid(workspace, mapname)
        kwargs['uuid'] = uuid_str

        map_result.update({
            'uuid': uuid_str,
        })

        file = FileStorage(io.BytesIO(json.dumps(file_json).encode()),
                           file.filename)
        input_file.save_map_files(workspace, mapname, [file])

        util.post_map(workspace, mapname, kwargs,
                      'layman.map.filesystem.input_file')
    except Exception as exception:
        try:
            if util.is_map_chain_ready(workspace, mapname):
                redis_util.unlock_publication(workspace, MAP_TYPE, mapname)
        finally:
            redis_util.unlock_publication(workspace, MAP_TYPE, mapname)
        raise exception

    # app.logger.info('uploaded map '+mapname)
    return jsonify([map_result]), 200