def run(self): tools.check_config_value(p_config=self._config, p_config_attribute_name="host") fmt = "Starting web server '{name}' on {address}:{port}{base_url}" self._logger.info( fmt.format(name=self._name, address=self._config.host, port=self._config.port, base_url=self._config.base_url)) # See https://stackoverflow.com/questions/14814201/can-i-serve-multiple-clients-using-just-flask-app-run-as-standalone try: self._app.run(port=self._config.port, host=self._config.host, threaded=True) except Exception as e: fmt = "Exception '%s' while starting web server %s" % (str(e), self._name) self._logger.error(fmt) self._server_exception = e raise e
def handle_section(self, p_section_name): login_mapping_section = LoginMappingSection(p_section_name=p_section_name) self.scan(p_section=login_mapping_section) tools.check_config_value(p_config=login_mapping_section, p_config_attribute_name="server_group") self._login_mapping_sections[login_mapping_section.server_group] = login_mapping_section
def start_server(self): tools.check_config_value(p_config=self._config, p_config_attribute_name="port") self._process = threading.Thread(target=self.run) self._process.start() time.sleep(1) if self._server_exception is not None: raise self._server_exception self._server_started = True
def handle_section(self, p_section_name): client_device_section = ClientDeviceConfigModel(p_section_name=p_section_name) self.scan(p_section=client_device_section) tools.check_config_value(p_config=client_device_section, p_config_attribute_name="username") tools.check_config_value(p_config=client_device_section, p_config_attribute_name="hostname") configs = self.client_device_configs.get(client_device_section.name) if configs is None: configs = [] self.client_device_configs[client_device_section.name] = client_device_section configs.append(client_device_section)
def handle_section(self, p_section_name): rule_set_section = RuleSetConfigModel(p_section_name=p_section_name) self.scan(p_section=rule_set_section) tools.check_config_value(p_config=rule_set_section, p_config_attribute_name="username") rule_set_section.post_process() configs = self.rule_set_configs.get(rule_set_section.username) if configs is None: configs = [] self.rule_set_configs[rule_set_section.username] = configs configs.append(rule_set_section)
def __init__(self, p_config, p_reuse_session=True): self._logger = log_handling.get_logger(self.__class__.__name__) self._config = p_config self._session_used = False self._admin_session = None self._create_table_session = None self._admin_engine = None self._reuse_session = p_reuse_session if self._config.database_user is not None: tools.check_config_value(p_config=self._config, p_config_attribute_name="database_password") if self._config.database_admin is not None and self._config.database_admin_password is not None: url = urllib.parse.urlunsplit( ( self._config.database_driver, "%s:%s@%s:%d" % ( self._config.database_admin, self._config.database_admin_password, self._config.database_host, self._config.database_port), '', None, None )) fmt = "Database URL for administrative access: '%s'" % tools.anonymize_url(url) self._logger.info(fmt) if DATABASE_DRIVER_POSTGRESQL in self._config.database_driver: isolation_level = 'AUTOCOMMIT' else: isolation_level = None if isolation_level is not None: self._create_table_engine = sqlalchemy.create_engine(url, isolation_level=isolation_level) else: self._create_table_engine = sqlalchemy.create_engine(url) self._admin_engine = sqlalchemy.create_engine(url, pool_recycle=self._config.pool_recycle) if self._config.database_user is not None: url = urllib.parse.urlunsplit( ( self._config.database_driver, "%s:%s@%s:%d" % ( self._config.database_user, self._config.database_password, self._config.database_host, self._config.database_port), self._config.database_name, None, None )) else: url = "{driver}://".format(driver=self._config.database_driver) fmt = "Database URL for normal access: '%s'" % tools.anonymize_url(url) self._logger.info(fmt) self._engine = sqlalchemy.create_engine(url, pool_recycle=self._config.pool_recycle)
def __init__(self, p_config, p_reuse_session=True): self._logger = log_handling.get_logger(self.__class__.__name__) self._config = p_config self._session_used = False self._admin_session = None self._create_table_session = None self._admin_engine = None self._create_table_engine = None self._reuse_session = p_reuse_session self._users = None self._devices = None self._users_session = None self._devices_session = None self._cache_entities = True if self._config.database_user is not None: tools.check_config_value( p_config=self._config, p_config_attribute_name="database_password") if self._config.database_admin is not None and self._config.database_admin_password is not None: url = urllib.parse.urlunsplit( (self._config.database_driver, "%s:%s@%s:%d" % (self._config.database_admin, self._config.database_admin_password, self._config.database_host, self._config.database_port), '', None, None)) fmt = "Database URL for administrative access: '%s'" % tools.anonymize_url( url) self._logger.info(fmt) if DATABASE_DRIVER_POSTGRESQL in self._config.database_driver: isolation_level = 'AUTOCOMMIT' else: isolation_level = None if isolation_level is not None: self._create_table_engine = sqlalchemy.create_engine( url, isolation_level=isolation_level) else: self._create_table_engine = sqlalchemy.create_engine(url) self._admin_engine = sqlalchemy.create_engine( url, pool_recycle=self._config.pool_recycle) url = self.build_url() fmt = "Database URL for normal access: '%s'" % tools.anonymize_url(url) self._logger.info(fmt) options = {'pool_recycle': self._config.pool_recycle} if (DATABASE_DRIVER_POSTGRESQL in self._config.database_driver or DATABASE_DRIVER_MYSQL in self._config.database_driver): options['pool_size'] = self._config.pool_size options['max_overflow'] = self._config.max_overflow # if DATABASE_DRIVER_SQLITE in self._config.database_driver: # options['check_same_thread'] = False self._engine = sqlalchemy.create_engine(url, **options)
def __init__(self, p_name, p_config, p_package_name, p_user_handler=None, p_login_view=None, p_logged_out_endpoint=None): self._login_manager = None self._flask_stopper = None self._auth_view_handler = None self._server_started = False self._user_handler = p_user_handler self._csrf = None self._name = p_name self._config = p_config self._login_view = p_login_view if p_package_name is None: raise configuration.ConfigurationException( "HttpServer: p_package_name must not be None") self._logger = log_handling.get_logger(self.__class__.__name__) self._app = flask.Flask(p_package_name) # see https://improveandrepeat.com/2020/10/python-friday-43-add-security-headers-to-your-flask-application/ # see https://secure.readthedocs.io/en/latest/frameworks.html#flask self._app.after_request(set_secure_headers) # see https://stackoverflow.com/questions/62992831/python-session-samesite-none-not-being-set # see https://flask.palletsprojects.com/en/2.0.x/security/#security-cookie self._app.config['SESSION_COOKIE_SAMESITE'] = "Strict" self._flask_stopper = some_flask_helpers.FlaskStopper( p_app=self._app, p_logger=self._logger) self._app.config["APPLICATION_ROOT"] = self._config.base_url if self._user_handler is not None: tools.check_config_value(p_config=self._config, p_config_attribute_name="app_secret") self._auth_view_handler = auth_view_handler.AuthViewHandler( p_user_handler=self._user_handler, p_app=self._app, p_logged_out_endpoint=p_logged_out_endpoint, p_url_prefix=self._config.base_url, p_login_view=p_login_view) # Activate CSRF protection self._app.config.update(SECRET_KEY=self._config.app_secret) self._csrf = CSRFProtect() self._csrf.init_app(self._app) self._server_exception = None # Install the actuator handler for the health check self._actuator_view_handler = actuator.ActuatorViewHandler( p_app=self._app, p_url_prefix=self._config.internal_base_url) logger = log_handling.get_logger("werkzeug") logger.setLevel(logging.WARNING) logger = log_handling.get_logger("sqlalchemy.engine") logger.setLevel(logging.WARNING)