From b6364c80f9c90426d1f42ca225088bf7e7e7b748 Mon Sep 17 00:00:00 2001 From: yaqubroli Date: Sun, 14 May 2023 22:37:41 -0700 Subject: [PATCH] added proper email function, actix endpoints etc --- Cargo.lock | 307 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 7 ++++--- src/email.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/endpoints.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 46 +++++++++++++++++++--------------------------- src/verification.rs | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- src/whitelist.rs | 23 +++++++++++++++++++++++ 7 files changed, 587 insertions(+), 92 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3fc933e..5bb89a2 100644 --- a/Cargo.lock +++ a/Cargo.lock @@ -253,6 +253,131 @@ checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a" [[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +dependencies = [ + "async-channel", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock", + "autocfg 1.1.0", + "cfg-if", + "concurrent-queue", + "futures-lite", + "log", + "parking", + "polling", + "rustix", + "slab", + "socket2", + "waker-fn", +] + +[[package]] +name = "async-lock" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-process" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" +dependencies = [ + "async-io", + "async-lock", + "autocfg 1.1.0", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", + "signal-hook", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" + +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + +[[package]] name = "autocfg" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -305,6 +430,21 @@ checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", +] + +[[package]] +name = "blocking" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "log", ] [[package]] @@ -402,6 +542,15 @@ dependencies = [ "termcolor", "unicode-width", +] + +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils", ] [[package]] @@ -451,6 +600,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", ] @@ -463,6 +621,16 @@ dependencies = [ "generic-array", "typenum", +] + +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn 1.0.109", ] [[package]] @@ -656,6 +824,12 @@ "cc", "libc", ] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fast_chemail" @@ -720,6 +894,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", +] [[package]] name = "futures-core" @@ -732,6 +915,21 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] [[package]] name = "futures-sink" @@ -779,6 +977,18 @@ "cfg-if", "libc", "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", ] [[package]] @@ -941,6 +1151,15 @@ checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" dependencies = [ "wasm-bindgen", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", ] [[package]] @@ -1058,6 +1277,7 @@ checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", + "value-bag", ] [[package]] @@ -1072,11 +1292,14 @@ dependencies = [ "actix-rt", "actix-web", + "async-process", + "async-std", "base64 0.21.0", "chrono", "lettre 0.10.4", "lettre_email", "openssl", + "rand 0.8.5", "serde", "serde_qs", ] @@ -1226,6 +1449,12 @@ "pkg-config", "vcpkg", ] + +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" [[package]] name = "parking_lot" @@ -1279,6 +1508,22 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg 1.1.0", + "bitflags", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] [[package]] name = "ppv-lite86" @@ -1593,6 +1838,20 @@ version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.162" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] [[package]] name = "serde_json" @@ -1637,6 +1896,16 @@ "cfg-if", "cpufeatures", "digest", +] + +[[package]] +name = "signal-hook" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +dependencies = [ + "libc", + "signal-hook-registry", ] [[package]] @@ -1893,6 +2162,16 @@ checksum = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" dependencies = [ "rand 0.6.5", +] + +[[package]] +name = "value-bag" +version = "1.0.0-alpha.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" +dependencies = [ + "ctor", + "version_check 0.9.4", ] [[package]] @@ -1912,6 +2191,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" [[package]] name = "wasi" @@ -1948,6 +2233,18 @@ "quote", "syn 1.0.109", "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", ] [[package]] @@ -1978,6 +2275,16 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + +[[package]] +name = "web-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "winapi" diff --git a/Cargo.toml b/Cargo.toml index e51c526..7fedd5f 100644 --- a/Cargo.toml +++ a/Cargo.toml @@ -1,17 +1,18 @@ [package] name = "mc-mailer" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] actix-rt = "2.8.0" actix-web = "4.3.1" +async-process = "1.7.0" +async-std = "1.12.0" base64 = "0.21.0" chrono = "0.4.24" lettre = "0.10.4" lettre_email = "0.9.4" openssl = "0.10.52" -serde = "1.0.162" +rand = "0.8.5" +serde = { version = "1.0.162", features = ["derive"] } serde_qs = "0.12.0" diff --git a/src/email.rs b/src/email.rs new file mode 100644 index 0000000..1929f64 100644 --- /dev/null +++ a/src/email.rs @@ -1,0 +1,83 @@ +use actix_web::Responder; +use lettre::message::Mailbox; +use lettre::*; +use lettre::address::Address; +use lettre::transport::smtp::authentication::Credentials; +use lettre_email::EmailBuilder; +use crate::verification::*; +use crate::secrets::*; + +pub async fn send_verification_email(request: VerificationRequest) -> Result<(), String> { + + // TODO: Move creds and mailer outside of the function; maybe just make them static? + + let creds = Credentials::new( + format!("{}@{}", EMAIL_USERNAME, EMAIL_DOMAIN), + EMAIL_PASSWORD.to_string() + ); + + let mailer = SmtpTransport::starttls_relay("mail.cock.li") + .unwrap() + .credentials(creds) + .build(); + + let email = Message::builder() + .from( + Mailbox::new( + Some(VERIFY_EMAIL_NICKNAME.to_string()), + Address::new(EMAIL_USERNAME.to_string(), EMAIL_DOMAIN.to_string()).unwrap() + ) + ) + .to( + Mailbox::new( + Some(request.minecraft_username.clone()), + Address::new(request.email.clone(), "st-andrews.ac.uk").unwrap() + ) + ) + .subject(VERIFY_EMAIL_SUBJECT) + .body( + VERIFY_EMAIL_BODY_1.to_string() + &request.as_code() + VERIFY_EMAIL_BODY_2 + ) + .unwrap(); + println!("Sending email..."); + match mailer.send(&email) { + Ok(_) => Ok(()), + Err(e) => Err(format!("Failed to send email: {}", e)) + } +} + +pub async fn send_written_reason_email(request: WrittenReasonRequest) -> Result<(), String> { + let creds = Credentials::new( + format!("{}@{}", EMAIL_USERNAME, EMAIL_DOMAIN), + EMAIL_PASSWORD.to_string() + ); + + let mailer = SmtpTransport::starttls_relay("mail.cock.li") + .unwrap() + .credentials(creds) + .build(); + + let email = Message::builder() + .from( + Mailbox::new( + Some(VERIFY_EMAIL_NICKNAME.to_string()), + Address::new(EMAIL_USERNAME.to_string(), EMAIL_DOMAIN.to_string()).unwrap() + ) + ) + .to( + Mailbox::new( + Some(request.minecraft_username.clone()), + Address::new("walchuk2018", "icloud.com").unwrap() + ) + ) + .subject("Request from ".to_string() + &request.minecraft_username) + .body( + format!("{:?}", request) + ) + .unwrap(); + println!("Sending email..."); + match mailer.send(&email) { + Ok(_) => Ok(()), + Err(e) => Err(format!("Failed to send email: {}", e)) + } +}diff --git a/src/endpoints.rs b/src/endpoints.rs new file mode 100644 index 0000000..08300d2 100644 --- /dev/null +++ a/src/endpoints.rs @@ -1,0 +1,56 @@ +use chrono::Utc; +use crate::secrets::*; +use crate::verification::*; +use crate::email::*; +use actix_web::{web, Responder, HttpResponse}; + +pub async fn index() -> impl Responder { + // generate a nonce verification request, and send it as an email + let request_proto = VerificationRequestProto { + email: String::from("jpw24"), + minecraft_username: String::from("jacobroly") + }; + let request = request_proto.hydrate(); + let response = HttpResponse::Ok() + .content_type("text/html; charset=utf-8") + .body( + HTML_ON_EMAIL_SENT_1.to_string() + &request.minecraft_username + HTML_ON_EMAIL_SENT_2 + &request.email + HTML_ON_EMAIL_SENT_3 + ); + // actix_rt::spawn(send_verification_email(request)); + println!("{}", request.as_code()); + return response; +} + +pub async fn send_sta(form: web::Form) -> impl Responder { + let request = form.into_inner().hydrate(); + let response = HttpResponse::Ok() + .content_type("text/html; charset=utf-8") + .body( + HTML_ON_EMAIL_SENT_1.to_string() + &request.minecraft_username + HTML_ON_EMAIL_SENT_2 + &request.email + HTML_ON_EMAIL_SENT_3 + ); + actix_rt::spawn(send_verification_email(request)); + return response; +} + +pub async fn send_written(form: web::Form) -> impl Responder { + let response = HttpResponse::Ok() + .content_type("text/html; charset=utf-8") + .body(HTML_ON_WRITTEN_REQUEST_SENT.to_string()); + actix_rt::spawn(send_written_reason_email(form.into_inner())); + return response; +} + +pub async fn verify(path: web::Path) -> impl Responder { + let code = path.into_inner(); + let receipt = VerificationReceipt::from_code(code); + if (receipt.valid) { + return HttpResponse::Ok() + .content_type("text/html; charset=utf-8") + .body(HTML_ON_EMAIL_VERIFIED_1.to_string() + &receipt.minecraft_username + HTML_ON_EMAIL_VERIFIED_2); + } else { + return HttpResponse::Ok() + .content_type("text/html; charset=utf-8") + .body(HTML_ON_EMAIL_VERIFICATION_FAILED.to_string()); + } +} + diff --git a/src/main.rs b/src/main.rs index f188803..e835538 100644 --- a/src/main.rs +++ a/src/main.rs @@ -1,30 +1,20 @@ -use chrono::Utc; -use lettre_email::EmailBuilder; -use secrets::secrets::EMAIL_USERNAME; -use crate::verification::verification::*; -use crate::secrets::secrets::SPECIAL_SALT_CODE; +mod endpoints; +mod secrets; +mod verification; +mod email; -pub mod verification; -pub mod secrets; +use actix_web::{web, App, HttpServer}; -async fn send_verification_email(verificationRequest: VerificationRequest, ) -> impl Responder { - let email = EmailBuilder::new() - .to(format("{}@st-andrews.ac.uk", verificationRequest.email)) - .from(EMAIL_USERNAME) - .subject("Minecraft Verification") - .text(format!("Here's your whitelist verification link: https://mc.7800.io/verify/{}", verificationRequest.as_code())) - .build(); -} - -fn main() { - let verification_request = VerificationRequest { - minecraft_username: String::from("jacobroly"), - date: Utc::now(), - seed: 45343, - }; - println!("Generated verification request: {:?}", verification_request); - let verification_code = verification_request.as_code(); - println!("Generated verification code: {}", verification_code); - let verification_receipt = VerificationReceipt::from_code(verification_code); - println!("Generated verification receipt: {:?}", verification_receipt); -} +#[actix_web::main] +async fn main() -> std::io::Result<()> { + HttpServer::new(|| { + App::new() + .route("/", web::get().to(endpoints::index)) + .route("/send-sta", web::post().to(endpoints::send_sta)) + .route("/send-written", web::post().to(endpoints::send_written)) + .route("/verify/{code}", web::get().to(endpoints::verify)) + }) + .bind("127.0.0.1:8080")? + .run() + .await +}diff --git a/src/verification.rs b/src/verification.rs index 114871e..e272649 100644 --- a/src/verification.rs +++ a/src/verification.rs @@ -1,66 +1,101 @@ -pub mod verification { - use openssl::hash::*; - use base64::engine::Engine as _; - use base64::engine::general_purpose::URL_SAFE_NO_PAD as BASE64; - use chrono::prelude::*; - use crate::SPECIAL_SALT_CODE; - - #[derive(Debug)] - pub struct VerificationRequest { - pub(crate) minecraft_username: String, - pub(crate) date: DateTime, - pub(crate) seed: u32, - } - - #[derive(Debug)] - pub struct VerificationReceipt { - valid: bool, - minecraft_username: String, - } - - pub trait VerificationCodeGenerator { - fn as_code(&self) -> String; - } - - pub trait VerificationCodeValidator { - fn from_code(code: String) -> VerificationReceipt; + +use openssl::{hash::*}; +use rand::{thread_rng, Rng}; +use base64::engine::Engine as _; +use base64::engine::general_purpose::URL_SAFE_NO_PAD as BASE64; +use chrono::prelude::*; +use serde::{Serialize, Deserialize}; +use crate::secrets::SPECIAL_SALT_CODE; + +#[derive(Debug, Serialize, Deserialize)] +pub struct VerificationRequestProto { + pub(crate) email: String, + pub(crate) minecraft_username: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct WrittenReasonRequest { + pub(crate) email: String, + pub(crate) minecraft_username: String, + pub(crate) reason: String, +} + +#[derive(Debug)] +pub struct VerificationRequest { + pub(crate) email: String, + pub(crate) minecraft_username: String, + pub(crate) date: DateTime, + pub(crate) seed: u32, +} + +#[derive(Debug)] +pub struct VerificationReceipt { + pub(crate) valid: bool, + pub(crate) minecraft_username: String, +} + +pub trait VerificationCodeGenerator { + fn as_code(&self) -> String; +} + +pub trait VerificationCodeValidator { + fn from_code(code: String) -> VerificationReceipt; +} + +pub trait VerificationCodeHydrator { + fn hydrate(&self) -> VerificationRequest; +} + +impl VerificationCodeGenerator for VerificationRequest { + fn as_code(&self) -> String { + println!("generating verification code from request: {:?}", self.clone()); + return format!( + "{}{}{}", + BASE64.encode( + &self.seed.to_be_bytes() + ), + BASE64.encode( + hash(MessageDigest::sha256(), + format!( + "{}{}{}{}", + self.seed, + self.date.format("%Y%m%d").to_string(), + SPECIAL_SALT_CODE, + self.minecraft_username + ).as_bytes()).unwrap().as_ref() + ), + BASE64.encode( + &self.minecraft_username.as_bytes() + ) + ); } +} - impl VerificationCodeGenerator for VerificationRequest { - fn as_code(&self) -> String { - return format!( - "{}{}{}", - BASE64.encode( - &self.seed.to_be_bytes() - ), - BASE64.encode( - hash(MessageDigest::sha256(), - format!( - "{}{}{}{}", - self.seed, - self.date.timestamp(), - SPECIAL_SALT_CODE, - self.minecraft_username - ).as_bytes()).unwrap().as_ref() - ), - BASE64.encode( - &self.minecraft_username.as_bytes() - ) - ); - } +impl VerificationCodeValidator for VerificationReceipt { + fn from_code(code: String) -> VerificationReceipt { + println!("code: {}", code); + println!("reconstructed username: {}", String::from_utf8(BASE64.decode(&code[49..]).unwrap()).unwrap()); + println!("reconstructed seed: {}", u32::from_be_bytes(BASE64.decode(&code[0..6]).unwrap().try_into().unwrap())); + let username = String::from_utf8(BASE64.decode(&code[49..]).unwrap()).unwrap(); + return VerificationReceipt { + minecraft_username: username.clone(), + valid: code == VerificationRequest { + email: String::from(""), + minecraft_username: username, + date: Utc::now(), + seed: u32::from_be_bytes(BASE64.decode(&code[0..6]).unwrap().try_into().unwrap()), + }.as_code() + }; } - - impl VerificationCodeValidator for VerificationReceipt { - fn from_code(code: String) -> VerificationReceipt { - let username = String::from_utf8(BASE64.decode(&code[49..]).unwrap()).unwrap(); - return VerificationReceipt { - minecraft_username: username.clone(), - valid: code == VerificationRequest { - minecraft_username: username, - date: Utc::now(), - seed: u32::from_be_bytes(BASE64.decode(&code[0..6]).unwrap().try_into().unwrap()), - }.as_code() - }; - } +} + +impl VerificationCodeHydrator for VerificationRequestProto { + fn hydrate(&self) -> VerificationRequest { + return VerificationRequest { + email: self.email.clone(), + minecraft_username: self.minecraft_username.clone(), + date: Utc::now(), + seed: rand::thread_rng().gen::(), + }; } }diff --git a/src/whitelist.rs b/src/whitelist.rs index e69de29..7bad0be 100644 --- a/src/whitelist.rs +++ a/src/whitelist.rs @@ -1,0 +1,23 @@ +use std::io::Error; +use std::process::Stdio; +use async_process::Command; +use async_std::prelude::*; +use actix_rt::System; +use crate::secrets::WHITELIST_SCRIPT_PATH; + +async fn add_to_whitelist(args: &str) -> Result { + let mut child = Command::new("sh") + .arg(WHITELIST_SCRIPT_PATH) + .arg(args) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .spawn()?; + + let output = child.output().await?; + + let success = output.status.success(); + let output_text = String::from_utf8_lossy(&output.stdout).to_string(); + let error_text = String::from_utf8_lossy(&output.stderr).to_string(); + + Ok(format!("=== STDOUT ===\n{}\n\n== STDERR ==\n{}", output_text, error_text)) +}-- rgit 0.1.5