iroh_proxy_utils/upstream/auth.rs
1use std::future::Future;
2
3use dynosaur::dynosaur;
4use iroh::EndpointId;
5use n0_error::StackError;
6
7use crate::parse::HttpProxyRequest;
8
9/// Authorization failure reasons.
10///
11/// Returned by [`AuthHandler::authorize`] to indicate why a request was rejected.
12/// The upstream proxy responds with 403 Forbidden for all variants.
13#[derive(StackError)]
14pub enum AuthError {
15 /// Credentials are malformed or failed validation.
16 InvalidCredentials,
17 /// Credentials were valid but have expired.
18 TokenExpired,
19 /// Authorization denied for this request.
20 Forbidden,
21 /// Request is invalid for the authentication scheme.
22 BadRequest,
23}
24
25#[dynosaur(pub(crate) DynAuthHandler = dyn(box) AuthHandler)]
26/// Authorizes proxy requests from remote endpoints.
27///
28/// Implement this trait to control which requests are allowed through the
29/// upstream proxy. Authorization decisions can be based on the remote endpoint
30/// identity, request target, headers, or any other criteria.
31pub trait AuthHandler: Send + Sync {
32 /// Checks if the request from `remote_id` should be authorized.
33 ///
34 /// Returns `Ok(())` to allow the request, or an [`AuthError`] to reject it.
35 fn authorize<'a>(
36 &'a self,
37 remote_id: EndpointId,
38 req: &'a HttpProxyRequest,
39 ) -> impl Future<Output = Result<(), AuthError>> + Send + 'a;
40}
41
42/// Authorization handler that rejects all requests with 403 Forbidden.
43#[derive(Debug, Default)]
44pub struct DenyAll;
45
46impl AuthHandler for DenyAll {
47 async fn authorize<'a>(
48 &'a self,
49 _remote_id: EndpointId,
50 _req: &'a HttpProxyRequest,
51 ) -> Result<(), AuthError> {
52 Err(AuthError::Forbidden)
53 }
54}
55
56/// Authorization handler that accepts all requests unconditionally.
57///
58/// Suitable for testing or when authorization is handled elsewhere.
59#[derive(Debug, Default)]
60pub struct AcceptAll;
61
62impl AuthHandler for AcceptAll {
63 async fn authorize<'a>(
64 &'a self,
65 _remote_id: EndpointId,
66 _req: &'a HttpProxyRequest,
67 ) -> Result<(), AuthError> {
68 Ok(())
69 }
70}