New player
All checks were successful
Publish Server Image / build-and-push-image (push) Successful in 2m7s
All checks were successful
Publish Server Image / build-and-push-image (push) Successful in 2m7s
This commit is contained in:
106
furumi-web-player/src/main.rs
Normal file
106
furumi-web-player/src/main.rs
Normal file
@@ -0,0 +1,106 @@
|
||||
mod db;
|
||||
mod web;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(version, about = "Furumi Web Player: database-backed music player")]
|
||||
struct Args {
|
||||
/// IP address and port for the web player
|
||||
#[arg(long, env = "FURUMI_PLAYER_BIND", default_value = "0.0.0.0:8080")]
|
||||
bind: String,
|
||||
|
||||
/// PostgreSQL connection URL
|
||||
#[arg(long, env = "FURUMI_PLAYER_DATABASE_URL")]
|
||||
database_url: String,
|
||||
|
||||
/// Root directory where music files are stored (agent's storage_dir)
|
||||
#[arg(long, env = "FURUMI_PLAYER_STORAGE_DIR")]
|
||||
storage_dir: std::path::PathBuf,
|
||||
|
||||
/// OIDC Issuer URL (e.g. https://auth.example.com/application/o/furumi/)
|
||||
#[arg(long, env = "FURUMI_PLAYER_OIDC_ISSUER_URL")]
|
||||
oidc_issuer_url: Option<String>,
|
||||
|
||||
/// OIDC Client ID
|
||||
#[arg(long, env = "FURUMI_PLAYER_OIDC_CLIENT_ID")]
|
||||
oidc_client_id: Option<String>,
|
||||
|
||||
/// OIDC Client Secret
|
||||
#[arg(long, env = "FURUMI_PLAYER_OIDC_CLIENT_SECRET")]
|
||||
oidc_client_secret: Option<String>,
|
||||
|
||||
/// OIDC Redirect URL (e.g. https://music.example.com/auth/callback)
|
||||
#[arg(long, env = "FURUMI_PLAYER_OIDC_REDIRECT_URL")]
|
||||
oidc_redirect_url: Option<String>,
|
||||
|
||||
/// OIDC Session Secret (32+ chars, for HMAC). Random if not provided.
|
||||
#[arg(long, env = "FURUMI_PLAYER_OIDC_SESSION_SECRET")]
|
||||
oidc_session_secret: Option<String>,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Install ring as the default crypto provider for rustls
|
||||
rustls::crypto::ring::default_provider()
|
||||
.install_default()
|
||||
.expect("Failed to install rustls crypto provider");
|
||||
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let args = Args::parse();
|
||||
|
||||
let version = option_env!("FURUMI_VERSION").unwrap_or(env!("CARGO_PKG_VERSION"));
|
||||
tracing::info!("Furumi Web Player v{} starting", version);
|
||||
tracing::info!("Storage directory: {:?}", args.storage_dir);
|
||||
|
||||
if !args.storage_dir.exists() || !args.storage_dir.is_dir() {
|
||||
eprintln!("Error: Storage directory {:?} does not exist or is not a directory", args.storage_dir);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
tracing::info!("Connecting to database...");
|
||||
let pool = db::connect(&args.database_url).await?;
|
||||
tracing::info!("Database connected");
|
||||
|
||||
// Initialize OIDC if configured
|
||||
let oidc_state = if let (Some(issuer), Some(client_id), Some(secret), Some(redirect)) = (
|
||||
args.oidc_issuer_url,
|
||||
args.oidc_client_id,
|
||||
args.oidc_client_secret,
|
||||
args.oidc_redirect_url,
|
||||
) {
|
||||
tracing::info!("OIDC (SSO): enabled (issuer: {})", issuer);
|
||||
match web::auth::oidc_init(issuer, client_id, secret, redirect, args.oidc_session_secret).await {
|
||||
Ok(state) => Some(Arc::new(state)),
|
||||
Err(e) => {
|
||||
eprintln!("Error initializing OIDC: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tracing::info!("OIDC (SSO): disabled (no OIDC configuration provided)");
|
||||
None
|
||||
};
|
||||
|
||||
let bind_addr: std::net::SocketAddr = args.bind.parse().unwrap_or_else(|e| {
|
||||
eprintln!("Error: Invalid bind address '{}': {}", args.bind, e);
|
||||
std::process::exit(1);
|
||||
});
|
||||
|
||||
let state = Arc::new(web::AppState {
|
||||
pool,
|
||||
storage_dir: Arc::new(args.storage_dir),
|
||||
oidc: oidc_state,
|
||||
});
|
||||
|
||||
tracing::info!("Web player: http://{}", bind_addr);
|
||||
|
||||
let app = web::build_router(state);
|
||||
let listener = tokio::net::TcpListener::bind(bind_addr).await?;
|
||||
axum::serve(listener, app).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user