This commit is contained in:
Mateusz Gruszczyński
2026-08-24 23:11:41 +02:00
parent 4ab878d587
commit 76a6f050ae
24 changed files with 600 additions and 108 deletions
+15 -2
View File
@@ -1,7 +1,7 @@
use std::{env, net::SocketAddr, path::PathBuf};
use anyhow::{Context, Result};
use clap::Parser;
use crate::models::{DebugSettings, HomeAssistantSettings, InfluxDbSettings, NightModeSettings, RuntimeSettings};
use crate::models::{DebugSettings, HomeAssistantSettings, InfluxDbSettings, NightModeSettings, NotificationSettings, RuntimeSettings};
#[derive(Debug, Clone, Parser)]
#[command(author, version, about)]
@@ -12,6 +12,8 @@ pub struct Config {
pub database: PathBuf,
#[arg(long, env = "GREE_CONTROLLER_APP_TOKEN", default_value = "")]
pub app_token: String,
#[arg(long, env = "GREE_CONTROLLER_BASE_PATH", default_value = "")]
pub base_path: String,
#[arg(long, env = "GREE_CONTROLLER_SIMULATE", default_value_t = false)]
pub simulate: bool,
#[arg(long, env = "GREE_CONTROLLER_AUTO_SEED", default_value_t = false)]
@@ -33,7 +35,8 @@ pub struct Config {
impl Config {
pub fn load() -> Result<Self> {
dotenvy::dotenv().ok();
let config = Self::parse();
let mut config = Self::parse();
config.base_path = normalize_base_path(&config.base_path)?;
if let Some(parent) = config.database.parent() {
std::fs::create_dir_all(parent)
.with_context(|| format!("cannot create database directory {}", parent.display()))?;
@@ -61,6 +64,7 @@ impl Config {
overlay_enabled: env_bool("GREE_CONTROLLER_DEBUG_OVERLAY").unwrap_or(false),
gree_frames: env_bool("GREE_CONTROLLER_DEBUG_GREE_FRAMES").unwrap_or(false),
},
notifications: NotificationSettings::default(),
night_mode: NightModeSettings {
enabled: env_bool("GREE_CONTROLLER_NIGHT_MODE_ENABLED").unwrap_or(false),
start_time: env::var("GREE_CONTROLLER_NIGHT_MODE_START").unwrap_or_else(|_| "22:00".into()),
@@ -128,6 +132,15 @@ impl Config {
}
}
fn normalize_base_path(value: &str) -> Result<String> {
let value = value.trim();
if value.is_empty() || value == "/" { return Ok(String::new()); }
if value.contains('?') || value.contains('#') || value.split('/').any(|part| matches!(part, "." | "..")) {
anyhow::bail!("GREE_CONTROLLER_BASE_PATH must be a simple URL path without '.', '..', query or fragment");
}
Ok(format!("/{}", value.trim_matches('/')))
}
fn env_bool(name: &str) -> Option<bool> {
env::var(name).ok().map(|v| matches!(v.to_ascii_lowercase().as_str(), "1" | "true" | "yes" | "on"))
}