rust
Elnu 1 year ago
parent 3d925edaad
commit 53de257960

@ -1,15 +1,15 @@
#[macro_use] #[macro_use]
extern crate rocket; extern crate rocket;
use core::panic;
use chrono::{Duration, Utc}; use chrono::{Duration, Utc};
use core::panic;
use derive_more::From; use derive_more::From;
use reqwest::StatusCode; use reqwest::StatusCode;
use rocket::form::Form; use rocket::form::Form;
use rocket::fs::{relative, FileServer}; use rocket::fs::{relative, FileServer};
use rocket::http::{Cookie, CookieJar}; use rocket::http::{Cookie, CookieJar};
use rocket::request::{FromRequest}; use rocket::request::FromRequest;
use rocket::response::{Redirect, content::RawHtml}; use rocket::response::{content::RawHtml, Redirect};
use rocket::{request, Request}; use rocket::{request, Request};
use rocket_dyn_templates::{context, Template}; use rocket_dyn_templates::{context, Template};
use sass_rocket_fairing::SassFairing; use sass_rocket_fairing::SassFairing;
@ -26,8 +26,13 @@ use challenge::Challenge;
mod kyujitai; mod kyujitai;
#[get("/<challenge>")] #[get("/<challenge>")]
async fn get_challenge(challenge: u32, cookies: &CookieJar<'_>) -> Template { async fn get_challenge(challenge: u32, cookies: &CookieJar<'_>) -> Template {
println!("{:?}", cookies.get_private("user_name").map(|cookie| cookie.value().to_owned())); println!(
"{:?}",
cookies
.get_private("user_name")
.map(|cookie| cookie.value().to_owned())
);
Template::render( Template::render(
"index", "index",
context! { context! {
@ -76,7 +81,6 @@ fn login() -> Redirect {
)) ))
} }
#[derive(FromForm)] #[derive(FromForm)]
struct Login<'r> { struct Login<'r> {
token_type: &'r str, token_type: &'r str,
@ -87,15 +91,23 @@ struct Login<'r> {
#[post("/login", data = "<login>")] #[post("/login", data = "<login>")]
async fn post_login(login: Form<Login<'_>>, cookies: &CookieJar<'_>) -> Redirect { async fn post_login(login: Form<Login<'_>>, cookies: &CookieJar<'_>) -> Redirect {
if (login.token_type != "Bearer" || login.scope != "guilds.join+identify+guilds") && User::init(login.access_token, cookies).await.is_ok() { if (login.token_type != "Bearer" || login.scope != "guilds.join+identify+guilds")
cookies.add(Cookie::new(TOKEN_EXPIRE_COOKIE, (Utc::now() + Duration::seconds(login.expires_in as i64)).timestamp().to_string())); && User::init(login.access_token, cookies).await.is_ok()
{
cookies.add(Cookie::new(
TOKEN_EXPIRE_COOKIE,
(Utc::now() + Duration::seconds(login.expires_in as i64))
.timestamp()
.to_string(),
));
} }
Redirect::to("/") Redirect::to("/")
} }
#[get("/success")] #[get("/success")]
fn success() -> RawHtml<&'static str> { fn success() -> RawHtml<&'static str> {
RawHtml("<form action=\"/login\" method=\"post\"></form> RawHtml(
"<form action=\"/login\" method=\"post\"></form>
<script> <script>
try { try {
const params = new URLSearchParams(location.hash.slice(1)); const params = new URLSearchParams(location.hash.slice(1));
@ -111,7 +123,8 @@ fn success() -> RawHtml<&'static str> {
} catch { } catch {
location.href = \"/\"; location.href = \"/\";
} }
</script>") </script>",
)
} }
struct Referer(Option<String>); struct Referer(Option<String>);
@ -208,7 +221,10 @@ enum GetUserError {
ReqwestError(reqwest::Error), ReqwestError(reqwest::Error),
DeserializeError(serde_json::Error), DeserializeError(serde_json::Error),
#[allow(unused)] #[allow(unused)]
DiscordError { status: StatusCode, message: Option<String> }, DiscordError {
status: StatusCode,
message: Option<String>,
},
} }
fn parse_cookie_value<T: std::str::FromStr>(cookies: &CookieJar<'_>, name: &str) -> Option<T> { fn parse_cookie_value<T: std::str::FromStr>(cookies: &CookieJar<'_>, name: &str) -> Option<T> {
@ -236,13 +252,16 @@ impl User {
return Err(GetUserError::DiscordError { return Err(GetUserError::DiscordError {
status, status,
message: text.ok(), message: text.ok(),
}) });
} }
let user: Self = serde_json::from_str(&text?)?; let user: Self = serde_json::from_str(&text?)?;
cookies.add_private(Cookie::new(TOKEN_COOKIE, token.to_owned())); cookies.add_private(Cookie::new(TOKEN_COOKIE, token.to_owned()));
cookies.add_private(Cookie::new("user_id", user.id.to_string())); cookies.add_private(Cookie::new("user_id", user.id.to_string()));
cookies.add_private(Cookie::new("user_name", user.name.clone())); cookies.add_private(Cookie::new("user_name", user.name.clone()));
cookies.add_private(Cookie::new("user_discriminator", user.discriminator.to_string())); cookies.add_private(Cookie::new(
"user_discriminator",
user.discriminator.to_string(),
));
cookies.add_private(Cookie::new("user_avatar", user.avatar.clone())); cookies.add_private(Cookie::new("user_avatar", user.avatar.clone()));
Ok(user) Ok(user)
} }
@ -270,18 +289,20 @@ impl User {
Some(user) => user, Some(user) => user,
None => return Ok(None), None => return Ok(None),
}; };
if cookies.get(TOKEN_EXPIRE_COOKIE) if cookies
.get(TOKEN_EXPIRE_COOKIE)
.map(|expire| expire.value().parse::<i64>()) .map(|expire| expire.value().parse::<i64>())
.and_then(Result::ok) .and_then(Result::ok)
.map_or(true, |timestamp| Utc::now().timestamp() >= timestamp) { .map_or(true, |timestamp| Utc::now().timestamp() >= timestamp)
cookies.remove_private(Cookie::named(TOKEN_COOKIE)); {
cookies.remove_private(Cookie::named("user_id")); cookies.remove_private(Cookie::named(TOKEN_COOKIE));
cookies.remove_private(Cookie::named("user_name")); cookies.remove_private(Cookie::named("user_id"));
cookies.remove_private(Cookie::named("user_discriminator")); cookies.remove_private(Cookie::named("user_name"));
cookies.remove_private(Cookie::named("user_avatar")); cookies.remove_private(Cookie::named("user_discriminator"));
cookies.remove(Cookie::named(TOKEN_EXPIRE_COOKIE)); cookies.remove_private(Cookie::named("user_avatar"));
return Ok(None); cookies.remove(Cookie::named(TOKEN_EXPIRE_COOKIE));
} return Ok(None);
}
Ok(Some(user)) Ok(Some(user))
} }
} }
@ -291,13 +312,15 @@ fn rocket() -> _ {
let config = rocket::Config::figment().merge(("port", 1313)); let config = rocket::Config::figment().merge(("port", 1313));
dotenv::dotenv().expect("Failed to load .env file"); dotenv::dotenv().expect("Failed to load .env file");
rocket::custom(config) rocket::custom(config)
.mount("/", routes![get_challenge, login, post_login, success, logout]) .mount(
"/",
routes![get_challenge, login, post_login, success, logout],
)
.mount("/css", FileServer::from(relative!("styles/css"))) .mount("/css", FileServer::from(relative!("styles/css")))
.attach(Template::fairing()) .attach(Template::fairing())
.attach(SassFairing::default()) .attach(SassFairing::default())
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::User; use crate::User;
@ -321,4 +344,4 @@ mod tests {
let user = test_user("test", 0); let user = test_user("test", 0);
assert_eq!(user.username(), "test"); assert_eq!(user.username(), "test");
} }
} }

Loading…
Cancel
Save