Pierre Hubert
9b18b787a9
All checks were successful
continuous-integration/drone/push Build is passing
Let BasicOIDC delegate authentication to upstream providers (Google, GitHub, GitLab, Keycloak...) Reviewed-on: #107
116 lines
2.9 KiB
Rust
116 lines
2.9 KiB
Rust
use std::path::{Path, PathBuf};
|
|
|
|
use clap::Parser;
|
|
|
|
use crate::constants::{
|
|
APP_NAME, CLIENTS_LIST_FILE, OIDC_PROVIDER_CB_URI, PROVIDERS_LIST_FILE, USERS_LIST_FILE,
|
|
};
|
|
|
|
/// Basic OIDC provider
|
|
#[derive(Parser, Debug, Clone)]
|
|
#[clap(author, version, about, long_about = None)]
|
|
pub struct AppConfig {
|
|
/// Listen address
|
|
#[clap(short, long, env, default_value = "0.0.0.0:8000")]
|
|
pub listen_address: String,
|
|
|
|
/// Storage path
|
|
#[clap(short, long, env)]
|
|
pub storage_path: String,
|
|
|
|
/// App token token
|
|
#[clap(short, long, env, default_value = "")]
|
|
pub token_key: String,
|
|
|
|
/// Website origin
|
|
#[clap(short, long, env, default_value = "http://localhost:8000")]
|
|
pub website_origin: String,
|
|
|
|
/// Proxy IP, might end with a star "*"
|
|
#[clap(short, long, env)]
|
|
pub proxy_ip: Option<String>,
|
|
|
|
/// IP location service API
|
|
///
|
|
/// Up instance of IP location service : https://gitlab.com/pierre42100/iplocationserver
|
|
///
|
|
/// Example: "https://api.geoip.rs"
|
|
#[arg(long, short, env)]
|
|
pub ip_location_service: Option<String>,
|
|
}
|
|
|
|
lazy_static::lazy_static! {
|
|
static ref ARGS: AppConfig = {
|
|
let mut config = AppConfig::parse();
|
|
|
|
// In debug mode only, use dummy token
|
|
if cfg!(debug_assertions) && config.token_key.is_empty() {
|
|
config.token_key = String::from_utf8_lossy(&[32; 64]).to_string();
|
|
}
|
|
|
|
config
|
|
};
|
|
}
|
|
|
|
impl AppConfig {
|
|
/// Get parsed command line arguments
|
|
pub fn get() -> &'static AppConfig {
|
|
&ARGS
|
|
}
|
|
|
|
pub fn secure_cookie(&self) -> bool {
|
|
self.website_origin.starts_with("https:")
|
|
}
|
|
|
|
pub fn storage_path(&self) -> &Path {
|
|
self.storage_path.as_ref()
|
|
}
|
|
|
|
pub fn users_file(&self) -> PathBuf {
|
|
self.storage_path().join(USERS_LIST_FILE)
|
|
}
|
|
|
|
pub fn clients_file(&self) -> PathBuf {
|
|
self.storage_path().join(CLIENTS_LIST_FILE)
|
|
}
|
|
|
|
pub fn providers_file(&self) -> PathBuf {
|
|
self.storage_path().join(PROVIDERS_LIST_FILE)
|
|
}
|
|
|
|
pub fn full_url(&self, uri: &str) -> String {
|
|
if uri.starts_with('/') {
|
|
format!("{}{}", self.website_origin, uri)
|
|
} else {
|
|
format!("{}/{}", self.website_origin, uri)
|
|
}
|
|
}
|
|
|
|
/// Get the URL where a upstream OpenID provider should redirect
|
|
/// the user after an authentication
|
|
pub fn oidc_provider_redirect_url(&self) -> String {
|
|
AppConfig::get().full_url(OIDC_PROVIDER_CB_URI)
|
|
}
|
|
|
|
pub fn domain_name(&self) -> &str {
|
|
self.website_origin.split('/').nth(2).unwrap_or(APP_NAME)
|
|
}
|
|
|
|
/// Get the domain without the port
|
|
pub fn domain_name_without_port(&self) -> &str {
|
|
let domain = self.domain_name();
|
|
domain.split_once(':').map(|i| i.0).unwrap_or(domain)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use crate::data::app_config::AppConfig;
|
|
|
|
#[test]
|
|
fn verify_cli() {
|
|
use clap::CommandFactory;
|
|
AppConfig::command().debug_assert()
|
|
}
|
|
}
|