use sqlx::query! macro
This commit is contained in:
parent
c89ee29d4d
commit
3cb122306a
12
.sqlx/query-73ffdf5be39aa5c4c160c2f77d6634a6970eeb4e1d3395f045ded747f0ce9d2a.json
generated
Normal file
12
.sqlx/query-73ffdf5be39aa5c4c160c2f77d6634a6970eeb4e1d3395f045ded747f0ce9d2a.json
generated
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "DELETE FROM users WHERE id = ?",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "73ffdf5be39aa5c4c160c2f77d6634a6970eeb4e1d3395f045ded747f0ce9d2a"
|
||||
}
|
20
.sqlx/query-b668f6787e6425e15414bb745bce55788deb3a996b8e51d651a9e4a07b1483b4.json
generated
Normal file
20
.sqlx/query-b668f6787e6425e15414bb745bce55788deb3a996b8e51d651a9e4a07b1483b4.json
generated
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT COUNT(*) as \"count!: i32\"\n FROM users\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "count!: i32",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "b668f6787e6425e15414bb745bce55788deb3a996b8e51d651a9e4a07b1483b4"
|
||||
}
|
12
.sqlx/query-bf1cc32644e82c80cd6ab4d8fec843384da66c0cac7d6f8f929470c72284d8c8.json
generated
Normal file
12
.sqlx/query-bf1cc32644e82c80cd6ab4d8fec843384da66c0cac7d6f8f929470c72284d8c8.json
generated
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO users (id, username, password_hash, email, display_name, created_at, admin) \n VALUES (?, ?, ?, ?, ?, ?, ?)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 7
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "bf1cc32644e82c80cd6ab4d8fec843384da66c0cac7d6f8f929470c72284d8c8"
|
||||
}
|
124
src/user.rs
124
src/user.rs
@ -45,19 +45,22 @@ impl User {
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Sqlite>,
|
||||
{
|
||||
sqlx::query(
|
||||
let id_str = self.id.to_string();
|
||||
let created_at_str = self.created_at.to_rfc3339();
|
||||
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO users (id, username, password_hash, email, display_name, created_at, admin)
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
"#,
|
||||
id_str,
|
||||
self.username,
|
||||
self.password_hash,
|
||||
self.email,
|
||||
self.display_name,
|
||||
created_at_str,
|
||||
self.admin
|
||||
)
|
||||
.bind(self.id.to_string())
|
||||
.bind(self.username.clone())
|
||||
.bind(self.password_hash.clone())
|
||||
.bind(self.email.clone())
|
||||
.bind(self.display_name.clone())
|
||||
.bind(self.created_at.to_rfc3339())
|
||||
.bind(self.admin)
|
||||
.execute(executor)
|
||||
.await?;
|
||||
|
||||
@ -173,12 +176,15 @@ pub async fn delete_user(mut db: Connection<Db>, user_id: &str) -> Status {
|
||||
Err(_) => return Status::BadRequest,
|
||||
};
|
||||
|
||||
let query = sqlx::query("DELETE FROM users WHERE id = ?")
|
||||
.bind(uuid.to_string())
|
||||
.execute(&mut **db)
|
||||
.await;
|
||||
let id_str = uuid.to_string();
|
||||
let result = sqlx::query!(
|
||||
"DELETE FROM users WHERE id = ?",
|
||||
id_str
|
||||
)
|
||||
.execute(&mut **db)
|
||||
.await;
|
||||
|
||||
match query {
|
||||
match result {
|
||||
Ok(result) => {
|
||||
if result.rows_affected() > 0 {
|
||||
Status::NoContent
|
||||
@ -201,6 +207,7 @@ pub async fn login(
|
||||
sessions: &State<SessionStore>,
|
||||
) -> Result<Json<LoginResponse>, Status> {
|
||||
let creds = credentials.into_inner();
|
||||
let username = creds.username.clone();
|
||||
|
||||
// Find user by username
|
||||
let user = sqlx::query!(
|
||||
@ -212,7 +219,7 @@ pub async fn login(
|
||||
FROM users
|
||||
WHERE username = ?
|
||||
"#,
|
||||
creds.username
|
||||
username
|
||||
)
|
||||
.fetch_optional(&mut **db)
|
||||
.await
|
||||
@ -300,19 +307,21 @@ impl<'r> rocket::request::FromRequest<'r> for AuthenticatedUser {
|
||||
#[get("/setup")]
|
||||
pub async fn setup_page(mut db: Connection<Db>) -> Result<Template, Status> {
|
||||
// Check if any users exist
|
||||
let count = sqlx::query!("SELECT COUNT(*) as count FROM users")
|
||||
.fetch_one(&mut **db)
|
||||
.await
|
||||
.map_err(|_| Status::InternalServerError)?
|
||||
.count;
|
||||
let count = sqlx::query!(
|
||||
r#"
|
||||
SELECT COUNT(*) as "count!: i32"
|
||||
FROM users
|
||||
"#
|
||||
)
|
||||
.fetch_one(&mut **db)
|
||||
.await
|
||||
.map_err(|_| Status::InternalServerError)?;
|
||||
|
||||
if count > 0 {
|
||||
// If users exist, redirect to login
|
||||
Err(Status::SeeOther)
|
||||
} else {
|
||||
// Show setup page
|
||||
Ok(Template::render("setup", context! {}))
|
||||
if count.count > 0 {
|
||||
return Err(Status::Forbidden);
|
||||
}
|
||||
|
||||
Ok(Template::render("setup", context! {}))
|
||||
}
|
||||
|
||||
#[post("/setup", data = "<new_user>")]
|
||||
@ -320,33 +329,33 @@ pub async fn setup(
|
||||
mut db: Connection<Db>,
|
||||
new_user: Json<NewUser>,
|
||||
) -> Result<Status, Json<SetupError>> {
|
||||
let new_user = new_user.into_inner();
|
||||
|
||||
// Check if any users exist
|
||||
let count = sqlx::query!("SELECT COUNT(*) as count FROM users")
|
||||
.fetch_one(&mut **db)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
eprintln!("Database error: {}", e);
|
||||
Json(SetupError {
|
||||
error: "Internal server error".to_string(),
|
||||
})
|
||||
})?
|
||||
.count;
|
||||
let count = sqlx::query!(
|
||||
r#"
|
||||
SELECT COUNT(*) as "count!: i32"
|
||||
FROM users
|
||||
"#
|
||||
)
|
||||
.fetch_one(&mut **db)
|
||||
.await
|
||||
.map_err(|_| {
|
||||
Json(SetupError {
|
||||
error: "Database error".to_string(),
|
||||
})
|
||||
})?;
|
||||
|
||||
if count > 0 {
|
||||
if count.count > 0 {
|
||||
return Err(Json(SetupError {
|
||||
error: "Setup has already been completed".to_string(),
|
||||
error: "Setup already completed".to_string(),
|
||||
}));
|
||||
}
|
||||
|
||||
let password = new_user.password.as_bytes();
|
||||
let new_user = new_user.into_inner();
|
||||
|
||||
// Hash the password
|
||||
let password_hash = bcrypt::hash(password, bcrypt::DEFAULT_COST).map_err(|e| {
|
||||
eprintln!("Password hashing error: {}", e);
|
||||
// Hash the password - we'll use bcrypt
|
||||
let password_hash = bcrypt::hash(new_user.password.as_bytes(), bcrypt::DEFAULT_COST).map_err(|_| {
|
||||
Json(SetupError {
|
||||
error: "Failed to process password".to_string(),
|
||||
error: "Failed to hash password".to_string(),
|
||||
})
|
||||
})?;
|
||||
|
||||
@ -356,22 +365,13 @@ pub async fn setup(
|
||||
new_user.email,
|
||||
new_user.display_name,
|
||||
);
|
||||
user.admin = true; // This is an admin user
|
||||
user.admin = true;
|
||||
|
||||
match user.write_to_database(&mut **db).await {
|
||||
Ok(_) => Ok(Status::Created),
|
||||
Err(e) => {
|
||||
error!("Database error: {}", e);
|
||||
match e {
|
||||
sqlx::Error::Database(db_err) if db_err.is_unique_violation() => {
|
||||
Err(Json(SetupError {
|
||||
error: "Username already exists".to_string(),
|
||||
}))
|
||||
}
|
||||
_ => Err(Json(SetupError {
|
||||
error: "Failed to create user".to_string(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
user.write_to_database(&mut **db)
|
||||
.await
|
||||
.map_err(|_| Json(SetupError {
|
||||
error: "Failed to create user".to_string(),
|
||||
}))?;
|
||||
|
||||
Ok(Status::Created)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user