summaryrefslogtreecommitdiff
path: root/src/types/extract.rs
diff options
context:
space:
mode:
authorTyler Murphy <tylermurphy534@gmail.com>2023-01-26 17:29:16 -0500
committerTyler Murphy <tylermurphy534@gmail.com>2023-01-26 17:29:16 -0500
commit88209d88236c3d865a9f5174a0dced31920859bf (patch)
tree89a9985927393005cf632950b585a6a227b1c679 /src/types/extract.rs
downloadxssbook-88209d88236c3d865a9f5174a0dced31920859bf.tar.gz
xssbook-88209d88236c3d865a9f5174a0dced31920859bf.tar.bz2
xssbook-88209d88236c3d865a9f5174a0dced31920859bf.zip
i did things
Diffstat (limited to 'src/types/extract.rs')
-rw-r--r--src/types/extract.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/types/extract.rs b/src/types/extract.rs
new file mode 100644
index 0000000..6518ca1
--- /dev/null
+++ b/src/types/extract.rs
@@ -0,0 +1,65 @@
+use std::io::Read;
+
+use axum::{extract::{FromRequestParts, FromRequest}, async_trait, response::Response, http::{request::Parts, Request}, TypedHeader, headers::Cookie, body::HttpBody, BoxError};
+use bytes::Bytes;
+use serde::de::DeserializeOwned;
+
+use crate::types::{user::User, response::{ResponseCode, Result}, session::Session};
+
+pub struct AuthorizedUser(pub User);
+
+#[async_trait]
+impl<S> FromRequestParts<S> for AuthorizedUser where S: Send + Sync {
+ type Rejection = Response;
+
+ async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self> {
+
+ let Ok(Some(cookies)) = Option::<TypedHeader<Cookie>>::from_request_parts(parts, state).await else {
+ return Err(ResponseCode::Forbidden.msg("No cookies provided"))
+ };
+
+ let Some(token) = cookies.get("auth") else {
+ return Err(ResponseCode::Forbidden.msg("No auth token provided"))
+ };
+
+ let Ok(session) = Session::from_token(&token) else {
+ return Err(ResponseCode::Unauthorized.msg("Auth token invalid"))
+ };
+
+ let Ok(user) = User::from_user_id(session.user_id, true) else {
+ return Err(ResponseCode::InternalServerError.msg("Valid token but no valid user"))
+ };
+
+ Ok(AuthorizedUser(user))
+ }
+}
+
+pub struct Json<T>(pub T);
+
+#[async_trait]
+impl<T, S, B> FromRequest<S, B> for Json<T> where
+ T: DeserializeOwned,
+ B: HttpBody + Send + 'static,
+ B::Data: Send,
+ B::Error: Into<BoxError>,
+ S: Send + Sync,
+{
+ type Rejection = Response;
+
+ async fn from_request(req: Request<B>, state: &S) -> Result<Self> {
+
+ let Ok(bytes) = Bytes::from_request(req, state).await else {
+ return Err(ResponseCode::InternalServerError.msg("Failed to read request body"));
+ };
+
+ let Ok(string) = String::from_utf8(bytes.bytes().flatten().collect()) else {
+ return Err(ResponseCode::BadRequest.msg("Invalid utf8 body"))
+ };
+
+ let Ok(value) = serde_json::from_str(&string) else {
+ return Err(ResponseCode::BadRequest.msg("Invalid request body"))
+ };
+
+ Ok(Json(value))
+ }
+} \ No newline at end of file