summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2024-05-07 19:04:46 -0500
committerToby Vincent <tobyv@tobyvin.dev>2024-05-07 19:04:46 -0500
commit82cc3b8054f4b126b422d946ea694d282a41cd78 (patch)
tree13052c98b2f4809ac3b9bc66156c536bfdc135c3 /src
parente56a04b88dfb8c141310a71d1a9c6b4be2fc9203 (diff)
feat(api): return user resource in location header
Diffstat (limited to 'src')
-rw-r--r--src/api.rs4
-rw-r--r--src/api/error.rs4
-rw-r--r--src/api/users.rs27
-rw-r--r--src/auth/claims.rs3
4 files changed, 28 insertions, 10 deletions
diff --git a/src/api.rs b/src/api.rs
index 6013a98..3641697 100644
--- a/src/api.rs
+++ b/src/api.rs
@@ -19,8 +19,8 @@ pub async fn healthcheck() -> &'static str {
"success"
}
-pub async fn fallback(uri: axum::http::Uri) -> self::error::Error {
- self::error::Error::RouteNotFound(uri)
+pub async fn fallback(uri: axum::http::Uri) -> error::Error {
+ error::Error::RouteNotFound(uri)
}
#[cfg(test)]
diff --git a/src/api/error.rs b/src/api/error.rs
index 10b5468..bc75d41 100644
--- a/src/api/error.rs
+++ b/src/api/error.rs
@@ -18,6 +18,9 @@ pub enum Error {
#[error("Failed to parse header: {0} (wrong token type?)")]
Header(axum_extra::typed_header::TypedHeaderRejection),
+ #[error("Failed to parse header: {0}")]
+ HeaderValue(#[from] axum::http::header::InvalidHeaderValue),
+
#[error("Invalid user token")]
InvalidToken,
@@ -72,6 +75,7 @@ impl axum::response::IntoResponse for Error {
Self::HeaderNotFound(_) => StatusCode::BAD_REQUEST,
Self::EmailInvalid(_) | Self::Header(_) => StatusCode::UNPROCESSABLE_ENTITY,
Self::AuthRequest(_) | Self::Sqlx(_) => StatusCode::INTERNAL_SERVER_ERROR,
+ Self::HeaderValue(_) => StatusCode::INTERNAL_SERVER_ERROR,
Self::Auth(err) => return err.into_response(),
};
diff --git a/src/api/users.rs b/src/api/users.rs
index d4e5d57..bfbc0d6 100644
--- a/src/api/users.rs
+++ b/src/api/users.rs
@@ -2,7 +2,8 @@ use std::str::FromStr;
use axum::{
extract::{Path, State},
- response::IntoResponse,
+ http::header::LOCATION,
+ response::{IntoResponse, IntoResponseParts},
Json,
};
use axum_extra::routing::Resource;
@@ -32,6 +33,20 @@ pub struct User {
pub updated_at: OffsetDateTime,
}
+impl IntoResponseParts for User {
+ type Error = Error;
+
+ fn into_response_parts(
+ self,
+ mut res: axum::response::ResponseParts,
+ ) -> Result<axum::response::ResponseParts, Self::Error> {
+ res.headers_mut()
+ .append(LOCATION, format!("/users/{}", self.id).try_into()?);
+
+ Ok(res)
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Registration {
pub name: String,
@@ -59,16 +74,16 @@ pub async fn create(
.await?;
// TODO: Move this into a micro service, possibly behind a feature flag.
- crate::auth::credentials::create(
- State(pool.clone()),
+ let (status, (access, refresh)) = crate::auth::credentials::create(
+ State(pool),
Json(Credential {
id: user.id,
password,
}),
)
- .await
- .map(|(status, claims)| (status, claims, Json(user)))
- .map_err(Into::into)
+ .await?;
+
+ Ok((status, user, access, refresh))
}
pub async fn show(
diff --git a/src/auth/claims.rs b/src/auth/claims.rs
index 6940844..9087598 100644
--- a/src/auth/claims.rs
+++ b/src/auth/claims.rs
@@ -4,7 +4,6 @@ use axum::{
http::{
header::{AUTHORIZATION, SET_COOKIE},
request::Parts,
- HeaderValue,
},
response::{IntoResponse, IntoResponseParts},
RequestPartsExt,
@@ -181,7 +180,7 @@ impl IntoResponseParts for RefreshClaims {
) -> Result<axum::response::ResponseParts, Self::Error> {
res.headers_mut().append(
AUTHORIZATION,
- HeaderValue::try_from(format!("Bearer {}", JWT.encode(&self)?))?,
+ format!("Bearer {}", JWT.encode(&self)?).try_into()?,
);
Ok(res)