Skip to main content

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}