summaryrefslogtreecommitdiffstats
path: root/src/api/users.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2024-05-07 14:30:23 -0500
committerToby Vincent <tobyv@tobyvin.dev>2024-05-07 14:30:23 -0500
commit69b2275a0aa9eaff5134777f8a228c2132df02e1 (patch)
tree76b8c2fb124ca7e1f532df3d3557d8741076f950 /src/api/users.rs
parent1dbe3776c682f469d1497247fac22f0aa233a598 (diff)
refactor(wip): experiment with rocksdbrocksdb
Diffstat (limited to 'src/api/users.rs')
-rw-r--r--src/api/users.rs83
1 files changed, 48 insertions, 35 deletions
diff --git a/src/api/users.rs b/src/api/users.rs
index e07bf7e..24bcf97 100644
--- a/src/api/users.rs
+++ b/src/api/users.rs
@@ -13,7 +13,7 @@ use uuid::Uuid;
use crate::{
auth::{credentials::Credential, AccessClaims},
- state::AppState,
+ state::{AppState, KVStore},
};
use super::error::Error;
@@ -40,54 +40,53 @@ pub struct Registration {
}
pub async fn create(
- State(pool): State<PgPool>,
+ State(state): State<AppState>,
Json(Registration {
name,
email,
password,
}): Json<Registration>,
-) -> impl IntoResponse {
+) -> Result<impl IntoResponse, Error> {
email_address::EmailAddress::from_str(&email)?;
- let exists: Option<bool> = sqlx::query_scalar!(
- "SELECT EXISTS(SELECT 1 FROM user_ WHERE email = $1 LIMIT 1)",
- email.to_ascii_lowercase()
- )
- .fetch_one(&pool)
- .await?;
-
- if exists.is_some_and(|b| b) {
- return Err(Error::EmailExists);
- }
-
// TODO: Move this into a micro service, possibly behind a feature flag.
let (status, (access, refresh)) =
- crate::auth::credentials::create(State(pool.clone()), Json(Credential { password }))
+ crate::auth::credentials::create(State(state.pool.clone()), Json(Credential { password }))
.await?;
- let user = sqlx::query_as!(
- User,
- "INSERT INTO user_ (id,name,email) VALUES ($1, $2, $3) RETURNING *",
- refresh.sub,
+ let user = User {
+ id: refresh.sub,
name,
- email.to_ascii_lowercase(),
- )
- .fetch_one(&pool)
- .await?;
+ email,
+ created_at: OffsetDateTime::now_utc(),
+ updated_at: OffsetDateTime::now_utc(),
+ };
+
+ let tx = state.kv_store.transaction();
+ tx.put(refresh.sub, serde_json::to_vec(&user).unwrap())
+ .unwrap();
Ok((status, access, refresh, Json(user)))
}
pub async fn show(
Path(uuid): Path<Uuid>,
- State(pool): State<PgPool>,
+ State(state): State<AppState>,
_: AccessClaims,
-) -> Result<impl IntoResponse, Error> {
- sqlx::query_as!(User, "SELECT * FROM user_ WHERE id = $1 LIMIT 1", uuid)
- .fetch_optional(&pool)
- .await?
+) -> Result<Json<User>, Error> {
+ let tx = state.kv_store.transaction();
+ Ok(tx
+ .get(uuid)
+ .unwrap()
.ok_or_else(|| Error::UserNotFound)
+ .map(|s| serde_json::from_slice(&s))?
.map(Json)
+ .unwrap())
+ //sqlx::query_as!(User, "SELECT * FROM user_ WHERE id = $1 LIMIT 1", uuid)
+ // .fetch_optional(&pool)
+ // .await?
+ // .ok_or_else(|| Error::UserNotFound)
+ // .map(Json)
}
#[cfg(test)]
@@ -120,7 +119,9 @@ mod tests {
async fn test_get_ok_self(pool: PgPool) -> TestResult {
setup_test_env();
- let router = Router::new().merge(router()).with_state(AppState { pool });
+ let router = Router::new()
+ .merge(router())
+ .with_state(AppState::with_pool(pool, "./rocks.db"));
let request = Request::builder()
.uri(format!("/users/{}", USER_ID))
@@ -150,7 +151,9 @@ mod tests {
async fn test_get_ok_other(pool: PgPool) -> TestResult {
setup_test_env();
- let router = Router::new().merge(router()).with_state(AppState { pool });
+ let router = Router::new()
+ .merge(router())
+ .with_state(AppState::with_pool(pool, "./rocks.db"));
let request = Request::builder()
.uri(format!("/users/{}", USER_ID))
@@ -182,7 +185,9 @@ mod tests {
async fn test_get_not_found(pool: PgPool) -> TestResult {
setup_test_env();
- let router = Router::new().merge(router()).with_state(AppState { pool });
+ let router = Router::new()
+ .merge(router())
+ .with_state(AppState::with_pool(pool, "./rocks.db"));
let request = Request::builder()
.uri(format!("/users/{}", USER_ID))
@@ -203,7 +208,9 @@ mod tests {
async fn test_get_unauthorized_invalid_token_format(pool: PgPool) -> TestResult {
setup_test_env();
- let router = Router::new().merge(router()).with_state(AppState { pool });
+ let router = Router::new()
+ .merge(router())
+ .with_state(AppState::with_pool(pool, "./rocks.db"));
let request = Request::builder()
.uri(format!("/users/{}", USER_ID))
@@ -221,7 +228,9 @@ mod tests {
async fn test_get_unauthorized_missing_token(pool: PgPool) -> TestResult {
setup_test_env();
- let router = Router::new().merge(router()).with_state(AppState { pool });
+ let router = Router::new()
+ .merge(router())
+ .with_state(AppState::with_pool(pool, "./rocks.db"));
let request = Request::builder()
.uri(format!("/users/{}", USER_ID))
@@ -238,7 +247,9 @@ mod tests {
async fn test_post_created(pool: PgPool) -> TestResult {
setup_test_env();
- let router = Router::new().merge(router()).with_state(AppState { pool });
+ let router = Router::new()
+ .merge(router())
+ .with_state(AppState::with_pool(pool, "./rocks.db"));
let user = serde_json::json!( {
"name": USER_NAME,
@@ -269,7 +280,9 @@ mod tests {
async fn test_post_conflict(pool: PgPool) -> TestResult {
setup_test_env();
- let router = Router::new().merge(router()).with_state(AppState { pool });
+ let router = Router::new()
+ .merge(router())
+ .with_state(AppState::with_pool(pool, "./rocks.db"));
let user = serde_json::json!( {
"name": USER_NAME,