Only trust the X-Identity header when it is specified on the command line

This commit is contained in:
Magnus Hoff 2017-10-18 16:45:04 +02:00
parent c85715c969
commit d22ac6ef84
3 changed files with 23 additions and 8 deletions

View file

@ -25,10 +25,13 @@ is built like other Rust projects, with `cargo build`.
Command line arguments Command line arguments
---------------------- ----------------------
USAGE: USAGE:
sausagewiki [OPTIONS] <DATABASE> sausagewiki [FLAGS] [OPTIONS] <DATABASE>
FLAGS: FLAGS:
-h, --help Prints help information -h, --help Prints help information
--trust_identity Trust the value in the X-Identity header to be an authenticated username.
This only makes sense when Sausagewiki runs behind a reverse proxy which
sets this header.
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:

View file

@ -52,6 +52,11 @@ fn args<'a>() -> clap::ArgMatches<'a> {
Err(_) => Err("Must be an integer in the range [0, 65535]".to_owned()) Err(_) => Err("Must be an integer in the range [0, 65535]".to_owned())
}) })
.takes_value(true)) .takes_value(true))
.arg(Arg::with_name("trust_identity")
.help("Trust the value in the X-Identity header to be an \
authenticated username. This only makes sense when Sausagewiki \
runs behind a reverse proxy which sets this header.")
.long("trust_identity"))
.get_matches() .get_matches()
} }
@ -64,6 +69,8 @@ fn core_main() -> Result<(), Box<std::error::Error>> {
.map(|p| p.parse().expect("Guaranteed by validator")) .map(|p| p.parse().expect("Guaranteed by validator"))
.unwrap_or(8080); .unwrap_or(8080);
let trust_identity = args.is_present("trust_identity");
let db_pool = db::create_pool(db_file)?; let db_pool = db::create_pool(db_file)?;
let cpu_pool = futures_cpupool::CpuPool::new_num_cpus(); let cpu_pool = futures_cpupool::CpuPool::new_num_cpus();
@ -74,7 +81,7 @@ fn core_main() -> Result<(), Box<std::error::Error>> {
hyper::server::Http::new() hyper::server::Http::new()
.bind( .bind(
&SocketAddr::new(bind_host, bind_port), &SocketAddr::new(bind_host, bind_port),
move || Ok(site::Site::new(lookup.clone())) move || Ok(site::Site::new(lookup.clone(), trust_identity))
)?; )?;
println!("Listening on http://{}", server.local_addr().unwrap()); println!("Listening on http://{}", server.local_addr().unwrap());

View file

@ -17,6 +17,8 @@ lazy_static! {
static ref TEXT_HTML: mime::Mime = "text/html;charset=utf-8".parse().unwrap(); static ref TEXT_HTML: mime::Mime = "text/html;charset=utf-8".parse().unwrap();
} }
header! { (XIdentity, "X-Identity") => [String] }
#[derive(BartDisplay)] #[derive(BartDisplay)]
#[template = "templates/layout.html"] #[template = "templates/layout.html"]
pub struct Layout<'a, T: 'a + fmt::Display> { pub struct Layout<'a, T: 'a + fmt::Display> {
@ -36,11 +38,12 @@ struct InternalServerError;
pub struct Site { pub struct Site {
root: WikiLookup, root: WikiLookup,
trust_identity: bool,
} }
impl Site { impl Site {
pub fn new(root: WikiLookup) -> Site { pub fn new(root: WikiLookup, trust_identity: bool) -> Site {
Site { root } Site { root, trust_identity }
} }
fn not_found(base: Option<&str>) -> Response { fn not_found(base: Option<&str>) -> Response {
@ -91,8 +94,10 @@ impl Service for Site {
println!("{} {}", method, uri); println!("{} {}", method, uri);
header! { (XIdentity, "X-Identity") => [String] } let identity: Option<String> = match self.trust_identity {
let identity: Option<String> = headers.get().map(|x: &XIdentity| x.to_string()); true => headers.get().map(|x: &XIdentity| x.to_string()),
false => None,
};
let base = root_base_from_request_uri(uri.path()); let base = root_base_from_request_uri(uri.path());
let base2 = base.clone(); // Bah, stupid clone let base2 = base.clone(); // Bah, stupid clone