delete http_bindings and rpc

This commit is contained in:
bitful-pannul 2023-10-20 21:50:38 +02:00
parent 13d5b19197
commit 498daadc82
19 changed files with 1 additions and 3207 deletions

View File

@ -125,15 +125,13 @@ fn main() {
return; return;
} }
// only execute if one of the modules has source code changes // only execute if one of the modules has source code changes
const WASI_APPS: [&str; 9] = [ const WASI_APPS: [&str; 7] = [
"app_store", "app_store",
"chess", "chess",
"homepage", "homepage",
"http_bindings",
"http_proxy", "http_proxy",
"orgs", "orgs",
"qns_indexer", "qns_indexer",
"rpc",
"terminal", "terminal",
]; ];
// NOT YET building KV, waiting for deps to be ready // NOT YET building KV, waiting for deps to be ready

View File

@ -1,3 +0,0 @@
# This file is automatically generated by cargo-component.
# It is not intended for manual editing.
version = 1

View File

@ -1,580 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "cargo-component-bindings"
version = "0.1.0"
source = "git+https://github.com/bytecodealliance/cargo-component#36c221e41db3e87dec4c82eadcb9bc8f37626533"
dependencies = [
"cargo-component-macro",
"wit-bindgen 0.11.0",
]
[[package]]
name = "cargo-component-macro"
version = "0.1.0"
source = "git+https://github.com/bytecodealliance/cargo-component#36c221e41db3e87dec4c82eadcb9bc8f37626533"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
"wit-bindgen-core",
"wit-bindgen-rust",
"wit-bindgen-rust-lib",
"wit-component",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cpufeatures"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
"subtle",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "form_urlencoded"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
dependencies = [
"percent-encoding",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "hashbrown"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
]
[[package]]
name = "http_bindings"
version = "0.1.0"
dependencies = [
"anyhow",
"bincode",
"cargo-component-bindings",
"hmac",
"jwt",
"serde",
"serde_json",
"sha2",
"url",
"wit-bindgen 0.9.0",
]
[[package]]
name = "id-arena"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]]
name = "idna"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "indexmap"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
dependencies = [
"equivalent",
"hashbrown",
"serde",
]
[[package]]
name = "itoa"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]]
name = "jwt"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6204285f77fe7d9784db3fdc449ecce1a0114927a51d5a41c4c7a292011c015f"
dependencies = [
"base64",
"crypto-common",
"digest",
"hmac",
"serde",
"serde_json",
"sha2",
]
[[package]]
name = "leb128"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]]
name = "libc"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "memchr"
version = "2.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
[[package]]
name = "percent-encoding"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
[[package]]
name = "proc-macro2"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "pulldown-cmark"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998"
dependencies = [
"bitflags 1.3.2",
"memchr",
"unicase",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "semver"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
[[package]]
name = "serde"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha2"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "smallvec"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]]
name = "spdx"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b19b32ed6d899ab23174302ff105c1577e45a06b08d4fe0a9dd13ce804bbbf71"
dependencies = [
"smallvec",
]
[[package]]
name = "subtle"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "syn"
version = "2.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "typenum"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "unicase"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-bidi"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
[[package]]
name = "unicode-ident"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-xid"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "url"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasm-encoder"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-metadata"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08dc59d1fa569150851542143ca79438ca56845ccb31696c70225c638e063471"
dependencies = [
"anyhow",
"indexmap",
"serde",
"serde_json",
"spdx",
"wasm-encoder",
"wasmparser",
]
[[package]]
name = "wasmparser"
version = "0.112.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e986b010f47fcce49cf8ea5d5f9e5d2737832f12b53ae8ae785bbe895d0877bf"
dependencies = [
"indexmap",
"semver",
]
[[package]]
name = "wit-bindgen"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5c3d15a04ce994fad2c5442a754b404ab1fee23c903a04a560f84f94fdf63c0"
dependencies = [
"bitflags 2.4.0",
]
[[package]]
name = "wit-bindgen"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8a3e8e965dc50e6eb4410d9a11720719fadc6a1713803ea5f3be390b81c8279"
dependencies = [
"bitflags 2.4.0",
"wit-bindgen-rust-macro",
]
[[package]]
name = "wit-bindgen-core"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77255512565dfbd0b61de466e854918041d1da53c7bc049d6188c6e02643dc1e"
dependencies = [
"anyhow",
"wit-component",
"wit-parser",
]
[[package]]
name = "wit-bindgen-rust"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "399c60e6ea8598d1380e792f13d557007834f0fb799fea6503408cbc5debb4ae"
dependencies = [
"anyhow",
"heck",
"wasm-metadata",
"wit-bindgen-core",
"wit-bindgen-rust-lib",
"wit-component",
]
[[package]]
name = "wit-bindgen-rust-lib"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd9fb7a43c7dc28b0b727d6ae01bf369981229b7539e768fba2b7a4df13feeeb"
dependencies = [
"heck",
"wit-bindgen-core",
]
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cea5ed784da06da0e55836a6c160e7502dbe28771c2368a595e8606243bf22"
dependencies = [
"anyhow",
"proc-macro2",
"syn",
"wit-bindgen-core",
"wit-bindgen-rust",
"wit-bindgen-rust-lib",
"wit-component",
]
[[package]]
name = "wit-component"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66d9f2d16dd55d1a372dcfd4b7a466ea876682a5a3cb97e71ec9eef04affa876"
dependencies = [
"anyhow",
"bitflags 2.4.0",
"indexmap",
"log",
"serde",
"serde_json",
"wasm-encoder",
"wasm-metadata",
"wasmparser",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61e8b849bea13cc2315426b16efe6eb6813466d78f5fde69b0bb150c9c40e0dc"
dependencies = [
"anyhow",
"id-arena",
"indexmap",
"log",
"pulldown-cmark",
"semver",
"unicode-xid",
"url",
]

View File

@ -1,34 +0,0 @@
[package]
name = "http_bindings"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
panic = "abort"
opt-level = "s"
lto = true
[dependencies]
anyhow = "1.0.72"
bincode = "1.3.3"
cargo-component-bindings = { git = "https://github.com/bytecodealliance/cargo-component" }
serde_json = "1.0"
serde = {version = "1.0", features = ["derive"] }
url = "2"
wit-bindgen = { version = "0.9.0", default_features = false }
jwt = "0.16"
sha2 = "0.10"
hmac = "0.12"
[lib]
crate-type = ["cdylib"]
[package.metadata.component]
package = "component:microkernel-process"
[package.metadata.component.target]
path = "wit"
[package.metadata.component.dependencies]

View File

@ -1,15 +0,0 @@
[
{
"process_name": "http_bindings",
"process_wasm_path": "/http_bindings.wasm",
"on_panic": "Restart",
"request_networking": false,
"request_messaging": [
"http_server:sys:uqbar",
"http_client:sys:uqbar",
"encryptor:sys:uqbar",
"vfs:sys:uqbar"
],
"public": false
}
]

View File

@ -1,4 +0,0 @@
{
"package": "http_bindings",
"publisher": "uqbar"
}

View File

@ -1,631 +0,0 @@
cargo_component_bindings::generate!();
use hmac::{Hmac, Mac};
use jwt::{Error, SignWithKey, VerifyWithKey};
use serde::{Deserialize, Serialize};
use sha2::Sha256;
use std::collections::HashMap;
use url::form_urlencoded;
use bindings::component::uq_process::types::*;
use bindings::{get_payload, print_to_terminal, receive, send_request, send_response, Guest};
#[allow(dead_code)]
mod process_lib;
struct Component;
#[derive(Debug, Serialize, Deserialize)]
struct BoundPath {
app: String,
authenticated: bool,
local_only: bool,
}
#[derive(Debug, Serialize, Deserialize)]
struct JwtClaims {
username: String,
expiration: u64,
}
fn generate_token(our_node: String, secret: Hmac<Sha256>) -> Option<String> {
let claims = JwtClaims {
username: our_node,
expiration: 0,
};
let token: Option<String> = match claims.sign_with_key(&secret) {
Ok(token) => Some(token),
Err(_) => None,
};
token
}
fn auth_cookie_valid(our_node: String, cookie: &str, secret: Hmac<Sha256>) -> bool {
let cookie_parts: Vec<&str> = cookie.split("; ").collect();
let mut auth_token = None;
for cookie_part in cookie_parts {
let cookie_part_parts: Vec<&str> = cookie_part.split("=").collect();
if cookie_part_parts.len() == 2
&& cookie_part_parts[0] == format!("uqbar-auth_{}", our_node)
{
auth_token = Some(cookie_part_parts[1].to_string());
break;
}
}
let auth_token = match auth_token {
Some(token) if !token.is_empty() => token,
_ => return false,
};
print_to_terminal(
1,
format!("http_bindings: auth_token: {}", auth_token).as_str(),
);
let claims: Result<JwtClaims, Error> = auth_token.verify_with_key(&secret);
match claims {
Ok(data) => {
print_to_terminal(
1,
format!(
"http_bindings: our name: {}, token_name {}",
our_node, data.username
)
.as_str(),
);
data.username == our_node
}
Err(_) => {
print_to_terminal(1, "http_bindings: failed to verify token");
false
}
}
}
fn send_http_response(status: u16, headers: HashMap<String, String>, payload_bytes: Vec<u8>) {
send_response(
&Response {
inherit: false,
ipc: Some(
serde_json::json!({
"status": status,
"headers": headers,
})
.to_string(),
),
metadata: None,
},
Some(&Payload {
mime: Some("application/octet-stream".to_string()),
bytes: payload_bytes,
}),
)
}
impl Guest for Component {
fn init(our: Address) {
print_to_terminal(0, "http_bindings: start");
let mut path_bindings: HashMap<String, BoundPath> = HashMap::new();
let mut jwt_secret: Option<Hmac<Sha256>> = None;
// get jwt secret from http_server, handle as a request with set-jwt-secret
send_request(
&Address {
node: our.node.clone(),
process: ProcessId::from_str("http_server:sys:uqbar").unwrap(),
},
&Request {
inherit: false,
expects_response: None,
ipc: Some(
serde_json::json!({
"ServerAction": {
"action": "get-jwt-secret",
}
})
.to_string(),
),
metadata: None,
},
None,
None,
);
loop {
let Ok((source, message)) = receive() else {
print_to_terminal(0, "http_bindings: got network error");
continue;
};
let Message::Request(request) = message else {
// Ignore responses for now
print_to_terminal(0, "http_bindings: got unexpected Respose, ignoring");
continue;
};
let Some(json) = request.ipc else {
print_to_terminal(0, "http_bindings: no ipc JSON, skipping");
continue;
};
let message_json: serde_json::Value = match serde_json::from_str(&json) {
Ok(v) => v,
Err(_) => {
print_to_terminal(1, "http_bindings: failed to parse ipc JSON, skipping");
continue;
}
};
let action = message_json["action"].as_str().unwrap_or("");
let address = message_json["address"].as_str().unwrap_or(""); // origin HTTP address
let path = message_json["path"].as_str().unwrap_or("");
let app: String = source.process.to_string();
print_to_terminal(1, "http_bindings: got message");
if action == "set-jwt-secret" {
let Some(payload) = get_payload() else {
panic!("set-jwt-secret with no payload");
};
let jwt_secret_bytes = payload.bytes;
print_to_terminal(1, "http_bindings: generating token secret...");
jwt_secret = match Hmac::new_from_slice(&jwt_secret_bytes) {
Ok(secret) => Some(secret),
Err(_) => {
print_to_terminal(1, "http_bindings: failed to generate token secret");
None
}
};
send_response(
&Response {
inherit: false,
ipc: None,
metadata: None,
},
None,
);
} else if action == "bind-app" && path != "" {
print_to_terminal(1, "http_bindings: binding app 1");
let path_segments = path
.trim_start_matches('/')
.split("/")
.collect::<Vec<&str>>();
if app != "homepage:homepage:uqbar"
&& (path_segments.is_empty()
|| path_segments[0] != app.clone().split(':').next().unwrap_or_default().to_string().replace("_", "-"))
{
print_to_terminal(
1,
format!(
"http_bindings: first path segment {} does not match process: {}",
path,
app.clone().replace("_", "-"),
)
.as_str(),
);
continue;
} else {
if !app.clone().ends_with(":sys:uqbar") && path_bindings.contains_key(path) {
print_to_terminal(0, &format!("http_bindings: path already bound {}", path));
continue;
}
print_to_terminal(
1,
format!("http_bindings: binding app 2 {}", path.to_string()).as_str(),
);
path_bindings.insert(path.to_string(), {
BoundPath {
app,
authenticated: message_json
.get("authenticated")
.and_then(|v| v.as_bool())
.unwrap_or(false),
local_only: message_json
.get("local_only")
.and_then(|v| v.as_bool())
.unwrap_or(false),
}
});
}
} else if action == "request" {
print_to_terminal(1, "http_bindings: got request");
// Start Login logic
if path == "/login" {
print_to_terminal(1, "http_bindings: got login request");
if message_json["method"] == "GET" {
print_to_terminal(1, "http_bindings: got login GET request");
let login_page_content = include_str!("login.html");
let personalized_login_page =
login_page_content.replace("${our}", &our.node);
send_http_response(
200,
{
let mut headers = HashMap::new();
headers.insert("Content-Type".to_string(), "text/html".to_string());
headers
},
personalized_login_page.as_bytes().to_vec(),
);
} else if message_json["method"] == "POST" {
print_to_terminal(1, "http_bindings: got login POST request");
let Some(payload) = get_payload() else {
panic!("/login POST with no bytes");
};
let body_json_string = match String::from_utf8(payload.bytes) {
Ok(s) => s,
Err(_) => String::new(),
};
let body: serde_json::Value =
serde_json::from_str(&body_json_string).unwrap();
let password = body["password"].as_str().unwrap_or("");
if password == "" {
send_http_response(
400,
HashMap::new(),
"Bad Request".as_bytes().to_vec(),
);
}
match jwt_secret.clone() {
Some(secret) => {
match generate_token(our.node.clone(), secret) {
Some(token) => {
// Token was generated successfully; you can use it here.
send_http_response(
200,
{
let mut headers = HashMap::new();
headers.insert(
"Content-Type".to_string(),
"text/html".to_string(),
);
headers.insert(
"set-cookie".to_string(),
format!("uqbar-auth_{}={};", our.node, token),
);
headers
},
"".as_bytes().to_vec(),
);
}
None => {
print_to_terminal(1, "so secret 1");
// Failed to generate token; you should probably return an error.
send_http_response(
500,
HashMap::new(),
"Server Error".as_bytes().to_vec(),
);
}
}
}
None => {
print_to_terminal(1, "so secret 2");
send_http_response(
500,
HashMap::new(),
"Server Error".as_bytes().to_vec(),
);
}
}
} else if message_json["method"] == "PUT" {
print_to_terminal(1, "http_bindings: got login PUT request");
let Some(payload) = get_payload() else {
panic!("/login PUT with no bytes");
};
let body_json_string = match String::from_utf8(payload.bytes) {
Ok(s) => s,
Err(_) => String::new(),
};
let body: serde_json::Value =
serde_json::from_str(&body_json_string).unwrap();
// let password = body["password"].as_str().unwrap_or("");
let signature = body["signature"].as_str().unwrap_or("");
if signature == "" {
send_http_response(
400,
HashMap::new(),
"Bad Request".as_bytes().to_vec(),
);
} else {
// TODO: Check signature against our address
print_to_terminal(1, "http_bindings: generating secret...");
// jwt_secret = generate_secret(password);
print_to_terminal(1, "http_bindings: generating token...");
match jwt_secret.clone() {
Some(secret) => {
match generate_token(our.node.clone(), secret) {
Some(token) => {
// Token was generated successfully; you can use it here.
send_http_response(
200,
{
let mut headers = HashMap::new();
headers.insert(
"Content-Type".to_string(),
"text/html".to_string(),
);
headers.insert(
"set-cookie".to_string(),
format!(
"uqbar-auth_{}={};",
our.node, token
),
);
headers
},
"".as_bytes().to_vec(),
);
}
None => {
// Failed to generate token; you should probably return an error.
send_http_response(
500,
HashMap::new(),
"Server Error".as_bytes().to_vec(),
);
}
}
}
None => {
send_http_response(
500,
HashMap::new(),
"Server Error".as_bytes().to_vec(),
);
}
}
}
} else {
send_http_response(404, HashMap::new(), "Not Found".as_bytes().to_vec());
}
continue;
}
// End Login logic
// Start Encryption Secret Logic
if path == "/encryptor" {
bindings::print_to_terminal(1, "http_bindings: got encryptor request");
let auth_success = match jwt_secret.clone() {
Some(secret) => {
bindings::print_to_terminal(1, "HAVE SECRET");
auth_cookie_valid(
our.node.clone(),
message_json["headers"]["cookie"].as_str().unwrap_or(""),
secret,
)
}
None => {
bindings::print_to_terminal(1, "NO SECRET");
false
}
};
if auth_success {
let body_bytes = match get_payload() {
Some(payload) => payload.bytes,
None => vec![],
};
let body_json_string = match String::from_utf8(body_bytes) {
Ok(s) => s,
Err(_) => String::new(),
};
let body: serde_json::Value =
serde_json::from_str(&body_json_string).unwrap();
let channel_id = body["channel_id"].as_str().unwrap_or("");
let public_key_hex = body["public_key_hex"].as_str().unwrap_or("");
send_request(
&Address {
node: our.node.clone(),
process: ProcessId::from_str("encryptor:sys:uqbar").unwrap(),
},
&Request {
inherit: true,
expects_response: None,
ipc: Some(
serde_json::json!({
"GetKeyAction": {
"channel_id": channel_id,
"public_key_hex": public_key_hex,
}
})
.to_string(),
),
metadata: None,
},
None,
None,
);
} else {
send_http_response(401, HashMap::new(), "Unauthorized".as_bytes().to_vec());
}
continue;
}
// End Encryption Secret Logic
let path_segments = path
.trim_start_matches('/')
.trim_end_matches('/')
.split("/")
.collect::<Vec<&str>>();
let mut registered_path = path;
let mut url_params: HashMap<String, String> = HashMap::new();
for (key, _value) in &path_bindings {
let key_segments = key
.trim_start_matches('/')
.trim_end_matches('/')
.split("/")
.collect::<Vec<&str>>();
if key_segments.len() != path_segments.len()
&& (!key.contains("/.*") || (key_segments.len() - 1) > path_segments.len())
{
continue;
}
let mut paths_match = true;
for i in 0..key_segments.len() {
if key_segments[i] == "*" {
break;
} else if !(key_segments[i].starts_with(":")
|| key_segments[i] == path_segments[i])
{
paths_match = false;
break;
} else if key_segments[i].starts_with(":") {
url_params.insert(
key_segments[i][1..].to_string(),
path_segments[i].to_string(),
);
}
}
if paths_match {
registered_path = key;
break;
}
url_params = HashMap::new();
}
print_to_terminal(
1,
&("http_bindings: registered path ".to_string() + registered_path),
);
match path_bindings.get(registered_path) {
Some(bound_path) => {
let app = bound_path.app.as_str();
print_to_terminal(
1,
&("http_bindings: properly unwrapped path ".to_string()
+ registered_path),
);
if bound_path.authenticated {
print_to_terminal(1, "AUTHENTICATED ROUTE");
let auth_success = match jwt_secret.clone() {
Some(secret) => auth_cookie_valid(
our.node.clone(),
message_json["headers"]["cookie"].as_str().unwrap_or(""),
secret,
),
None => {
print_to_terminal(1, "NO SECRET");
false
}
};
// if !auth_success {
// print_to_terminal(1, "http_bindings: failure to authenticate");
// let proxy_path = message_json["proxy_path"].as_str();
// let redirect_path: String = match proxy_path {
// Some(pp) => {
// form_urlencoded::byte_serialize(pp.as_bytes()).collect()
// }
// None => {
// form_urlencoded::byte_serialize(path.as_bytes()).collect()
// }
// };
// let location = match proxy_path {
// Some(_) => format!(
// "/http-proxy/serve/{}/login?redirect={}",
// &our.node, redirect_path
// ),
// None => format!("/login?redirect={}", redirect_path),
// };
// send_http_response(
// 302,
// {
// let mut headers = HashMap::new();
// headers.insert(
// "Content-Type".to_string(),
// "text/html".to_string(),
// );
// headers.insert("Location".to_string(), location);
// headers
// },
// "Auth cookie not valid".as_bytes().to_vec(),
// );
// continue;
// }
}
if bound_path.local_only && !address.starts_with("127.0.0.1:") {
send_http_response(
403,
{
let mut headers = HashMap::new();
headers.insert(
"Content-Type".to_string(),
"text/html".to_string(),
);
headers
},
"<h1>Localhost Origin Required</h1>".as_bytes().to_vec(),
);
continue;
}
// import send-request: func(target: address, request: request, context: option<context>, payload: option<payload>)
send_request(
&Address {
node: our.node.clone(),
process: ProcessId::from_str(app).unwrap(),
},
&Request {
inherit: true,
expects_response: None,
ipc: Some(
serde_json::json!({
"path": registered_path,
"raw_path": path,
"method": message_json["method"],
"headers": message_json["headers"],
"query_params": message_json["query_params"],
"url_params": url_params,
})
.to_string(),
),
metadata: None,
},
None,
get_payload().as_ref(),
);
continue;
}
None => {
print_to_terminal(1, "http_bindings: no app found at this path");
send_http_response(404, HashMap::new(), "Not Found".as_bytes().to_vec());
}
}
} else {
print_to_terminal(
1,
format!(
"http_bindings: unexpected action: {:?}",
&message_json["action"],
)
.as_str(),
);
}
}
}
}
// TODO: handle auth correctly, generate a secret and store in filesystem if non-existent

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
../../../src/process_lib.rs

View File

@ -1,3 +0,0 @@
# This file is automatically generated by cargo-component.
# It is not intended for manual editing.
version = 1

469
modules/rpc/Cargo.lock generated
View File

@ -1,469 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "cargo-component-bindings"
version = "0.1.0"
source = "git+https://github.com/bytecodealliance/cargo-component#36c221e41db3e87dec4c82eadcb9bc8f37626533"
dependencies = [
"cargo-component-macro",
"wit-bindgen 0.11.0",
]
[[package]]
name = "cargo-component-macro"
version = "0.1.0"
source = "git+https://github.com/bytecodealliance/cargo-component#36c221e41db3e87dec4c82eadcb9bc8f37626533"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
"wit-bindgen-core",
"wit-bindgen-rust",
"wit-bindgen-rust-lib",
"wit-component",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "form_urlencoded"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
dependencies = [
"percent-encoding",
]
[[package]]
name = "hashbrown"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "id-arena"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
[[package]]
name = "idna"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "indexmap"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
dependencies = [
"equivalent",
"hashbrown",
"serde",
]
[[package]]
name = "itoa"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]]
name = "leb128"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "memchr"
version = "2.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
[[package]]
name = "percent-encoding"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
[[package]]
name = "proc-macro2"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "pulldown-cmark"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998"
dependencies = [
"bitflags 1.3.2",
"memchr",
"unicase",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rpc"
version = "0.1.0"
dependencies = [
"anyhow",
"base64",
"bincode",
"cargo-component-bindings",
"serde",
"serde_json",
"wit-bindgen 0.9.0",
]
[[package]]
name = "ryu"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "semver"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
[[package]]
name = "serde"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "smallvec"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]]
name = "spdx"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b19b32ed6d899ab23174302ff105c1577e45a06b08d4fe0a9dd13ce804bbbf71"
dependencies = [
"smallvec",
]
[[package]]
name = "syn"
version = "2.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "unicase"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-bidi"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
[[package]]
name = "unicode-ident"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-xid"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "url"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasm-encoder"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7"
dependencies = [
"leb128",
]
[[package]]
name = "wasm-metadata"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08dc59d1fa569150851542143ca79438ca56845ccb31696c70225c638e063471"
dependencies = [
"anyhow",
"indexmap",
"serde",
"serde_json",
"spdx",
"wasm-encoder",
"wasmparser",
]
[[package]]
name = "wasmparser"
version = "0.112.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e986b010f47fcce49cf8ea5d5f9e5d2737832f12b53ae8ae785bbe895d0877bf"
dependencies = [
"indexmap",
"semver",
]
[[package]]
name = "wit-bindgen"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5c3d15a04ce994fad2c5442a754b404ab1fee23c903a04a560f84f94fdf63c0"
dependencies = [
"bitflags 2.4.0",
]
[[package]]
name = "wit-bindgen"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8a3e8e965dc50e6eb4410d9a11720719fadc6a1713803ea5f3be390b81c8279"
dependencies = [
"bitflags 2.4.0",
"wit-bindgen-rust-macro",
]
[[package]]
name = "wit-bindgen-core"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77255512565dfbd0b61de466e854918041d1da53c7bc049d6188c6e02643dc1e"
dependencies = [
"anyhow",
"wit-component",
"wit-parser",
]
[[package]]
name = "wit-bindgen-rust"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "399c60e6ea8598d1380e792f13d557007834f0fb799fea6503408cbc5debb4ae"
dependencies = [
"anyhow",
"heck",
"wasm-metadata",
"wit-bindgen-core",
"wit-bindgen-rust-lib",
"wit-component",
]
[[package]]
name = "wit-bindgen-rust-lib"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd9fb7a43c7dc28b0b727d6ae01bf369981229b7539e768fba2b7a4df13feeeb"
dependencies = [
"heck",
"wit-bindgen-core",
]
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cea5ed784da06da0e55836a6c160e7502dbe28771c2368a595e8606243bf22"
dependencies = [
"anyhow",
"proc-macro2",
"syn",
"wit-bindgen-core",
"wit-bindgen-rust",
"wit-bindgen-rust-lib",
"wit-component",
]
[[package]]
name = "wit-component"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66d9f2d16dd55d1a372dcfd4b7a466ea876682a5a3cb97e71ec9eef04affa876"
dependencies = [
"anyhow",
"bitflags 2.4.0",
"indexmap",
"log",
"serde",
"serde_json",
"wasm-encoder",
"wasm-metadata",
"wasmparser",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61e8b849bea13cc2315426b16efe6eb6813466d78f5fde69b0bb150c9c40e0dc"
dependencies = [
"anyhow",
"id-arena",
"indexmap",
"log",
"pulldown-cmark",
"semver",
"unicode-xid",
"url",
]

View File

@ -1,31 +0,0 @@
[package]
name = "rpc"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
panic = "abort"
opt-level = "s"
lto = true
[dependencies]
anyhow = "1.0"
bincode = "1.3.3"
cargo-component-bindings = { git = "https://github.com/bytecodealliance/cargo-component" }
serde = {version = "1.0", features = ["derive"] }
serde_json = "1.0"
wit-bindgen = { version = "0.9.0", default_features = false }
base64 = "0.13"
[lib]
crate-type = ["cdylib"]
[package.metadata.component]
package = "component:microkernel-process"
[package.metadata.component.target]
path = "wit"
[package.metadata.component.dependencies]

View File

@ -1,14 +0,0 @@
[
{
"process_name": "rpc",
"process_wasm_path": "/rpc.wasm",
"on_panic": "Restart",
"request_networking": false,
"request_messaging": [
"http_bindings:http_bindings:uqbar",
"main:app_store:uqbar",
"http_server:sys:uqbar"
],
"public": false
}
]

View File

@ -1,4 +0,0 @@
{
"package": "rpc",
"publisher": "uqbar"
}

View File

@ -1 +0,0 @@
../../../src/kernel_types.rs

View File

@ -1,764 +0,0 @@
cargo_component_bindings::generate!();
use bindings::component::uq_process::types::*;
use bindings::{
get_capabilities, get_capability, get_payload, print_to_terminal, receive,
send_and_await_response, send_request, send_requests, send_response, Guest,
};
use kernel_types::de_wit_signed_capability;
use serde::{Deserialize, Serialize};
use serde_json::json;
use std::collections::{HashMap, HashSet};
extern crate base64;
#[allow(dead_code)]
mod kernel_types;
#[allow(dead_code)]
mod process_lib;
struct Component;
#[derive(Debug, Serialize, Deserialize)]
struct RpcMessage {
pub node: String,
pub process: String,
pub inherit: Option<bool>,
pub expects_response: Option<u64>,
pub ipc: Option<String>,
pub metadata: Option<String>,
pub context: Option<String>,
pub mime: Option<String>,
pub data: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
struct StartProcess {
pub node: Option<String>,
pub process: String,
pub capabilities: Option<Vec<(String, String)>>, // list of (process, params) for the caps
pub wasm: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct CapabilitiesTransfer {
pub destination_node: String,
pub destination_process: String,
pub node: String,
pub process: String,
pub params: String,
}
#[derive(Debug, Deserialize)]
struct WriteFileId {
write: u128,
}
#[derive(Debug, Deserialize)]
struct WriteFileResult {
ok: WriteFileId,
}
// curl http://localhost:8080/rpc/message -H 'content-type: application/json' -d '{"node": "hosted", "process": "vfs", "inherit": false, "expects_response": null, "ipc": "{\"New\": {\"drive\": \"foo\"}}", "metadata": null, "context": null, "mime": null, "data": null}'
fn send_http_response(status: u16, headers: HashMap<String, String>, payload_bytes: Vec<u8>) {
send_response(
&Response {
inherit: false,
ipc: Some(
json!({
"status": status,
"headers": headers,
})
.to_string(),
),
metadata: None,
},
Some(&Payload {
mime: Some("application/octet-stream".to_string()),
bytes: payload_bytes,
}),
)
}
const RPC_PAGE: &str = include_str!("rpc.html");
impl Guest for Component {
fn init(our: Address) {
print_to_terminal(0, "RPC: start");
let bindings_address = Address {
node: our.node.clone(),
process: ProcessId::from_str("http_bindings:http_bindings:uqbar").unwrap(),
};
let http_endpoint_binding_requests: [(Address, Request, Option<Context>, Option<Payload>);
4] = [
(
bindings_address.clone(),
Request {
inherit: false,
expects_response: None,
ipc: Some(
json!({
"action": "bind-app",
"path": "/rpc/message",
"app": "rpc",
"local_only": true,
})
.to_string(),
),
metadata: None,
},
None,
None,
),
(
bindings_address.clone(),
Request {
inherit: false,
expects_response: None,
ipc: Some(
json!({
"action": "bind-app",
"path": "/rpc/start-process",
"app": "rpc",
"local_only": true,
})
.to_string(),
),
metadata: None,
},
None,
None,
),
(
bindings_address.clone(),
Request {
inherit: false,
expects_response: None,
ipc: Some(
json!({
"action": "bind-app",
"path": "/rpc/capabilities",
"app": "rpc",
"local_only": true,
})
.to_string(),
),
metadata: None,
},
None,
None,
),
(
bindings_address.clone(),
Request {
inherit: false,
expects_response: None,
ipc: Some(
json!({
"action": "bind-app",
"path": "/rpc/capabilities/transfer",
"app": "rpc",
"local_only": true,
})
.to_string(),
),
metadata: None,
},
None,
None,
),
];
send_requests(&http_endpoint_binding_requests);
loop {
let Ok((_source, message)) = receive() else {
print_to_terminal(0, "rpc: got network error");
continue;
};
let Message::Request(request) = message else {
print_to_terminal(0, "rpc: got unexpected message");
continue;
};
if let Some(json) = request.ipc {
print_to_terminal(1, format!("rpc: JSON {}", json).as_str());
let message_json: serde_json::Value = match serde_json::from_str(&json) {
Ok(v) => v,
Err(_) => {
print_to_terminal(1, "rpc: failed to parse ipc JSON, skipping");
continue;
}
};
print_to_terminal(1, "rpc: parsed ipc JSON");
let path = message_json["path"].as_str().unwrap_or("");
let method = message_json["method"].as_str().unwrap_or("");
let mut default_headers = HashMap::new();
default_headers.insert("Content-Type".to_string(), "text/html".to_string());
// Handle incoming http
print_to_terminal(1, format!("rpc: path {}", path).as_str());
print_to_terminal(1, format!("rpc: method {}", method).as_str());
match method {
"GET" => match path {
"/rpc" => {
send_response(
&Response {
inherit: false,
ipc: Some(
json!({
"action": "response",
"status": 200,
"headers": {
"Content-Type": "text/html",
},
})
.to_string(),
),
metadata: None,
},
Some(&Payload {
mime: Some("text/html".to_string()),
bytes: RPC_PAGE
.replace("${our}", &our.node)
.to_string()
.as_bytes()
.to_vec(),
}),
);
}
"/rpc/capabilities" => {
let capabilities = get_capabilities();
let caps = capabilities
.iter()
.map(|cap| {
json!({
"issuer": {
"node": cap.issuer.node.clone(),
"process": cap.issuer.process.to_string(),
},
"params": cap.params.clone(),
})
})
.collect::<Vec<serde_json::Value>>();
send_http_response(
200,
default_headers.clone(),
json!(caps).to_string().as_bytes().to_vec(),
);
continue;
}
_ => {
send_http_response(
404,
default_headers.clone(),
"Not Found".to_string().as_bytes().to_vec(),
);
continue;
}
},
"POST" => match path {
"/rpc/message" => {
let Some(payload) = get_payload() else {
print_to_terminal(1, "rpc: no bytes in payload, skipping...");
send_http_response(
400,
default_headers.clone(),
"No payload".to_string().as_bytes().to_vec(),
);
continue;
};
let body_json: RpcMessage =
match serde_json::from_slice::<RpcMessage>(&payload.bytes) {
Ok(v) => v,
Err(_) => {
print_to_terminal(
1,
&format!(
"rpc: JSON is not valid RpcMessage: {:?}",
serde_json::from_slice::<serde_json::Value>(
&payload.bytes
)
),
);
send_http_response(
400,
default_headers.clone(),
"JSON is not valid RpcMessage"
.to_string()
.as_bytes()
.to_vec(),
);
continue;
}
};
let payload =
match base64::decode(&body_json.data.unwrap_or("".to_string())) {
Ok(bytes) => Some(Payload {
mime: body_json.mime,
bytes,
}),
Err(_) => None,
};
// let caps = get_capabilities();
// print_to_terminal(
// 0,
// format!("rpc: got capabilities {:?}", caps).as_str(),
// );
let result = send_and_await_response(
&Address {
node: body_json.node,
process: ProcessId::from_str(&body_json.process).unwrap(),
},
&Request {
inherit: false,
expects_response: Some(5), // TODO evaluate timeout
ipc: body_json.ipc,
metadata: body_json.metadata,
},
payload.as_ref(),
);
match result {
Ok((_source, message)) => {
let Message::Response((response, _context)) = message else {
print_to_terminal(
1,
"rpc: got unexpected response to message",
);
send_http_response(
500,
default_headers,
"Invalid Internal Response"
.to_string()
.as_bytes()
.to_vec(),
);
continue;
};
let (mime, data) = match get_payload() {
Some(p) => {
let mime = match p.mime {
Some(mime) => mime,
None => "application/octet-stream".to_string(),
};
let bytes = p.bytes;
(mime, base64::encode(bytes))
}
None => ("".to_string(), "".to_string()),
};
let body = json!({
"ipc": response.ipc,
"payload": {
"mime": mime,
"data": data,
},
})
.to_string()
.as_bytes()
.to_vec();
send_http_response(200, default_headers.clone(), body);
continue;
}
Err(_) => {
print_to_terminal(1, "rpc: error coming back");
send_http_response(
500,
default_headers.clone(),
"Network Error".to_string().as_bytes().to_vec(),
);
continue;
}
}
}
"/rpc/start-process" => {
let Some(payload) = get_payload() else {
print_to_terminal(1, "rpc: no bytes in payload, skipping...");
send_http_response(
400,
default_headers.clone(),
"No payload".to_string().as_bytes().to_vec(),
);
continue;
};
let body_json: StartProcess =
match serde_json::from_slice::<StartProcess>(&payload.bytes) {
Ok(v) => v,
Err(_) => {
print_to_terminal(
1,
&format!(
"rpc: JSON is not valid StartProcess: {:?}",
serde_json::from_slice::<serde_json::Value>(
&payload.bytes
)
),
);
send_http_response(
400,
default_headers.clone(),
"JSON is not valid StartProcess"
.to_string()
.as_bytes()
.to_vec(),
);
continue;
}
};
let payload = match base64::decode(&body_json.wasm) {
Ok(bytes) => Some(Payload {
mime: Some("bytes".to_string()),
bytes,
}),
Err(_) => None,
};
let node = match body_json.node {
Some(node) => node,
None => our.node.clone(),
};
// let caps = get_capabilities();
// print_to_terminal(
// 0,
// format!("rpc: got capabilities {:?}", caps).as_str(),
// );
let write_wasm_result = send_and_await_response(
&Address {
node: node.clone(),
process: ProcessId::from_str("filesystem:sys:uqbar").unwrap(),
},
&Request {
inherit: false,
expects_response: Some(5),
ipc: Some(
json!({
"Write": None::<String>,
})
.to_string(),
),
metadata: None,
},
payload.as_ref(),
);
match write_wasm_result {
Ok((_source, message)) => {
let Message::Response((response, _context)) = message else {
print_to_terminal(
1,
"rpc: got unexpected response to message",
);
send_http_response(
500,
default_headers,
"Invalid Internal Response"
.to_string()
.as_bytes()
.to_vec(),
);
continue;
};
let wasm_bytes_handle = match response.ipc {
Some(ipc) => {
match serde_json::from_str::<WriteFileResult>(&ipc) {
Ok(result) => result.ok.write,
Err(_) => {
send_http_response(
500,
default_headers.clone(),
"Write Error"
.to_string()
.as_bytes()
.to_vec(),
);
continue;
}
}
}
None => {
send_http_response(
500,
default_headers.clone(),
"Write Error".to_string().as_bytes().to_vec(),
);
continue;
}
};
let mut capabilities_to_grant: HashSet<
kernel_types::SignedCapability,
> = HashSet::new();
match body_json.capabilities {
Some(caps) => {
for cap in caps {
let addr = Address {
node: our.node.clone(),
process: ProcessId::from_str(&cap.0).unwrap(),
};
let Some(signed) = bindings::get_capability(&addr, &cap.1) else {
bindings::print_to_terminal(0, &format!("rpc: failed to get capability {} {}", cap.0, cap.1));
continue;
};
capabilities_to_grant
.insert(de_wit_signed_capability(signed));
}
}
None => (),
};
let stop_process_command =
kernel_types::KernelCommand::KillProcess(
kernel_types::ProcessId::from_str(&body_json.process)
.unwrap(),
);
send_request(
&Address {
node: node.clone(),
process: ProcessId::from_str("kernel:sys:uqbar")
.unwrap(),
},
&Request {
inherit: false,
expects_response: Some(5),
ipc: Some(
serde_json::to_string(&stop_process_command)
.unwrap(),
),
metadata: None,
},
None,
None,
);
let start_process_command =
kernel_types::KernelCommand::StartProcess {
id: kernel_types::ProcessId::from_str(&body_json.process).unwrap(),
wasm_bytes_handle,
on_panic: kernel_types::OnPanic::Restart,
initial_capabilities: capabilities_to_grant,
public: false, // TODO ADD TO RPC
};
let ipc = match serde_json::to_string(&start_process_command) {
Ok(ipc) => ipc,
Err(_) => {
print_to_terminal(
1,
"rpc: failed to serialize StartProcess command",
);
send_http_response(
500,
default_headers.clone(),
"Internal Error".to_string().as_bytes().to_vec(),
);
continue;
}
};
let start_wasm_result = send_and_await_response(
&Address {
node,
process: ProcessId::from_str("kernel:sys:uqbar")
.unwrap(),
},
&Request {
inherit: false,
expects_response: Some(5),
ipc: Some(ipc),
metadata: None,
},
None,
);
match start_wasm_result {
Ok((_source, _message)) => {
send_http_response(
200,
default_headers.clone(),
"Success".to_string().as_bytes().to_vec(),
);
continue;
}
Err(_) => {
print_to_terminal(1, "rpc: error coming back");
send_http_response(
500,
default_headers.clone(),
"Network Error".to_string().as_bytes().to_vec(),
);
continue;
}
}
}
Err(_) => {
print_to_terminal(1, "rpc: error coming back");
send_http_response(
500,
default_headers.clone(),
"Network Error".to_string().as_bytes().to_vec(),
);
continue;
}
}
}
"/rpc/capabilities/transfer" => {
let Some(payload) = get_payload() else {
print_to_terminal(1, "rpc: no bytes in payload, skipping...");
send_http_response(
400,
default_headers.clone(),
"No payload".to_string().as_bytes().to_vec(),
);
continue;
};
let body_json: CapabilitiesTransfer = match serde_json::from_slice::<
CapabilitiesTransfer,
>(
&payload.bytes
) {
Ok(v) => v,
Err(_) => {
print_to_terminal(
1,
&format!(
"rpc: JSON is not valid CapabilitiesTransfer: {:?}",
serde_json::from_slice::<serde_json::Value>(
&payload.bytes
)
),
);
send_http_response(
400,
default_headers.clone(),
"JSON is not valid CapabilitiesTransfer"
.to_string()
.as_bytes()
.to_vec(),
);
continue;
}
};
// print_to_terminal(
// 0,
// format!("rpc: node {:?}", body_json.node).as_str(),
// );
// print_to_terminal(
// 0,
// format!("rpc: process {:?}", body_json.process).as_str(),
// );
// print_to_terminal(
// 0,
// format!("rpc: params {:?}", body_json.params).as_str(),
// );
// // let caps = get_capabilities();
// print_to_terminal(
// 0,
// format!("rpc: got capabilities {:?}", caps).as_str(),
// );
let capability = get_capability(
&Address {
node: body_json.node,
process: ProcessId::from_str(&body_json.process).unwrap(),
},
&body_json.params,
);
print_to_terminal(
0,
format!("rpc: got capability {:?}", capability).as_str(),
);
match capability {
Some(capability) => {
let process = capability.issuer.process.to_string();
send_request(
&Address {
node: body_json.destination_node,
process: ProcessId::from_str(
&body_json.destination_process,
)
.unwrap(),
},
&Request {
inherit: false,
expects_response: None,
ipc: Some(
json!({
"action": "transfer_capability",
"info": {
"issuer": {
"node": capability.issuer.node,
"process": process,
},
"params": capability.params,
}
})
.to_string(),
),
metadata: None,
},
None,
Some(&Payload {
mime: Some("bytes".to_string()),
bytes: capability.signature,
}),
);
send_http_response(
200,
default_headers.clone(),
"Success".to_string().as_bytes().to_vec(),
);
}
None => send_http_response(
404,
default_headers.clone(),
"Not Found".to_string().as_bytes().to_vec(),
),
}
continue;
}
_ => {
send_http_response(
404,
default_headers.clone(),
"Not Found".to_string().as_bytes().to_vec(),
);
continue;
}
},
_ => {
send_http_response(
405,
default_headers.clone(),
"Method Not Allowed".to_string().as_bytes().to_vec(),
);
continue;
}
}
}
}
}
}

View File

@ -1 +0,0 @@
../../../src/process_lib.rs

File diff suppressed because one or more lines are too long

View File

@ -1,25 +0,0 @@
#!/bin/bash
# Use this script to upload a .wasm file and start the process through rpc.
# Check if there are enough parameters provided.
if [ "$#" -ne 4 ]; then
echo "Usage: $0 <url> <node-id> <process> <wasm-file>"
exit 1
fi
URL="$1"
NODE="$2"
PROCESS="$3"
WASM_FILE="$4"
# Put the payload in a temporary file (.wasm is too large otherwise).
JSON_PAYLOAD=$(echo -n '{"node": "'"$NODE"'", "process": "'"$PROCESS"'", "capabilities": [["http_bindings", "{\"messaging\": \"{\"Name\":\"http_bindings\"}\"}"]], "wasm": "'"$(base64 < "$WASM_FILE")"'"}')
echo -n "$JSON_PAYLOAD" > /tmp/temp_payload.json
# Upload the wasm file and start the process through rpc.
OUTPUT=$(curl -s "$URL/rpc/start-process" -H 'content-type: application/json' --data-binary @/tmp/temp_payload.json)
echo $OUTPUT
rm /tmp/temp_payload.json