Protect the session_key from external libs. Clean-up config docs.

This commit is contained in:
Sergio Benitez 2016-10-15 18:58:57 -07:00
parent cf9f746ee2
commit 471239c567
3 changed files with 44 additions and 26 deletions

View File

@ -1,6 +1,8 @@
use std::collections::HashMap;
use std::net::ToSocketAddrs;
use std::path::Path;
use std::cell::RefCell;
use std::fmt;
use config::Environment::*;
use config::{self, Environment, ConfigError};
@ -8,13 +10,13 @@ use config::{self, Environment, ConfigError};
use logger::LoggingLevel;
use toml::Value;
#[derive(Debug, PartialEq, Clone)]
#[derive(PartialEq)]
pub struct Config {
pub address: String,
pub port: usize,
pub log_level: LoggingLevel,
pub session_key: Option<String>,
pub env: Environment,
session_key: RefCell<Option<String>>,
extra: HashMap<String, Value>,
filename: String,
}
@ -41,7 +43,7 @@ impl Config {
address: "localhost".to_string(),
port: 8000,
log_level: LoggingLevel::Normal,
session_key: None,
session_key: RefCell::new(None),
extra: HashMap::new(),
env: env,
filename: filename.to_string(),
@ -52,7 +54,7 @@ impl Config {
address: "0.0.0.0".to_string(),
port: 80,
log_level: LoggingLevel::Normal,
session_key: None,
session_key: RefCell::new(None),
extra: HashMap::new(),
env: env,
filename: filename.to_string(),
@ -63,7 +65,7 @@ impl Config {
address: "0.0.0.0".to_string(),
port: 80,
log_level: LoggingLevel::Critical,
session_key: None,
session_key: RefCell::new(None),
extra: HashMap::new(),
env: env,
filename: filename.to_string(),
@ -101,7 +103,7 @@ impl Config {
return Err(self.bad_type(name, val, "a 192-bit base64 string"));
}
self.session_key = Some(key.to_string());
self.session_key = RefCell::new(Some(key.to_string()));
} else if name == "log" {
let level_str = parse!(self, name, val, as_str, "a string")?;
self.log_level = match level_str.parse() {
@ -116,6 +118,16 @@ impl Config {
Ok(())
}
#[inline(always)]
pub fn take_session_key(&self) -> Option<String> {
self.session_key.borrow_mut().take()
}
#[inline(always)]
pub fn extras<'a>(&'a self) -> impl Iterator<Item=(&'a String, &'a Value)> {
self.extra.iter()
}
pub fn get_str<'a>(&'a self, name: &str) -> config::Result<&'a str> {
let value = self.extra.get(name).ok_or_else(|| ConfigError::NotFound)?;
parse!(self, name, value, as_str, "a string")
@ -143,11 +155,6 @@ impl Config {
}
}
#[inline(always)]
pub fn extras<'a>(&'a self) -> impl Iterator<Item=(&'a String, &'a Value)> {
self.extra.iter()
}
// Builder pattern below, mostly for testing.
#[inline(always)]
@ -170,7 +177,7 @@ impl Config {
#[inline(always)]
pub fn session_key(mut self, var: String) -> Self {
self.session_key = Some(var);
self.session_key = RefCell::new(Some(var));
self
}
@ -180,3 +187,10 @@ impl Config {
self
}
}
impl fmt::Debug for Config {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Config[{}] {{ address: {}, port: {}, log_level: {:?} }}",
self.env, self.address, self.port, self.log_level)
}
}

View File

@ -11,8 +11,8 @@ use std::env;
pub use self::error::{ConfigError, ParsingError};
pub use self::environment::Environment;
pub use self::config::Config;
use self::Environment::*;
use self::config::Config;
use toml::{self, Table};
use logger::{self, LoggingLevel};
@ -23,7 +23,7 @@ const CONFIG_FILENAME: &'static str = "Rocket.toml";
pub type Result<T> = ::std::result::Result<T, ConfigError>;
#[derive(Debug, PartialEq, Clone)]
#[derive(Debug, PartialEq)]
pub struct RocketConfig {
pub active_env: Environment,
config: HashMap<Environment, Config>,
@ -152,14 +152,16 @@ impl RocketConfig {
///
/// # Panics
///
/// If there is a problem, prints a nice error message and bails.
/// If there is a problem, prints a nice error message and bails. This function
/// also panics if it is called more than once.
///
/// # Thread-Safety
///
/// This function is _not_ thread-safe. It should be called by a single thread.
#[doc(hidden)]
pub fn init() -> &'static Config {
if let Some(config) = active() {
return config;
if active().is_some() {
panic!("Configuration has already been initialized!")
}
let bail = |e: ConfigError| -> ! {
@ -192,6 +194,7 @@ pub fn init() -> &'static Config {
}
}
/// Retrieve the active configuration, if there is one.
pub fn active() -> Option<&'static Config> {
unsafe { CONFIG.as_ref().map(|c| c.active()) }
}
@ -225,9 +228,9 @@ mod test {
);
($env:expr, $rconfig:expr, $econfig:expr) => (
match $rconfig.clone() {
Ok(config) => assert_eq!(config.get($env), &$econfig),
Err(e) => panic!("Config {} failed: {:?}", stringify!($rconfig), e)
match $rconfig {
Ok(ref config) => assert_eq!(config.get($env), &$econfig),
Err(ref e) => panic!("Config {} failed: {:?}", stringify!($rconfig), e)
}
);
}
@ -306,11 +309,12 @@ mod test {
pi = 3.14
"#;
let mut expected = default_config(Development);
expected.address = "1.2.3.4".to_string();
expected.port = 7810;
expected.log_level = LoggingLevel::Critical;
expected.session_key = Some("01234567890123456789012345678901".to_string());
let mut expected = default_config(Development)
.address("1.2.3.4".to_string())
.port(7810)
.log_level(LoggingLevel::Critical)
.session_key("01234567890123456789012345678901".into());
expected.set("template_dir", &Value::String("mine".into())).unwrap();
expected.set("json", &Value::Boolean(true)).unwrap();
expected.set("pi", &Value::Float(3.14)).unwrap();

View File

@ -235,7 +235,7 @@ impl Rocket {
White.paint(&config.address),
White.paint(&config.port));
info_!("logging: {:?}", White.paint(config.log_level));
info_!("session key: {}", White.paint(config.session_key.is_some()));
info_!("session key: {}", White.paint(config.take_session_key().is_some()));
for (name, value) in config.extras() {
info_!("{} {}: {}", Yellow.paint("[extra]"), name, White.paint(value));
}