summaryrefslogtreecommitdiffstats
path: root/src/api/users.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/users.rs')
-rw-r--r--src/api/users.rs123
1 files changed, 49 insertions, 74 deletions
diff --git a/src/api/users.rs b/src/api/users.rs
index 7a9bb6e..2440e6e 100644
--- a/src/api/users.rs
+++ b/src/api/users.rs
@@ -22,28 +22,13 @@ pub fn router() -> Resource<AppState> {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, FromRow)]
#[serde(rename_all = "camelCase")]
pub struct UserSchema {
- pub uuid: Uuid,
+ pub id: Uuid,
pub name: String,
pub email: String,
- pub session_epoch: OffsetDateTime,
pub created_at: OffsetDateTime,
pub updated_at: OffsetDateTime,
}
-impl Default for UserSchema {
- fn default() -> Self {
- let now = time::OffsetDateTime::now_utc();
- Self {
- uuid: Default::default(),
- name: Default::default(),
- email: Default::default(),
- session_epoch: now,
- created_at: now,
- updated_at: now,
- }
- }
-}
-
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RegisterSchema {
pub name: String,
@@ -61,37 +46,35 @@ pub async fn create(
) -> impl IntoResponse {
email_address::EmailAddress::from_str(&email)?;
- let exists: Option<bool> =
- sqlx::query_scalar("SELECT EXISTS(SELECT 1 FROM users WHERE email = $1 LIMIT 1)")
- .bind(email.to_ascii_lowercase())
- .fetch_one(&state.pool)
- .await?;
+ let exists: Option<bool> = sqlx::query_scalar!(
+ "SELECT EXISTS(SELECT 1 FROM user_ WHERE email = $1 LIMIT 1)",
+ email.to_ascii_lowercase()
+ )
+ .fetch_one(&state.pool)
+ .await?;
if exists.is_some_and(|b| b) {
return Err(Error::EmailExists);
}
- let mut transaction = state.pool.begin().await?;
+ // TODO: Move this into a tower service
+ let (status, (access, refresh)) = crate::auth::create(
+ State(state.clone()),
+ TypedHeader(Authorization::basic(&email, &password)),
+ )
+ .await?;
let user = sqlx::query_as!(
UserSchema,
- "INSERT INTO users (name,email) VALUES ($1, $2) RETURNING *",
+ "INSERT INTO user_ (id,name,email) VALUES ($1, $2, $3) RETURNING *",
+ refresh.sub,
name,
email.to_ascii_lowercase(),
)
- .fetch_one(&mut *transaction)
+ .fetch_one(&state.pool)
.await?;
- let (parts, _) = crate::auth::create(
- State(state),
- TypedHeader(Authorization::basic(&user.uuid.to_string(), &password)),
- )
- .await?
- .into_response()
- .into_parts();
-
- transaction.commit().await?;
- Ok((parts, Json(user)))
+ Ok((status, access, refresh, Json(user)))
}
pub async fn show(
@@ -103,15 +86,11 @@ pub async fn show(
return Err(Error::InvalidToken);
}
- sqlx::query_as!(
- UserSchema,
- "SELECT * FROM users WHERE uuid = $1 LIMIT 1",
- sub
- )
- .fetch_optional(&state.pool)
- .await?
- .ok_or_else(|| Error::UserNotFound)
- .map(Json)
+ sqlx::query_as!(UserSchema, "SELECT * FROM user_ WHERE id = $1 LIMIT 1", sub)
+ .fetch_optional(&state.pool)
+ .await?
+ .ok_or_else(|| Error::UserNotFound)
+ .map(Json)
}
#[cfg(test)]
@@ -136,7 +115,10 @@ mod tests {
tests::{setup_test_env, TestResult},
};
- const UUID: uuid::Uuid = uuid::uuid!("4c14f795-86f0-4361-a02f-0edb966fb145");
+ const USER_ID: Uuid = uuid::uuid!("4c14f795-86f0-4361-a02f-0edb966fb145");
+ const USER_NAME: &str = "Arthur Dent";
+ const USER_EMAIL: &str = "adent@earth.sol";
+ const USER_PASSWORD: &str = "solongandthanksforallthefish";
#[sqlx::test(fixtures(path = "../../fixtures", scripts("users")))]
async fn test_uuid_ok(pool: PgPool) -> TestResult {
@@ -144,16 +126,9 @@ mod tests {
let router = Router::new().merge(router()).with_state(AppState { pool });
- let user = UserSchema {
- uuid: UUID,
- name: "Arthur Dent".to_string(),
- email: "adent@earth.sol".to_string(),
- ..Default::default()
- };
-
let request = Request::builder()
- .uri(format!("/users/{UUID}"))
- .header(COOKIE, HeaderValue::try_from(AccessClaims::new(UUID))?)
+ .uri(format!("/users/{}", USER_ID))
+ .header(COOKIE, HeaderValue::try_from(AccessClaims::new(USER_ID))?)
.body(Body::empty())?;
let response = router.oneshot(request).await?;
@@ -162,12 +137,12 @@ mod tests {
let body_bytes = response.into_body().collect().await?.to_bytes();
let UserSchema {
- uuid, name, email, ..
+ id, name, email, ..
} = serde_json::from_slice(&body_bytes)?;
- assert_eq!(user.uuid, uuid);
- assert_eq!(user.name, name);
- assert_eq!(user.email, email);
+ assert_eq!(USER_ID, id);
+ assert_eq!(USER_NAME, name);
+ assert_eq!(USER_EMAIL, email);
Ok(())
}
@@ -179,8 +154,8 @@ mod tests {
let router = Router::new().merge(router()).with_state(AppState { pool });
let request = Request::builder()
- .uri(format!("/users/{UUID}"))
- .header(COOKIE, HeaderValue::try_from(AccessClaims::new(UUID))?)
+ .uri(format!("/users/{}", USER_ID))
+ .header(COOKIE, HeaderValue::try_from(AccessClaims::new(USER_ID))?)
.body(Body::empty())?;
let response = router.oneshot(request).await?;
@@ -197,7 +172,7 @@ mod tests {
let router = Router::new().merge(router()).with_state(AppState { pool });
let request = Request::builder()
- .uri(format!("/users/{UUID}"))
+ .uri(format!("/users/{}", USER_ID))
.header(
COOKIE,
HeaderValue::try_from(AccessClaims::new(uuid::Uuid::new_v4()))?,
@@ -218,7 +193,7 @@ mod tests {
let router = Router::new().merge(router()).with_state(AppState { pool });
let request = Request::builder()
- .uri(format!("/users/{UUID}"))
+ .uri(format!("/users/{}", USER_ID))
.header(COOKIE, "token=sadfasdfsdfs")
.body(Body::empty())?;
@@ -236,7 +211,7 @@ mod tests {
let router = Router::new().merge(router()).with_state(AppState { pool });
let request = Request::builder()
- .uri(format!("/users/{UUID}"))
+ .uri(format!("/users/{}", USER_ID))
.body(Body::empty())?;
let response = router.oneshot(request).await?;
@@ -252,11 +227,11 @@ mod tests {
let router = Router::new().merge(router()).with_state(AppState { pool });
- let user = RegisterSchema {
- name: "Arthur Dent".to_string(),
- email: "adent@earth.sol".to_string(),
- password: "solongandthanksforallthefish".to_string(),
- };
+ let user = serde_json::json!( {
+ "name": USER_NAME,
+ "email": USER_EMAIL,
+ "password": USER_PASSWORD,
+ });
let request = Request::builder()
.uri("/users")
@@ -271,8 +246,8 @@ mod tests {
let body_bytes = response.into_body().collect().await?.to_bytes();
let UserSchema { name, email, .. } = serde_json::from_slice(&body_bytes)?;
- assert_eq!(user.name, name);
- assert_eq!(user.email, email);
+ assert_eq!(USER_NAME, name);
+ assert_eq!(USER_EMAIL, email);
Ok(())
}
@@ -283,11 +258,11 @@ mod tests {
let router = Router::new().merge(router()).with_state(AppState { pool });
- let user = RegisterSchema {
- name: "Arthur Dent".to_string(),
- email: "adent@earth.sol".to_string(),
- password: "solongandthanksforallthefish".to_string(),
- };
+ let user = serde_json::json!( {
+ "name": USER_NAME,
+ "email": USER_EMAIL,
+ "password": USER_PASSWORD,
+ });
let request = Request::builder()
.uri("/users")