@@ -6,11 +6,15 @@ use std::path::PathBuf;
66use std:: sync:: Arc ;
77use std:: time:: { Duration , Instant } ;
88
9+ use crate :: common:: auth:: encode;
910use crate :: common:: http:: Client ;
1011use crate :: common:: net:: { init_tracing, SimServer , TestServer , TurmoilAcceptor , TurmoilConnector } ;
11- use crate :: common:: snapshot_metrics;
12+ use crate :: common:: { self , snapshot_metrics} ;
1213use libsql:: Database ;
13- use libsql_server:: config:: { AdminApiConfig , DbConfig , RpcServerConfig , UserApiConfig } ;
14+ use libsql_server:: auth:: { user_auth_strategies, Auth } ;
15+ use libsql_server:: config:: {
16+ AdminApiConfig , DbConfig , RpcClientConfig , RpcServerConfig , UserApiConfig ,
17+ } ;
1418use serde_json:: json;
1519use tempfile:: tempdir;
1620use tokio:: sync:: Notify ;
@@ -1362,3 +1366,149 @@ fn replicated_return() {
13621366
13631367 sim. run ( ) . unwrap ( ) ;
13641368}
1369+
1370+ #[ test]
1371+ fn replicate_auth ( ) {
1372+ init_tracing ( ) ;
1373+ let mut sim = Builder :: new ( )
1374+ . simulation_duration ( Duration :: from_secs ( 1000 ) )
1375+ . build ( ) ;
1376+
1377+ let ( encoding, decoding) = common:: auth:: key_pair ( ) ;
1378+ sim. host ( "primary" , {
1379+ let decoding = decoding. clone ( ) ;
1380+ move || {
1381+ let decoding = decoding. clone ( ) ;
1382+ async move {
1383+ let tmp = tempdir ( ) ?;
1384+ let jwt_keys =
1385+ vec ! [ jsonwebtoken:: DecodingKey :: from_ed_components( & decoding) . unwrap( ) ] ;
1386+ let auth = Auth :: new ( user_auth_strategies:: Jwt :: new ( jwt_keys) ) ;
1387+ let server = TestServer {
1388+ path : tmp. path ( ) . to_owned ( ) . into ( ) ,
1389+ user_api_config : UserApiConfig {
1390+ hrana_ws_acceptor : None ,
1391+ auth_strategy : auth,
1392+ ..Default :: default ( )
1393+ } ,
1394+ admin_api_config : Some ( AdminApiConfig {
1395+ acceptor : TurmoilAcceptor :: bind ( ( [ 0 , 0 , 0 , 0 ] , 9090 ) ) . await ?,
1396+ connector : TurmoilConnector ,
1397+ disable_metrics : true ,
1398+ } ) ,
1399+ rpc_server_config : Some ( RpcServerConfig {
1400+ acceptor : TurmoilAcceptor :: bind ( ( [ 0 , 0 , 0 , 0 ] , 4567 ) ) . await ?,
1401+ tls_config : None ,
1402+ } ) ,
1403+ ..Default :: default ( )
1404+ } ;
1405+
1406+ server. start_sim ( 8080 ) . await ?;
1407+
1408+ Ok ( ( ) )
1409+ }
1410+ }
1411+ } ) ;
1412+
1413+ sim. host ( "replica" , {
1414+ let decoding = decoding. clone ( ) ;
1415+ move || {
1416+ let decoding = decoding. clone ( ) ;
1417+ async move {
1418+ let tmp = tempdir ( ) ?;
1419+ let jwt_keys =
1420+ vec ! [ jsonwebtoken:: DecodingKey :: from_ed_components( & decoding) . unwrap( ) ] ;
1421+ let auth = Auth :: new ( user_auth_strategies:: Jwt :: new ( jwt_keys) ) ;
1422+ let server = TestServer {
1423+ path : tmp. path ( ) . to_owned ( ) . into ( ) ,
1424+ user_api_config : UserApiConfig {
1425+ hrana_ws_acceptor : None ,
1426+ auth_strategy : auth,
1427+ ..Default :: default ( )
1428+ } ,
1429+ admin_api_config : Some ( AdminApiConfig {
1430+ acceptor : TurmoilAcceptor :: bind ( ( [ 0 , 0 , 0 , 0 ] , 9090 ) ) . await ?,
1431+ connector : TurmoilConnector ,
1432+ disable_metrics : true ,
1433+ } ) ,
1434+ rpc_client_config : Some ( RpcClientConfig {
1435+ remote_url : "http://primary:4567" . into ( ) ,
1436+ connector : TurmoilConnector ,
1437+ tls_config : None ,
1438+ } ) ,
1439+ ..Default :: default ( )
1440+ } ;
1441+
1442+ server. start_sim ( 8080 ) . await ?;
1443+
1444+ Ok ( ( ) )
1445+ }
1446+ }
1447+ } ) ;
1448+
1449+ sim. client ( "client" , async move {
1450+ let token = encode (
1451+ & serde_json:: json!( {
1452+ "id" : "default" ,
1453+ } ) ,
1454+ & encoding,
1455+ ) ;
1456+
1457+ // no auth
1458+ let tmp = tempdir ( ) . unwrap ( ) ;
1459+ let db = Database :: open_with_remote_sync_connector (
1460+ tmp. path ( ) . join ( "embedded" ) . to_str ( ) . unwrap ( ) ,
1461+ "http://primary:8080" ,
1462+ "" ,
1463+ TurmoilConnector ,
1464+ false ,
1465+ None ,
1466+ )
1467+ . await ?;
1468+
1469+ assert ! ( db. sync( ) . await . is_err( ) ) ;
1470+
1471+ let tmp = tempdir ( ) . unwrap ( ) ;
1472+ let db = Database :: open_with_remote_sync_connector (
1473+ tmp. path ( ) . join ( "embedded" ) . to_str ( ) . unwrap ( ) ,
1474+ "http://replica:8080" ,
1475+ "" ,
1476+ TurmoilConnector ,
1477+ false ,
1478+ None ,
1479+ )
1480+ . await ?;
1481+
1482+ assert ! ( db. sync( ) . await . is_err( ) ) ;
1483+
1484+ // auth
1485+ let tmp = tempdir ( ) . unwrap ( ) ;
1486+ let db = Database :: open_with_remote_sync_connector (
1487+ tmp. path ( ) . join ( "embedded" ) . to_str ( ) . unwrap ( ) ,
1488+ "http://primary:8080" ,
1489+ token. clone ( ) ,
1490+ TurmoilConnector ,
1491+ false ,
1492+ None ,
1493+ )
1494+ . await ?;
1495+
1496+ assert ! ( db. sync( ) . await . is_ok( ) ) ;
1497+
1498+ let tmp = tempdir ( ) . unwrap ( ) ;
1499+ let db = Database :: open_with_remote_sync_connector (
1500+ tmp. path ( ) . join ( "embedded" ) . to_str ( ) . unwrap ( ) ,
1501+ "http://replica:8080" ,
1502+ token. clone ( ) ,
1503+ TurmoilConnector ,
1504+ false ,
1505+ None ,
1506+ )
1507+ . await ?;
1508+
1509+ assert ! ( db. sync( ) . await . is_ok( ) ) ;
1510+ Ok ( ( ) )
1511+ } ) ;
1512+
1513+ sim. run ( ) . unwrap ( ) ;
1514+ }
0 commit comments