Skip to content

Commit

Permalink
fix: support symlinked /files directory (#18702)
Browse files Browse the repository at this point in the history
Easiest way to move site/files or site/private directories is to symlink
them, the validation for file path was failing because it resolves only
until site path.

Resolving real path doesn't seem to be _REALLY_ required here.

(cherry picked from commit 56640a0)

Co-authored-by: Ankush Menat <ankush@frappe.io>
  • Loading branch information
mergify[bot] and ankush committed Nov 1, 2022
1 parent 18fa732 commit 7b8cbd0
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
30 changes: 30 additions & 0 deletions frappe/core/doctype/file/test_file.py
Expand Up @@ -3,6 +3,8 @@
import base64
import json
import os
import shutil
import tempfile
from contextlib import contextmanager
from typing import TYPE_CHECKING

Expand Down Expand Up @@ -519,6 +521,34 @@ def test_create_file_without_file_url(self):
).insert()
assert test_file is not None

def test_symlinked_files_folder(self):
files_dir = os.path.abspath(get_files_path())
with convert_to_symlink(files_dir):
file = frappe.get_doc(
{
"doctype": "File",
"file_name": "symlinked_folder_test.txt",
"content": "42",
}
)
file.save()
file.content = ""
file._content = ""
file.save().reload()
self.assertIn("42", file.get_content())


@contextmanager
def convert_to_symlink(directory):
"""Moves a directory to temp directory and symlinks original path for testing"""
try:
new_directory = shutil.move(directory, tempfile.mkdtemp())
os.symlink(new_directory, directory)
yield
finally:
os.unlink(directory)
shutil.move(new_directory, directory)


class TestAttachment(FrappeTestCase):
test_doctype = "Test For Attachment"
Expand Down
4 changes: 2 additions & 2 deletions frappe/utils/file_manager.py
Expand Up @@ -457,7 +457,7 @@ def is_safe_path(path: str) -> bool:

basedir = frappe.get_site_path()
# ref: https://docs.python.org/3/library/os.path.html#os.path.commonpath
matchpath = os.path.realpath(os.path.abspath(path))
basedir = os.path.realpath(os.path.abspath(basedir))
matchpath = os.path.abspath(path)
basedir = os.path.abspath(basedir)

return basedir == os.path.commonpath((basedir, matchpath))

0 comments on commit 7b8cbd0

Please sign in to comment.