def setUp(self):
        super().setUp()
        test_utils.setup()

        executor._process_creator = _MockProcessWrapper
        self.executor_service = ExecutionService(AnyUserAuthorizer(), _IdGeneratorMock())

        self.feature = FileDownloadFeature(UserFileStorage(b'123456'), test_utils.temp_folder)
        self.feature.subscribe(self.executor_service)
Esempio n. 2
0
def main():
    tool_utils.validate_web_imports_exist(os.getcwd())

    logging_conf_file = os.path.join(CONFIG_FOLDER, 'logging.json')
    with open(logging_conf_file, 'rt') as f:
        log_config = json.load(f)
        file_utils.prepare_folder(os.path.join('logs'))

        logging.config.dictConfig(log_config)

    file_utils.prepare_folder(CONFIG_FOLDER)
    file_utils.prepare_folder(TEMP_FOLDER)

    migrations.migrate.migrate(TEMP_FOLDER, CONFIG_FOLDER)

    server_config = server_conf.from_json(SERVER_CONF_PATH)

    secret = get_secret(TEMP_FOLDER)

    config_service = ConfigService(CONFIG_FOLDER)

    alerts_service = AlertsService(server_config.get_alerts_config())
    alerts_service = alerts_service

    execution_logs_path = os.path.join('logs', 'processes')
    log_name_creator = LogNameCreator(
        server_config.logging_config.filename_pattern,
        server_config.logging_config.date_format)
    execution_logging_service = ExecutionLoggingService(
        execution_logs_path, log_name_creator)

    existing_ids = [
        entry.id for entry in execution_logging_service.get_history_entries()
    ]
    id_generator = IdGenerator(existing_ids)

    execution_service = ExecutionService(id_generator)

    execution_logging_initiator = ExecutionLoggingInitiator(
        execution_service, execution_logging_service)
    execution_logging_initiator.start()

    user_file_storage = UserFileStorage(secret)
    file_download_feature = FileDownloadFeature(user_file_storage, TEMP_FOLDER)
    file_download_feature.subscribe(execution_service)
    file_upload_feature = FileUploadFeature(user_file_storage, TEMP_FOLDER)

    alerter_feature = FailAlerterFeature(execution_service, alerts_service)
    alerter_feature.start()

    server.init(server_config, execution_service, execution_logging_service,
                config_service, alerts_service, file_upload_feature,
                file_download_feature, secret)
Esempio n. 3
0
    def start_server(self,
                     port,
                     address,
                     *,
                     xsrf_protection=XSRF_PROTECTION_TOKEN):
        file_download_feature = FileDownloadFeature(
            UserFileStorage(b'some_secret'), test_utils.temp_folder)
        config = ServerConfig()
        config.port = port
        config.address = address
        config.xsrf_protection = xsrf_protection
        config.max_request_size_mb = 1

        authorizer = Authorizer(ANY_USER, [], [], EmptyGroupProvider())
        execution_service = MagicMock()
        execution_service.start_script.return_value = 3

        server.init(config,
                    None,
                    authorizer,
                    execution_service,
                    MagicMock(),
                    MagicMock(),
                    ConfigService(authorizer, self.conf_folder),
                    MagicMock(),
                    FileUploadFeature(UserFileStorage(b'cookie_secret'),
                                      test_utils.temp_folder),
                    file_download_feature,
                    'cookie_secret',
                    None,
                    self.conf_folder,
                    start_server=False)
        self.start_loop()
    def setUp(self):
        super().setUp()
        test_utils.setup()

        executor._process_creator = _MockProcessWrapper
        self.executor_service = ExecutionService(_IdGeneratorMock())

        self.feature = FileDownloadFeature(UserFileStorage(b'123456'), test_utils.temp_folder)
        self.feature.subscribe(self.executor_service)
Esempio n. 5
0
    def start_server(self,
                     port,
                     address,
                     *,
                     xsrf_protection=XSRF_PROTECTION_TOKEN):
        file_download_feature = FileDownloadFeature(
            UserFileStorage(b'some_secret'), test_utils.temp_folder)
        config = ServerConfig()
        config.port = port
        config.address = address
        config.xsrf_protection = xsrf_protection
        config.max_request_size_mb = 1

        authorizer = Authorizer(ANY_USER, ['admin_user'], [], ['admin_user'],
                                EmptyGroupProvider())
        execution_service = MagicMock()
        execution_service.start_script.return_value = 3

        cookie_secret = b'cookie_secret'

        server.init(config,
                    MockAuthenticator(),
                    authorizer,
                    execution_service,
                    MagicMock(),
                    MagicMock(),
                    ConfigService(authorizer, self.conf_folder),
                    MagicMock(),
                    FileUploadFeature(UserFileStorage(cookie_secret),
                                      test_utils.temp_folder),
                    file_download_feature,
                    'cookie_secret',
                    None,
                    self.conf_folder,
                    start_server=False)
        self.start_loop()

        self._user_session = requests.Session()
        self._user_session.cookies['username'] = create_signed_value(cookie_secret, 'username', 'normal_user') \
            .decode('utf8')

        self._admin_session = requests.Session()
        self._admin_session.cookies['username'] = create_signed_value(cookie_secret, 'username', 'admin_user') \
            .decode('utf8')
    def start_server(self, port, address):
        file_download_feature = FileDownloadFeature(UserFileStorage(b'123456'),
                                                    test_utils.temp_folder)
        config = ServerConfig()
        config.port = port
        config.address = address

        server.init(config,
                    None,
                    None,
                    None,
                    None,
                    None,
                    None,
                    None,
                    file_download_feature,
                    None,
                    None,
                    start_server=False)
        self.start_loop()
    def start_server(self, port, address):
        file_download_feature = FileDownloadFeature(
            UserFileStorage(b'some_secret'), test_utils.temp_folder)
        config = ServerConfig()
        config.port = port
        config.address = address

        authorizer = Authorizer(ANY_USER, [], [], EmptyGroupProvider())
        server.init(config,
                    None,
                    authorizer,
                    None,
                    None,
                    ConfigService(authorizer, self.conf_folder),
                    None,
                    None,
                    file_download_feature,
                    'cookie_secret',
                    None,
                    start_server=False)
        self.start_loop()
Esempio n. 8
0
def init(server_config: ServerConfig, authenticator, authorizer,
         execution_service: ExecutionService,
         execution_logging_service: ExecutionLoggingService,
         config_service: ConfigService, alerts_service: AlertsService,
         file_upload_feature: FileUploadFeature,
         file_download_feature: FileDownloadFeature, secret, server_version):
    ssl_context = None
    if server_config.is_ssl():
        ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
        ssl_context.load_cert_chain(server_config.get_ssl_cert_path(),
                                    server_config.get_ssl_key_path())

    auth = TornadoAuth(authenticator)
    if auth.is_enabled():
        identification = AuthBasedIdentification(auth)
    else:
        identification = IpBasedIdentification(server_config.trusted_ips,
                                               server_config.user_header_name)

    downloads_folder = file_download_feature.get_result_files_folder()

    handlers = [
        (r'/conf', GetServerConf), (r'/scripts', GetScripts),
        (r'/scripts/([^/]*)', ScriptConfigSocket),
        (r'/scripts/([^/]*)/([^/]*)/list-files', ScriptParameterListFiles),
        (r'/executions/start', ScriptExecute),
        (r'/executions/stop/(.*)', ScriptStop),
        (r'/executions/kill/(.*)', ScriptKill),
        (r'/executions/io/(.*)', ScriptStreamSocket),
        (r'/executions/active', GetActiveExecutionIds),
        (r'/executions/config/(.*)', GetExecutingScriptConfig),
        (r'/executions/cleanup/(.*)', CleanupExecutingScript),
        (r'/executions/status/(.*)', GetExecutionStatus),
        (r'/admin/execution_log/short', GetShortHistoryEntriesHandler),
        (r'/admin/execution_log/long/(.*)', GetLongHistoryEntryHandler),
        (r'/auth/info', AuthInfoHandler),
        (r'/result_files/(.*)', DownloadResultFile, {
            'path': downloads_folder
        }), (r"/", ProxiedRedirectHandler, {
            "url": "/index.html"
        })
    ]

    if auth.is_enabled():
        handlers.append((r'/login', LoginHandler))
        handlers.append((r'/auth/config', AuthConfigHandler))
        handlers.append((r'/logout', LogoutHandler))

    handlers.append((r"/(.*)", AuthorizedStaticFileHandler, {"path": "web"}))

    settings = {
        "cookie_secret": secret,
        "login_url": "/login.html",
        'websocket_ping_interval': 30,
        'websocket_ping_timeout': 300
    }

    application = tornado.web.Application(handlers, **settings)

    application.auth = auth

    application.server_config = server_config
    application.server_version = server_version
    application.authorizer = authorizer
    application.downloads_folder = downloads_folder
    application.file_download_feature = file_download_feature
    application.file_upload_feature = file_upload_feature
    application.execution_service = execution_service
    application.execution_logging_service = execution_logging_service
    application.config_service = config_service
    application.alerts_service = alerts_service
    application.identification = identification
    application.max_request_size_mb = server_config.max_request_size_mb

    io_loop = tornado.ioloop.IOLoop.current()

    http_server = httpserver.HTTPServer(application,
                                        ssl_options=ssl_context,
                                        max_buffer_size=10 * BYTES_IN_MB)
    http_server.listen(server_config.port, address=server_config.address)

    intercept_stop_when_running_scripts(io_loop, execution_service)

    http_protocol = 'https' if server_config.ssl else 'http'
    print('Server is running on: %s://%s:%s' %
          (http_protocol, server_config.address, server_config.port))
    io_loop.start()
Esempio n. 9
0
class FileDownloadFeatureTest(unittest.TestCase):
    def test_prepare_file_on_finish(self):
        file1_path = test_utils.create_file('file1.txt')

        downloadable_files = self.perform_execution([file1_path])

        self.assert_downloadable_files(downloadable_files, [file1_path])

    def test_no_output_files_in_config(self):
        test_utils.create_file('file1.txt')

        downloadable_files = self.perform_execution(None)

        self.assertEqual([], downloadable_files)

    def test_output_files_with_parameter_substitution(self):
        file1 = test_utils.create_file('file1.txt', text='hello world')
        file2 = test_utils.create_file(os.path.join('sub', 'child',
                                                    'admin.log'),
                                       text='password=123')

        downloadable_files = self.perform_execution([
            os.path.join(test_utils.temp_folder, '${p1}.txt'),
            os.path.join(test_utils.temp_folder, 'sub', '${p2}', 'admin.log')
        ],
                                                    parameter_values={
                                                        'p1': 'file1',
                                                        'p2': 'child'
                                                    })

        self.assert_downloadable_files(downloadable_files, [file1, file2])

    def test_output_files_with_secure_parameters(self):
        test_utils.create_file('file1.txt', text='hello world')
        file2 = test_utils.create_file(os.path.join('sub', 'child',
                                                    'admin.log'),
                                       text='password=123')

        param1 = create_script_param_config('p1', secure=True)
        param2 = create_script_param_config('p2')

        downloadable_files = self.perform_execution([
            os.path.join(test_utils.temp_folder, '${p1}.txt'),
            os.path.join(test_utils.temp_folder, 'sub', '${p2}', 'admin.log')
        ],
                                                    parameter_values={
                                                        'p1': 'file1',
                                                        'p2': 'child'
                                                    },
                                                    parameters=[
                                                        param1, param2
                                                    ])

        self.assert_downloadable_files(downloadable_files, [file2])

    def perform_execution(self,
                          output_files,
                          parameter_values=None,
                          parameters=None):
        if parameter_values is None:
            parameter_values = {}

        if parameters is None:
            parameters = [
                create_script_param_config(key)
                for key in parameter_values.keys()
            ]

        config_model = create_config_model('my_script',
                                           output_files=output_files,
                                           parameters=parameters)

        execution_id = self.executor_service.start_script(
            config_model, parameter_values, 'userX',
            create_audit_names(ip='127.0.0.1'))
        self.executor_service.stop_script(execution_id)

        finish_condition = threading.Event()
        self.executor_service.add_finish_listener(
            lambda: finish_condition.set(), execution_id)
        finish_condition.wait(2)

        downloadable_files = self.feature.get_downloadable_files(execution_id)

        return downloadable_files

    def setUp(self):
        super().setUp()
        test_utils.setup()

        executor._process_creator = _MockProcessWrapper
        self.executor_service = ExecutionService(_IdGeneratorMock())

        self.feature = FileDownloadFeature(UserFileStorage(b'123456'),
                                           test_utils.temp_folder)
        self.feature.subscribe(self.executor_service)

    def tearDown(self):
        super().tearDown()
        test_utils.cleanup()

    def assert_downloadable_files(self, prepared_files, original_files):
        prepared_files_dict = {os.path.basename(f): f for f in prepared_files}
        original_files_dict = {os.path.basename(f): f for f in original_files}

        self.assertEqual(original_files_dict.keys(),
                         prepared_files_dict.keys())

        for filename in original_files_dict.keys():
            prepared_file = prepared_files_dict[filename]
            original_file = original_files_dict[filename]

            prepared_content = file_utils.read_file(prepared_file)
            original_content = file_utils.read_file(original_file)

            self.assertEqual(original_content, prepared_content,
                             'Different content for file ' + filename)
class FileDownloadFeatureTest(unittest.TestCase):

    def test_prepare_file_on_finish(self):
        file1_path = test_utils.create_file('file1.txt')

        downloadable_files = self.perform_execution([file1_path])

        self.assert_downloadable_files(downloadable_files, [file1_path])

    def test_no_output_files_in_config(self):
        test_utils.create_file('file1.txt')

        downloadable_files = self.perform_execution(None)

        self.assertEqual([], downloadable_files)

    def test_output_files_with_parameter_substitution(self):
        file1 = test_utils.create_file('file1.txt', text='hello world')
        file2 = test_utils.create_file(os.path.join('sub', 'child', 'admin.log'), text='password=123')

        downloadable_files = self.perform_execution([
            os.path.join(test_utils.temp_folder, '${p1}.txt'),
            os.path.join(test_utils.temp_folder, 'sub', '${p2}', 'admin.log')],
            parameter_values={'p1': 'file1', 'p2': 'child'})

        self.assert_downloadable_files(downloadable_files, [file1, file2])

    def test_output_files_with_secure_parameters(self):
        test_utils.create_file('file1.txt', text='hello world')
        file2 = test_utils.create_file(os.path.join('sub', 'child', 'admin.log'), text='password=123')

        param1 = create_script_param_config('p1', secure=True)
        param2 = create_script_param_config('p2')

        downloadable_files = self.perform_execution([
            os.path.join(test_utils.temp_folder, '${p1}.txt'),
            os.path.join(test_utils.temp_folder, 'sub', '${p2}', 'admin.log')],
            parameter_values={'p1': 'file1', 'p2': 'child'},
            parameters=[param1, param2])

        self.assert_downloadable_files(downloadable_files, [file2])

    def perform_execution(self, output_files, parameter_values=None, parameters=None):
        if parameter_values is None:
            parameter_values = {}

        if parameters is None:
            parameters = [create_script_param_config(key) for key in parameter_values.keys()]

        config_model = create_config_model('my_script', output_files=output_files, parameters=parameters)

        execution_id = self.executor_service.start_script(
            config_model, parameter_values, 'userX', create_audit_names(ip='127.0.0.1'))
        self.executor_service.stop_script(execution_id)

        finish_condition = threading.Event()
        self.executor_service.add_finish_listener(lambda: finish_condition.set(), execution_id)
        finish_condition.wait(2)

        downloadable_files = self.feature.get_downloadable_files(execution_id)

        return downloadable_files

    def setUp(self):
        super().setUp()
        test_utils.setup()

        executor._process_creator = _MockProcessWrapper
        self.executor_service = ExecutionService(_IdGeneratorMock())

        self.feature = FileDownloadFeature(UserFileStorage(b'123456'), test_utils.temp_folder)
        self.feature.subscribe(self.executor_service)

    def tearDown(self):
        super().tearDown()
        test_utils.cleanup()

    def assert_downloadable_files(self, prepared_files, original_files):
        prepared_files_dict = {os.path.basename(f): f for f in prepared_files}
        original_files_dict = {os.path.basename(f): f for f in original_files}

        self.assertEqual(original_files_dict.keys(), prepared_files_dict.keys())

        for filename in original_files_dict.keys():
            prepared_file = prepared_files_dict[filename]
            original_file = original_files_dict[filename]

            prepared_content = file_utils.read_file(prepared_file)
            original_content = file_utils.read_file(original_file)

            self.assertEqual(original_content, prepared_content, 'Different content for file ' + filename)
Esempio n. 11
0
def main():
    tool_utils.validate_web_imports_exist(os.getcwd())

    logging_conf_file = os.path.join(CONFIG_FOLDER, 'logging.json')
    with open(logging_conf_file, "rt") as f:
        log_config = json.load(f)
        file_utils.prepare_folder(os.path.join("logs", "processes"))

        logging.config.dictConfig(log_config)

    file_utils.prepare_folder(CONFIG_FOLDER)
    file_utils.prepare_folder(SCRIPT_CONFIGS_FOLDER)

    server_config = server_conf.from_json(SERVER_CONF_PATH)
    ssl_context = None
    if server_config.is_ssl():
        ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
        ssl_context.load_cert_chain(server_config.get_ssl_cert_path(),
                                    server_config.get_ssl_key_path())

    file_utils.prepare_folder(TEMP_FOLDER)

    settings = {
        "cookie_secret": get_tornado_secret(),
        "login_url": "/login.html"
    }

    auth = TornadoAuth(server_config.authenticator, server_config.authorizer)

    user_file_storage = UserFileStorage(get_tornado_secret())
    file_download_feature = FileDownloadFeature(user_file_storage, TEMP_FOLDER)
    file_upload_feature = FileUploadFeature(user_file_storage, TEMP_FOLDER)

    result_files_folder = file_download_feature.get_result_files_folder()

    handlers = [(r"/conf/title", GetServerTitle),
                (r"/scripts/list", GetScripts),
                (r"/scripts/info", GetScriptInfo),
                (r"/scripts/execute", ScriptExecute),
                (r"/scripts/execute/stop", ScriptStop),
                (r"/scripts/execute/io/(.*)", ScriptStreamSocket),
                (r'/' + os.path.basename(result_files_folder) + '/(.*)',
                 DownloadResultFile, {
                     'path': result_files_folder
                 }), (r"/", ProxiedRedirectHandler, {
                     "url": "/index.html"
                 })]

    if auth.is_enabled():
        handlers.append((r'/login', LoginHandler))
        handlers.append((r'/auth/config', AuthConfigHandler))
        handlers.append((r'/logout', LogoutHandler))

    handlers.append((r"/username", GetUsernameHandler))

    handlers.append((r"/(.*)", AuthorizedStaticFileHandler, {"path": "web"}))

    application = tornado.web.Application(handlers, **settings)

    application.auth = auth

    application.alerts_config = server_config.get_alerts_config()
    application.server_title = server_config.title

    application.file_download_feature = file_download_feature
    application.file_upload_feature = file_upload_feature

    http_server = httpserver.HTTPServer(application, ssl_options=ssl_context)
    http_server.listen(server_config.port, address=server_config.address)

    http_protocol = 'https' if server_config.ssl else 'http'
    print('Server is running on: %s://%s:%s' %
          (http_protocol, server_config.address, server_config.port))

    tornado.ioloop.IOLoop.current().start()
Esempio n. 12
0
def init(server_config: ServerConfig,
         authenticator,
         authorizer,
         execution_service: ExecutionService,
         schedule_service: ScheduleService,
         execution_logging_service: ExecutionLoggingService,
         config_service: ConfigService,
         alerts_service: AlertsService,
         file_upload_feature: FileUploadFeature,
         file_download_feature: FileDownloadFeature,
         secret,
         server_version,
         conf_folder,
         *,
         start_server=True):
    ssl_context = None
    if server_config.is_ssl():
        ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
        ssl_context.load_cert_chain(server_config.get_ssl_cert_path(),
                                    server_config.get_ssl_key_path())

    auth = TornadoAuth(authenticator)
    if auth.is_enabled():
        identification = AuthBasedIdentification(auth)
    else:
        identification = IpBasedIdentification(server_config.ip_validator, server_config.user_header_name)

    downloads_folder = file_download_feature.get_result_files_folder()

    handlers = [(r'/conf', GetServerConf),
                (r'/scripts', GetScripts),
                (r'/scripts/([^/]*)', ScriptConfigSocket),
                (r'/scripts/([^/]*)/([^/]*)/list-files', ScriptParameterListFiles),
                (r'/executions/start', ScriptExecute),
                (r'/executions/stop/(.*)', ScriptStop),
                (r'/executions/kill/(.*)', ScriptKill),
                (r'/executions/io/(.*)', ScriptStreamSocket),
                (r'/executions/active', GetActiveExecutionIds),
                (r'/executions/config/(.*)', GetExecutingScriptConfig),
                (r'/executions/cleanup/(.*)', CleanupExecutingScript),
                (r'/executions/status/(.*)', GetExecutionStatus),
                (r'/history/execution_log/short', GetShortHistoryEntriesHandler),
                (r'/history/execution_log/long/(.*)', GetLongHistoryEntryHandler),
                (r'/schedule', AddSchedule),
                (r'/auth/info', AuthInfoHandler),
                (r'/result_files/(.*)',
                 DownloadResultFile,
                 {'path': downloads_folder}),
                (r'/admin/scripts', AdminUpdateScriptEndpoint),
                (r'/admin/scripts/(.*)', AdminGetScriptEndpoint),
                (r"/", ProxiedRedirectHandler, {"url": "/index.html"})]

    if auth.is_enabled():
        handlers.append((r'/login', LoginHandler))
        handlers.append((r'/auth/config', AuthConfigHandler))
        handlers.append((r'/logout', LogoutHandler))

    handlers.append((r'/theme/(.*)', ThemeStaticFileHandler, {'path': os.path.join(conf_folder, 'theme')}))
    handlers.append((r"/(.*)", AuthorizedStaticFileHandler, {"path": "web"}))

    settings = {
        "cookie_secret": secret,
        "login_url": "/login.html",
        'websocket_ping_interval': 30,
        'websocket_ping_timeout': 300,
        'compress_response': True,
        'xsrf_cookies': server_config.xsrf_protection != XSRF_PROTECTION_DISABLED,
    }

    application = tornado.web.Application(handlers, **settings)
    autoapply_xheaders(application)

    application.auth = auth

    application.server_config = server_config
    application.server_version = server_version
    application.authorizer = authorizer
    application.downloads_folder = downloads_folder
    application.file_download_feature = file_download_feature
    application.file_upload_feature = file_upload_feature
    application.execution_service = execution_service
    application.schedule_service = schedule_service
    application.execution_logging_service = execution_logging_service
    application.config_service = config_service
    application.alerts_service = alerts_service
    application.identification = identification
    application.max_request_size_mb = server_config.max_request_size_mb

    if os_utils.is_win() and env_utils.is_min_version('3.8'):
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    io_loop = tornado.ioloop.IOLoop.current()

    global _http_server
    _http_server = httpserver.HTTPServer(
        application,
        ssl_options=ssl_context,
        max_buffer_size=10 * BYTES_IN_MB)
    _http_server.listen(server_config.port, address=server_config.address)

    intercept_stop_when_running_scripts(io_loop, execution_service)

    http_protocol = 'https' if server_config.ssl else 'http'
    print('Server is running on: %s://%s:%s' % (http_protocol, server_config.address, server_config.port))

    if start_server:
        io_loop.start()
Esempio n. 13
0
def main():
    try:
        tool_utils.validate_web_build_exists(os.getcwd())
    except InvalidWebBuildException as e:
        print(str(e))
        sys.exit(-1)

    logging_conf_file = os.path.join(CONFIG_FOLDER, 'logging.json')
    with open(logging_conf_file, 'rt') as f:
        log_config = json.load(f)
        file_utils.prepare_folder(LOG_FOLDER)

        logging.config.dictConfig(log_config)

    file_utils.prepare_folder(CONFIG_FOLDER)
    file_utils.prepare_folder(TEMP_FOLDER)

    migrations.migrate.migrate(TEMP_FOLDER, CONFIG_FOLDER, SERVER_CONF_PATH,
                               LOG_FOLDER)

    server_config = server_conf.from_json(SERVER_CONF_PATH, TEMP_FOLDER)

    secret = get_secret(TEMP_FOLDER)

    tornado_client_config.initialize()

    group_provider = create_group_provider(server_config.user_groups,
                                           server_config.authenticator,
                                           server_config.admin_users)

    authorizer = Authorizer(server_config.allowed_users,
                            server_config.admin_users, group_provider)

    config_service = ConfigService(authorizer, CONFIG_FOLDER)

    alerts_service = AlertsService(server_config.get_alerts_config())
    alerts_service = alerts_service

    execution_logs_path = os.path.join(LOG_FOLDER, 'processes')
    log_name_creator = LogNameCreator(
        server_config.logging_config.filename_pattern,
        server_config.logging_config.date_format)
    execution_logging_service = ExecutionLoggingService(
        execution_logs_path, log_name_creator)

    existing_ids = [
        entry.id for entry in execution_logging_service.get_history_entries()
    ]
    id_generator = IdGenerator(existing_ids)

    execution_service = ExecutionService(id_generator)

    execution_logging_initiator = ExecutionLoggingInitiator(
        execution_service, execution_logging_service)
    execution_logging_initiator.start()

    user_file_storage = UserFileStorage(secret)
    file_download_feature = FileDownloadFeature(user_file_storage, TEMP_FOLDER)
    file_download_feature.subscribe(execution_service)
    file_upload_feature = FileUploadFeature(user_file_storage, TEMP_FOLDER)

    alerter_feature = FailAlerterFeature(execution_service, alerts_service)
    alerter_feature.start()

    server.init(server_config, server_config.authenticator, authorizer,
                execution_service, execution_logging_service, config_service,
                alerts_service, file_upload_feature, file_download_feature,
                secret)
Esempio n. 14
0
def main():
    project_path = os.getcwd()

    try:
        tool_utils.validate_web_build_exists(project_path)
    except InvalidWebBuildException as e:
        print(str(e))
        sys.exit(-1)

    logging_conf_file = os.path.join(CONFIG_FOLDER, 'logging.json')
    with open(logging_conf_file, 'rt') as f:
        log_config = json.load(f)
        file_utils.prepare_folder(LOG_FOLDER)

        logging.config.dictConfig(log_config)

    server_version = tool_utils.get_server_version(project_path)
    logging.info('Starting Script Server' +
                 (', v' +
                  server_version if server_version else ' (custom version)'))

    file_utils.prepare_folder(CONFIG_FOLDER)
    file_utils.prepare_folder(TEMP_FOLDER)

    migrations.migrate.migrate(TEMP_FOLDER, CONFIG_FOLDER, SERVER_CONF_PATH,
                               LOG_FOLDER)

    server_config = server_conf.from_json(SERVER_CONF_PATH, TEMP_FOLDER)

    secret = get_secret(server_config.secret_storage_file)

    tornado_client_config.initialize()

    group_provider = create_group_provider(server_config.user_groups,
                                           server_config.authenticator,
                                           server_config.admin_users)

    authorizer = Authorizer(server_config.allowed_users,
                            server_config.admin_users,
                            server_config.full_history_users,
                            server_config.code_editor_users, group_provider)

    config_service = ConfigService(authorizer, CONFIG_FOLDER)

    alerts_service = AlertsService(server_config.alerts_config)
    alerts_service = alerts_service

    execution_logs_path = os.path.join(LOG_FOLDER, 'processes')
    log_name_creator = LogNameCreator(
        server_config.logging_config.filename_pattern,
        server_config.logging_config.date_format)
    execution_logging_service = ExecutionLoggingService(
        execution_logs_path, log_name_creator, authorizer)

    existing_ids = [
        entry.id for entry in execution_logging_service.get_history_entries(
            None, system_call=True)
    ]
    id_generator = IdGenerator(existing_ids)

    execution_service = ExecutionService(authorizer, id_generator)

    execution_logging_controller = ExecutionLoggingController(
        execution_service, execution_logging_service)
    execution_logging_controller.start()

    user_file_storage = UserFileStorage(secret)
    file_download_feature = FileDownloadFeature(user_file_storage, TEMP_FOLDER)
    file_download_feature.subscribe(execution_service)
    file_upload_feature = FileUploadFeature(user_file_storage, TEMP_FOLDER)

    alerter_feature = FailAlerterFeature(execution_service, alerts_service)
    alerter_feature.start()

    executions_callback_feature = ExecutionsCallbackFeature(
        execution_service, server_config.callbacks_config)
    executions_callback_feature.start()

    schedule_service = ScheduleService(config_service, execution_service,
                                       CONFIG_FOLDER)

    server.init(server_config, server_config.authenticator, authorizer,
                execution_service, schedule_service, execution_logging_service,
                config_service, alerts_service, file_upload_feature,
                file_download_feature, secret, server_version, CONFIG_FOLDER)
Esempio n. 15
0
def init(server_config: ServerConfig,
         authenticator,
         authorizer,
         execution_service: ExecutionService,
         execution_logging_service: ExecutionLoggingService,
         config_service: ConfigService,
         alerts_service: AlertsService,
         file_upload_feature: FileUploadFeature,
         file_download_feature: FileDownloadFeature,
         secret):
    ssl_context = None
    if server_config.is_ssl():
        ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
        ssl_context.load_cert_chain(server_config.get_ssl_cert_path(),
                                    server_config.get_ssl_key_path())

    auth = TornadoAuth(authenticator)
    if auth.is_enabled():
        identification = AuthBasedIdentification(auth)
    else:
        identification = IpBasedIdentification(server_config.trusted_ips)

    downloads_folder = file_download_feature.get_result_files_folder()

    handlers = [(r'/conf/title', GetServerTitle),
                (r'/scripts', GetScripts),
                (r'/scripts/([^/]*)', ScriptConfigSocket),
                (r'/scripts/([^/]*)/([^/]*)/list-files', ScriptParameterListFiles),
                (r'/executions/start', ScriptExecute),
                (r'/executions/stop/(.*)', ScriptStop),
                (r'/executions/io/(.*)', ScriptStreamSocket),
                (r'/executions/active', GetActiveExecutionIds),
                (r'/executions/config/(.*)', GetExecutingScriptConfig),
                (r'/executions/cleanup/(.*)', CleanupExecutingScript),
                (r'/executions/status/(.*)', GetExecutionStatus),
                (r'/admin/execution_log/short', GetShortHistoryEntriesHandler),
                (r'/admin/execution_log/long/(.*)', GetLongHistoryEntryHandler),
                (r'/auth/info', AuthInfoHandler),
                (r'/result_files/(.*)',
                 DownloadResultFile,
                 {'path': downloads_folder}),
                (r"/", ProxiedRedirectHandler, {"url": "/index.html"})]

    if auth.is_enabled():
        handlers.append((r'/login', LoginHandler))
        handlers.append((r'/auth/config', AuthConfigHandler))
        handlers.append((r'/logout', LogoutHandler))

    handlers.append((r"/(.*)", AuthorizedStaticFileHandler, {"path": "web"}))

    settings = {
        "cookie_secret": secret,
        "login_url": "/login.html",
        'websocket_ping_interval': 30,
        'websocket_ping_timeout': 300
    }

    application = tornado.web.Application(handlers, **settings)

    application.auth = auth

    application.server_title = server_config.title
    application.authorizer = authorizer
    application.downloads_folder = downloads_folder
    application.file_download_feature = file_download_feature
    application.file_upload_feature = file_upload_feature
    application.execution_service = execution_service
    application.execution_logging_service = execution_logging_service
    application.config_service = config_service
    application.alerts_service = alerts_service
    application.identification = identification
    application.max_request_size_mb = server_config.max_request_size_mb

    io_loop = tornado.ioloop.IOLoop.current()

    http_server = httpserver.HTTPServer(application, ssl_options=ssl_context, max_buffer_size=10 * BYTES_IN_MB)
    http_server.listen(server_config.port, address=server_config.address)

    intercept_stop_when_running_scripts(io_loop, execution_service)

    http_protocol = 'https' if server_config.ssl else 'http'
    print('Server is running on: %s://%s:%s' % (http_protocol, server_config.address, server_config.port))
    io_loop.start()