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}