diff --git a/cozoserver/src/main.rs b/cozoserver/src/main.rs
index db81b54e..96fc61f6 100644
--- a/cozoserver/src/main.rs
+++ b/cozoserver/src/main.rs
@@ -1,5 +1,7 @@
use std::collections::BTreeMap;
+use std::env;
use std::fmt::Debug;
+use std::process::exit;
use std::time::Instant;
use clap::Parser;
@@ -28,6 +30,17 @@ struct Args {
fn main() {
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
let args = Args::parse();
+ let auth_str = env::var("COZO_AUTH").ok();
+ if args.bind != "127.0.0.1" && auth_str.is_none() {
+ eprintln!(
+ r#"You instructed Cozo to bind to address {}, which can potentially be accessed from
+external networks. Please note that Cozo is designed to be accessed by trusted clients inside
+trusted environments only. If you are absolutely sure that exposing Cozo to the address is OK,
+set the environment variable COZO_AUTH and configure clients appropriately."#,
+ args.bind
+ );
+ exit(1);
+ }
let builder = DbBuilder::default()
.path(&args.path)
@@ -37,6 +50,17 @@ fn main() {
let addr = format!("{}:{}", args.bind, args.port);
println!("Service running at http://{}", addr);
rouille::start_server(addr, move |request| {
+ if let Some(auth) = &auth_str {
+ match request.header("x-cozo-auth") {
+ None => return Response::text("Unauthorized").with_status_code(401),
+ Some(code) => {
+ if auth != code {
+ return Response::text("Unauthorized").with_status_code(401);
+ }
+ }
+ }
+ }
+
router!(request,
(POST) (/text-query) => {
#[derive(serde_derive::Serialize, serde_derive::Deserialize)]
diff --git a/tutorial/2-storage.ipynb b/tutorial/2-storage.ipynb
index 5a8f2cf0..0ff84830 100644
--- a/tutorial/2-storage.ipynb
+++ b/tutorial/2-storage.ipynb
@@ -15,8 +15,17 @@
"metadata": {},
"outputs": [],
"source": [
- "%reload_ext pycozo.ipyext_direct\n",
- "%cozo_auth tutorial *******"
+ "%reload_ext pycozo.ipyext_direct"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "5b4a724b-f8d9-44cd-8821-77edeadf772d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%cozo_auth *******"
]
},
{
@@ -37,14 +46,14 @@
},
{
"cell_type": "code",
- "execution_count": 31,
+ "execution_count": 3,
"id": "5f1bc86f-eaa6-4793-8a56-78daa1288540",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
- "
Completed in 1ms
"
+ "Completed in 0ms
"
],
"text/plain": [
""
@@ -57,30 +66,30 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " status | \n",
+ " status | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " OK | \n",
+ " 0 | \n",
+ " OK | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 31,
+ "execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
@@ -124,7 +133,7 @@
},
{
"cell_type": "code",
- "execution_count": 32,
+ "execution_count": 4,
"id": "2d76fb9c-ee23-4d95-b60f-b06eb5faf5b3",
"metadata": {},
"outputs": [
@@ -144,67 +153,67 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " a | \n",
- " b | \n",
+ " a | \n",
+ " b | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " alice | \n",
- " eve | \n",
+ " 0 | \n",
+ " alice | \n",
+ " eve | \n",
"
\n",
" \n",
- " 1 | \n",
- " bob | \n",
- " alice | \n",
+ " 1 | \n",
+ " bob | \n",
+ " alice | \n",
"
\n",
" \n",
- " 2 | \n",
- " charlie | \n",
- " eve | \n",
+ " 2 | \n",
+ " charlie | \n",
+ " eve | \n",
"
\n",
" \n",
- " 3 | \n",
- " david | \n",
- " george | \n",
+ " 3 | \n",
+ " david | \n",
+ " george | \n",
"
\n",
" \n",
- " 4 | \n",
- " eve | \n",
- " alice | \n",
+ " 4 | \n",
+ " eve | \n",
+ " alice | \n",
"
\n",
" \n",
- " 5 | \n",
- " eve | \n",
- " bob | \n",
+ " 5 | \n",
+ " eve | \n",
+ " bob | \n",
"
\n",
" \n",
- " 6 | \n",
- " eve | \n",
- " charlie | \n",
+ " 6 | \n",
+ " eve | \n",
+ " charlie | \n",
"
\n",
" \n",
- " 7 | \n",
- " george | \n",
- " george | \n",
+ " 7 | \n",
+ " george | \n",
+ " george | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 32,
+ "execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
@@ -231,7 +240,7 @@
},
{
"cell_type": "code",
- "execution_count": 35,
+ "execution_count": 5,
"id": "099f6ec2-a55c-4116-ac8b-efe564657f99",
"metadata": {},
"outputs": [
@@ -251,30 +260,30 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " status | \n",
+ " status | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " OK | \n",
+ " 0 | \n",
+ " OK | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 35,
+ "execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
@@ -288,7 +297,7 @@
},
{
"cell_type": "code",
- "execution_count": 36,
+ "execution_count": 6,
"id": "bcb24ccf-9956-49e8-b286-67d5464bb21e",
"metadata": {},
"outputs": [
@@ -308,77 +317,77 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " a | \n",
- " b | \n",
+ " a | \n",
+ " b | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " alice | \n",
- " eve | \n",
+ " 0 | \n",
+ " alice | \n",
+ " eve | \n",
"
\n",
" \n",
- " 1 | \n",
- " bob | \n",
- " alice | \n",
+ " 1 | \n",
+ " bob | \n",
+ " alice | \n",
"
\n",
" \n",
- " 2 | \n",
- " charlie | \n",
- " eve | \n",
+ " 2 | \n",
+ " charlie | \n",
+ " eve | \n",
"
\n",
" \n",
- " 3 | \n",
- " david | \n",
- " george | \n",
+ " 3 | \n",
+ " david | \n",
+ " george | \n",
"
\n",
" \n",
- " 4 | \n",
- " eve | \n",
- " alice | \n",
+ " 4 | \n",
+ " eve | \n",
+ " alice | \n",
"
\n",
" \n",
- " 5 | \n",
- " eve | \n",
- " bob | \n",
+ " 5 | \n",
+ " eve | \n",
+ " bob | \n",
"
\n",
" \n",
- " 6 | \n",
- " eve | \n",
- " charlie | \n",
+ " 6 | \n",
+ " eve | \n",
+ " charlie | \n",
"
\n",
" \n",
- " 7 | \n",
- " fred | \n",
- " alice | \n",
+ " 7 | \n",
+ " fred | \n",
+ " alice | \n",
"
\n",
" \n",
- " 8 | \n",
- " fred | \n",
- " eve | \n",
+ " 8 | \n",
+ " fred | \n",
+ " eve | \n",
"
\n",
" \n",
- " 9 | \n",
- " george | \n",
- " george | \n",
+ " 9 | \n",
+ " george | \n",
+ " george | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 36,
+ "execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
@@ -405,7 +414,7 @@
},
{
"cell_type": "code",
- "execution_count": 37,
+ "execution_count": 7,
"id": "f6e400d6-6571-42e7-8044-5807bb789f8f",
"metadata": {},
"outputs": [
@@ -425,30 +434,30 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " status | \n",
+ " status | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " OK | \n",
+ " 0 | \n",
+ " OK | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 37,
+ "execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
@@ -462,7 +471,7 @@
},
{
"cell_type": "code",
- "execution_count": 38,
+ "execution_count": 8,
"id": "c1ffa2b1-2ce4-4edb-a1db-ed03f2e4ddfd",
"metadata": {},
"outputs": [
@@ -482,67 +491,67 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " a | \n",
- " b | \n",
+ " a | \n",
+ " b | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " alice | \n",
- " eve | \n",
+ " 0 | \n",
+ " alice | \n",
+ " eve | \n",
"
\n",
" \n",
- " 1 | \n",
- " bob | \n",
- " alice | \n",
+ " 1 | \n",
+ " bob | \n",
+ " alice | \n",
"
\n",
" \n",
- " 2 | \n",
- " charlie | \n",
- " eve | \n",
+ " 2 | \n",
+ " charlie | \n",
+ " eve | \n",
"
\n",
" \n",
- " 3 | \n",
- " david | \n",
- " george | \n",
+ " 3 | \n",
+ " david | \n",
+ " george | \n",
"
\n",
" \n",
- " 4 | \n",
- " eve | \n",
- " bob | \n",
+ " 4 | \n",
+ " eve | \n",
+ " bob | \n",
"
\n",
" \n",
- " 5 | \n",
- " fred | \n",
- " alice | \n",
+ " 5 | \n",
+ " fred | \n",
+ " alice | \n",
"
\n",
" \n",
- " 6 | \n",
- " fred | \n",
- " eve | \n",
+ " 6 | \n",
+ " fred | \n",
+ " eve | \n",
"
\n",
" \n",
- " 7 | \n",
- " george | \n",
- " george | \n",
+ " 7 | \n",
+ " george | \n",
+ " george | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 38,
+ "execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
@@ -569,7 +578,7 @@
},
{
"cell_type": "code",
- "execution_count": 39,
+ "execution_count": 9,
"id": "c72cc224-2b50-441b-803f-f622968a6b77",
"metadata": {},
"outputs": [
@@ -589,30 +598,30 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " status | \n",
+ " status | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " OK | \n",
+ " 0 | \n",
+ " OK | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 39,
+ "execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
@@ -626,7 +635,7 @@
},
{
"cell_type": "code",
- "execution_count": 40,
+ "execution_count": 10,
"id": "1e6b41eb-baf9-4933-8c82-5dfbc8c9d34e",
"metadata": {},
"outputs": [
@@ -646,37 +655,37 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " a | \n",
- " b | \n",
+ " a | \n",
+ " b | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " eve | \n",
- " alice | \n",
+ " 0 | \n",
+ " eve | \n",
+ " alice | \n",
"
\n",
" \n",
- " 1 | \n",
- " eve | \n",
- " charlie | \n",
+ " 1 | \n",
+ " eve | \n",
+ " charlie | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 40,
+ "execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
@@ -703,14 +712,14 @@
},
{
"cell_type": "code",
- "execution_count": 42,
+ "execution_count": 11,
"id": "f051c4c6-55db-4099-b2da-1e55cea5deb3",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
- "Completed in 1ms
"
+ "Completed in 0ms
"
],
"text/plain": [
""
@@ -723,95 +732,55 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " name | \n",
- " arity | \n",
- " n_keys | \n",
- " n_non_keys | \n",
- " n_put_triggers | \n",
- " n_rm_triggers | \n",
- " n_replace_triggers | \n",
+ " name | \n",
+ " arity | \n",
+ " n_keys | \n",
+ " n_non_keys | \n",
+ " n_put_triggers | \n",
+ " n_rm_triggers | \n",
+ " n_replace_triggers | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " airport | \n",
- " 11 | \n",
- " 1 | \n",
- " 10 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- "
\n",
- " \n",
- " 1 | \n",
- " contain | \n",
- " 2 | \n",
- " 2 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- "
\n",
- " \n",
- " 2 | \n",
- " continent | \n",
- " 2 | \n",
- " 1 | \n",
- " 1 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- "
\n",
- " \n",
- " 3 | \n",
- " country | \n",
- " 2 | \n",
- " 1 | \n",
- " 1 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
+ " 0 | \n",
+ " airport | \n",
+ " 11 | \n",
+ " 1 | \n",
+ " 10 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
"
\n",
" \n",
- " 4 | \n",
- " route | \n",
- " 3 | \n",
- " 2 | \n",
- " 1 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- "
\n",
- " \n",
- " 5 | \n",
- " triangles | \n",
- " 2 | \n",
- " 2 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
+ " 1 | \n",
+ " triangles | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 42,
+ "execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
@@ -830,7 +799,7 @@
},
{
"cell_type": "code",
- "execution_count": 44,
+ "execution_count": 12,
"id": "01baf1c4-40de-4edc-b9c8-efba9c3c2cb0",
"metadata": {},
"outputs": [
@@ -850,30 +819,30 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " status | \n",
+ " status | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " OK | \n",
+ " 0 | \n",
+ " OK | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 44,
+ "execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
@@ -884,14 +853,14 @@
},
{
"cell_type": "code",
- "execution_count": 45,
+ "execution_count": 13,
"id": "8932c693-590a-43b3-83ee-8a99ee92278a",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
- "Completed in 0ms
"
+ "Completed in 6ms
"
],
"text/plain": [
""
@@ -904,95 +873,55 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " name | \n",
- " arity | \n",
- " n_keys | \n",
- " n_non_keys | \n",
- " n_put_triggers | \n",
- " n_rm_triggers | \n",
- " n_replace_triggers | \n",
+ " name | \n",
+ " arity | \n",
+ " n_keys | \n",
+ " n_non_keys | \n",
+ " n_put_triggers | \n",
+ " n_rm_triggers | \n",
+ " n_replace_triggers | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " airport | \n",
- " 11 | \n",
- " 1 | \n",
- " 10 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- "
\n",
- " \n",
- " 1 | \n",
- " contain | \n",
- " 2 | \n",
- " 2 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- "
\n",
- " \n",
- " 2 | \n",
- " continent | \n",
- " 2 | \n",
- " 1 | \n",
- " 1 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- "
\n",
- " \n",
- " 3 | \n",
- " country | \n",
- " 2 | \n",
- " 1 | \n",
- " 1 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
+ " 0 | \n",
+ " airport | \n",
+ " 11 | \n",
+ " 1 | \n",
+ " 10 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
"
\n",
" \n",
- " 4 | \n",
- " love_triangles | \n",
- " 2 | \n",
- " 2 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
- "
\n",
- " \n",
- " 5 | \n",
- " route | \n",
- " 3 | \n",
- " 2 | \n",
- " 1 | \n",
- " 0 | \n",
- " 0 | \n",
- " 0 | \n",
+ " 1 | \n",
+ " love_triangles | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 45,
+ "execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
@@ -1003,7 +932,7 @@
},
{
"cell_type": "code",
- "execution_count": 46,
+ "execution_count": 14,
"id": "ede55ffc-ca41-4e08-9938-e88c139c0937",
"metadata": {},
"outputs": [
@@ -1023,37 +952,37 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " a | \n",
- " b | \n",
+ " a | \n",
+ " b | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " eve | \n",
- " alice | \n",
+ " 0 | \n",
+ " eve | \n",
+ " alice | \n",
"
\n",
" \n",
- " 1 | \n",
- " eve | \n",
- " charlie | \n",
+ " 1 | \n",
+ " eve | \n",
+ " charlie | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 46,
+ "execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
@@ -1072,7 +1001,7 @@
},
{
"cell_type": "code",
- "execution_count": 47,
+ "execution_count": 15,
"id": "bc525dc4-257b-48d9-b2ee-3238ed961fad",
"metadata": {},
"outputs": [
@@ -1092,30 +1021,30 @@
"data": {
"text/html": [
"\n",
- "\n",
+ "\n",
" \n",
" \n",
" | \n",
- " status | \n",
+ " status | \n",
"
\n",
" \n",
" \n",
" \n",
- " 0 | \n",
- " OK | \n",
+ " 0 | \n",
+ " OK | \n",
"
\n",
" \n",
"
\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": 47,
+ "execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
@@ -1134,7 +1063,7 @@
},
{
"cell_type": "code",
- "execution_count": 48,
+ "execution_count": 16,
"id": "f39a7c6c-3d78-4ca4-b2d6-cc5855343200",
"metadata": {},
"outputs": [
@@ -1146,7 +1075,7 @@
" \u001b[31m×\u001b[0m Cannot find requested stored relation 'love_triangles'\n"
]
},
- "execution_count": 48,
+ "execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
@@ -1168,6 +1097,14 @@
"\n",
"Stored relations are suitable for data that has a well-defined structure at the onset, and which is loaded and updated in bulk. For example, you may have obtained from domain experts an [ontology](https://www.wikiwand.com/en/Ontology_\\(information_science\\)) in the form of a network of metadata. The ontology comes in nice tables with clear, detailed documentation. You store this ontology as a group of stored relations, and use them to extract insights from your business data. The ontology is updated periodically, and when an update comes you just use the `rederive` operation to replace the old version. Very simple and efficient. But if you need more guarantees for your data, or your data shapes change rapidly, use the triple store instead: see a later tutorial for how to use it."
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "82735cec-aa4e-4a0e-8959-f522ea05c990",
+ "metadata": {},
+ "outputs": [],
+ "source": []
}
],
"metadata": {