diff --git a/Cargo.lock b/Cargo.lock index 87372cd..16b72f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + [[package]] name = "async-trait" version = "0.1.74" @@ -107,6 +113,21 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -244,6 +265,20 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.28" @@ -251,6 +286,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -259,6 +295,12 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + [[package]] name = "futures-macro" version = "0.3.28" @@ -270,6 +312,12 @@ dependencies = [ "syn 2.0.38", ] +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + [[package]] name = "futures-task" version = "0.3.28" @@ -282,9 +330,13 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -317,6 +369,31 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hermit-abi" version = "0.3.3" @@ -383,6 +460,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", + "h2", "http", "http-body", "httparse", @@ -423,6 +501,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "ipnet" version = "2.8.0" @@ -438,6 +526,78 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "jsonrpsee" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc" +dependencies = [ + "jsonrpsee-core", + "jsonrpsee-server", + "jsonrpsee-types", + "tokio", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b" +dependencies = [ + "anyhow", + "async-trait", + "beef", + "futures-util", + "hyper", + "jsonrpsee-types", + "parking_lot", + "rand", + "rustc-hash", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-server" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82c39a00449c9ef3f50b84fc00fc4acba20ef8f559f07902244abf4c15c5ab9c" +dependencies = [ + "futures-util", + "http", + "hyper", + "jsonrpsee-core", + "jsonrpsee-types", + "route-recognizer", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" +dependencies = [ + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", + "tracing", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -538,6 +698,7 @@ dependencies = [ "axum", "custom_error", "ipnet", + "jsonrpsee", "macaddr", "pwhash", "serde", @@ -797,12 +958,24 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "route-recognizer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" + [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustversion" version = "1.0.14" @@ -953,6 +1126,22 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64", + "bytes", + "futures", + "http", + "httparse", + "log", + "rand", + "sha-1", +] + [[package]] name = "subtle" version = "2.4.1" @@ -1091,6 +1280,32 @@ dependencies = [ "syn 2.0.38", ] +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "tower" version = "0.4.13" diff --git a/Cargo.toml b/Cargo.toml index 4a65bef..43ca43e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ async-trait = "0.1.74" axum = "0.6.20" custom_error = "1.9.2" ipnet = { version = "2.8.0", features = ["serde"] } +jsonrpsee = { version = "0.20.3", features = ["server"] } macaddr = { version = "1.0.1", features = ["serde"] } pwhash = "1.0.0" serde = { version = "1.0.189", features = ["derive"] } diff --git a/src/web/rpc.rs b/src/web/rpc.rs index cab913a..3b776e5 100644 --- a/src/web/rpc.rs +++ b/src/web/rpc.rs @@ -1,7 +1,11 @@ -use super::super::json_rpc::{JsonRpcExtractor, JsonRpcResponse, JsonRpcResult}; +use std::collections::HashMap; + +use super::super::definitions::network::StaticRoute; +use super::super::definitions::system::User; use super::super::AppState; use axum::routing::post; use axum::{Json, Router}; +use jsonrpsee::types::Params; use tower_cookies::{Cookie, Cookies}; use axum::{ @@ -12,8 +16,29 @@ use axum::{ response::{IntoResponse, Response}, }; +use jsonrpsee::server::{RpcModule, Server}; + use tracing::info; +use custom_error::custom_error; + +custom_error! { ApiError + BadRequest = "Bad Request Parameters", +} + +struct RpcRequest<'a> { + id: i64, + params: Params<'a>, + jsonrpc: String, + method: String, +} + +struct RpcResponse<'a> { + id: i64, + payload: Params<'a>, + jsonrpc: String, +} + pub fn routes() -> Router { Router::new().route("/api", post(api_handler)) } @@ -21,22 +46,49 @@ pub fn routes() -> Router { async fn api_handler( State(state): State, session: Extension, - req: JsonRpcExtractor, -) -> JsonRpcResult { + Json(rpc_request): Json>, +) -> impl IntoResponse { info!("api hit! user: {:?}", session.username); - let req_id = req.get_request_id(); - let method = req.method(); - let response = match method { - "add" => { - let params: [i32; 2] = req.parse_params()?; - JsonRpcResponse::success(req_id, params[0] + params[1]) - } - "System.GetUsers" => JsonRpcResponse::success( - req_id, - state.config_manager.get_pending_config().system.users, - ), - m => req.method_not_found(m), - }; + let module = RpcModule::new(state); + module + .register_method("say_hello", |_, _| { + println!("say_hello method called!"); + "Hello there!!" + }) + .unwrap(); - Ok(response) + module + .register_method("System.GetUsers", get_users) + .unwrap(); + module + .register_method("Network.GetStaticRoutes", get_static_routes) + .unwrap(); + + let res = module.call(&rpc_request.method, rpc_request.params).await; + + match res { + Ok(res) => RpcResponse { + id: rpc_request.id, + jsonrpc: rpc_request.jsonrpc, + payload: res, + }, + // TODO make Error Response + Err(err) => RpcResponse { + id: rpc_request.id, + jsonrpc: rpc_request.jsonrpc, + payload: res, + }, + } +} + +fn get_users(_: Params, state: &AppState) -> Result, String> { + Ok(state.config_manager.get_pending_config().system.users) +} + +fn get_static_routes(_: Params, state: &AppState) -> Result, String> { + Ok(state + .config_manager + .get_pending_config() + .network + .static_routes) }