summaryrefslogtreecommitdiff
path: root/src/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'src/handlers')
-rw-r--r--src/handlers/mod.rs115
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>,