CREATE OR REPLACE FUNCTION utils.move_processed_file(
p_folder text,
p_file_name text
)
RETURNS text
LANGUAGE plpython3u
SECURITY DEFINER
AS $function$
import os
if not p_folder or not p_file_name:
plpy.error("Не указана папка или имя файла")
# Имя должно содержать только название файла.
if (
p_file_name in (".", "..")
or "/" in p_file_name
or "\\" in p_file_name
):
plpy.error("Недопустимое имя файла")
rows = plpy.execute(
"SELECT value FROM robot.params WHERE name = 'root'",
1
)
if not rows or not rows[0]["value"]:
plpy.error("Не задан robot.params.root")
root = os.path.realpath(rows[0]["value"])
source_dir = os.path.realpath(os.path.join(root, p_folder))
# Разрешены только папки внутри настроенного корня.
if (
os.path.isabs(p_folder)
or os.path.commonpath([root, source_dir]) != root
):
plpy.error("Папка находится вне robot.params.root")
source_file = os.path.join(source_dir, p_file_name)
target_dir = os.path.realpath(
os.path.join(source_dir, "Обработано")
)
if os.path.commonpath([source_dir, target_dir]) != source_dir:
plpy.error("Подпапка Обработано находится вне исходной папки")
target_file = os.path.join(target_dir, p_file_name)
if not os.path.isfile(source_file):
plpy.error("Исходный файл не найден: " + source_file)
if os.path.islink(source_file):
plpy.error("Перемещение символической ссылки запрещено")
try:
os.makedirs(target_dir, exist_ok=True)
if os.path.lexists(target_file):
plpy.error(
"В папке Обработано уже есть файл: " + p_file_name
)
os.rename(source_file, target_file)
except OSError as exc:
plpy.error("Ошибка перемещения файла: " + str(exc))
return target_file
$function$;