ci(ruff): add bandit checks (#575)

Added bandit checks to continuous integration.

Updated sources to pass bandit checks:
- replaced asserts
- added timeouts to requests
- added checks for process command execution
- changed to 127.0.0.1 as default IP address for EOS and EOSdash for security reasons

Added a rudimentary check for outdated config files.

BREAKING CHANGE: Default IP address for EOS and EOSdash changed to 127.0.0.1

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
This commit is contained in:
Bobby Noelte
2025-06-03 08:30:37 +02:00
committed by GitHub
parent aa39ff475c
commit 3421b2303b
34 changed files with 163 additions and 86 deletions

View File

@@ -82,8 +82,8 @@ def AdminConfig(
try:
if config:
config_file_path = get_nested_value(config, ["general", "config_file_path"])
except:
pass
except Exception as e:
logger.debug(f"general.config_file_path: {e}")
# export config file
export_to_file_next_tag = to_datetime(as_string="YYYYMMDDHHmmss")
export_to_file_status = (None,)
@@ -95,7 +95,7 @@ def AdminConfig(
if data["action"] == "save_to_file":
# Safe current configuration to file
try:
result = requests.put(f"{server}/v1/config/file")
result = requests.put(f"{server}/v1/config/file", timeout=10)
result.raise_for_status()
config_file_path = result.json()["general"]["config_file_path"]
status = Success(f"Saved to '{config_file_path}' on '{eos_hostname}'")
@@ -143,7 +143,7 @@ def AdminConfig(
try:
with import_file_path.open("r", encoding="utf-8", newline=None) as fd:
import_config = json.load(fd)
result = requests.put(f"{server}/v1/config", json=import_config)
result = requests.put(f"{server}/v1/config", json=import_config, timeout=10)
result.raise_for_status()
import_from_file_status = Success(
f"Config imported from '{import_file_path}' on '{eosdash_hostname}'"
@@ -267,7 +267,7 @@ def Admin(eos_host: str, eos_port: Union[str, int], data: Optional[dict] = None)
# Get current configuration from server
server = f"http://{eos_host}:{eos_port}"
try:
result = requests.get(f"{server}/v1/config")
result = requests.get(f"{server}/v1/config", timeout=10)
result.raise_for_status()
config = result.json()
except requests.exceptions.HTTPError as e:

View File

@@ -218,7 +218,7 @@ def get_configuration(eos_host: str, eos_port: Union[str, int]) -> list[dict]:
# Get current configuration from server
try:
result = requests.get(f"{server}/v1/config")
result = requests.get(f"{server}/v1/config", timeout=10)
result.raise_for_status()
config = result.json()
except requests.exceptions.HTTPError as e:
@@ -303,9 +303,14 @@ def ConfigPlanesCard(
planes_update_open = True
plane_update_open = True
# Make mypy happy - should never trigger
assert isinstance(update_error, (str, type(None)))
assert isinstance(update_value, (str, type(None)))
assert isinstance(update_open, (bool, type(None)))
if (
not isinstance(update_error, (str, type(None)))
or not isinstance(update_value, (str, type(None)))
or not isinstance(update_open, (bool, type(None)))
):
error_msg = "update_error or update_value or update_open of wrong type."
logger.error(error_msg)
raise TypeError(error_msg)
plane_rows.append(
ConfigCard(
config["name"],
@@ -441,9 +446,14 @@ def Configuration(
update_value = config_update_latest.get(config["name"], {}).get("value")
update_open = config_update_latest.get(config["name"], {}).get("open")
# Make mypy happy - should never trigger
assert isinstance(update_error, (str, type(None)))
assert isinstance(update_value, (str, type(None)))
assert isinstance(update_open, (bool, type(None)))
if (
not isinstance(update_error, (str, type(None)))
or not isinstance(update_value, (str, type(None)))
or not isinstance(update_open, (bool, type(None)))
):
error_msg = "update_error or update_value or update_open of wrong type."
logger.error(error_msg)
raise TypeError(error_msg)
if (
config["type"]
== "Optional[list[akkudoktoreos.prediction.pvforecast.PVForecastPlaneSetting]]"
@@ -505,7 +515,7 @@ def ConfigKeyUpdate(eos_host: str, eos_port: Union[str, int], key: str, value: s
error = None
config = None
try:
response = requests.put(f"{server}/v1/config/{path}", json=data)
response = requests.put(f"{server}/v1/config/{path}", json=data, timeout=10)
response.raise_for_status()
config = response.json()
except requests.exceptions.HTTPError as err:

View File

@@ -75,9 +75,9 @@
},
"server": {
"startup_eosdash": true,
"host": "0.0.0.0",
"host": "127.0.0.1",
"port": 8503,
"eosdash_host": "0.0.0.0",
"eosdash_host": "127.0.0.1",
"eosdash_port": 8504
},
"weather": {

View File

@@ -186,7 +186,7 @@ def Demo(eos_host: str, eos_port: Union[str, int]) -> str:
# Get current configuration from server
try:
result = requests.get(f"{server}/v1/config")
result = requests.get(f"{server}/v1/config", timeout=10)
result.raise_for_status()
except requests.exceptions.HTTPError as err:
detail = result.json()["detail"]
@@ -200,12 +200,12 @@ def Demo(eos_host: str, eos_port: Union[str, int]) -> str:
with FILE_DEMOCONFIG.open("r", encoding="utf-8") as fd:
democonfig = json.load(fd)
try:
result = requests.put(f"{server}/v1/config", json=democonfig)
result = requests.put(f"{server}/v1/config", json=democonfig, timeout=10)
result.raise_for_status()
except requests.exceptions.HTTPError as err:
detail = result.json()["detail"]
# Try to reset to original config
requests.put(f"{server}/v1/config", json=config)
requests.put(f"{server}/v1/config", json=config, timeout=10)
return P(
f"Can not set demo configuration on {server}: {err}, {detail}",
cls="text-center",
@@ -213,12 +213,12 @@ def Demo(eos_host: str, eos_port: Union[str, int]) -> str:
# Update all predictions
try:
result = requests.post(f"{server}/v1/prediction/update")
result = requests.post(f"{server}/v1/prediction/update", timeout=10)
result.raise_for_status()
except requests.exceptions.HTTPError as err:
detail = result.json()["detail"]
# Try to reset to original config
requests.put(f"{server}/v1/config", json=config)
requests.put(f"{server}/v1/config", json=config, timeout=10)
return P(
f"Can not update predictions on {server}: {err}, {detail}",
cls="text-center",
@@ -239,7 +239,7 @@ def Demo(eos_host: str, eos_port: Union[str, int]) -> str:
"load_mean_adjusted",
],
}
result = requests.get(f"{server}/v1/prediction/dataframe", params=params)
result = requests.get(f"{server}/v1/prediction/dataframe", params=params, timeout=10)
result.raise_for_status()
predictions = PydanticDateTimeDataFrame(**result.json()).to_dataframe()
except requests.exceptions.HTTPError as err:
@@ -255,7 +255,7 @@ def Demo(eos_host: str, eos_port: Union[str, int]) -> str:
)
# Reset to original config
requests.put(f"{server}/v1/config", json=config)
requests.put(f"{server}/v1/config", json=config, timeout=10)
return Grid(
DemoPVForecast(predictions, democonfig),

View File

@@ -24,7 +24,7 @@ def get_alive(eos_host: str, eos_port: Union[str, int]) -> str:
"""
result = requests.Response()
try:
result = requests.get(f"http://{eos_host}:{eos_port}/v1/health")
result = requests.get(f"http://{eos_host}:{eos_port}/v1/health", timeout=10)
if result.status_code == 200:
alive = result.json()["status"]
else: