diff --git a/_sql/migrations/2024-09-25-000050_alter_users_add_email_confirmed_by_google/down.sql b/_sql/migrations/2024-09-25-000050_alter_users_add_email_confirmed_by_google/down.sql new file mode 100644 index 0000000000..66d2bc1640 --- /dev/null +++ b/_sql/migrations/2024-09-25-000050_alter_users_add_email_confirmed_by_google/down.sql @@ -0,0 +1,5 @@ +-- noinspection SqlDialectInspectionForFile +-- noinspection SqlNoDataSourceInspectionForFile +-- noinspection SqlResolveForFile + +ALTER TABLE users DROP COLUMN email_confirmed_by_google; diff --git a/_sql/migrations/2024-09-25-000050_alter_users_add_email_confirmed_by_google/up.sql b/_sql/migrations/2024-09-25-000050_alter_users_add_email_confirmed_by_google/up.sql new file mode 100644 index 0000000000..3a7e872715 --- /dev/null +++ b/_sql/migrations/2024-09-25-000050_alter_users_add_email_confirmed_by_google/up.sql @@ -0,0 +1,8 @@ +-- noinspection SqlDialectInspectionForFile +-- noinspection SqlNoDataSourceInspectionForFile +-- noinspection SqlResolveForFile + +ALTER TABLE users + ADD COLUMN + email_confirmed_by_google BOOLEAN NOT NULL DEFAULT false + AFTER email_confirmed; diff --git a/_sql/migrations/2024-09-25-000059_alter_users_add_is_without_password/down.sql b/_sql/migrations/2024-09-25-000059_alter_users_add_is_without_password/down.sql new file mode 100644 index 0000000000..0805772c08 --- /dev/null +++ b/_sql/migrations/2024-09-25-000059_alter_users_add_is_without_password/down.sql @@ -0,0 +1,5 @@ +-- noinspection SqlDialectInspectionForFile +-- noinspection SqlNoDataSourceInspectionForFile +-- noinspection SqlResolveForFile + +ALTER TABLE users DROP COLUMN is_without_password; diff --git a/_sql/migrations/2024-09-25-000059_alter_users_add_is_without_password/up.sql b/_sql/migrations/2024-09-25-000059_alter_users_add_is_without_password/up.sql new file mode 100644 index 0000000000..1434bbeb05 --- /dev/null +++ b/_sql/migrations/2024-09-25-000059_alter_users_add_is_without_password/up.sql @@ -0,0 +1,8 @@ +-- noinspection SqlDialectInspectionForFile +-- noinspection SqlNoDataSourceInspectionForFile +-- noinspection SqlResolveForFile + +ALTER TABLE users + ADD COLUMN + is_without_password BOOLEAN NOT NULL DEFAULT false + AFTER password_version; diff --git a/_sql/migrations/2024-09-25-000108_alter_users_add_maybe_create_method/down.sql b/_sql/migrations/2024-09-25-000108_alter_users_add_maybe_create_method/down.sql new file mode 100644 index 0000000000..1c6b1a047e --- /dev/null +++ b/_sql/migrations/2024-09-25-000108_alter_users_add_maybe_create_method/down.sql @@ -0,0 +1,5 @@ +-- noinspection SqlDialectInspectionForFile +-- noinspection SqlNoDataSourceInspectionForFile +-- noinspection SqlResolveForFile + +ALTER TABLE users DROP COLUMN maybe_create_method; diff --git a/_sql/migrations/2024-09-25-000108_alter_users_add_maybe_create_method/up.sql b/_sql/migrations/2024-09-25-000108_alter_users_add_maybe_create_method/up.sql new file mode 100644 index 0000000000..5df9a4aa38 --- /dev/null +++ b/_sql/migrations/2024-09-25-000108_alter_users_add_maybe_create_method/up.sql @@ -0,0 +1,8 @@ +-- noinspection SqlDialectInspectionForFile +-- noinspection SqlNoDataSourceInspectionForFile +-- noinspection SqlResolveForFile + +ALTER TABLE users + ADD COLUMN + maybe_create_method VARCHAR(32) DEFAULT NULL + AFTER maybe_source; diff --git a/_sql/migrations_squashed/user_tables/users.sql b/_sql/migrations_squashed/user_tables/users.sql index b47a4c6e77..b10d2a69bb 100644 --- a/_sql/migrations_squashed/user_tables/users.sql +++ b/_sql/migrations_squashed/user_tables/users.sql @@ -16,9 +16,18 @@ CREATE TABLE users ( username VARCHAR(20) NOT NULL, display_name VARCHAR(20) NOT NULL, + -- Set by the user at sign up: + -- - When email + password signup, this is the email provided. + -- - When Google SSO, this is the email provided by Google. email_address VARCHAR(255) NOT NULL, + + -- Email address is confirmed by us. + -- We do not set this on 3rd party (ie. Google) "email confirmation", only our own. email_confirmed BOOLEAN NOT NULL DEFAULT false, + -- Email address is confirmed by Google. + email_confirmed_by_google BOOLEAN NOT NULL DEFAULT false, + -- The role assigned to the user confers permissions. user_role_slug VARCHAR(16) NOT NULL, @@ -65,6 +74,9 @@ CREATE TABLE users ( -- Incremented with every update to the password. password_version INT UNSIGNED NOT NULL DEFAULT 0, + -- Users signing up from SSO do not have a password at time of account creation. + is_without_password BOOLEAN NOT NULL DEFAULT false, + -- ========== ABUSE TRACKING ========== -- For abuse tracking. @@ -167,6 +179,10 @@ CREATE TABLE users ( -- or overload this to handle other cases or metadata. maybe_source VARCHAR(255) DEFAULT NULL, + -- How users created their account + -- Initially this will be "email" or "google_sso" + maybe_create_method VARCHAR(32) DEFAULT NULL, + -- ========== MODERATION DETAILS ========== -- Different than deleted. diff --git a/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_from_email.rs b/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_from_email.rs index 391e26496a..ca1a72bf23 100644 --- a/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_from_email.rs +++ b/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_from_email.rs @@ -44,6 +44,7 @@ pub async fn create_account_from_email( email_gravatar_hash: args.email_gravatar_hash, password_hash: args.password_hash, ip_address: args.ip_address, + maybe_feature_flags: None, maybe_source: args.maybe_source, maybe_user_token: args.maybe_user_token, }, diff --git a/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_from_google_sso.rs b/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_from_google_sso.rs index 6617a0edde..e11338ee32 100644 --- a/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_from_google_sso.rs +++ b/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_from_google_sso.rs @@ -3,28 +3,29 @@ #![forbid(unused_mut)] #![forbid(unused_variables)] -use sqlx::{MySql, MySqlPool, Transaction}; - use crate::queries::users::user::account_creation::create_account_error::CreateAccountError; use crate::queries::users::user::account_creation::create_account_generic::{create_account_generic, GenericCreateAccountArgs}; use crate::utils::transactor::Transactor; use tokens::tokens::users::UserToken; -pub struct CreateAccountFromGoogleSsoArgs<'a, 't> { +/// SSO accounts do not have passwords at account creation +/// The password hash field is nullable, so we can't leave it null/empty. +const SSO_PASSWORD : &str = "*"; + +pub struct CreateAccountFromGoogleSsoArgs<'a> { pub username: &'a str, pub display_name: &'a str, + pub email_address: &'a str, pub email_gravatar_hash: &'a str, - pub password_hash: &'a str, + pub ip_address: &'a str, pub maybe_source: Option<&'a str>, - - pub transaction: &'a mut Transaction<'t, MySql>, } pub async fn create_account_from_google_sso( - mysql_pool: &MySqlPool, - args: CreateAccountFromGoogleSsoArgs<'_, '_>, + args: CreateAccountFromGoogleSsoArgs<'_>, + transactor: Transactor<'_, '_>, ) -> Result { @@ -34,12 +35,13 @@ pub async fn create_account_from_google_sso( display_name: args.display_name, email_address: args.email_address, email_gravatar_hash: args.email_gravatar_hash, - password_hash: args.password_hash, + password_hash: SSO_PASSWORD, ip_address: args.ip_address, maybe_source: args.maybe_source, + maybe_feature_flags: None, maybe_user_token: None, }, - Transactor::for_pool(mysql_pool), + transactor, ).await?; Ok(result.user_token) diff --git a/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_generic.rs b/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_generic.rs index 0444b71782..81110a1b54 100644 --- a/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_generic.rs +++ b/crates/lib/mysql_queries/src/queries/users/user/account_creation/create_account_generic.rs @@ -21,6 +21,9 @@ pub struct GenericCreateAccountArgs<'a> { pub ip_address: &'a str, pub maybe_source: Option<&'a str>, + // Comma separated string of feature flags. + pub maybe_feature_flags: Option<&'a str>, + /// In production code, send this as `None`. /// Only provide an external user token for db integration tests and db seeding tools. /// This allows for knowing the user token a priori. @@ -64,6 +67,8 @@ SET password_hash = ?, + maybe_feature_flags = ?, + ip_address_creation = ?, ip_address_last_login = ?, ip_address_last_update = ?, @@ -83,6 +88,8 @@ SET args.password_hash, + args.maybe_feature_flags, + args.ip_address, args.ip_address, args.ip_address,