Profile edit (WIP)

This commit is contained in:
Greg Burri 2024-11-15 14:47:10 +01:00
parent 405aa68526
commit 327b2d0a5b
15 changed files with 174 additions and 46 deletions

View file

@ -244,19 +244,46 @@ FROM [UserLoginToken] WHERE [token] = $1
}
pub async fn load_user(&self, user_id: i64) -> Result<Option<model::User>> {
sqlx::query_as("SELECT [id], [email] FROM [User] WHERE [id] = $1")
sqlx::query_as("SELECT [id], [email], [name] FROM [User] WHERE [id] = $1")
.bind(user_id)
.fetch_optional(&self.pool)
.await
.map_err(DBError::from)
}
pub async fn set_user_name(&self, user_id: i64, name: &str) -> Result<()> {
sqlx::query("UPDATE [User] SET [name] = $2 WHERE [id] = $1")
.bind(user_id)
.bind(name)
.execute(&self.pool)
.await?;
pub async fn update_user(
&self,
user_id: i64,
new_email: Option<&str>,
new_name: Option<&str>,
new_password: Option<&str>,
) -> Result<()> {
let mut tx = self.tx().await?;
let hashed_new_password = new_password.map(|p| hash(p).unwrap());
let (email, name, password) = sqlx::query_as::<_, (String, String, String)>(
"SELECT [email], [name], [password] FROM [User] WHERE [id] = $1",
)
.bind(user_id)
.fetch_one(&mut *tx)
.await?;
sqlx::query(
r#"
UPDATE [User]
SET [email] = $2, [name] = $3, [password] = $4
WHERE [id] = $1
"#,
)
.bind(user_id)
.bind(new_email.unwrap_or(&email))
.bind(new_name.unwrap_or(&name))
.bind(hashed_new_password.unwrap_or(password))
.execute(&mut *tx)
.await?;
tx.commit().await?;
Ok(())
}
@ -1075,6 +1102,59 @@ VALUES (
Ok(())
}
#[tokio::test]
async fn update_user() -> Result<()> {
let connection = Connection::new_in_memory().await?;
connection.execute_sql(
sqlx::query(
r#"
INSERT INTO [User]
([id], [email], [name], [password], [creation_datetime], [validation_token])
VALUES
($1, $2, $3, $4, $5, $6)
"#
)
.bind(1)
.bind("paul@atreides.com")
.bind("paul")
.bind("$argon2id$v=19$m=4096,t=3,p=1$G4fjepS05MkRbTqEImUdYg$GGziE8uVQe1L1oFHk37lBno10g4VISnVqynSkLCH3Lc")
.bind("2022-11-29 22:05:04.121407300+00:00")
.bind(None::<&str>) // 'null'.
).await?;
let user = connection.load_user(1).await?.unwrap();
assert_eq!(user.name, "paul");
assert_eq!(user.email, "paul@atreides.com");
connection
.update_user(
1,
Some("muaddib@fremen.com"),
Some("muaddib"),
Some("Chani"),
)
.await?;
let user = connection.load_user(1).await?.unwrap();
assert_eq!(user.name, "muaddib");
assert_eq!(user.email, "muaddib@fremen.com");
// Tets if password has been updated correctly.
if let SignInResult::Ok(_token, id) = connection
.sign_in("muaddib@fremen.com", "Chani", "127.0.0.1", "Mozilla/5.0")
.await?
{
assert_eq!(id, 1);
} else {
panic!("Can't sign in");
}
Ok(())
}
#[tokio::test]
async fn create_a_new_recipe_then_update_its_title() -> Result<()> {
let connection = Connection::new_in_memory().await?;

View file

@ -28,6 +28,7 @@ impl FromRow<'_, SqliteRow> for model::User {
Ok(model::User {
id: row.try_get("id")?,
email: row.try_get("email")?,
name: row.try_get("name")?,
})
}
}