1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-28 11:18:11 +00:00

Controll of the project directory in the controller

This commit is contained in:
Julien Duponchelle 2016-04-26 14:34:49 +02:00
parent 893b05d26b
commit 9a1eeb57e9
No known key found for this signature in database
GPG Key ID: CE8B29639E07F5E8
4 changed files with 77 additions and 13 deletions

View File

@ -127,9 +127,6 @@ class Project:
if path != self._path and self.is_local() is False:
raise aiohttp.web.HTTPForbidden(text="You are not allowed to modify the project directory path")
if '"' in path:
raise aiohttp.web.HTTPForbidden(text="You are not allowed to use \" in the project directory path. It's not supported by Dynamips.")
self._path = path
self._update_temporary_file()

View File

@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import asyncio
import aiohttp
from uuid import UUID, uuid4
@ -23,6 +24,7 @@ from contextlib import contextmanager
from .vm import VM
from .udp_link import UDPLink
from ..notification_queue import NotificationQueue
from ..config import Config
class Project:
@ -45,7 +47,13 @@ class Project:
except ValueError:
raise aiohttp.web.HTTPBadRequest(text="{} is not a valid UUID".format(project_id))
self._id = project_id
self._path = path
#TODO: Security check if not locale
if path is None:
location = self._config().get("project_directory", self._get_default_project_directory())
path = os.path.join(location, self._id)
self.path = path
self._temporary = temporary
self._computes = set()
self._vms = {}
@ -68,6 +76,30 @@ class Project:
def path(self):
return self._path
@path.setter
def path(self, path):
try:
os.makedirs(path, exist_ok=True)
except OSError as e:
raise aiohttp.web.HTTPInternalServerError(text="Could not create project directory: {}".format(e))
if '"' in path:
raise aiohttp.web.HTTPForbidden(text="You are not allowed to use \" in the project directory path. It's not supported by Dynamips.")
self._path = path
def _config(self):
return Config.instance().get_section_config("Server")
@property
def captures_directory(self):
"""
Location of the captures file
"""
path = os.path.join(self._path, "project-files", "captures")
os.makedirs(path, exist_ok=True)
return path
@asyncio.coroutine
def addCompute(self, compute):
self._computes.add(compute)
@ -142,6 +174,7 @@ class Project:
def delete(self):
for compute in self._computes:
yield from compute.delete("/projects/{}".format(self._id))
shutil.rmtree(self.path)
@contextmanager
def queue(self):
@ -166,6 +199,22 @@ class Project:
for listener in self._listeners:
listener.put_nowait((action, event, kwargs))
@classmethod
def _get_default_project_directory(cls):
"""
Return the default location for the project directory
depending of the operating system
"""
server_config = Config.instance().get_section_config("Server")
path = os.path.expanduser(server_config.get("projects_path", "~/GNS3/projects"))
path = os.path.normpath(path)
try:
os.makedirs(path, exist_ok=True)
except OSError as e:
raise aiohttp.web.HTTPInternalServerError(text="Could not create project directory: {}".format(e))
return path
def __json__(self):
return {

View File

@ -118,13 +118,6 @@ def test_changing_path_not_allowed(tmpdir):
p.path = str(tmpdir)
def test_changing_path_with_quote_not_allowed(tmpdir):
with patch("gns3server.compute.project.Project.is_local", return_value=True):
with pytest.raises(aiohttp.web.HTTPForbidden):
p = Project(project_id=str(uuid4()))
p.path = str(tmpdir / "project\"53")
def test_json(tmpdir):
p = Project(project_id=str(uuid4()))
assert p.__json__() == {"name": p.name, "project_id": p.id, "temporary": False}

View File

@ -16,13 +16,16 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import pytest
import aiohttp
from unittest.mock import MagicMock
from tests.utils import AsyncioMagicMock
from unittest.mock import patch
from uuid import uuid4
from gns3server.controller.project import Project
from gns3server.config import Config
def test_affect_uuid():
@ -35,7 +38,29 @@ def test_affect_uuid():
def test_json(tmpdir):
p = Project()
assert p.__json__() == {"name": p.name, "project_id": p.id, "temporary": False, "path": None}
assert p.__json__() == {"name": p.name, "project_id": p.id, "temporary": False, "path": p.path}
def test_path(tmpdir):
directory = Config.instance().get_section_config("Server").get("project_directory")
with patch("gns3server.compute.project.Project._get_default_project_directory", return_value=directory):
p = Project(project_id=str(uuid4()))
assert p.path == os.path.join(directory, p.id)
assert os.path.exists(os.path.join(directory, p.id))
def test_init_path(tmpdir):
p = Project(path=str(tmpdir), project_id=str(uuid4()))
assert p.path == str(tmpdir)
def test_changing_path_with_quote_not_allowed(tmpdir):
with pytest.raises(aiohttp.web.HTTPForbidden):
p = Project(project_id=str(uuid4()))
p.path = str(tmpdir / "project\"53")
def test_addVM(async_run):