fix: guest membership

This commit is contained in:
Evan Carroll 2026-01-23 13:15:28 -06:00
parent 80c03483ee
commit 9acb688379
2 changed files with 50 additions and 2 deletions

View file

@ -35,12 +35,30 @@ pub async fn get_user_membership(
}
/// Create a new membership (join a realm).
/// This function is idempotent - if the membership already exists, it returns the existing id.
pub async fn create_membership(
pool: &PgPool,
user_id: Uuid,
realm_id: Uuid,
role: RealmRole,
) -> Result<Uuid, AppError> {
// Check if membership already exists
let existing: Option<(Uuid,)> = sqlx::query_as(
r#"
SELECT id FROM realm.memberships
WHERE user_id = $1 AND realm_id = $2
"#,
)
.bind(user_id)
.bind(realm_id)
.fetch_optional(pool)
.await?;
if let Some((id,)) = existing {
return Ok(id);
}
// Create new membership
let (membership_id,): (Uuid,) = sqlx::query_as(
r#"
INSERT INTO realm.memberships (realm_id, user_id, role)
@ -54,7 +72,7 @@ pub async fn create_membership(
.fetch_one(pool)
.await?;
// Update member count on the realm
// Only increment count for new memberships
sqlx::query("UPDATE realm.realms SET member_count = member_count + 1 WHERE id = $1")
.bind(realm_id)
.execute(pool)
@ -64,12 +82,30 @@ pub async fn create_membership(
}
/// Create a new membership using a connection (for RLS support).
/// This function is idempotent - if the membership already exists, it returns the existing id.
pub async fn create_membership_conn(
conn: &mut sqlx::PgConnection,
user_id: Uuid,
realm_id: Uuid,
role: RealmRole,
) -> Result<Uuid, AppError> {
// Check if membership already exists
let existing: Option<(Uuid,)> = sqlx::query_as(
r#"
SELECT id FROM realm.memberships
WHERE user_id = $1 AND realm_id = $2
"#,
)
.bind(user_id)
.bind(realm_id)
.fetch_optional(&mut *conn)
.await?;
if let Some((id,)) = existing {
return Ok(id);
}
// Create new membership
let (membership_id,): (Uuid,) = sqlx::query_as(
r#"
INSERT INTO realm.memberships (realm_id, user_id, role)
@ -83,7 +119,7 @@ pub async fn create_membership_conn(
.fetch_one(&mut *conn)
.await?;
// Update member count on the realm
// Only increment count for new memberships
sqlx::query("UPDATE realm.realms SET member_count = member_count + 1 WHERE id = $1")
.bind(realm_id)
.execute(&mut *conn)

View file

@ -368,6 +368,7 @@ pub async fn signup(
/// Creates a real user account with the 'guest' tag. Guests are regular users
/// with limited capabilities (no prop pickup, etc.) that can be reaped after 24 hours.
pub async fn guest_login(
rls_conn: crate::auth::RlsConn,
State(pool): State<PgPool>,
session: Session,
Json(req): Json<GuestLoginRequest>,
@ -393,6 +394,17 @@ pub async fn guest_login(
// Create guest user (no password) - trigger creates avatar automatically
let user_id = users::create_guest_user(&pool, &guest_name).await?;
// Set RLS context to the new guest user for membership creation
rls_conn
.set_user_id(user_id)
.await
.map_err(|e| AppError::Internal(format!("Failed to set RLS context: {}", e)))?;
// Create membership for the guest so their position can be persisted
let mut conn = rls_conn.acquire().await;
memberships::create_membership_conn(&mut *conn, user_id, realm.id, RealmRole::Member).await?;
drop(conn);
// Set up tower session (same as regular user login)
session
.insert(SESSION_USER_ID_KEY, user_id)