floonet-rs: hardened nostr-rs-relay for the Grin community
Test and build / test_floonet-rs (push) Has been cancelled
Test and build / test_floonet-rs (push) Has been cancelled
nostr-rs-relay + a default-deny admission pipeline (kinds 0,3,5,13,1059, 10002,10050,27235 only), NIP-42 auth, neutral NIP-11, a built-in name authority (paid names via GoblinPay), and a config-toggled co-located mixnet exit supervisor. Single binary + installer + hardened systemd, or Docker Compose. Relay core untouched (additive admission + authority).
This commit is contained in:
Generated
+1010
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "nauthz-server"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
# Common dependencies
|
||||
tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] }
|
||||
prost = "0.11"
|
||||
tonic = "0.8.3"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = { version="0.8.3", features = ["prost"] }
|
||||
@@ -0,0 +1,7 @@
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tonic_build::configure()
|
||||
.build_server(true)
|
||||
.protoc_arg("--experimental_allow_proto3_optional")
|
||||
.compile(&["../../proto/nauthz.proto"], &["../../proto"])?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
use tonic::{transport::Server, Request, Response, Status};
|
||||
|
||||
use nauthz_grpc::authorization_server::{Authorization, AuthorizationServer};
|
||||
use nauthz_grpc::{Decision, EventReply, EventRequest};
|
||||
|
||||
pub mod nauthz_grpc {
|
||||
tonic::include_proto!("nauthz");
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct EventAuthz {
|
||||
allowed_kinds: Vec<u64>,
|
||||
}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl Authorization for EventAuthz {
|
||||
async fn event_admit(
|
||||
&self,
|
||||
request: Request<EventRequest>,
|
||||
) -> Result<Response<EventReply>, Status> {
|
||||
let reply;
|
||||
let req = request.into_inner();
|
||||
let event = req.event.unwrap();
|
||||
let content_prefix: String = event.content.chars().take(40).collect();
|
||||
println!("recvd event, [kind={}, origin={:?}, nip05_domain={:?}, tag_count={}, content_sample={:?}]",
|
||||
event.kind, req.origin, req.nip05.map(|x| x.domain), event.tags.len(), content_prefix);
|
||||
// Permit any event with a whitelisted kind
|
||||
if self.allowed_kinds.contains(&event.kind) {
|
||||
println!("This looks fine! (kind={})", event.kind);
|
||||
reply = nauthz_grpc::EventReply {
|
||||
decision: Decision::Permit as i32,
|
||||
message: None,
|
||||
};
|
||||
} else {
|
||||
println!("Blocked! (kind={})", event.kind);
|
||||
reply = nauthz_grpc::EventReply {
|
||||
decision: Decision::Deny as i32,
|
||||
message: Some(format!("kind {} not permitted", event.kind)),
|
||||
};
|
||||
}
|
||||
Ok(Response::new(reply))
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let addr = "[::1]:50051".parse().unwrap();
|
||||
|
||||
// A simple authorization engine that allows kinds 0-3
|
||||
let checker = EventAuthz {
|
||||
allowed_kinds: vec![0, 1, 2, 3],
|
||||
};
|
||||
println!("EventAuthz Server listening on {}", addr);
|
||||
// Start serving
|
||||
Server::builder()
|
||||
.add_service(AuthorizationServer::new(checker))
|
||||
.serve(addr)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user