xref: /tonic/examples/src/authentication/server.rs (revision e683ffef)
1 pub mod pb {
2     tonic::include_proto!("grpc.examples.echo");
3 }
4 
5 use futures::Stream;
6 use pb::{EchoRequest, EchoResponse};
7 use std::pin::Pin;
8 use tonic::{metadata::MetadataValue, transport::Server, Request, Response, Status, Streaming};
9 
10 type EchoResult<T> = Result<Response<T>, Status>;
11 type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send + Sync>>;
12 
13 #[derive(Default)]
14 pub struct EchoServer;
15 
16 #[tonic::async_trait]
17 impl pb::echo_server::Echo for EchoServer {
18     async fn unary_echo(&self, request: Request<EchoRequest>) -> EchoResult<EchoResponse> {
19         let message = request.into_inner().message;
20         Ok(Response::new(EchoResponse { message }))
21     }
22 
23     type ServerStreamingEchoStream = ResponseStream;
24 
25     async fn server_streaming_echo(
26         &self,
27         _: Request<EchoRequest>,
28     ) -> EchoResult<Self::ServerStreamingEchoStream> {
29         Err(Status::unimplemented("not implemented"))
30     }
31 
32     async fn client_streaming_echo(
33         &self,
34         _: Request<Streaming<EchoRequest>>,
35     ) -> EchoResult<EchoResponse> {
36         Err(Status::unimplemented("not implemented"))
37     }
38 
39     type BidirectionalStreamingEchoStream = ResponseStream;
40 
41     async fn bidirectional_streaming_echo(
42         &self,
43         _: Request<Streaming<EchoRequest>>,
44     ) -> EchoResult<Self::BidirectionalStreamingEchoStream> {
45         Err(Status::unimplemented("not implemented"))
46     }
47 }
48 
49 #[tokio::main]
50 async fn main() -> Result<(), Box<dyn std::error::Error>> {
51     let addr = "[::1]:50051".parse().unwrap();
52     let server = EchoServer::default();
53 
54     let svc = pb::echo_server::EchoServer::with_interceptor(server, check_auth);
55 
56     Server::builder().add_service(svc).serve(addr).await?;
57 
58     Ok(())
59 }
60 
61 fn check_auth(req: Request<()>) -> Result<Request<()>, Status> {
62     let token = MetadataValue::from_str("Bearer some-secret-token").unwrap();
63 
64     match req.metadata().get("authorization") {
65         Some(t) if token == t => Ok(req),
66         _ => Err(Status::unauthenticated("No valid auth token")),
67     }
68 }
69