diff options
Diffstat (limited to 'src/handlers')
| -rw-r--r-- | src/handlers/mod.rs | 115 | 
1 files changed, 108 insertions, 7 deletions
| diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index efd99f5..1aba908 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -1,18 +1,18 @@  use crate::templates;  use handlebars::Handlebars; +use hyper::body::HttpBody as _;  use hyper::Method;  use hyper::StatusCode;  use hyper::{Body, Request, Response};  use serde::{Deserialize, Serialize};  use std::convert::Infallible; // TODO: -pub async fn router( -    req: Request<Body>, -    _client: mongodb::Client, -) -> Result<Response<Body>, Infallible> { +pub async fn router(req: Request<Body>) -> Result<Response<Body>, Infallible> {      match (req.method(), req.uri().path()) { -        (&Method::GET, "/") | (&Method::GET, "/index.html") => Ok(Response::new("Welcome!".into())), -        (&Method::GET, "/parts") | (&Method::GET, "/parts/index.html") => get_parts(req).await, +        (&Method::GET, "/") | (&Method::GET, "/index.html") => index(req).await, +        (&Method::GET, "/login") | (&Method::GET, "/login/index.html") => login().await, +        (&Method::GET, "/login/google") => login_google().await, +        (&Method::GET, "/login/google/code") => login_google_code(req).await,          _ => Ok(Response::builder()              .status(StatusCode::NOT_FOUND)              .body("Not found.".into()) @@ -20,7 +20,102 @@ pub async fn router(      }  } -async fn get_parts(req: Request<Body>) -> Result<Response<Body>, Infallible> { +async fn login() -> Result<Response<Body>, Infallible> { +    Ok(Response::new(templates::LOGIN_T.into())) +} + +async fn login_google() -> Result<Response<Body>, Infallible> { +    let uri = hyper::Uri::builder() +        .scheme("https") +        .authority("accounts.google.com") +        .path_and_query(format!( +            "{}?client_id={}&redirect_uri={}&response_type={}&scope={}&state={}", +            "/o/oauth2/v2/auth", +            "???", +            "http://localhost:3000/login/google/code", +            "code", +            "openid%20profile%20email", +            "BLARGH" +        )) +        .build() +        .unwrap(); +    let resp = Response::builder() +        .header(hyper::header::LOCATION, uri.to_string()) +        .status(StatusCode::TEMPORARY_REDIRECT) +        .body("".into()) +        .unwrap(); +    Ok(resp) +} + +#[derive(Serialize)] +struct AuthRequest { +    client_id: String, +    client_secret: String, +    grant_type: &'static str, +    redirect_uri: String, +    code: String, +} + +impl Default for AuthRequest { +    fn default() -> Self { +        Self { +            client_id: "???".into(), +            client_secret: "???".into(), +            grant_type: "authorization_code", +            redirect_uri: String::new(), +            code: String::new(), +        } +    } +} + +async fn login_google_code(req: Request<Body>) -> Result<Response<Body>, Infallible> { +    let query = req.uri().query().unwrap_or_default(); +    let query = serde_urlencoded::de::from_str::<GoogleOAuthQuery>(query).unwrap(); +    if query.state != "BLARGH" { +        dbg!("tampering?"); +    } + +    // get access token +    let auth_body = AuthRequest { +        code: query.code, +        redirect_uri: "http://localhost:3000/login/google/code".to_owned(), +        ..Default::default() +    }; + +    let https = hyper_rustls::HttpsConnector::with_native_roots(); +    let client: hyper::Client<_, hyper::Body> = hyper::Client::builder().build(https); + +    let req = Request::builder() +        .method(Method::POST) +        .uri("https://oauth2.googleapis.com/token") +        .header( +            hyper::header::CONTENT_TYPE, +            "application/x-www-form-urlencoded", +        ) +        .body(serde_urlencoded::ser::to_string(auth_body).unwrap().into()) +        .unwrap(); +    let mut resp = client.request(req).await.unwrap(); +    use std::io::prelude::*; +    while let Some(chunk) = resp.body_mut().data().await { +        std::io::stdout().write_all(&chunk.unwrap()).unwrap(); +    } + +    let resp = Response::builder() +        .header(hyper::header::LOCATION, "/".to_string()) +        .status(StatusCode::TEMPORARY_REDIRECT) +        .body("Successful login, redirecting...".into()) +        .unwrap(); +    Ok(resp) +} + +pub struct AccessToken { +    access_token: String, +    expires_in: String, +    scope: String, +    token_type: String, +} + +async fn index(req: Request<Body>) -> Result<Response<Body>, Infallible> {      let query = req.uri().query().unwrap_or_default();      let filter = serde_urlencoded::de::from_str::<PartsQuery>(query).unwrap();      let mut reg = Handlebars::new(); @@ -49,6 +144,12 @@ async fn get_parts(req: Request<Body>) -> Result<Response<Body>, Infallible> {  }  #[derive(Debug, Deserialize)] +struct GoogleOAuthQuery { +    code: String, +    state: String, +} + +#[derive(Debug, Deserialize)]  struct PartsQuery {      make: Option<String>,      year: Option<String>, |