Implement directory whitelisting in webide

This commit is contained in:
Kristóf Tóth 2018-04-05 14:43:39 +02:00
parent 35421649c9
commit b74ff39438

View File

@ -1,7 +1,7 @@
# Copyright (C) 2018 Avatao.com Innovative Learning Kft. # Copyright (C) 2018 Avatao.com Innovative Learning Kft.
# All Rights Reserved. See LICENSE file for details. # All Rights Reserved. See LICENSE file for details.
from os.path import isfile, join, relpath, exists, isdir from os.path import isfile, join, relpath, exists, isdir, realpath
from glob import glob from glob import glob
from fnmatch import fnmatchcase from fnmatch import fnmatchcase
from collections import Iterable from collections import Iterable
@ -13,9 +13,10 @@ from tfw.config.logs import logging
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class FileManager: class FileManager: # pylint: disable=too-many-instance-attributes
def __init__(self, working_directory, selected_file=None, exclude=None): def __init__(self, working_directory, allowed_directories=None, selected_file=None, exclude=None):
self._exclude, self.exclude = None, exclude self._exclude, self.exclude = None, exclude
self._allowed_directories, self.allowed_directories = None, allowed_directories
self._workdir, self.workdir = None, working_directory self._workdir, self.workdir = None, working_directory
self._filename, self.filename = None, selected_file or self.files[0] self._filename, self.filename = None, selected_file or self.files[0]
@ -39,8 +40,19 @@ class FileManager:
def workdir(self, directory): def workdir(self, directory):
if not exists(directory) or not isdir(directory): if not exists(directory) or not isdir(directory):
raise EnvironmentError('"{}" is not a directory!'.format(directory)) raise EnvironmentError('"{}" is not a directory!'.format(directory))
if self.allowed_directories:
if realpath(directory) not in self._allowed_directories:
raise EnvironmentError('Directory "{}" is not in whitelist!'.format(directory))
self._workdir = directory self._workdir = directory
@property
def allowed_directories(self):
return self._allowed_directories
@allowed_directories.setter
def allowed_directories(self, directories):
self._allowed_directories = directories
@property @property
def filename(self): def filename(self):
return self._filename return self._filename
@ -75,9 +87,11 @@ class FileManager:
class SourceCodeEventHandler(TriggerlessEventHandler): class SourceCodeEventHandler(TriggerlessEventHandler):
def __init__(self, key, directory, selected_file=None, exclude=None): # pylint: disable=too-many-arguments
def __init__(self, key, directory, allowed_directories=None, selected_file=None, exclude=None):
super().__init__(key) super().__init__(key)
self.filemanager = FileManager(directory, selected_file=selected_file, exclude=exclude) self.filemanager = FileManager(allowed_directories=allowed_directories, working_directory=directory,
selected_file=selected_file, exclude=exclude)
self.commands = {'read': self.read, self.commands = {'read': self.read,
'write': self.write, 'write': self.write,