diff --git a/Cargo.lock b/Cargo.lock index 885e99ce..ca2c24e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,6 +155,8 @@ dependencies = [ "memchr", "pin-project-lite", "tokio", + "zstd", + "zstd-safe", ] [[package]] @@ -322,6 +324,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + [[package]] name = "base64" version = "0.21.0" @@ -353,15 +361,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -474,7 +473,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" dependencies = [ - "nom 5.1.2", + "nom", ] [[package]] @@ -714,7 +713,7 @@ dependencies = [ "serde_bytes", "serde_derive", "serde_json", - "sha2 0.9.9", + "sha2", "sled", "smallvec", "smartstring", @@ -961,7 +960,7 @@ version = "3.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639" dependencies = [ - "nix 0.26.2", + "nix", "windows-sys 0.45.0", ] @@ -1044,22 +1043,13 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - [[package]] name = "digest" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "crypto-common", ] @@ -1524,9 +1514,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f" +checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" dependencies = [ "bytes", "fnv", @@ -1785,11 +1775,12 @@ checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" [[package]] name = "iri-string" -version = "0.4.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0f7638c1e223529f1bfdc48c8b133b9e0b434094d1d28473161ee48b235f78" +checksum = "21859b667d66a4c1dacd9df0863b3efb65785474255face87f5bca39dd8407c0" dependencies = [ - "nom 7.1.3", + "memchr", + "serde", ] [[package]] @@ -2076,12 +2067,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.6.2" @@ -2210,18 +2195,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "nix" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" -dependencies = [ - "autocfg", - "bitflags", - "cfg-if 1.0.0", - "libc", -] - [[package]] name = "nix" version = "0.26.2" @@ -2244,16 +2217,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "num" version = "0.4.0" @@ -2365,12 +2328,6 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "openssl" version = "0.10.50" @@ -2572,7 +2529,7 @@ checksum = "6733073c7cff3d8459fda0e42f13a047870242aed8b509fe98000928975f359e" dependencies = [ "once_cell", "pest", - "sha2 0.10.6", + "sha2", ] [[package]] @@ -3187,9 +3144,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" @@ -3256,9 +3213,9 @@ checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "rustyline" -version = "10.1.1" +version = "11.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e83c32c3f3c33b08496e0d1df9ea8c64d39adb8eb36a1ebb1440c690697aef" +checksum = "5dfc8644681285d1fb67a467fb3021bfea306b99b4146b166a1fe3ada965eece" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -3268,7 +3225,7 @@ dependencies = [ "libc", "log", "memchr", - "nix 0.25.1", + "nix", "radix_trie", "scopeguard", "unicode-segmentation", @@ -3438,19 +3395,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha2" version = "0.10.6" @@ -3459,7 +3403,7 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.6", + "digest", ] [[package]] @@ -4041,12 +3985,12 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.3.5" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +checksum = "5d1d42a9b3f3ec46ba828e8d376aec14592ea199f70a06a548587ecd1c4ab658" dependencies = [ "async-compression", - "base64 0.13.1", + "base64 0.20.0", "bitflags", "bytes", "futures-core", @@ -4611,6 +4555,25 @@ dependencies = [ "winapi", ] +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + [[package]] name = "zstd-sys" version = "2.0.8+zstd.1.5.5" diff --git a/cozo-bin/Cargo.toml b/cozo-bin/Cargo.toml index 8e97c2fb..e74f22f3 100644 --- a/cozo-bin/Cargo.toml +++ b/cozo-bin/Cargo.toml @@ -52,7 +52,7 @@ serde = { version = "1.0.137" } chrono = "0.4.19" serde_json = "1.0.81" prettytable = "0.10.0" -rustyline = "10.0.0" +rustyline = "11.0.0" minreq = { version = "2.6.0", features = ["https-rustls"] } miette = { version = "5.5.0", features = ["fancy"] } ctrlc = "3.2.4" @@ -64,4 +64,4 @@ async-stream = "0.3.3" futures = "0.3.25" crossbeam = "0.8.2" eventsource-client = "0.11.0" -tower-http = { version = "0.3.5", features = ["full"] } \ No newline at end of file +tower-http = { version = "0.4.0", features = ["full"] } \ No newline at end of file diff --git a/cozo-bin/src/repl.rs b/cozo-bin/src/repl.rs index d79fb9a1..b1eeebda 100644 --- a/cozo-bin/src/repl.rs +++ b/cozo-bin/src/repl.rs @@ -16,6 +16,8 @@ use std::io::{Read, Write}; use clap::Args; use miette::{bail, miette, IntoDiagnostic}; +use rustyline::history::DefaultHistory; +use rustyline::Changeset; use serde_json::{json, Value}; use cozo::{DataValue, DbInstance, NamedRows}; @@ -35,6 +37,7 @@ impl rustyline::completion::Completer for Indented { _line: &mut rustyline::line_buffer::LineBuffer, _start: usize, _elected: &str, + _cl: &mut Changeset, ) { unreachable!(); } @@ -96,7 +99,7 @@ pub(crate) fn repl_main(args: ReplArgs) -> Result<(), Box> { println!("Type a space followed by newline to enter multiline mode."); let mut exit = false; - let mut rl = rustyline::Editor::::new()?; + let mut rl = rustyline::Editor::::new()?; let mut params = BTreeMap::new(); let mut save_next: Option = None; rl.set_helper(Some(Indented)); @@ -113,7 +116,9 @@ pub(crate) fn repl_main(args: ReplArgs) -> Result<(), Box> { if let Err(err) = process_line(&line, &db, &mut params, &mut save_next) { eprintln!("{err:?}"); } - rl.add_history_entry(line); + if let Err(err) = rl.add_history_entry(line) { + eprintln!("{err:?}"); + } exit = false; } Err(rustyline::error::ReadlineError::Interrupted) => { diff --git a/cozo-bin/src/server.rs b/cozo-bin/src/server.rs index 02283e53..9c762ecf 100644 --- a/cozo-bin/src/server.rs +++ b/cozo-bin/src/server.rs @@ -14,7 +14,7 @@ use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::{Arc, Mutex}; use std::thread; -use axum::body::{Body, BoxBody}; +use axum::body::{boxed, Body, BoxBody}; use axum::extract::{Path, Query, State}; use axum::http::{Method, Request, Response, StatusCode}; use axum::response::sse::{Event, KeepAlive}; @@ -22,6 +22,7 @@ use axum::response::{Html, Sse}; use axum::routing::{get, post, put}; use axum::{Json, Router}; use clap::Args; +use futures::future::BoxFuture; use futures::stream::Stream; use itertools::Itertools; use log::{error, info, warn}; @@ -29,7 +30,7 @@ use miette::miette; use rand::Rng; use serde_json::json; use tokio::task::spawn_blocking; -use tower_http::auth::RequireAuthorizationLayer; +use tower_http::auth::{AsyncAuthorizeRequest, AsyncRequireAuthorizationLayer}; use tower_http::compression::CompressionLayer; use tower_http::cors::{Any, CorsLayer}; @@ -76,6 +77,68 @@ struct DbState { txs: Arc>>>, } +#[derive(Clone)] +struct MyAuth { + skip_auth: bool, + auth_guard: String, +} + +impl AsyncAuthorizeRequest for MyAuth +where + B: Send + Sync + 'static, +{ + type RequestBody = B; + type ResponseBody = BoxBody; + type Future = BoxFuture<'static, Result, Response>>; + + fn authorize(&mut self, request: Request) -> Self::Future { + let skip_auth = self.skip_auth; + let auth_guard = self.auth_guard.clone(); + Box::pin(async move { + if skip_auth { + return Ok(request); + } + + let ok = match request.headers().get("x-cozo-auth") { + None => match request.uri().query() { + None => false, + Some(q_str) => { + let mut bingo = false; + for pair in q_str.split('&') { + if let Some((k, v)) = pair.split_once('=') { + if k == "auth" { + if v == auth_guard.as_str() { + bingo = true + } + break; + } + } + } + bingo + } + }, + Some(data) => match data.to_str() { + Ok(s) => s == auth_guard.as_str(), + Err(_) => false, + }, + }; + if ok { + Ok(request) + } else { + let unauthorized_response = Response::builder() + .status(StatusCode::UNAUTHORIZED) + .body(boxed(Body::empty())) + .unwrap(); + + Err(unauthorized_response) + } + }) + } +} + +#[test] +fn x() {} + pub(crate) async fn server_main(args: ServerArgs) { let db = DbInstance::new(&args.engine, &args.path, &args.config).unwrap(); if let Some(p) = &args.restore { @@ -88,7 +151,11 @@ pub(crate) async fn server_main(args: ServerArgs) { let skip_auth = args.bind == "127.0.0.1"; - let conf_path = if skip_auth {"".to_string()} else { format!("{}.{}.cozo_auth", args.path, args.engine)}; + let conf_path = if skip_auth { + "".to_string() + } else { + format!("{}.{}.cozo_auth", args.path, args.engine) + }; let auth_guard = if skip_auth { "".to_string() } else { @@ -132,47 +199,10 @@ pub(crate) async fn server_main(args: ServerArgs) { .route("/transact", post(start_transact)) .route("/transact/:id", post(transact_query).put(finish_query)) .with_state(state) - .layer(RequireAuthorizationLayer::custom( - move |request: &mut Request| { - if skip_auth { - return Ok(()); - } - - let ok = match request.headers().get("x-cozo-auth") { - None => match request.uri().query() { - None => false, - Some(q_str) => { - let mut bingo = false; - for pair in q_str.split('&') { - if let Some((k, v)) = pair.split_once('=') { - if k == "auth" { - if v == &auth_guard { - bingo = true - } - break; - } - } - } - bingo - } - }, - Some(data) => match data.to_str() { - Ok(s) => s == &auth_guard, - Err(_) => false, - }, - }; - if ok { - Ok(()) - } else { - let unauthorized_response = Response::builder() - .status(StatusCode::UNAUTHORIZED) - .body(BoxBody::default()) - .unwrap(); - - Err(unauthorized_response.into()) - } - }, - )) + .layer(AsyncRequireAuthorizationLayer::new(MyAuth { + skip_auth, + auth_guard, + })) .fallback(not_found) .route("/", get(root)) .layer(cors) diff --git a/cozo-core/Cargo.toml b/cozo-core/Cargo.toml index c1a135f2..7340ac2a 100644 --- a/cozo-core/Cargo.toml +++ b/cozo-core/Cargo.toml @@ -128,4 +128,4 @@ js-sys = { version = "0.3.60", optional = true } graph = { version = "0.3.0", optional = true } crossbeam = "0.8.2" ndarray = { version = "0.15.6", features = ["serde"] } -sha2 = "0.9.8" \ No newline at end of file +sha2 = "0.10.6" \ No newline at end of file