Skip to content

Commit a4e0125

Browse files
committed
refactor(valar-core): replace tower Service with custom Handler trait
- Consolidate AuthenticationHandler, SignInHandler, SignOutHandler into single Handler trait - Replace tower dependency with tower-layer only - Implement BoxCloneSyncHandler for type-erased handler storage - Change state parameter from generic to &dyn State - Add AuthenticationContext trait for ergonomic auth API - Add gen_test_layer_service! macro for test boilerplate reduction BREAKING CHANGE: Handler trait replaces tower::Service for authentication
1 parent 950f28e commit a4e0125

File tree

14 files changed

+386
-199
lines changed

14 files changed

+386
-199
lines changed

crates/valar-core/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ identity = ["authorization"]
2525
[dependencies]
2626
http = "1.3.1"
2727
thiserror = { workspace = true }
28-
tower-service = { workspace = true }
2928
tower-layer = "0.3.3"
30-
tower = { workspace = true, features = ["util"] }
3129
derive-new = { workspace = true }
3230
tracing = { workspace = true }
3331
paste = "1.0.15"

crates/valar-core/src/http/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,22 @@ impl IntoRequest for Parts {
2727
}
2828
}
2929

30-
impl IntoRequest for Body {
30+
impl IntoRequest for Request<Body> {
3131
type Body = Self;
3232

3333
fn into_request(self) -> Request<Self::Body> {
3434
todo!()
3535
}
3636
}
3737

38+
impl IntoResponse for Response<Body> {
39+
type Body = Self;
40+
41+
fn into_response(self) -> Response<Self::Body> {
42+
todo!()
43+
}
44+
}
45+
3846
#[cfg(test)]
3947
mod tests {
4048

crates/valar-core/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//!
55
#![forbid(unsafe_code)]
66
// Silence the noise in development!
7-
#![cfg_attr(debug_assertions, allow(dead_code, unused_variables, unused_imports))]
7+
// #![cfg_attr(debug_assertions, allow(dead_code, unused_variables, unused_imports))]
88
// Docs and linting rules
99
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
1010
#![cfg_attr(test, allow(clippy::float_cmp))]
@@ -16,7 +16,6 @@
1616
pub mod http;
1717
pub mod identity;
1818
pub mod metrics;
19-
pub mod util;
2019
pub mod valar;
2120

2221
#[macro_use]
@@ -25,3 +24,4 @@ extern crate derive_new;
2524
extern crate tracing;
2625

2726
pub use valar::handler::resolve_state;
27+
pub type BoxFuture<'a, T> = std::pin::Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>;

crates/valar-core/src/util.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
use crate::http::{Response, body::Body};
2-
use crate::valar::Error;
3-
use std::{
4-
future::{Ready, ready},
5-
task::Poll,
6-
};
1+
// use crate::http::{Response, body::Body};
2+
// use crate::valar::Error;
3+
// use std::{
4+
// future::{Ready, ready},
5+
// task::Poll,
6+
// };
77

8-
#[derive(Debug, Clone)]
9-
pub struct NoopService;
8+
// #[derive(Debug, Clone)]
9+
// pub struct NoopService;
1010

11-
impl<Request> tower::Service<Request> for NoopService {
12-
type Response = Response;
13-
type Error = Error;
14-
type Future = Ready<Result<Self::Response, Self::Error>>;
11+
// impl<Request> tower::Service<Request> for NoopService {
12+
// type Response = Response;
13+
// type Error = Error;
14+
// type Future = Ready<Result<Self::Response, Self::Error>>;
1515

16-
fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
17-
Poll::Ready(Ok(()))
18-
}
16+
// fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
17+
// Poll::Ready(Ok(()))
18+
// }
1919

20-
fn call(&mut self, _req: Request) -> Self::Future {
21-
ready(Ok(Response::new(Body::new(()))))
22-
}
23-
}
20+
// fn call(&mut self, _req: Request) -> Self::Future {
21+
// ready(Ok(Response::new(Body::new(()))))
22+
// }
23+
// }

crates/valar-core/src/valar/builder.rs

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use super::scope::Scope;
2-
use crate::{
3-
http::IntoRequest,
4-
valar::{Valar, map::Map, scope::ScopeLayer},
5-
};
6-
use tower::Layer;
2+
use crate::valar::{Valar, scope::ScopeLayer};
3+
use tower_layer::Layer;
74

85
#[derive(Debug, Clone, new)]
96
pub struct Builder<S>(S);
@@ -12,6 +9,10 @@ impl<S> Builder<S>
129
where
1310
S: Clone,
1411
{
12+
pub fn into_inner(self) -> S {
13+
self.0
14+
}
15+
1516
pub fn layer<L>(self, layer: L) -> Builder<S::Output>
1617
where
1718
S: ApplyLayer<L>,
@@ -188,10 +189,15 @@ impl_apply_layer!(
188189

189190
#[cfg(test)]
190191
mod tests {
191-
use std::convert::Infallible;
192192

193193
use super::*;
194-
use crate::{http::Request, util::NoopService};
194+
use crate::BoxFuture;
195+
use crate::http::{IntoRequest, Response};
196+
use crate::valar::builder;
197+
use crate::valar::{
198+
credential::Credential,
199+
handler::{Handler, State},
200+
};
195201

196202
#[derive(Debug, Clone)]
197203
struct FooLayer;
@@ -201,21 +207,69 @@ mod tests {
201207
inner: S,
202208
}
203209

204-
impl<S> tower::Service<Request> for FooService<S> {
205-
type Response = Infallible;
206-
type Error = Infallible;
207-
type Future = std::pin::Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
210+
impl<S, Request> Handler<Request> for FooService<S>
211+
where
212+
S: Handler<Request>,
213+
Request: IntoRequest,
214+
{
215+
type Response = S::Response;
216+
type Error = S::Error;
217+
type Future = S::Future;
218+
219+
fn authenticate(&self, request: Request, state: &dyn State) -> Self::Future {
220+
todo!()
221+
}
222+
223+
fn forbid(&self, request: Request, state: &dyn State) -> Self::Future {
224+
todo!()
225+
}
226+
227+
fn challenge(&self, request: Request, state: &dyn State) -> Self::Future {
228+
todo!()
229+
}
230+
231+
fn sign_out(&self, request: Request, state: &dyn State) -> Self::Future {
232+
todo!()
233+
}
234+
235+
fn sign_in(&self, request: Request, state: &dyn State, credential: Credential) -> Self::Future {
236+
todo!()
237+
}
238+
}
239+
240+
#[derive(Debug, Clone)]
241+
struct NoopHandler;
242+
243+
impl<Request> Handler<Request> for NoopHandler
244+
where
245+
Request: IntoRequest,
246+
{
247+
type Response = Response;
248+
type Error = Response;
249+
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
250+
251+
fn authenticate(&self, request: Request, state: &dyn State) -> Self::Future {
252+
todo!()
253+
}
254+
255+
fn forbid(&self, request: Request, state: &dyn State) -> Self::Future {
256+
todo!()
257+
}
208258

209-
fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll<Result<(), Self::Error>> {
259+
fn challenge(&self, request: Request, state: &dyn State) -> Self::Future {
210260
todo!()
211261
}
212262

213-
fn call(&mut self, req: Request) -> Self::Future {
263+
fn sign_out(&self, request: Request, state: &dyn State) -> Self::Future {
264+
todo!()
265+
}
266+
267+
fn sign_in(&self, request: Request, state: &dyn State, credential: Credential) -> Self::Future {
214268
todo!()
215269
}
216270
}
217271

218-
impl<S> tower::Layer<S> for FooLayer
272+
impl<S> tower_layer::Layer<S> for FooLayer
219273
where
220274
S: Clone,
221275
{
@@ -228,10 +282,11 @@ mod tests {
228282

229283
#[test]
230284
fn test_builder() {
231-
let builder = Builder::new((NoopService,))
232-
.handler(NoopService)
285+
let (_service_1, _) = builder::Builder::new((NoopHandler,))
233286
.layer(FooLayer)
234-
.handler(NoopService)
235-
.scope_layer(Scope::SignIn, FooLayer);
287+
.handler(NoopHandler)
288+
.into_inner();
289+
290+
// let _ = service_1.authenticate(request, state);
236291
}
237292
}

crates/valar-core/src/valar/context.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
use tower::Service;
2-
31
use crate::{
4-
http::{IntoRequest, IntoResponse, Response, body::Body},
5-
metrics::Metrics,
2+
http::{IntoRequest, IntoResponse, Response},
63
valar::{
74
Valar,
85
credential::Credential,
9-
handler::{AuthenticationHandler, SignInHandler, SignOutHandler, State},
6+
handler::{Handler, State},
107
},
118
};
129

10+
pub trait AuthenticationContext<Request>: Sized
11+
where
12+
Request: IntoRequest,
13+
{
14+
fn auth(&self, request: Request) -> Context<'_, Request>;
15+
}
16+
1317
#[derive(Debug, new)]
1418
pub struct Context<'a, Request> {
1519
valar_instace: &'a Valar,
@@ -27,11 +31,10 @@ impl<'a, Request> Context<'a, Request>
2731
where
2832
Request: IntoRequest,
2933
{
30-
pub async fn authenticate<H, T>(self, state: T) -> Result<Response, Error>
34+
pub async fn authenticate<H>(self, state: &dyn State) -> Result<Response, Error>
3135
where
32-
H: AuthenticationHandler<Request> + Clone + Send + Sync + 'static,
36+
H: Handler<Request> + Clone + Send + Sync + 'static,
3337
H::Response: IntoResponse,
34-
T: Sync + Send + 'static,
3538
{
3639
let handler = self
3740
.valar_instace
@@ -58,29 +61,29 @@ where
5861

5962
todo!()
6063
}
61-
pub async fn forbid<H, T>(self, state: T) -> Result<Response, Error>
64+
pub async fn forbid<H>(self, state: &dyn State) -> Result<Response, Error>
6265
where
63-
H: AuthenticationHandler<Request>,
66+
H: Handler<Request>,
6467
{
6568
todo!()
6669
}
67-
pub async fn challenge<H, T>(self, state: T) -> Result<Response, Error>
70+
pub async fn challenge<H>(self, state: &dyn State) -> Result<Response, Error>
6871
where
69-
H: AuthenticationHandler<Request>,
72+
H: Handler<Request>,
7073
{
7174
todo!()
7275
}
7376

74-
pub async fn sign_out<H, T>(self, state: T) -> Result<Response, Error>
77+
pub async fn sign_out<H>(self, state: &dyn State) -> Result<Response, Error>
7578
where
76-
H: SignOutHandler<Request>,
79+
H: Handler<Request>,
7780
{
7881
todo!()
7982
}
8083

81-
pub async fn sign_in<H, T>(self, state: T, credential: Credential) -> Result<Response, Error>
84+
pub async fn sign_in<H>(self, state: &dyn State, credential: Credential) -> Result<Response, Error>
8285
where
83-
H: SignInHandler<Request>,
86+
H: Handler<Request>,
8487
{
8588
todo!()
8689
}

0 commit comments

Comments
 (0)