mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 14:01:15 +02:00
Merge branch '2.2' into 3.1
# Conflicts: # gns3server/compute/qemu/qemu_vm.py # gns3server/controller/import_project.py # gns3server/controller/project.py # gns3server/crash_report.py # gns3server/version.py # tests/compute/docker/test_docker_vm.py # tests/controller/test_import_project.py # tests/controller/test_project.py
This commit is contained in:
11 files changed
+260
-32
No files matched your search
@@ -20,6 +20,8 @@ import os
|
||||
import uuid
|
||||
import json
|
||||
import zipfile
|
||||
import pytest
|
||||
import aiohttp
|
||||
|
||||
from pathlib import Path
|
||||
from tests.utils import asyncio_patch, AsyncioMagicMock
|
||||
@@ -122,24 +124,49 @@ async def write_file(path, z):
|
||||
f.write(chunk)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_import_project_containing_symlink(tmpdir, controller):
|
||||
@pytest.fixture
|
||||
def export_project_with_symlink(tmpdir, controller):
|
||||
async def _export(symlink_target):
|
||||
project = Project(controller=controller, name="test")
|
||||
project.dump = MagicMock()
|
||||
|
||||
project = Project(controller=controller, name="test")
|
||||
project.dump = MagicMock()
|
||||
path = project.path
|
||||
topology = {
|
||||
"project_id": str(uuid.uuid4()),
|
||||
"name": "test",
|
||||
"auto_open": True,
|
||||
"auto_start": True,
|
||||
"topology": {
|
||||
},
|
||||
"version": "2.0.0"
|
||||
}
|
||||
|
||||
with open(os.path.join(project.path, "project.gns3"), 'w+') as f:
|
||||
json.dump(topology, f)
|
||||
|
||||
os.makedirs(os.path.join(project.path, "vm1", "dynamips"))
|
||||
symlink_path = os.path.join(project.path, "vm1", "dynamips", "symlink")
|
||||
os.symlink(symlink_target, symlink_path)
|
||||
|
||||
zip_path = str(tmpdir / "project.zip")
|
||||
with aiozipstream.ZipFile() as z:
|
||||
with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS"),):
|
||||
await export_project(z, project, str(tmpdir), include_images=False)
|
||||
await write_file(zip_path, z)
|
||||
|
||||
return zip_path
|
||||
|
||||
return _export
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_import_project_containing_symlink(controller, export_project_with_symlink):
|
||||
"""
|
||||
Test importing a project containing a valid symlink (target inside the project directory).
|
||||
"""
|
||||
|
||||
project_id = str(uuid.uuid4())
|
||||
os.makedirs(os.path.join(path, "vm1", "dynamips"))
|
||||
symlink_path = os.path.join(project.path, "vm1", "dynamips", "symlink")
|
||||
symlink_target = "/tmp/anywhere"
|
||||
os.symlink(symlink_target, symlink_path)
|
||||
|
||||
zip_path = str(tmpdir / "project.zip")
|
||||
with aiozipstream.ZipFile() as z:
|
||||
with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS"),):
|
||||
await export_project(z, project, str(tmpdir), include_images=False)
|
||||
await write_file(zip_path, z)
|
||||
symlink_target = "../symlink_target"
|
||||
zip_path = await export_project_with_symlink(symlink_target)
|
||||
|
||||
with open(zip_path, "rb") as f:
|
||||
project = await import_project(controller, project_id, f)
|
||||
@@ -152,6 +179,36 @@ async def test_import_project_containing_symlink(tmpdir, controller):
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_import_project_containing_absolute_symlink(controller, export_project_with_symlink):
|
||||
"""
|
||||
Test importing a project containing an absolute symlink.
|
||||
This should fail because absolute symlinks are not allowed for security reasons.
|
||||
"""
|
||||
|
||||
project_id = str(uuid.uuid4())
|
||||
symlink_target = "/tmp/anywhere"
|
||||
zip_path = await export_project_with_symlink(symlink_target)
|
||||
|
||||
with pytest.raises(aiohttp.web.HTTPConflict):
|
||||
with open(zip_path, "rb") as f:
|
||||
await import_project(controller, project_id, f)
|
||||
|
||||
|
||||
async def test_import_project_containing_escaping_symlink(controller, export_project_with_symlink):
|
||||
"""
|
||||
Test importing a project containing a symlink that escapes the project directory.
|
||||
This should fail because symlinks that escape the project directory are not allowed for security reasons.
|
||||
"""
|
||||
|
||||
project_id = str(uuid.uuid4())
|
||||
symlink_target = "../../../../symlink_target"
|
||||
zip_path = await export_project_with_symlink(symlink_target)
|
||||
|
||||
with pytest.raises(aiohttp.web.HTTPConflict):
|
||||
with open(zip_path, "rb") as f:
|
||||
await import_project(controller, project_id, f)
|
||||
|
||||
|
||||
async def test_import_upgrade(tmpdir, controller):
|
||||
"""
|
||||
Topology made for previous GNS3 version are upgraded during the process
|
||||
|
||||
@@ -700,6 +700,19 @@ async def test_delete(project):
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_delete_does_not_start_nodes(project):
|
||||
"""
|
||||
Deleting a project must not start its nodes, even when auto_start is enabled.
|
||||
"""
|
||||
|
||||
project.auto_start = True
|
||||
project.dump()
|
||||
await project.close()
|
||||
project.start_all = AsyncioMagicMock()
|
||||
await project.delete()
|
||||
assert not project.start_all.called
|
||||
|
||||
|
||||
async def test_dump(projects_dir):
|
||||
|
||||
directory = projects_dir
|
||||
|
||||
Reference in new issue
Block a user