aboutsummaryrefslogtreecommitdiffstats
path: root/crates/rocie-server/src/storage/sql/insert
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-12-09 13:07:14 +0100
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-12-09 13:07:14 +0100
commitc91dce4f77ae12453203f0a28b91efb6533cc095 (patch)
tree4f50e755dff7f717d45309b08f9fe2c8c87f88bd /crates/rocie-server/src/storage/sql/insert
parentchore(rocie-client): Regenerate (diff)
downloadserver-c91dce4f77ae12453203f0a28b91efb6533cc095.zip
feat(rocie-server): Implement basic user handling and authentication
Diffstat (limited to 'crates/rocie-server/src/storage/sql/insert')
-rw-r--r--crates/rocie-server/src/storage/sql/insert/mod.rs1
-rw-r--r--crates/rocie-server/src/storage/sql/insert/user/mod.rs117
2 files changed, 118 insertions, 0 deletions
diff --git a/crates/rocie-server/src/storage/sql/insert/mod.rs b/crates/rocie-server/src/storage/sql/insert/mod.rs
index 8a15385..54717c3 100644
--- a/crates/rocie-server/src/storage/sql/insert/mod.rs
+++ b/crates/rocie-server/src/storage/sql/insert/mod.rs
@@ -13,6 +13,7 @@ pub(crate) mod product_parent;
pub(crate) mod unit;
pub(crate) mod unit_property;
pub(crate) mod recipe;
+pub(crate) mod user;
pub(crate) trait Transactionable:
Sized + std::fmt::Debug + Serialize + DeserializeOwned
diff --git a/crates/rocie-server/src/storage/sql/insert/user/mod.rs b/crates/rocie-server/src/storage/sql/insert/user/mod.rs
new file mode 100644
index 0000000..325253e
--- /dev/null
+++ b/crates/rocie-server/src/storage/sql/insert/user/mod.rs
@@ -0,0 +1,117 @@
+use serde::{Deserialize, Serialize};
+use sqlx::query;
+use uuid::Uuid;
+
+use crate::storage::sql::{
+ insert::{Operations, Transactionable},
+ user::{PasswordHash, User, UserId},
+};
+
+#[derive(Debug, Deserialize, Serialize)]
+pub(crate) enum Operation {
+ RegisterUser {
+ id: UserId,
+ name: String,
+ description: Option<String>,
+ password_hash: PasswordHash,
+ },
+}
+
+impl Transactionable for Operation {
+ type ApplyError = apply::Error;
+ type UndoError = undo::Error;
+
+ async fn apply(self, txn: &mut sqlx::SqliteConnection) -> Result<(), apply::Error> {
+ match self {
+ Operation::RegisterUser {
+ id,
+ name,
+ description,
+ password_hash,
+ } => {
+ let password_hash = password_hash.to_string();
+
+ query!(
+ "
+ INSERT INTO users (id, name, password_hash, description)
+ VALUES (?,?,?,?)
+",
+ id,
+ name,
+ password_hash,
+ description,
+ )
+ .execute(txn)
+ .await?;
+ }
+ }
+ Ok(())
+ }
+
+ async fn undo(self, txn: &mut sqlx::SqliteConnection) -> Result<(), undo::Error> {
+ match self {
+ Operation::RegisterUser {
+ id,
+ name,
+ description,
+ password_hash,
+ } => {
+ let password_hash = password_hash.to_string();
+
+ query!(
+ "
+ DELETE FROM users
+ WHERE id = ? AND name = ? AND description = ? AND password_hash = ?;
+",
+ id,
+ name,
+ description,
+ password_hash,
+ )
+ .execute(txn)
+ .await?;
+ }
+ }
+ Ok(())
+ }
+}
+
+pub(crate) mod undo {
+ #[derive(thiserror::Error, Debug)]
+ pub(crate) enum Error {
+ #[error("Failed to execute undo sql statments: {0}")]
+ SqlError(#[from] sqlx::Error),
+ }
+}
+pub(crate) mod apply {
+ #[derive(thiserror::Error, Debug)]
+ pub(crate) enum Error {
+ #[error("Failed to execute apply sql statments: {0}")]
+ SqlError(#[from] sqlx::Error),
+ }
+}
+
+impl User {
+ pub(crate) fn register(
+ name: String,
+ password_hash: PasswordHash,
+ description: Option<String>,
+ ops: &mut Operations<Operation>,
+ ) -> Self {
+ let id = UserId::from(Uuid::new_v4());
+
+ ops.push(Operation::RegisterUser {
+ id,
+ name: name.clone(),
+ description: description.clone(),
+ password_hash: password_hash.clone(),
+ });
+
+ Self {
+ id,
+ name,
+ description,
+ password_hash,
+ }
+ }
+}