/* Copyright 2021 Dominik George <dominik.george@teckids.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ use crate::BASE_NAME; use serde::de::Deserialize; extern crate config; pub fn get_config(conf_args: Option<config::Config>) -> config::Config { // Preset default configuration let mut conf = config::Config::default(); conf.set("pam.flow", "password").ok(); // Unwrap passed arguments or use empty fallback let conf_args = conf_args.unwrap_or_default(); // Determine config file from args if provided and load config file let config_file = match conf_args.get_str("config") { Ok(filename) => filename.to_string(), Err(_) => "/etc/".to_string() + BASE_NAME, }; conf.merge(config::File::with_name(&config_file)).ok(); // Override configuration from environment variables conf.merge(config::Environment::with_prefix(BASE_NAME.to_string().to_uppercase().as_str())).ok(); // Override configuration from args passed on module loading (e.g. args in PAM stack) conf.merge(conf_args).ok(); return conf; } pub fn argv_to_config(argv: &Vec<String>) -> config::Config { let mut conf = config::Config::default(); for arg in argv { if arg.contains("=") { let split: Vec<&str> = arg.split("=").collect(); conf.set(split[0], split[1]).ok(); } else { conf.set(arg, true).ok(); } } return conf; } pub fn get_optional<'de, T: Deserialize<'de>>(conf: &config::Config, key: &str) -> Option<T> { debug!("Looking up key {} in config", key); match conf.get(key) { Ok(v) => Some(v), Err(_) => { // Try falling back to parent block match key.find('.') { Some(i) => { debug!("Key {} not found in config, trying parent block", key); get_optional(conf, &key[i+1..]) }, None => None, } }, } } pub fn get_or_error<'de, T: Deserialize<'de>, E>(config: &config::Config, key: &str, error_value: E) -> Result<T, E> { match get_optional(config, key) { Some(v) => { debug!("Configuration key found: {}", key); return Ok(v); }, None => { error!("Configuration key not found: {}", key); return Err(error_value); }, } }