diff --git a/TODO b/TODO index 64b7b3c..17c54c6 100644 --- a/TODO +++ b/TODO @@ -11,6 +11,15 @@ Auth using email ##### API v0 # Auth link (device check url with this session and get data) -/auth?session= +/v0/auth?session=&back_url= # Get auth data -/auth_finish?session= +/v0/auth_finish?session= + + +##### API v1 +# Auth link +/v1/auth?session=&back_url= +# Get token +/v1/auth_finish?session= +# Refresh token +/v1/refresh?token= diff --git a/src/main.rs b/src/main.rs index ce91b65..8ac3ef0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ mod funcs; mod types; mod html; -mod api; +mod url; use { std::{ @@ -84,6 +84,9 @@ use { }, html::*, funcs::*, + url::{ + api, + }, }, }; diff --git a/src/url.rs b/src/url.rs new file mode 100644 index 0000000..e5fdf85 --- /dev/null +++ b/src/url.rs @@ -0,0 +1 @@ +pub mod api; diff --git a/src/api.rs b/src/url/api.rs similarity index 90% rename from src/api.rs rename to src/url/api.rs index eea2d3e..ec4d233 100644 --- a/src/api.rs +++ b/src/url/api.rs @@ -1,4 +1,5 @@ mod v0; +mod v1; use { hyper::{ @@ -26,6 +27,7 @@ pub async fn endpoint(req: Request, pool: DBPool) -> (String, StatusCo let res: Json = match &uri[4..uri.len()] { "/test" => json!({"error": false, "msg": "test"}), x if x.starts_with("/v0/") => v0::api(req, pool.clone()).await, + x if x.starts_with("/v1/") => v1::api(req, pool.clone()).await, _ => json!({"error": true, "msg": "No endpoint"}) }; diff --git a/src/api/v0.rs b/src/url/api/v0.rs similarity index 100% rename from src/api/v0.rs rename to src/url/api/v0.rs diff --git a/src/url/api/v1.rs b/src/url/api/v1.rs new file mode 100644 index 0000000..f970298 --- /dev/null +++ b/src/url/api/v1.rs @@ -0,0 +1,83 @@ +use { + hyper::{ + Request, + body::{ + Incoming, + }, + }, + serde_json::{ + Value as Json, + json, + }, + skytable::{ + pool::ConnectionMgrTcp, + query, + }, + bb8::Pool, + std::sync::Arc, + crate::{ + time, + double_split, + }, +}; + +type DBPool = Arc>; + + +pub async fn api(req: Request, pool: DBPool) -> Json { + let uri: &str = req.uri().path().as_ref(); + match &uri[7..uri.len()] { + "/auth" => auth(req, pool.clone()).await, + "/auth_get" => auth_get(req, pool.clone()).await, + _ => json!({"error": true, "msg": "No endpoint"}) + } +} + +async fn auth(req: Request, _pool: DBPool) -> Json { + let query = req.uri().query().or(Some("")).unwrap(); + let query = double_split(query.to_string(), "&", "="); + let sess = std::string::String::from(query + .get("session") + .or(Some(&"".to_string())) + .unwrap()); + match sess.as_str() { + "" => json!({"error": true, "msg": "No session in request"}), + x if x.len() > 128 => json!({"error": true, "msg": "Session len is too long"}), + _ => json!({ + "error": false, + "link": format!("https://auth.bitheaven.ru/authorize?v=0&session={}", sess) + }) + } +} + +async fn auth_get(req: Request, pool: DBPool) -> Json { + let mut con = pool.get().await.unwrap(); + + let query = req.uri().query().or(Some("")).unwrap(); + let query = double_split(query.to_string(), "&", "="); + let session = match query.get("session").is_none() { + false => query.get("session").unwrap(), + _ => "" + }; + + let res = con.query_parse::<(String, String, u32)>(&query!( + "SELECT login, uuid, expire FROM bitauth.v0 WHERE session = ?", + session + )).await; + let _ = con.query_parse::<()>(&query!( + "DELETE FROM bitauth.v0 WHERE session = ?", + session + )).await; + + let (login, uuid, exp) = match res.is_ok() { + false => ("".to_owned(), "".to_owned(), 0), + _ => res.unwrap() + }; + + if login.as_str() == "" || exp < time() { + json!({"error": true, "msg": "Not auth yet"}) + } + else { + json!({"error": false, "login": login, "uuid": uuid}) + } +}