mod.rs (5143B)
1 #![forbid(unsafe_code)] 2 3 use anyhow::Result; 4 use jsonrpsee::server::RpcModule; 5 6 use crate::transport::jsonrpc::{MethodRegistry, RpcContext}; 7 8 pub mod nip46; 9 pub mod publish_proxy; 10 11 pub fn register_all( 12 root: &mut RpcModule<RpcContext>, 13 ctx: RpcContext, 14 registry: MethodRegistry, 15 ) -> Result<()> { 16 if ctx.state.publish_proxy.config.enabled { 17 root.merge(publish_proxy::module(ctx.clone(), registry.clone())?)?; 18 } 19 if ctx.state.nip46_config.public_jsonrpc_enabled { 20 root.merge(nip46::module(ctx, registry)?)?; 21 } 22 Ok(()) 23 } 24 25 #[cfg(test)] 26 mod tests { 27 use jsonrpsee::server::RpcModule; 28 use radroots_identity::RadrootsIdentity; 29 use radroots_nostr::prelude::RadrootsNostrMetadata; 30 31 use super::register_all; 32 use crate::app::config::{Nip46Config, PublishProxyConfig}; 33 use crate::core::Radrootsd; 34 use crate::transport::jsonrpc::auth::PublishProxyAuthorization; 35 use crate::transport::jsonrpc::{MethodRegistry, RpcContext}; 36 37 fn state(publish_proxy_enabled: bool, nip46_public_jsonrpc_enabled: bool) -> Radrootsd { 38 let identity = RadrootsIdentity::generate(); 39 let metadata: RadrootsNostrMetadata = 40 serde_json::from_str(r#"{"name":"radrootsd-test"}"#).expect("metadata"); 41 let publish_proxy = PublishProxyConfig { 42 enabled: publish_proxy_enabled, 43 ..PublishProxyConfig::default() 44 }; 45 let nip46 = Nip46Config { 46 public_jsonrpc_enabled: nip46_public_jsonrpc_enabled, 47 ..Nip46Config::default() 48 }; 49 Radrootsd::new(identity, metadata, publish_proxy, nip46).expect("state") 50 } 51 52 #[test] 53 fn register_all_exposes_publish_proxy_methods_by_default() { 54 let registry = MethodRegistry::default(); 55 let ctx = RpcContext::new(state(true, false), registry.clone()); 56 let mut root = RpcModule::new(ctx.clone()); 57 register_all(&mut root, ctx, registry).expect("register"); 58 59 assert!(root.method("publish.capabilities").is_some()); 60 assert!(root.method("publish.event").is_some()); 61 assert!(root.method("publish.job.get").is_some()); 62 assert!(root.method("publish.job.list").is_some()); 63 assert!(root.method("publish.relays.resolve").is_some()); 64 let legacy_method = ["br", "idge.status"].concat(); 65 assert!(root.method(legacy_method.as_str()).is_none()); 66 assert!(root.method("nip46.connect").is_none()); 67 } 68 69 #[test] 70 fn register_all_exposes_nip46_when_public_jsonrpc_is_enabled() { 71 let registry = MethodRegistry::default(); 72 let ctx = RpcContext::new(state(true, true), registry.clone()); 73 let mut root = RpcModule::new(ctx.clone()); 74 register_all(&mut root, ctx, registry).expect("register"); 75 76 assert!(root.method("publish.capabilities").is_some()); 77 assert!(root.method("nip46.connect").is_some()); 78 } 79 80 #[tokio::test] 81 async fn publish_capabilities_rejects_unauthenticated_requests() { 82 let registry = MethodRegistry::default(); 83 let ctx = RpcContext::new(state(true, false), registry.clone()); 84 let mut root = RpcModule::new(ctx.clone()); 85 register_all(&mut root, ctx, registry).expect("register"); 86 87 let (response, _stream) = root 88 .raw_json_request( 89 r#"{"jsonrpc":"2.0","method":"publish.capabilities","id":1}"#, 90 1, 91 ) 92 .await 93 .expect("request"); 94 assert!(response.get().contains("unauthorized")); 95 } 96 97 #[tokio::test] 98 async fn publish_capabilities_accepts_authenticated_requests() { 99 let registry = MethodRegistry::default(); 100 let ctx = RpcContext::new(state(true, false), registry.clone()); 101 let principal = ctx 102 .state 103 .publish_proxy 104 .store 105 .create_principal(crate::core::publish_proxy::PublishPrincipalInit { 106 label: "tester".to_owned(), 107 token_hash: crate::core::publish_proxy::hash_bearer_token("secret"), 108 allowed_pubkeys: vec!["a".repeat(64)], 109 allowed_kinds: vec![30_402], 110 allowed_relay_policies: vec![ 111 radroots_publish_proxy_protocol::PublishRelayPolicy::DaemonDefaultOnly, 112 ], 113 allow_request_relays: false, 114 job_visibility: crate::core::publish_proxy::PublishJobVisibility::Own, 115 expires_at_unix: None, 116 }) 117 .expect("principal"); 118 let mut root = RpcModule::new(ctx.clone()); 119 root.extensions_mut() 120 .insert(PublishProxyAuthorization::Authorized(principal)); 121 register_all(&mut root, ctx, registry).expect("register"); 122 123 let (response, _stream) = root 124 .raw_json_request( 125 r#"{"jsonrpc":"2.0","method":"publish.capabilities","id":1}"#, 126 1, 127 ) 128 .await 129 .expect("request"); 130 assert!(response.get().contains("\"scoped_bearer_token\"")); 131 assert!(response.get().contains("\"signed_event_ingress\":true")); 132 } 133 }