nostr_rs_ext/
grpc.rs

1
2use crate::config::Settings;
3use tracing::info;
4use crate::plugins::{ load_plugins, ExtPlugin};
5
6use tonic::{transport::Server, Request, Response, Status};
7
8use nostr_rs_proto::nauthz_grpc::authorization_server::{Authorization, AuthorizationServer};
9use nostr_rs_proto::nauthz_grpc::{Decision, EventReply, EventRequest};
10
11
12pub struct EventAuthz {
13    plugins: Vec<ExtPlugin>,
14}
15
16const DENY: i32 = Decision::Deny as i32;
17
18#[tonic::async_trait]
19impl Authorization for EventAuthz {
20    async fn event_admit(
21        &self,
22        request: Request<EventRequest>,
23    ) -> Result<Response<EventReply>, Status> {
24        let req = request.into_inner();
25        
26        for ext_plugin in &self.plugins {
27            let plugin_reply = ext_plugin.plugin.admit_event(&req);
28
29            if plugin_reply.decision == DENY {
30                return Ok(Response::new(plugin_reply));
31            }
32        }
33        
34        Ok(Response::new(EventReply {
35            decision: Decision::Permit as i32,
36            message: None,
37        }))
38    }
39}
40
41pub async fn start_server(
42    settings: Settings,
43) {
44    let addr = format!(
45        "{}:{}",
46        settings.network.address.trim(),
47        settings.network.port
48    );
49
50    let plugins = load_plugins(settings.plugins.folder).await;
51
52    let socket_addr = addr.parse().expect("listening address not valid");
53
54    info!("Listening on: {}", socket_addr);
55
56    let auth_plugins = EventAuthz {
57        plugins
58    };
59
60    Server::builder()
61        .add_service(AuthorizationServer::new(auth_plugins))
62        .serve(socket_addr)
63        .await.ok();
64
65    info!("Stopped")
66}