Validate the session token with file uploads

File uploads now check the session token before continuing.

Resolves: https://www.pivotaltracker.com/story/show/186174680
This commit is contained in:
Savanni D'Gerinel 2023-10-03 17:30:43 -04:00
parent b3bfa84691
commit 9bb32a378c
2 changed files with 38 additions and 33 deletions

View File

@ -97,14 +97,15 @@ pub async fn handle_auth(
} }
} }
pub async fn handle_upload( pub async fn handle_upload(app: App, token: SessionToken) -> Result<http::Response<String>, Error> {
_app: App, match app.validate_session(token).await {
_token: SessionToken, Ok(Some(_)) => Response::builder()
) -> Result<http::Response<String>, Error> {
println!("handle_upload");
Response::builder()
.status(StatusCode::NOT_IMPLEMENTED) .status(StatusCode::NOT_IMPLEMENTED)
.body("".to_owned()) .body("".to_owned()),
_ => Response::builder()
.status(StatusCode::UNAUTHORIZED)
.body("".to_owned()),
}
} }
fn serve_file<F>( fn serve_file<F>(

View File

@ -159,26 +159,25 @@ fn with_app(app: App) -> impl Filter<Extract = (App,), Error = Infallible> + Clo
warp::any().map(move || app.clone()) warp::any().map(move || app.clone())
} }
fn parse_cookies(cookie_str: &str) -> Result<HashMap<String, String>, cookie::ParseError> {
Cookie::split_parse(cookie_str)
.map(|c| c.map(|c| (c.name().to_owned(), c.value().to_owned())))
.collect::<Result<HashMap<String, String>, cookie::ParseError>>()
}
fn get_session_token(cookies: HashMap<String, String>) -> Option<SessionToken> {
cookies
.get("session")
.cloned()
.and_then(|session| Some(SessionToken::from(session)))
}
fn maybe_with_session() -> impl Filter<Extract = (Option<SessionToken>,), Error = Rejection> + Copy fn maybe_with_session() -> impl Filter<Extract = (Option<SessionToken>,), Error = Rejection> + Copy
{ {
warp::any() warp::any()
.and(warp::header::optional::<String>("cookie")) .and(warp::header::optional::<String>("cookie"))
.map(|cookies| match cookies { .map(|cookie_str: Option<String>| match cookie_str {
Some(cookies) => { Some(cookie_str) => parse_cookies(&cookie_str).ok().and_then(get_session_token),
let c = Cookie::split_parse(cookies)
.collect::<Result<Vec<Cookie>, cookie::ParseError>>();
match c {
Ok(cookies) => {
for c in cookies {
if c.name() == "session" {
return Some(SessionToken::from(c.value()));
}
}
None
}
Err(_) => None,
}
}
None => None, None => None,
}) })
} }
@ -186,7 +185,12 @@ fn maybe_with_session() -> impl Filter<Extract = (Option<SessionToken>,), Error
fn with_session() -> impl Filter<Extract = (SessionToken,), Error = Rejection> + Copy { fn with_session() -> impl Filter<Extract = (SessionToken,), Error = Rejection> + Copy {
warp::any() warp::any()
.and(warp::header::<String>("cookie")) .and(warp::header::<String>("cookie"))
.map(|token: String| SessionToken::from(token)) .and_then(|cookie_str: String| async move {
match parse_cookies(&cookie_str).ok().and_then(get_session_token) {
Some(session_token) => Ok(session_token),
None => Err(warp::reject()),
}
})
} }
#[tokio::main] #[tokio::main]
@ -220,7 +224,7 @@ pub async fn main() {
.and(warp::filters::body::form()) .and(warp::filters::body::form())
.then(handle_auth); .then(handle_auth);
let upload_handler = warp::path!("upload") let upload_via_form = warp::path!("upload")
.and(warp::post()) .and(warp::post())
.and(with_app(app.clone())) .and(with_app(app.clone()))
.and(with_session()) .and(with_session())
@ -239,7 +243,7 @@ pub async fn main() {
.then(move |id, old_etags, app: App| file(app, id, old_etags)); .then(move |id, old_etags, app: App| file(app, id, old_etags));
let server = warp::serve( let server = warp::serve(
root.or(auth).with(log), /* root.or(auth).or(upload_via_form).with(log), /*
root.or(auth) root.or(auth)
.or(thumbnail) .or(thumbnail)
.or(file) .or(file)