mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 15:27:13 +03:00
edenapi_server: use client identity middleware
Summary: Use the client identity middleware from gotham_ext in the EdenAPI server. This middleware parses validated client identities from HTTP headers inserted by Proxygen; these identities can then be used to enforce repo ACLs. Reviewed By: HarveyHunt Differential Revision: D20744887 fbshipit-source-id: 651e171d1b20448b3e99bfc938d118fb6dddea91
This commit is contained in:
parent
063ce6dbe9
commit
e236ef9df3
@ -8,6 +8,7 @@
|
||||
#![deny(warnings)]
|
||||
|
||||
use std::net::SocketAddr;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
@ -26,13 +27,17 @@ use openssl::ssl::SslAcceptor;
|
||||
use slog::{error, info, warn, Logger};
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
use aclchecker::Identity;
|
||||
use cmdlib::{
|
||||
args,
|
||||
helpers::serve_forever,
|
||||
monitoring::{start_fb303_server, AliveService},
|
||||
};
|
||||
use fbinit::FacebookInit;
|
||||
use gotham_ext::{handler::MononokeHttpHandler, middleware::ServerIdentityMiddleware};
|
||||
use gotham_ext::{
|
||||
handler::MononokeHttpHandler,
|
||||
middleware::{ClientIdentityMiddleware, ServerIdentityMiddleware},
|
||||
};
|
||||
use mononoke_api::Mononoke;
|
||||
use secure_utils::SslConfig;
|
||||
|
||||
@ -50,6 +55,7 @@ const ARG_TLS_CERTIFICATE: &str = "tls-certificate";
|
||||
const ARG_TLS_PRIVATE_KEY: &str = "tls-private-key";
|
||||
const ARG_TLS_CA: &str = "tls-ca";
|
||||
const ARG_TLS_TICKET_SEEDS: &str = "tls-ticket-seeds";
|
||||
const ARG_TRUSTED_PROXY_IDENTITY: &str = "trusted-proxy-identity";
|
||||
|
||||
const SERVICE_NAME: &str = "mononoke_edenapi_server";
|
||||
|
||||
@ -116,6 +122,14 @@ fn build_tls_acceptor(
|
||||
Ok(builder.build())
|
||||
}
|
||||
|
||||
/// Parse AclChecker identities passed in as arguments.
|
||||
fn parse_identities(matches: &ArgMatches) -> Result<Vec<Identity>> {
|
||||
match matches.values_of(ARG_TRUSTED_PROXY_IDENTITY) {
|
||||
Some(values) => values.map(FromStr::from_str).collect(),
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
#[fbinit::main]
|
||||
fn main(fb: FacebookInit) -> Result<()> {
|
||||
let app = args::MononokeApp::new("EdenAPI Server")
|
||||
@ -157,6 +171,15 @@ fn main(fb: FacebookInit) -> Result<()> {
|
||||
Arg::with_name(ARG_TLS_TICKET_SEEDS)
|
||||
.long("--tls-ticket-seeds")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_TRUSTED_PROXY_IDENTITY)
|
||||
.long(ARG_TRUSTED_PROXY_IDENTITY)
|
||||
.takes_value(true)
|
||||
.multiple(true)
|
||||
.number_of_values(1)
|
||||
.required(false)
|
||||
.help("Proxy identity to trust"),
|
||||
);
|
||||
|
||||
let matches = app.get_matches();
|
||||
@ -165,6 +188,7 @@ fn main(fb: FacebookInit) -> Result<()> {
|
||||
let mysql_options = args::parse_mysql_options(&matches);
|
||||
let readonly_storage = args::parse_readonly_storage(&matches);
|
||||
let blobstore_options = args::parse_blobstore_options(&matches);
|
||||
let trusted_proxy_idents = parse_identities(&matches)?;
|
||||
|
||||
let caching = args::init_cachelib(fb, &matches, None);
|
||||
let logger = args::init_logging(fb, &matches);
|
||||
@ -198,6 +222,7 @@ fn main(fb: FacebookInit) -> Result<()> {
|
||||
// middleware is set up during router setup in build_router.
|
||||
let router = build_router(ctx);
|
||||
let handler = MononokeHttpHandler::builder()
|
||||
.add(ClientIdentityMiddleware::new(trusted_proxy_idents))
|
||||
.add(ServerIdentityMiddleware::new(HeaderValue::from_static(
|
||||
"edenapi_server",
|
||||
)))
|
||||
|
@ -5,14 +5,15 @@
|
||||
* GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
use gotham::state::{request_id, State};
|
||||
use gotham::state::{request_id, FromState, State};
|
||||
use gotham_derive::StateData;
|
||||
use hyper::{Body, Response};
|
||||
use slog::{o, Logger};
|
||||
|
||||
use context::{CoreContext, SessionContainer};
|
||||
use fbinit::FacebookInit;
|
||||
use gotham_ext::middleware::Middleware;
|
||||
use gotham_ext::middleware::{ClientIdentity, Middleware};
|
||||
use identity::{Identity, IdentitySet};
|
||||
use scuba::ScubaSampleBuilder;
|
||||
|
||||
#[derive(StateData)]
|
||||
@ -45,10 +46,13 @@ impl RequestContextMiddleware {
|
||||
#[async_trait::async_trait]
|
||||
impl Middleware for RequestContextMiddleware {
|
||||
async fn inbound(&self, state: &mut State) -> Option<Response<Body>> {
|
||||
let request_id = request_id(&state);
|
||||
let identities = extract_identities(state);
|
||||
let session = SessionContainer::builder(self.fb)
|
||||
.identities(identities)
|
||||
.build();
|
||||
|
||||
let request_id = request_id(&state);
|
||||
let logger = self.logger.new(o!("request_id" => request_id.to_string()));
|
||||
let session = SessionContainer::new_with_defaults(self.fb);
|
||||
let ctx = session.new_context(logger, ScubaSampleBuilder::with_discard());
|
||||
|
||||
state.put(RequestContext::new(ctx));
|
||||
@ -56,3 +60,10 @@ impl Middleware for RequestContextMiddleware {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_identities(state: &State) -> Option<IdentitySet> {
|
||||
ClientIdentity::borrow_from(state)
|
||||
.identities()
|
||||
.clone()
|
||||
.map(|ids: Vec<Identity>| ids.into_iter().collect())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user