2021-04-20 10:07:11 -06:00
|
|
|
use std::convert::Infallible;
|
|
|
|
|
|
|
|
use eyre::Result;
|
2021-04-25 11:21:52 -06:00
|
|
|
use warp::{hyper::StatusCode, Filter};
|
2021-04-20 10:07:11 -06:00
|
|
|
|
2021-04-20 14:53:07 -06:00
|
|
|
use atuin_common::api::SyncHistoryRequest;
|
|
|
|
|
2022-03-13 13:53:49 -06:00
|
|
|
use super::{
|
|
|
|
database::{Database, Postgres},
|
|
|
|
handlers,
|
|
|
|
};
|
|
|
|
use crate::{models::User, settings::Settings};
|
2021-04-20 10:07:11 -06:00
|
|
|
|
|
|
|
fn with_settings(
|
|
|
|
settings: Settings,
|
|
|
|
) -> impl Filter<Extract = (Settings,), Error = Infallible> + Clone {
|
|
|
|
warp::any().map(move || settings.clone())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn with_db(
|
|
|
|
db: impl Database + Clone + Send + Sync,
|
|
|
|
) -> impl Filter<Extract = (impl Database + Clone,), Error = Infallible> + Clone {
|
|
|
|
warp::any().map(move || db.clone())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn with_user(
|
|
|
|
postgres: Postgres,
|
|
|
|
) -> impl Filter<Extract = (User,), Error = warp::Rejection> + Clone {
|
|
|
|
warp::header::<String>("authorization").and_then(move |header: String| {
|
|
|
|
// async closures are still buggy :(
|
|
|
|
let postgres = postgres.clone();
|
|
|
|
|
|
|
|
async move {
|
|
|
|
let header: Vec<&str> = header.split(' ').collect();
|
|
|
|
|
2022-03-13 13:53:49 -06:00
|
|
|
let token = if header.len() == 2 {
|
2021-04-20 10:07:11 -06:00
|
|
|
if header[0] != "Token" {
|
|
|
|
return Err(warp::reject());
|
|
|
|
}
|
|
|
|
|
2022-03-13 13:53:49 -06:00
|
|
|
header[1]
|
2021-04-20 10:07:11 -06:00
|
|
|
} else {
|
|
|
|
return Err(warp::reject());
|
2022-03-13 13:53:49 -06:00
|
|
|
};
|
2021-04-20 10:07:11 -06:00
|
|
|
|
|
|
|
let user = postgres
|
|
|
|
.get_session_user(token)
|
|
|
|
.await
|
|
|
|
.map_err(|_| warp::reject())?;
|
|
|
|
|
|
|
|
Ok(user)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn router(
|
|
|
|
settings: &Settings,
|
2021-04-25 11:21:52 -06:00
|
|
|
) -> Result<impl Filter<Extract = impl warp::Reply, Error = Infallible> + Clone> {
|
2021-04-20 14:53:07 -06:00
|
|
|
let postgres = Postgres::new(settings.db_uri.as_str()).await?;
|
2021-04-20 10:07:11 -06:00
|
|
|
let index = warp::get().and(warp::path::end()).map(handlers::index);
|
|
|
|
|
|
|
|
let count = warp::get()
|
|
|
|
.and(warp::path("sync"))
|
|
|
|
.and(warp::path("count"))
|
|
|
|
.and(warp::path::end())
|
|
|
|
.and(with_user(postgres.clone()))
|
|
|
|
.and(with_db(postgres.clone()))
|
2021-11-21 07:34:04 -07:00
|
|
|
.and_then(handlers::history::count)
|
|
|
|
.boxed();
|
2021-04-20 10:07:11 -06:00
|
|
|
|
|
|
|
let sync = warp::get()
|
|
|
|
.and(warp::path("sync"))
|
|
|
|
.and(warp::path("history"))
|
|
|
|
.and(warp::query::<SyncHistoryRequest>())
|
|
|
|
.and(warp::path::end())
|
|
|
|
.and(with_user(postgres.clone()))
|
|
|
|
.and(with_db(postgres.clone()))
|
2021-11-21 07:34:04 -07:00
|
|
|
.and_then(handlers::history::list)
|
|
|
|
.boxed();
|
2021-04-20 10:07:11 -06:00
|
|
|
|
|
|
|
let add_history = warp::post()
|
|
|
|
.and(warp::path("history"))
|
|
|
|
.and(warp::path::end())
|
|
|
|
.and(warp::body::json())
|
|
|
|
.and(with_user(postgres.clone()))
|
|
|
|
.and(with_db(postgres.clone()))
|
2021-11-21 07:34:04 -07:00
|
|
|
.and_then(handlers::history::add)
|
|
|
|
.boxed();
|
2021-04-20 10:07:11 -06:00
|
|
|
|
|
|
|
let user = warp::get()
|
|
|
|
.and(warp::path("user"))
|
|
|
|
.and(warp::path::param::<String>())
|
|
|
|
.and(warp::path::end())
|
|
|
|
.and(with_db(postgres.clone()))
|
2021-11-21 07:34:04 -07:00
|
|
|
.and_then(handlers::user::get)
|
|
|
|
.boxed();
|
2021-04-20 10:07:11 -06:00
|
|
|
|
|
|
|
let register = warp::post()
|
|
|
|
.and(warp::path("register"))
|
|
|
|
.and(warp::path::end())
|
|
|
|
.and(warp::body::json())
|
|
|
|
.and(with_settings(settings.clone()))
|
|
|
|
.and(with_db(postgres.clone()))
|
2021-11-21 07:34:04 -07:00
|
|
|
.and_then(handlers::user::register)
|
|
|
|
.boxed();
|
2021-04-20 10:07:11 -06:00
|
|
|
|
|
|
|
let login = warp::post()
|
|
|
|
.and(warp::path("login"))
|
|
|
|
.and(warp::path::end())
|
|
|
|
.and(warp::body::json())
|
|
|
|
.and(with_db(postgres))
|
2021-11-21 07:34:04 -07:00
|
|
|
.and_then(handlers::user::login)
|
|
|
|
.boxed();
|
2021-04-20 10:07:11 -06:00
|
|
|
|
|
|
|
let r = warp::any()
|
|
|
|
.and(
|
|
|
|
index
|
|
|
|
.or(count)
|
|
|
|
.or(sync)
|
|
|
|
.or(add_history)
|
|
|
|
.or(user)
|
|
|
|
.or(register)
|
2021-04-25 11:21:52 -06:00
|
|
|
.or(login)
|
|
|
|
.or(warp::any().map(|| warp::reply::with_status("☕", StatusCode::IM_A_TEAPOT))),
|
2021-04-20 10:07:11 -06:00
|
|
|
)
|
|
|
|
.with(warp::filters::log::log("atuin::api"));
|
|
|
|
|
|
|
|
Ok(r)
|
|
|
|
}
|