Skip to content

Commit 2f303e2

Browse files
avinasshLucioFranco
authored andcommitted
server: trim quotes in namespace string in attach statement (#1117)
* Add a regression test when UUIDs are used in attach statements Also, added a test to check if the UUID is wrapped in quotes * bugfix: trim namespace string if it is wrapped in quotes the client might send namespace wrapped in quotes in case of uuids, so we will just trim the string.
1 parent 63e4626 commit 2f303e2

4 files changed

Lines changed: 142 additions & 3 deletions

File tree

libsql-server/src/query_analysis.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,16 @@ impl StmtKind {
128128
Cmd::Stmt(Stmt::Attach {
129129
expr: Expr::Id(Id(db_name)),
130130
..
131-
}) => Some(Self::Attach(
132-
NamespaceName::from_string(db_name.to_string()).ok()?,
133-
)),
131+
}) => {
132+
let db_name = db_name
133+
.strip_prefix('"')
134+
.unwrap_or(db_name)
135+
.strip_suffix('"')
136+
.unwrap_or(db_name);
137+
Some(Self::Attach(
138+
NamespaceName::from_string(db_name.to_string()).ok()?,
139+
))
140+
}
134141
Cmd::Stmt(Stmt::Detach(_)) => Some(Self::Detach),
135142
_ => None,
136143
}

libsql-server/tests/standalone/attach.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use insta::assert_debug_snapshot;
22
use libsql::Database;
3+
use uuid::Uuid;
34

45
use crate::{
56
common::{http::Client, net::TurmoilConnector},
@@ -214,3 +215,96 @@ fn attach_auth() {
214215

215216
sim.run().unwrap();
216217
}
218+
219+
#[test]
220+
fn attach_auth_with_uuids() {
221+
let mut sim = turmoil::Builder::new().build();
222+
223+
sim.host("primary", make_standalone_server);
224+
225+
sim.client("test", async {
226+
let client = Client::new();
227+
228+
let (enc, jwt_key) = key_pair();
229+
230+
let main_db_id = Uuid::new_v4();
231+
let attach_db_id = Uuid::new_v4();
232+
233+
assert!(client
234+
.post(
235+
format!("http://primary:9090/v1/namespaces/{}/create", main_db_id).as_str(),
236+
serde_json::json!({ "jwt_key": jwt_key })
237+
)
238+
.await
239+
.unwrap()
240+
.status()
241+
.is_success());
242+
assert!(client
243+
.post(
244+
format!("http://primary:9090/v1/namespaces/{}/create", attach_db_id).as_str(),
245+
serde_json::json!({ "allow_attach": true, "jwt_key": jwt_key })
246+
)
247+
.await
248+
.unwrap()
249+
.status()
250+
.is_success());
251+
252+
let claims = serde_json::json!({
253+
"p": {
254+
"rw": {
255+
"ns": [main_db_id, attach_db_id]
256+
},
257+
"roa": {
258+
"ns": [attach_db_id]
259+
}
260+
}
261+
});
262+
let token = encode(&claims, &enc);
263+
264+
let attach_conn = Database::open_remote_with_connector(
265+
format!("http://{}.primary:8080", attach_db_id).as_str(),
266+
&token,
267+
TurmoilConnector,
268+
)?
269+
.connect()
270+
.unwrap();
271+
attach_conn
272+
.execute("CREATE TABLE bar_table (x)", ())
273+
.await
274+
.unwrap();
275+
attach_conn
276+
.execute("insert into bar_table values (43)", ())
277+
.await
278+
.unwrap();
279+
280+
let main_conn = Database::open_remote_with_connector(
281+
format!("http://{}.primary:8080", main_db_id).as_str(),
282+
&token,
283+
TurmoilConnector,
284+
)?
285+
.connect()
286+
.unwrap();
287+
288+
// fails: namespace is uuid, hence needs to be wrapped in quotes
289+
assert_debug_snapshot!(main_conn
290+
.execute(
291+
"ATTACH DATABASE ae308915-caca-480f-a6b4-9f9f9dc84b11 as bar",
292+
()
293+
)
294+
.await
295+
.unwrap_err());
296+
297+
let txn = main_conn.transaction().await.unwrap();
298+
txn.execute(
299+
format!("ATTACH DATABASE \"{}\" as bar", attach_db_id).as_str(),
300+
(),
301+
)
302+
.await
303+
.unwrap();
304+
let mut rows = txn.query("SELECT * FROM bar.bar_table", ()).await.unwrap();
305+
assert_debug_snapshot!(rows.next().await);
306+
Ok(())
307+
});
308+
309+
sim.run().unwrap();
310+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
source: libsql-server/tests/standalone/attach.rs
3+
expression: rows.next().await
4+
---
5+
Ok(
6+
Some(
7+
Row {
8+
cols: [
9+
Col {
10+
name: Some(
11+
"x",
12+
),
13+
decltype: None,
14+
},
15+
],
16+
inner: [
17+
Integer {
18+
value: 43,
19+
},
20+
],
21+
},
22+
),
23+
)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
source: libsql-server/tests/standalone/attach.rs
3+
assertion_line: 289
4+
expression: "main_conn.execute(format!(\"ATTACH DATABASE {} as bar\", attach_db_id).as_str(),\n ()).await.unwrap_err()"
5+
---
6+
Sqlite3ParserError(
7+
BadNumber(
8+
Some(
9+
(
10+
1,
11+
31,
12+
),
13+
),
14+
),
15+
)

0 commit comments

Comments
 (0)