From 883dfd67ea44185207634b1ae60ade940c5f02fe Mon Sep 17 00:00:00 2001
From: Joe Ardent
Date: Sun, 25 Feb 2024 17:58:28 -0800
Subject: [PATCH] prepare for when a username gets snatched between initial
signup and having paid
---
src/main.rs | 124 ++++++++++++++++++++++------------
templates/signup.html | 3 +-
templates/signup_success.html | 2 +-
3 files changed, 83 insertions(+), 46 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index 343f409..b78866b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -27,7 +27,9 @@ struct Counter(usize);
/// Displays the signup form.
async fn get_signup() -> impl IntoResponse {
- SignupPage::default()
+ SignupPage {
+ ..Default::default()
+ }
}
/// Receives the form with the user signup fields filled out.
@@ -35,41 +37,7 @@ async fn post_signup(
session: Session,
Form(form): Form,
) -> Result {
- let username = form.username.trim();
- let password = form.password.trim();
- let verify = form.pw_verify.trim();
-
- let name_len = username.graphemes(true).size_hint().1.unwrap();
- // we are not ascii exclusivists around here
- if !(1..=20).contains(&name_len) {
- return Err(CreateUserErrorKind::BadUsername.into());
- }
-
- if password != verify {
- return Err(CreateUserErrorKind::PasswordMismatch.into());
- }
- let pwlen = password.graphemes(true).size_hint().1.unwrap_or(0);
- if !(4..=50).contains(&pwlen) {
- return Err(CreateUserErrorKind::BadPassword.into());
- }
-
- // clean up the optionals
- let displayname = validate_optional_length(
- &form.displayname,
- 0..100,
- CreateUserErrorKind::BadDisplayname,
- )?;
-
- let email = validate_optional_length(&form.email, 5..30, CreateUserErrorKind::BadEmail)?;
-
- let user = User {
- username: username.to_string(),
- displayname,
- email,
- password: password.to_string(),
- pw_verify: verify.to_string(),
- };
-
+ let user = verify_user(&form).await?;
session.insert(SIGNUP_KEY, user).await.unwrap();
Ok(Redirect::to(
@@ -77,14 +45,29 @@ async fn post_signup(
))
}
+async fn get_edit_signup(
+ session: Session,
+ receipt: Option>,
+) -> Result {
+ Ok(())
+}
+
+async fn post_edit_signup(
+ session: Session,
+ Form(form): Form,
+) -> Result {
+ Ok(())
+}
+
/// Called from Stripe with the receipt of payment.
async fn signup_success(session: Session, receipt: Option>) -> impl IntoResponse {
let user: User = session.get(SIGNUP_KEY).await.unwrap().unwrap_or_default();
- if user != User::default() {
- SignupSuccessPage(user).into_response()
- } else {
- SignupErrorPage("who you?".to_string()).into_response()
+ if user == User::default() {
+ return SignupErrorPage("who you?".to_string()).into_response();
}
+
+ // TODO: check Stripe for the receipt, verify it's legit
+ SignupSuccessPage(user).into_response()
}
#[tokio::main]
@@ -135,8 +118,7 @@ pub struct SignupForm {
pub username: String,
#[serde(default, deserialize_with = "empty_string_as_none")]
pub displayname: Option,
- #[serde(default, deserialize_with = "empty_string_as_none")]
- pub email: Option,
+ pub email: String,
pub password: String,
pub pw_verify: String,
}
@@ -149,6 +131,7 @@ pub struct SignupPage {
pub email: Option,
pub password: String,
pub pw_verify: String,
+ pub receipt: String,
}
#[derive(Debug, Clone, Template, Default, Deserialize, Serialize, PartialEq, Eq)]
@@ -163,7 +146,7 @@ pub struct SignupErrorPage(pub String);
pub struct User {
pub username: String,
pub displayname: Option,
- pub email: Option,
+ pub email: String,
pub password: String,
pub pw_verify: String,
}
@@ -192,11 +175,50 @@ impl Display for User {
} else {
""
};
- let email = if let Some(ref e) = self.email { e } else { "" };
+ let email = &self.email;
write!(f, "Username: {uname}\nDisplayname: {dname}\nEmail: {email}")
}
}
+async fn verify_user(form: &SignupForm) -> Result {
+ let username = form.username.trim();
+ let password = form.password.trim();
+ let verify = form.pw_verify.trim();
+
+ let name_len = username.graphemes(true).size_hint().1.unwrap();
+ // we are not ascii exclusivists around here
+ if !(1..=20).contains(&name_len) {
+ return Err(CreateUserErrorKind::BadUsername.into());
+ }
+
+ if password != verify {
+ return Err(CreateUserErrorKind::PasswordMismatch.into());
+ }
+ let pwlen = password.graphemes(true).size_hint().1.unwrap_or(0);
+ if !(4..=50).contains(&pwlen) {
+ return Err(CreateUserErrorKind::BadPassword.into());
+ }
+
+ // clean up the optionals
+ let displayname = validate_optional_length(
+ &form.displayname,
+ 0..100,
+ CreateUserErrorKind::BadDisplayname,
+ )?;
+
+ let email = validate_length(&form.email, 5..30, CreateUserErrorKind::BadEmail)?;
+
+ let user = User {
+ username: username.to_string(),
+ displayname,
+ email,
+ password: password.to_string(),
+ pw_verify: verify.to_string(),
+ };
+
+ Ok(user)
+}
+
pub(crate) fn empty_string_as_none<'de, D, T>(de: D) -> Result
-Now, head on over to the login page and get watchin'!
+
Now, head on over to the login page and git going!
{% endblock %}