Merge 482192dda320dd348ad1333866bbe72fa33f3397 into 144905369e4316bcbf230ad96e0e6317098cc4d1
This commit is contained in:
commit
91410f0a9d
1
.env.dev
1
.env.dev
@ -1,2 +1,3 @@
|
|||||||
DATABASE_URL=postgres://app:app@db/todo_baggins
|
DATABASE_URL=postgres://app:app@db/todo_baggins
|
||||||
LANGUAGE_CODE=en-US
|
LANGUAGE_CODE=en-US
|
||||||
|
AUTH_TOKEN=my_token
|
||||||
|
16
Cargo.lock
generated
16
Cargo.lock
generated
@ -558,6 +558,17 @@ dependencies = [
|
|||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie"
|
||||||
|
version = "0.18.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
|
||||||
|
dependencies = [
|
||||||
|
"percent-encoding",
|
||||||
|
"time",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation-sys"
|
name = "core-foundation-sys"
|
||||||
version = "0.8.7"
|
version = "0.8.7"
|
||||||
@ -2943,16 +2954,21 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"async-std",
|
"async-std",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"cookie",
|
||||||
"diesel",
|
"diesel",
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"dioxus-logger",
|
"dioxus-logger",
|
||||||
"dioxus-query",
|
"dioxus-query",
|
||||||
"dioxus-sdk",
|
"dioxus-sdk",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
|
"http 1.1.0",
|
||||||
|
"pin-project-lite",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"time",
|
"time",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-wasm",
|
"tracing-wasm",
|
||||||
"unic-langid-impl",
|
"unic-langid-impl",
|
||||||
|
@ -27,6 +27,11 @@ time = "0.3.36"
|
|||||||
dioxus-sdk = { version = "0.5.0", features = ["i18n"] }
|
dioxus-sdk = { version = "0.5.0", features = ["i18n"] }
|
||||||
unic-langid-impl = "0.9.5"
|
unic-langid-impl = "0.9.5"
|
||||||
voca_rs = "1.15.2"
|
voca_rs = "1.15.2"
|
||||||
|
http = "1.1.0"
|
||||||
|
pin-project-lite = "0.2.14"
|
||||||
|
tower-layer = "0.3.3"
|
||||||
|
tower-service = "0.3.3"
|
||||||
|
cookie = { version = "0.18.1", features = ["percent-encode"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
@ -4,7 +4,7 @@ use dotenvy::dotenv;
|
|||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
pub(crate) fn establish_database_connection() -> ConnectionResult<PgConnection> {
|
pub(crate) fn establish_database_connection() -> ConnectionResult<PgConnection> {
|
||||||
dotenv().expect("Could not load environment variables.");
|
dotenv().expect("Could not load environment variables from the .env file.");
|
||||||
|
|
||||||
let database_url =
|
let database_url =
|
||||||
env::var("DATABASE_URL").expect("The environment variable DATABASE_URL has to be set.");
|
env::var("DATABASE_URL").expect("The environment variable DATABASE_URL has to be set.");
|
||||||
|
108
src/server/middleware/mod.rs
Normal file
108
src/server/middleware/mod.rs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
use http::{Request, Response, StatusCode};
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
|
use std::{env, future::Future, pin::Pin, task::{Context, Poll}};
|
||||||
|
use cookie::Cookie;
|
||||||
|
use dotenvy::dotenv;
|
||||||
|
use http::header::COOKIE;
|
||||||
|
use tower_layer::Layer;
|
||||||
|
use tower_service::Service;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct AuthLayer {}
|
||||||
|
|
||||||
|
impl AuthLayer {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
AuthLayer {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> Layer<S> for AuthLayer {
|
||||||
|
type Service = Auth<S>;
|
||||||
|
|
||||||
|
fn layer(&self, inner: S) -> Self::Service {
|
||||||
|
Auth::new(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Auth<S> {
|
||||||
|
inner: S,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> Auth<S> {
|
||||||
|
pub fn new(inner: S) -> Self {
|
||||||
|
Self { inner }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn layer() -> AuthLayer {
|
||||||
|
AuthLayer::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, ReqBody, ResBody> Service<Request<ReqBody>> for Auth<S>
|
||||||
|
where
|
||||||
|
S: Service<Request<ReqBody>, Response=Response<ResBody>>,
|
||||||
|
ResBody: Default,
|
||||||
|
{
|
||||||
|
type Response = S::Response;
|
||||||
|
type Error = S::Error;
|
||||||
|
type Future = ResponseFuture<S::Future>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
self.inner.poll_ready(cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: Request<ReqBody>) -> Self::Future {
|
||||||
|
let cookies = req.headers()
|
||||||
|
.get(COOKIE)
|
||||||
|
.and_then(|header| header.to_str().ok())
|
||||||
|
.map(Cookie::split_parse_encoded);
|
||||||
|
|
||||||
|
let token = cookies.and_then(
|
||||||
|
|cookies| cookies
|
||||||
|
.filter_map(|cookie| cookie.ok())
|
||||||
|
.find(|cookie| cookie.name() == "auth_token")
|
||||||
|
.map(|cookie| cookie.value().to_string())
|
||||||
|
);
|
||||||
|
|
||||||
|
ResponseFuture {
|
||||||
|
inner: self.inner.call(req),
|
||||||
|
token,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_project! {
|
||||||
|
pub struct ResponseFuture<F> {
|
||||||
|
#[pin]
|
||||||
|
inner: F,
|
||||||
|
#[pin]
|
||||||
|
token: Option<String>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, B, E> Future for ResponseFuture<F>
|
||||||
|
where
|
||||||
|
F: Future<Output=Result<Response<B>, E>>,
|
||||||
|
B: Default,
|
||||||
|
{
|
||||||
|
type Output = Result<Response<B>, E>;
|
||||||
|
|
||||||
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
dotenv().expect("Could not load environment variables from the .env file.");
|
||||||
|
|
||||||
|
let this = self.project();
|
||||||
|
|
||||||
|
if !(*this.token).as_ref().is_some_and(
|
||||||
|
|token| token == env::var("AUTH_TOKEN")
|
||||||
|
.expect("The environment variable DATABASE_URL has to be set.").as_str()
|
||||||
|
) {
|
||||||
|
let mut res = Response::new(B::default());
|
||||||
|
*res.status_mut() = StatusCode::UNAUTHORIZED;
|
||||||
|
return Poll::Ready(Ok(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inner.poll(cx)
|
||||||
|
}
|
||||||
|
}
|
@ -3,3 +3,4 @@ pub(crate) mod projects;
|
|||||||
pub(crate) mod tasks;
|
pub(crate) mod tasks;
|
||||||
pub(crate) mod subtasks;
|
pub(crate) mod subtasks;
|
||||||
pub(crate) mod internationalization;
|
pub(crate) mod internationalization;
|
||||||
|
mod middleware;
|
||||||
|
@ -14,9 +14,17 @@ use crate::models::subtask::Subtask;
|
|||||||
use crate::server::subtasks::restore_subtasks_of_task;
|
use crate::server::subtasks::restore_subtasks_of_task;
|
||||||
|
|
||||||
#[server]
|
#[server]
|
||||||
|
#[middleware(crate::server::middleware::AuthLayer::new())]
|
||||||
pub(crate) async fn create_task(new_task: NewTask)
|
pub(crate) async fn create_task(new_task: NewTask)
|
||||||
-> Result<Task, ServerFnError<ErrorVec<TaskError>>> {
|
-> Result<Task, ServerFnError<ErrorVec<TaskError>>> {
|
||||||
use crate::schema::tasks;
|
use crate::schema::tasks;
|
||||||
|
|
||||||
|
println!("test");
|
||||||
|
|
||||||
|
let headers: http::HeaderMap = extract().await.unwrap();
|
||||||
|
|
||||||
|
dbg!(headers.iter().collect::<Vec<_>>());
|
||||||
|
// println!(headers.values().collect())
|
||||||
|
|
||||||
new_task.validate()
|
new_task.validate()
|
||||||
.map_err::<ErrorVec<TaskError>, _>(|errors| errors.into())?;
|
.map_err::<ErrorVec<TaskError>, _>(|errors| errors.into())?;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user