pull/1900/head
grossmj 3 years ago
parent 6294ad9e76
commit 9a6978902d

@ -494,14 +494,8 @@ class BaseManager:
if re.match(r"^[A-Z]:", path) is not None:
raise NodeError("{} is not allowed on this remote server. Please only use a file from '{}'".format(path, img_directory))
# For local server we allow using absolute path outside image directory
if server_config.getboolean("local", False) is True:
log.debug("Searching for '{}'".format(orig_path))
path = force_unix_path(path)
if os.path.exists(path):
return path
raise ImageMissingError(orig_path)
else:
if not os.path.isabs(orig_path):
for directory in valid_directory_prefices:
log.debug("Searching for image '{}' in '{}'".format(orig_path, directory))
path = self._recursive_search_file_in_directory(directory, orig_path)
@ -512,11 +506,9 @@ class BaseManager:
log.debug("Searching for image '{}' in default directory".format(orig_path))
# check that the image path is in the default image directory
requested_path = os.path.relpath(orig_path, start=img_directory)
requested_path = os.path.abspath(requested_path)
common_prefix = os.path.commonprefix([requested_path, img_directory])
if common_prefix != img_directory:
raise NodeError("{} is not allowed. Please only use a file from '{}'".format(orig_path, img_directory))
#common_prefix = os.path.commonprefix([orig_path, img_directory])
#if common_prefix != img_directory:
# raise NodeError("{} is not allowed. Please only use a file from '{}'".format(orig_path, img_directory))
s = os.path.split(orig_path)
path = force_unix_path(os.path.join(img_directory, *s))
@ -524,6 +516,24 @@ class BaseManager:
return path
raise ImageMissingError(orig_path)
# For local server we allow using absolute path outside image directory
if server_config.getboolean("local", False) is True:
log.debug("Searching for '{}'".format(orig_path))
path = force_unix_path(path)
if os.path.exists(path):
return path
raise ImageMissingError(orig_path)
path = force_unix_path(path)
for directory in valid_directory_prefices:
log.debug("Searching for image '{}' in '{}'".format(orig_path, directory))
if os.path.commonprefix([directory, path]) == directory:
if os.path.exists(path):
return path
raise ImageMissingError(orig_path)
raise NodeError("{} is not allowed on this remote server. Please only use a file from '{}'"
.format(path, img_directory))
def _recursive_search_file_in_directory(self, directory, searched_file):
"""
Search for a file in directory and is subdirectories
@ -535,7 +545,7 @@ class BaseManager:
for root, dirs, files in os.walk(directory):
for file in files:
# If filename is the same
if s[1] == file and (s[0] == '' or s[0] == os.path.basename(root)):
if s[1] == file and (s[0] == '' or os.path.basename(s[0]) == os.path.basename(root)):
path = os.path.normpath(os.path.join(root, s[1]))
if os.path.exists(path):
return path

@ -422,7 +422,6 @@ class NodeHandler:
response.enable_chunked_encoding()
await response.prepare(request)
await response.write(res.body)
# await response.write_eof() #FIXME: shound't be needed anymore
@Route.post(
r"/projects/{project_id}/nodes/{node_id}/files/{path:.+}",

@ -43,8 +43,7 @@ def is_safe_path(file_path, directory):
(the file is stored inside directory or one of its sub-directory)
"""
requested_path = os.path.relpath(file_path, start=directory)
requested_path = os.path.abspath(requested_path)
requested_path = os.path.abspath(file_path)
common_prefix = os.path.commonprefix([requested_path, directory])
return common_prefix != directory

@ -172,7 +172,7 @@ async def test_write_file(compute_api, tmpdir):
project = ProjectManager.instance().create_project(project_id="01010203-0405-0607-0809-0a0b0c0d0e0b")
response = await compute_api.post("/projects/{project_id}/files/hello".format(project_id=project.id), body="world", raw=True)
assert response.status == 200
assert response.status == 201
with open(os.path.join(project.path, "hello")) as f:
assert f.read() == "world"

@ -108,7 +108,7 @@ async def test_qemu_create_with_params(compute_api, compute_project, base_params
async def test_qemu_create_with_project_file(compute_api, compute_project, base_params, fake_qemu_vm):
response = await compute_api.post("/projects/{project_id}/files/hello.img".format(project_id=compute_project.id), body="world", raw=True)
assert response.status == 200
assert response.status == 201
params = base_params
params["hda_disk_image"] = "hello.img"
response = await compute_api.post("/projects/{project_id}/qemu/nodes".format(project_id=compute_project.id), params)
@ -278,7 +278,6 @@ async def test_images(compute_api, fake_qemu_vm):
response = await compute_api.get("/qemu/images")
assert response.status == 200
assert {"filename": "linux载.img", "path": "linux载.img", "md5sum": "c4ca4238a0b923820dcc509a6f75849b", "filesize": 1} in response.json
assert {'filename': 'config.img', 'filesize': 1048576, 'md5sum': '0ab49056760ae1db6c25376446190b47', 'path': 'config.img'} in response.json
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Does not work on Windows")

@ -218,6 +218,7 @@ async def test_get_file(controller_api, project, node, compute):
response = MagicMock()
response.body = b"world"
response.status = 200
compute.http_query = AsyncioMagicMock(return_value=response)
response = await controller_api.get("/projects/{project_id}/nodes/{node_id}/files/hello".format(project_id=project.id, node_id=node.id))
@ -232,7 +233,9 @@ async def test_get_file(controller_api, project, node, compute):
async def test_post_file(controller_api, project, node, compute):
compute.http_query = AsyncioMagicMock()
response = MagicMock()
response.status = 201
compute.http_query = AsyncioMagicMock(return_value=response)
response = await controller_api.post("/projects/{project_id}/nodes/{node_id}/files/hello".format(project_id=project.id, node_id=node.id), body=b"hello", raw=True)
assert response.status == 201
@ -247,6 +250,7 @@ async def test_get_and_post_with_nested_paths_normalization(controller_api, proj
response = MagicMock()
response.body = b"world"
response.status = 200
compute.http_query = AsyncioMagicMock(return_value=response)
response = await controller_api.get("/projects/{project_id}/nodes/{node_id}/files/hello\\nested".format(project_id=project.id, node_id=node.id))
assert response.status == 200
@ -254,7 +258,9 @@ async def test_get_and_post_with_nested_paths_normalization(controller_api, proj
compute.http_query.assert_called_with("GET", "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello/nested".format(project_id=project.id, node_id=node.id), timeout=None, raw=True)
compute.http_query = AsyncioMagicMock()
response = MagicMock()
response.status = 201
compute.http_query = AsyncioMagicMock(return_value=response)
response = await controller_api.post("/projects/{project_id}/nodes/{node_id}/files/hello\\nested".format(project_id=project.id, node_id=node.id), body=b"hello", raw=True)
assert response.status == 201

@ -318,7 +318,7 @@ async def test_get_file(controller_api, project):
async def test_write_file(controller_api, project):
response = await controller_api.post("/projects/{project_id}/files/hello".format(project_id=project.id), body="world", raw=True)
assert response.status == 200
assert response.status == 201
with open(os.path.join(project.path, "hello")) as f:
assert f.read() == "world"

Loading…
Cancel
Save