Skip to content

Commit 68e9a47

Browse files
authored
Enforce explicit https addresses for TLS connections (#780)
## Usage and product changes Drivers return explicit error messages when connection addresses and TLS options are mismatched. TLS connections require addresses to have `https`. Non-TLS connections require addresses not to have `https`. ## Implementation Enhance `address.rs` to retrieve URI schemes from the stored addresses. Before creating a single server connection in Rust, validate the addresses based on the requirements described above.
1 parent e38d663 commit 68e9a47

File tree

12 files changed

+55
-15
lines changed

12 files changed

+55
-15
lines changed

docs/modules/ROOT/partials/rust/errors/ConnectionError.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
[options="header"]
99
|===
1010
|Variant
11+
a| `AbsentTlsConfigForTlsConnection`
1112
a| `AddressTranslationMismatch`
1213
a| `BrokenPipe`
1314
a| `ClusterAllNodesFailed`
@@ -23,13 +24,15 @@ a| `InvalidResponseField`
2324
a| `ListsNotImplemented`
2425
a| `MissingPort`
2526
a| `MissingResponseField`
27+
a| `NonTlsConnectionWithHttps`
2628
a| `QueryStreamNoResponse`
2729
a| `RPCMethodUnavailable`
2830
a| `SSLCertificateNotValidated`
2931
a| `ServerConnectionFailed`
3032
a| `ServerConnectionFailedStatusError`
3133
a| `ServerConnectionFailedWithError`
3234
a| `ServerConnectionIsClosed`
35+
a| `TlsConnectionWithoutHttps`
3336
a| `TokenCredentialInvalid`
3437
a| `TransactionIsClosed`
3538
a| `TransactionIsClosedWithErrors`

python/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class TypeDBExample:
4040
def typedb_example(self):
4141
# Open a driver connection. Specify your parameters if needed
4242
# The connection will be automatically closed on the "with" block exit
43-
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions()) as driver:
43+
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions(is_tls_enabled=False)) as driver:
4444
# Create a database
4545
driver.databases.create("typedb")
4646
database = driver.databases.get("typedb")

python/example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class TypeDBExample:
88
def typedb_example(self):
99
# Open a driver connection. Specify your parameters if needed
1010
# The connection will be automatically closed on the "with" block exit
11-
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions()) as driver:
11+
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions(is_tls_enabled=False)) as driver:
1212
# Create a database
1313
driver.databases.create("typedb")
1414
database = driver.databases.get("typedb")

python/tests/behaviour/background/cluster/environment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def create_driver(context, host="localhost", port=None, username=None, password=
5353
if password is None:
5454
password = "password"
5555
credentials = Credentials(username, password)
56-
return TypeDB.driver(address=f"{host}:{port}", credentials=credentials, driver_options=DriverOptions())
56+
return TypeDB.driver(address=f"{host}:{port}", credentials=credentials, driver_options=DriverOptions(is_tls_enabled=False))
5757

5858

5959
def after_scenario(context: Context, scenario):

python/tests/behaviour/background/community/environment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def create_driver(context, host="localhost", port=None, username=None, password=
5050
if password is None:
5151
password = "password"
5252
credentials = Credentials(username, password)
53-
return TypeDB.driver(address=f"{host}:{port}", credentials=credentials, driver_options=DriverOptions())
53+
return TypeDB.driver(address=f"{host}:{port}", credentials=credentials, driver_options=DriverOptions(is_tls_enabled=False))
5454

5555

5656
def after_scenario(context: Context, scenario):

python/tests/deployment/test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class TestDeployedPythonDriver(TestCase):
3535
def setUpClass(cls):
3636
super(TestDeployedPythonDriver, cls).setUpClass()
3737
global driver
38-
driver = TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions())
38+
driver = TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions(is_tls_enabled=False))
3939

4040
@classmethod
4141
def tearDownClass(cls):

python/tests/integration/test_debug.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
class TestDebug(TestCase):
3030

3131
def setUp(self):
32-
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions()) as driver:
32+
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions(is_tls_enabled=False)) as driver:
3333
if TYPEDB not in [db.name for db in driver.databases.all()]:
3434
driver.databases.create(TYPEDB)
3535

python/tests/integration/test_example.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class TestExample(TestCase):
2727
# EXAMPLE END MARKER
2828

2929
def setUp(self):
30-
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions()) as driver:
30+
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions(is_tls_enabled=False)) as driver:
3131
if driver.databases.contains("typedb"):
3232
driver.databases.get("typedb").delete()
3333

@@ -36,7 +36,7 @@ def setUp(self):
3636
def test_example(self):
3737
# Open a driver connection. Specify your parameters if needed
3838
# The connection will be automatically closed on the "with" block exit
39-
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions()) as driver:
39+
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions(is_tls_enabled=False)) as driver:
4040
# Create a database
4141
driver.databases.create("typedb")
4242
database = driver.databases.get("typedb")

python/tests/integration/test_values.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
class TestValues(TestCase):
3535

3636
def setUp(self):
37-
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions()) as driver:
37+
with TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions(is_tls_enabled=False)) as driver:
3838
if driver.databases.contains(TYPEDB):
3939
driver.databases.get(TYPEDB).delete()
4040
driver.databases.create(TYPEDB)
@@ -67,7 +67,7 @@ def test_values(self):
6767
"expiration": "P1Y10M7DT15H44M5.00394892S"
6868
}
6969

70-
with (TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions()) as driver):
70+
with (TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions(is_tls_enabled=False)) as driver):
7171
database = driver.databases.get(TYPEDB)
7272

7373
with driver.transaction(database.name, SCHEMA) as tx:
@@ -184,7 +184,7 @@ def test_datetime(self):
184184
Datetime.fromstring("2024-09-21", tz_name="Asia/Calcutta", datetime_fmt="%Y-%m-%d")
185185
Datetime.fromstring("21/09/24 18:34", tz_name="Africa/Cairo", datetime_fmt="%d/%m/%y %H:%M")
186186

187-
with (TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions()) as driver):
187+
with (TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions(is_tls_enabled=False)) as driver):
188188
database = driver.databases.get(TYPEDB)
189189

190190
with driver.transaction(database.name, SCHEMA) as tx:
@@ -374,7 +374,7 @@ def test_duration(self):
374374
Duration.fromstring("P1Y10M7DT15H44M5.00394892S")
375375
Duration.fromstring("P55W")
376376

377-
with (TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions()) as driver):
377+
with (TypeDB.driver(TypeDB.DEFAULT_ADDRESS, Credentials("admin", "password"), DriverOptions(is_tls_enabled=False)) as driver):
378378
database = driver.databases.get(TYPEDB)
379379

380380
with driver.transaction(database.name, SCHEMA) as tx:

rust/src/common/address.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,25 @@ use crate::{
2626
error::ConnectionError,
2727
};
2828

29-
#[derive(Clone, Hash, PartialEq, Eq)]
29+
#[derive(Clone, Hash, PartialEq, Eq, Default)]
3030
pub struct Address {
3131
uri: Uri,
3232
}
3333

3434
impl Address {
35+
const DEFAULT_SCHEME: &'static str = "http";
36+
3537
pub(crate) fn into_uri(self) -> Uri {
3638
self.uri
3739
}
40+
41+
pub(crate) fn uri_scheme(&self) -> Option<&http::uri::Scheme> {
42+
self.uri.scheme()
43+
}
44+
45+
pub(crate) fn is_https(&self) -> bool {
46+
self.uri_scheme().map_or(false, |scheme| scheme == &http::uri::Scheme::HTTPS)
47+
}
3848
}
3949

4050
impl FromStr for Address {
@@ -44,7 +54,7 @@ impl FromStr for Address {
4454
let uri = if address.contains("://") {
4555
address.parse::<Uri>()?
4656
} else {
47-
format!("http://{address}").parse::<Uri>()?
57+
format!("{}://{}", Self::DEFAULT_SCHEME, address).parse::<Uri>()?
4858
};
4959
if uri.port().is_none() {
5060
return Err(Error::Connection(ConnectionError::MissingPort { address: address.to_owned() }));
@@ -61,6 +71,6 @@ impl fmt::Display for Address {
6171

6272
impl fmt::Debug for Address {
6373
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64-
fmt::Display::fmt(self, f)
74+
write!(f, "{:?}", self.uri)
6575
}
6676
}

0 commit comments

Comments
 (0)