Skip to content

Commit

Permalink
More tests on Dns lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
giorgiofran committed Aug 24, 2020
1 parent e815b18 commit cc455f7
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 16 deletions.
15 changes: 15 additions & 0 deletions lib/src/database/utils/check_same_domain.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:mongo_dart/mongo_dart.dart';

bool checkSameDomain(Uri uri, Uri checkUri) {
var uriParts = uri.host.split('.');
var checkParts = checkUri.host.split('.');
if (uriParts.length < 2) {
throw MongoDartError('At list a domain is required, but got "${uri.host}"');
}
if (checkParts.length < 2) {
throw MongoDartError(
'At list a domain is required, but got "${checkUri.host}"');
}
return uriParts.last == checkParts.last &&
uriParts[uriParts.length - 2] == checkParts[checkParts.length - 2];
}
22 changes: 21 additions & 1 deletion lib/src/database/utils/dns_lookup.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import 'package:basic_utils/basic_utils.dart' show DnsUtils, RRecordType;
import 'package:logging/logging.dart' show Logger;
import 'package:mongo_dart/mongo_dart.dart' show MongoDartError;
import 'package:mongo_dart/src/database/utils/check_same_domain.dart';

var _log = Logger('dns_llokup');

/// This method receive an Uri with "mongodb+srv" schema and returns
/// A List of urls in "mongodb" schema format
Expand Down Expand Up @@ -69,5 +73,21 @@ Future<List<String>> decodeDnsSeedlist(Uri dnsSeedlistUri) async {
}
addresses.add('$host:${parts[parts.length - 2]}');
}
return <String>[for (var address in addresses) '$prefix$address$suffix'];
var ret = <String>[for (var address in addresses) '$prefix$address$suffix'];
// check if the returned addresses pertain to the same domain as the
// dnsSeedListUri
for (var address in ret) {
var actualUri = Uri.parse(address);
if (!checkSameDomain(actualUri, dnsSeedlistUri)) {
var dnsParts = dnsSeedlistUri.host.split('.');
var dnsDomain = '${dnsParts[dnsParts.length - 2]}.${dnsParts.last}';
var actualParts = actualUri.host.split('.');
var actualDomain =
'${actualParts[actualParts.length - 2]}.${actualParts.last}';
throw MongoDartError('Different domain detected in DNS SRV record: '
'required "$dnsDomain", detected "$actualDomain"');
}
_log.info('Dns host detected: $address');
}
return ret;
}
27 changes: 16 additions & 11 deletions lib/src/database/utils/split_hosts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,27 @@ import 'package:mongo_dart/mongo_dart.dart';

List<String> splitHosts(String uriString) {
String prefix, suffix;
var startServersIndex, endServersIndex;
var startHostsIndex, endServersIndex;
if (uriString.startsWith('mongodb://')) {
startServersIndex = 10;
startHostsIndex = 'mongodb://'.length;
} else {
throw MongoDartError('Unexpected scheme in url $uriString. '
throw MongoDartError('Unexpected scheme in url "$uriString". '
'The url is expected to start with "mongodb://"');
}
endServersIndex = uriString.indexOf('/', startServersIndex);
var serversString = uriString.substring(startServersIndex, endServersIndex);
var credentialsIndex = serversString.indexOf('@');
endServersIndex = uriString.indexOf('/', startHostsIndex);
if (endServersIndex == -1) {
endServersIndex = uriString.length;
suffix = '';
} else {
suffix = uriString.substring(endServersIndex).trim();
}
var hostsString = uriString.substring(startHostsIndex, endServersIndex);
var credentialsIndex = hostsString.indexOf('@');
if (credentialsIndex != -1) {
startServersIndex += credentialsIndex + 1;
serversString = uriString.substring(startServersIndex, endServersIndex);
startHostsIndex += credentialsIndex + 1;
hostsString = uriString.substring(startHostsIndex, endServersIndex);
}
prefix = uriString.substring(0, startServersIndex);
suffix = uriString.substring(endServersIndex);
var parts = serversString.split(',');
prefix = uriString.substring(0, startHostsIndex).trim();
var parts = hostsString.split(',');
return [for (var server in parts) '$prefix${server.trim()}$suffix'];
}
3 changes: 3 additions & 0 deletions test/all_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import 'packet_converter_test.dart' as converter;
import 'mongo_dart_query_test.dart' as mongo_dart_query;
import 'authentication_test.dart' as auth_tests;
import 'ssl_connection_test.dart' as ssl_tests;
import 'utils_test.dart' as utils_tests;

//import 'replica_tests.dart' as replica;

void main() {
Expand All @@ -15,5 +17,6 @@ void main() {
mongo_dart_query.main();
auth_tests.main();
ssl_tests.main();
utils_tests.main();
//replica.main();
}
6 changes: 2 additions & 4 deletions test/ssl_connection_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'package:mongo_dart/src/database/utils/dns_lookup.dart';
import 'package:test/test.dart';
import 'package:mongo_dart/mongo_dart.dart';

import 'utils/throw_utils.dart' show throwsMongoDartError;

const sslDbConnectionString =
'mongodb://cluster0-shard-00-00-smeth.gcp.mongodb.net:27017/'
'test?authSource=admin,'
Expand All @@ -20,8 +22,6 @@ const sslQueryParmConnectionString =
const tlsQueryParmConnectionString = 'mongodb://cluster0-shard-00-01-smeth'
'.gcp.mongodb.net:27017/test?tls=true&authSource=admin';

var throwsMongoDartError = throwsA((e) => e is MongoDartError);

void main() {
group('Dns lookup', () {
test('Testing connection TXT', () async {
Expand All @@ -42,7 +42,6 @@ void main() {
var result =
await decodeDnsSeedlist(Uri.parse('mongodb+srv://user:password@'
'rs.joedrumgoole.com/test?retryWrites=true&w=majority'));
print(result);

expect(
result.first,
Expand All @@ -64,7 +63,6 @@ void main() {
decodeDnsSeedlist(Uri.parse('mongodb+srv://user:password@'
'rs.joedrumgoole.com/test?retryWrites=true&w=majority'))
.then((result) {
print(result);
expect(
result.first,
'mongodb://user:password@rs1.joedrumgoole.com:27022/'
Expand Down
4 changes: 4 additions & 0 deletions test/utils/throw_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import 'package:mongo_dart/mongo_dart.dart' show MongoDartError;
import 'package:test/test.dart' show throwsA;

var throwsMongoDartError = throwsA((e) => e is MongoDartError);
126 changes: 126 additions & 0 deletions test/utils_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import 'package:mongo_dart/src/database/utils/check_same_domain.dart'
show checkSameDomain;
import 'package:mongo_dart/src/database/utils/split_hosts.dart';
import 'package:test/test.dart' show expect, group, isFalse, isTrue, test;

import 'utils/throw_utils.dart' show throwsMongoDartError;

void main() {
group('Check Same Domain', () {
test('Same Domain', () async {
expect(
checkSameDomain(
Uri.parse(
'mongodb://cluster0-shard-00-00-smeth.gcp.mongodb.net:27017'),
Uri.parse(
'mongodb://cluster0-shard-00-02-smeth.gcp.mongodb.net:27017/'
'test?authSource=admin&ssl=true')),
isTrue);
expect(
checkSameDomain(
Uri.parse(
'mongodb://cluster0-shard-00-00-smeth.gcp.mongodb.net:27017'),
Uri.parse('http://mongodb.net')),
isTrue);
});
test('Different Domain', () async {
expect(
checkSameDomain(
Uri.parse(
'mongodb://cluster0-shard-00-00-smeth.gcp.mongodb.net:27017'),
Uri.parse(
'mongodb://cluster0-shard-00-02-smeth.gcp.mongodb.org:27017/'
'test?authSource=admin&ssl=true')),
isFalse);
expect(
checkSameDomain(
Uri.parse(
'mongodb://cluster0-shard-00-00-smeth.gcp.mongodb.net:27017'),
Uri.parse('http://mongo.net')),
isFalse);
});
test('Error', () async {
expect(
() => checkSameDomain(
Uri.parse('mongodb://mongodb:27017'),
Uri.parse(
'mongodb://cluster0-shard-00-02-smeth.gcp.mongodb.org:27017/'
'test?authSource=admin&ssl=true')),
throwsMongoDartError);
expect(
() => checkSameDomain(
Uri.parse(
'mongodb://cluster0-shard-00-00-smeth.gcp.mongodb.net:27017'),
Uri.parse('http://mongo')),
throwsMongoDartError);
expect(
() => checkSameDomain(
Uri.parse(
'mongodb://cluster0-shard-00-00-smeth.gcp.mongodb.net:27017'),
Uri.parse('mongodb.net')),
throwsMongoDartError);
});
});

group('Split Hosts', () {
test('three hosts', () async {
var hosts = splitHosts(
'mongodb:// cluster0-shard-00-00-smeth.gcp.mongodb.net:27017,'
'cluster0-shard-00-01-smeth.gcp.mongodb.net:27017, '
'cluster0-shard-00-02-smeth.gcp.mongodb.net:27017/'
'test?authSource=admin&ssl=true ');
expect(
hosts.first,
'mongodb://cluster0-shard-00-00-smeth.gcp.mongodb.net:27017/'
'test?authSource=admin&ssl=true');
expect(
hosts[1],
'mongodb://cluster0-shard-00-01-smeth.gcp.mongodb.net:27017/'
'test?authSource=admin&ssl=true');
expect(
hosts.last,
'mongodb://cluster0-shard-00-02-smeth.gcp.mongodb.net:27017/'
'test?authSource=admin&ssl=true');

hosts = splitHosts(
'mongodb:// cluster0-shard-00-00-smeth.gcp.mongodb.net:27017,'
'cluster0-shard-00-01-smeth.gcp.mongodb.net:27017, '
'cluster0-shard-00-02-smeth.gcp.mongodb.net:27017');
expect(hosts.first,
'mongodb://cluster0-shard-00-00-smeth.gcp.mongodb.net:27017');
expect(hosts[1],
'mongodb://cluster0-shard-00-01-smeth.gcp.mongodb.net:27017');
expect(hosts.last,
'mongodb://cluster0-shard-00-02-smeth.gcp.mongodb.net:27017');

hosts = splitHosts(
'mongodb:// cluster0-shard-00-00-smeth.gcp.mongodb.net:27017,'
'cluster0-shard-00-01-smeth.gcp.mongodb.net/'
'test?authSource=admin&ssl=true');
expect(
hosts.first,
'mongodb://cluster0-shard-00-00-smeth.gcp.mongodb.net:27017/'
'test?authSource=admin&ssl=true');
expect(
hosts.last,
'mongodb://cluster0-shard-00-01-smeth.gcp.mongodb.net/'
'test?authSource=admin&ssl=true');
});

test('Error', () async {
expect(
() => splitHosts(
' mongodb:// cluster0-shard-00-00-smeth.gcp.mongodb.net:27017,'
'cluster0-shard-00-01-smeth.gcp.mongodb.net:27017, '
'cluster0-shard-00-02-smeth.gcp.mongodb.net:27017/'
'test?authSource=admin&ssl=true'),
throwsMongoDartError);
expect(
() => splitHosts('cluster0-shard-00-00-smeth.gcp.mongodb.net:27017,'
'cluster0-shard-00-01-smeth.gcp.mongodb.net:27017, '
'cluster0-shard-00-02-smeth.gcp.mongodb.net:27017/'
'test?authSource=admin&ssl=true'),
throwsMongoDartError);
});
});
}

0 comments on commit cc455f7

Please sign in to comment.