mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 09:28:11 +00:00
plumbing database fields
This commit is contained in:
1 parent
55f557278a
commit
aa66d77a8a
6 files changed
+89
-13
No files matched your search
@@ -207,17 +207,17 @@ CREATE TABLE users (
|
||||
maybe_source VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- How users created their account
|
||||
-- Initially this will be "email_password" or "google_sign_in"
|
||||
-- Older users do not have a value and are assumed to be "email_sign_in"
|
||||
-- Older users do not have a value and are assumed to be "email_password"
|
||||
-- Values:
|
||||
-- - "email_sign_in" / "email_password" (todo: check which is correct)
|
||||
-- - "email_password"
|
||||
-- - "google_sign_in"
|
||||
-- - "stripe_checkout" (eager stripe checkout account provisioning)
|
||||
maybe_signup_method VARCHAR(16) DEFAULT NULL,
|
||||
|
||||
-- Account was provisioned automatically (eg. stripe eager checkout flow)
|
||||
-- This will remain true even if the user finishes account setup, email change,
|
||||
-- password setup, etc.
|
||||
-- password setup, etc. (It's a permanent label on the account for later
|
||||
-- statistical evaluation.)
|
||||
was_eagerly_provisioned BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- ========== MODERATION DETAILS ==========
|
||||
|
||||
+5
@@ -64,6 +64,11 @@ pub async fn create_account_from_email_and_password(
|
||||
|
||||
// NB: This is just for testing.
|
||||
maybe_user_token: args.maybe_user_token,
|
||||
|
||||
// These flags represent eagerly created users and are false for this flow
|
||||
is_temporary: false,
|
||||
email_is_synthetic: false,
|
||||
was_eagerly_provisioned: false,
|
||||
},
|
||||
Transactor::for_pool(mysql_pool),
|
||||
).await?;
|
||||
|
||||
+5
@@ -59,6 +59,11 @@ pub async fn create_account_from_google_sso(
|
||||
|
||||
// NB: This is just for testing.
|
||||
maybe_user_token: None,
|
||||
|
||||
// These flags represent eagerly created users and are false for this flow
|
||||
is_temporary: false,
|
||||
email_is_synthetic: false,
|
||||
was_eagerly_provisioned: false,
|
||||
},
|
||||
transactor,
|
||||
).await?;
|
||||
|
||||
+25
-8
@@ -16,6 +16,14 @@ use tokens::tokens::users::UserToken;
|
||||
const SSO_PASSWORD : &str = "*";
|
||||
|
||||
pub struct CreateAccountFromGoogleSsoArgs<'a> {
|
||||
// NB: Username will likely be generated by our code, not the user.
|
||||
pub username: &'a str,
|
||||
pub display_name: &'a str,
|
||||
|
||||
// NB: Email will likely be generated by our code, not the user.
|
||||
pub email_address: &'a str,
|
||||
pub email_gravatar_hash: &'a str,
|
||||
|
||||
pub ip_address: &'a str,
|
||||
pub maybe_source: Option<UserSignupSource>,
|
||||
|
||||
@@ -30,23 +38,32 @@ pub async fn create_account_from_google_sso(
|
||||
{
|
||||
let result= create_account_generic(
|
||||
GenericCreateAccountArgs {
|
||||
maybe_signup_method: Some(UserSignupMethod::GoogleSignIn),
|
||||
maybe_signup_method: Some(UserSignupMethod::StripeCheckout),
|
||||
|
||||
username: args.username,
|
||||
display_name: args.display_name,
|
||||
ip_address: args.ip_address,
|
||||
maybe_feature_flags: args.maybe_feature_flags,
|
||||
maybe_source: args.maybe_source,
|
||||
|
||||
// SSO accounts have an email reported from Google
|
||||
email_address: args.email_address,
|
||||
email_gravatar_hash: args.email_gravatar_hash,
|
||||
email_confirmed_by_google: args.email_confirmed_by_google,
|
||||
// These are synthetic user accounts that are being eagerly created
|
||||
// If the user abandons the onboarding flow, they can be deleted later.
|
||||
is_temporary: true,
|
||||
was_eagerly_provisioned: true,
|
||||
|
||||
// User-created accounts in this flow have randomly generated usernames
|
||||
// Stripe checkout users have randomly generated usernames
|
||||
username: args.username,
|
||||
display_name: args.display_name,
|
||||
username_is_generated: true,
|
||||
username_is_not_customized: true,
|
||||
|
||||
// Stripe checkout users have NO REAL EMAIL ADDRESS yet.
|
||||
// Stripe will tell us what their email address is once
|
||||
// they complete the checkout (or the user can update it,
|
||||
// and their write wins.)
|
||||
email_address: args.email_address,
|
||||
email_gravatar_hash: args.email_gravatar_hash,
|
||||
email_confirmed_by_google: false,
|
||||
email_is_synthetic: true,
|
||||
|
||||
// SSO accounts start without a password
|
||||
password_hash: SSO_PASSWORD,
|
||||
is_without_password: true,
|
||||
|
||||
+37
@@ -23,10 +23,35 @@ pub struct GenericCreateAccountArgs<'a> {
|
||||
|
||||
pub email_address: &'a str,
|
||||
pub email_gravatar_hash: &'a str,
|
||||
|
||||
/// Google did email IDV and told us it's legitimate.
|
||||
pub email_confirmed_by_google: bool,
|
||||
|
||||
/// The email address is not real yet. We generated a fake/synthetic value
|
||||
/// that will hopefully be replaced later. This is for automated user creation
|
||||
/// flows, like Stripe Checkout onboarding flow.
|
||||
pub email_is_synthetic: bool,
|
||||
|
||||
pub password_hash: &'a str,
|
||||
pub is_without_password: bool,
|
||||
|
||||
/// This is initially TRUE for accounts that were provisioned automatically,
|
||||
/// without user intervention, e.g. in the eager Stripe Checkout onboarding
|
||||
/// flow. Accounts in this state have not yet been customized by users and may
|
||||
/// not in fact represent real users if the users abandon the flow. Once the
|
||||
/// user finishes setup, this will be set to false.
|
||||
///
|
||||
/// Existing and normal setup flow sets this flag to false.
|
||||
///
|
||||
/// If enough time has passed without the user interacting with the account,
|
||||
/// then it might be prudent to delete these records.
|
||||
pub is_temporary: bool,
|
||||
|
||||
/// Whether the account was created eagerly (e.g. via stripe checkout flow)
|
||||
/// without the user explicitly setting up an account, choosing an email or
|
||||
/// password, etc. (It's a technical choice to do faster checkout flow.)
|
||||
/// This is a permanent label on the account.
|
||||
pub was_eagerly_provisioned: bool,
|
||||
|
||||
pub ip_address: &'a str,
|
||||
pub maybe_source: Option<UserSignupSource>,
|
||||
@@ -66,6 +91,9 @@ pub async fn create_account_generic(
|
||||
INSERT INTO users
|
||||
SET
|
||||
token = ?,
|
||||
|
||||
is_temporary = ?,
|
||||
|
||||
username = ?,
|
||||
display_name = ?,
|
||||
|
||||
@@ -77,6 +105,9 @@ SET
|
||||
|
||||
email_confirmed = FALSE,
|
||||
email_confirmed_by_google = ?,
|
||||
email_is_synthetic = ?,
|
||||
|
||||
was_eagerly_provisioned = ?,
|
||||
|
||||
profile_markdown = ?,
|
||||
profile_rendered_html = ?,
|
||||
@@ -96,6 +127,9 @@ SET
|
||||
maybe_signup_method = ?
|
||||
"#,
|
||||
user_token.as_str(),
|
||||
|
||||
args.is_temporary,
|
||||
|
||||
args.username,
|
||||
args.display_name,
|
||||
|
||||
@@ -106,6 +140,9 @@ SET
|
||||
args.email_gravatar_hash,
|
||||
|
||||
args.email_confirmed_by_google,
|
||||
args.email_is_synthetic,
|
||||
|
||||
args.was_eagerly_provisioned,
|
||||
|
||||
INITIAL_PROFILE_MARKDOWN,
|
||||
INITIAL_PROFILE_RENDERED_HTML,
|
||||
|
||||
@@ -18,6 +18,11 @@ pub enum UserSignupMethod {
|
||||
|
||||
/// "Sign in With Google" SSO
|
||||
GoogleSignIn,
|
||||
|
||||
/// Stripe Checkout flow, where we provision user accounts for users with a
|
||||
/// synthetic/fake email address and no password. After checkout completes,
|
||||
/// the user gets a real email and password - or the user can set them.
|
||||
StripeCheckout,
|
||||
}
|
||||
|
||||
// TODO(bt, 2022-12-21): This desperately needs MySQL integration tests!
|
||||
@@ -31,6 +36,7 @@ impl UserSignupMethod {
|
||||
match self {
|
||||
Self::EmailPassword => "email_password",
|
||||
Self::GoogleSignIn=> "google_sign_in",
|
||||
Self::StripeCheckout => "stripe_checkout",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +44,7 @@ impl UserSignupMethod {
|
||||
match value {
|
||||
"email_password" => Ok(Self::EmailPassword),
|
||||
"google_sign_in" => Ok(Self::GoogleSignIn),
|
||||
"stripe_checkout" => Ok(Self::StripeCheckout),
|
||||
_ => Err(format!("invalid value: {:?}", value)),
|
||||
}
|
||||
}
|
||||
@@ -48,6 +55,7 @@ impl UserSignupMethod {
|
||||
BTreeSet::from([
|
||||
Self::EmailPassword,
|
||||
Self::GoogleSignIn,
|
||||
Self::StripeCheckout,
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -64,6 +72,7 @@ mod tests {
|
||||
fn test_serialization() {
|
||||
assert_serialization(UserSignupMethod::EmailPassword, "email_password");
|
||||
assert_serialization(UserSignupMethod::GoogleSignIn, "google_sign_in");
|
||||
assert_serialization(UserSignupMethod::StripeCheckout, "stripe_checkout");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,12 +83,14 @@ mod tests {
|
||||
fn to_str() {
|
||||
assert_eq!(UserSignupMethod::EmailPassword.to_str(), "email_password");
|
||||
assert_eq!(UserSignupMethod::GoogleSignIn.to_str(), "google_sign_in");
|
||||
assert_eq!(UserSignupMethod::StripeCheckout.to_str(), "stripe_checkout");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str() {
|
||||
assert_eq!(UserSignupMethod::from_str("email_password").unwrap(), UserSignupMethod::EmailPassword);
|
||||
assert_eq!(UserSignupMethod::from_str("google_sign_in").unwrap(), UserSignupMethod::GoogleSignIn);
|
||||
assert_eq!(UserSignupMethod::from_str("stripe_checkout").unwrap(), UserSignupMethod::StripeCheckout);
|
||||
assert!(UserSignupMethod::from_str("foo").is_err());
|
||||
}
|
||||
}
|
||||
@@ -90,9 +101,10 @@ mod tests {
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = UserSignupMethod::all_variants();
|
||||
assert_eq!(variants.len(), 2);
|
||||
assert_eq!(variants.len(), 3);
|
||||
assert_eq!(variants.pop_first(), Some(UserSignupMethod::EmailPassword));
|
||||
assert_eq!(variants.pop_first(), Some(UserSignupMethod::GoogleSignIn));
|
||||
assert_eq!(variants.pop_first(), Some(UserSignupMethod::StripeCheckout));
|
||||
assert_eq!(variants.pop_first(), None);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user