summaryrefslogtreecommitdiff
path: root/src/authorization/server.rs
blob: ded609da2608d721ff0aaffbd93d5fbe1665ae5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use super::cedar_authorizer::CedarAuthorizer;
use super::check_service::CheckService;
use envoy_types::ext_authz::v3::pb::AuthorizationServer;
use std::sync::Arc;

pub struct Server {
    router: tonic::transport::server::Router,
}

impl Server {
    pub fn new() -> Result<Server, Box<dyn std::error::Error>> {
        let (health_reporter, health_service) = tonic_health::server::health_reporter();
        std::mem::drop(
            health_reporter.set_service_status("", tonic_health::ServingStatus::Serving),
        );
        let authorization_service =
            AuthorizationServer::new(CheckService::new(Arc::new(CedarAuthorizer::default())));

        let reflection_service = tonic_reflection::server::Builder::configure()
            .register_encoded_file_descriptor_set(tonic_health::pb::FILE_DESCRIPTOR_SET)
            .build_v1()?;

        Ok(Self::new_with(|mut builder| {
            builder
                .add_service(authorization_service)
                .add_service(health_service)
                .add_service(reflection_service)
        }))
    }

    pub fn new_with<F>(f: F) -> Server
    where
        F: FnOnce(tonic::transport::Server) -> tonic::transport::server::Router,
    {
        let builder = tonic::transport::Server::builder()
            .trace_fn(|req| {
                tracing::info_span!(
                    "request",
                    method = %req.method(),
                    path = %req.uri().path(),
                    headers = ?req.headers(),
                )
            })
            .timeout(std::time::Duration::from_secs(30));
        let router = f(builder);
        Server { router }
    }

    pub async fn serve(self, addr: std::net::SocketAddr) -> Result<(), tonic::transport::Error> {
        self.router.serve(addr).await
    }
}

impl Default for Server {
    fn default() -> Self {
        Self::new().unwrap()
    }
}