Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class CertificatePinningConfiguration {

final Map<String, Set<String>> _pins = {};

Map<String, Set<String>> get pins => _pins;

CertificatePinningConfiguration addPin(String host, String pin) {
pin = pin.trim();
if (pin.isEmpty) {
return this;
}

if (!_pins.containsKey(host)) {
_pins[host] = <String>{};
}

_pins[host]?.add(pin);
return this;
}
}
11 changes: 11 additions & 0 deletions splitio_platform_interface/lib/split_configuration.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:splitio_platform_interface/certificate_pinning_configuration.dart';
import 'package:splitio_platform_interface/split_sync_config.dart';

class SplitConfiguration {
Expand Down Expand Up @@ -44,6 +45,8 @@ class SplitConfiguration {
/// [logLevel] Enables logging according to the level specified. Options are [SplitLogLevel.verbose], [SplitLogLevel.none], [SplitLogLevel.debug], [SplitLogLevel.info], [SplitLogLevel.warning], and [SplitLogLevel.error].
///
/// [readyTimeout] Maximum amount of time in seconds to wait before firing the SDK_READY_TIMED_OUT event. Defaults to 10 seconds.
///
/// [certificatePinningConfig] Certificate pinning configuration. It is a map where the key is the host and the value is a set of base64 SHA-256 or base64 SHA-1 hashes of the SPKI.
SplitConfiguration({
int? featuresRefreshRate,
int? segmentsRefreshRate,
Expand All @@ -70,6 +73,7 @@ class SplitConfiguration {
bool? encryptionEnabled,
SplitLogLevel? logLevel,
int? readyTimeout = 10,
CertificatePinningConfiguration? certificatePinningConfig,
}) {
if (featuresRefreshRate != null) {
configurationMap['featuresRefreshRate'] = featuresRefreshRate;
Expand Down Expand Up @@ -175,6 +179,13 @@ class SplitConfiguration {
if (readyTimeout != null) {
configurationMap['readyTimeout'] = readyTimeout;
}

if (certificatePinningConfig != null &&
certificatePinningConfig.pins.isNotEmpty) {
configurationMap['certificatePinningConfiguration'] = {
'pins': certificatePinningConfig.pins
};
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:splitio_platform_interface/certificate_pinning_configuration.dart';

void main() {
test('single pin can be added', () {
var config = CertificatePinningConfiguration();
config.addPin('host', 'pin');

expect(config.pins, {
'host': {'pin'}
});
});

test('multiple pins can be added for the same host', () {
var config = CertificatePinningConfiguration();
config.addPin('host', 'pin1');
config.addPin('host', 'pin2');

expect(config.pins, {
'host': {'pin1', 'pin2'}
});
});

test('multiple pins can be added for multiple hosts', () {
var config = CertificatePinningConfiguration();
config.addPin('host1', 'pin1');
config.addPin('host2', 'pin2');
config.addPin('host1', 'pin2');

expect(config.pins, {
'host1': {'pin1', 'pin2'},
'host2': {'pin2'}
});
});

test('same pin for same host is not duplicated', () {
var config = CertificatePinningConfiguration();
config.addPin('host', 'pin');
config.addPin('host', 'pin');

expect(config.pins, {
'host': {'pin'}
});
});

test('only whitespace pin is not added', () {
var config = CertificatePinningConfiguration();
config.addPin('host', ' ');

expect(config.pins, {});
});

test('empty pin is not added', () {
var config = CertificatePinningConfiguration();
config.addPin('host', '');

expect(config.pins, {});
});
}
14 changes: 11 additions & 3 deletions splitio_platform_interface/test/splitio_configuration_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:splitio_platform_interface/certificate_pinning_configuration.dart';
import 'package:splitio_platform_interface/split_configuration.dart';
import 'package:splitio_platform_interface/split_sync_config.dart';

Expand Down Expand Up @@ -29,8 +30,11 @@ void main() {
userConsent: UserConsent.declined,
encryptionEnabled: true,
logLevel: SplitLogLevel.debug,
readyTimeout: 1
);
readyTimeout: 1,
certificatePinningConfig: CertificatePinningConfiguration()
.addPin('host1', 'pin1')
.addPin('host2', 'pin3')
.addPin('host1', 'pin2'));

expect(config.configurationMap['eventFlushInterval'], 2000);
expect(config.configurationMap['eventsPerPush'], 300);
Expand Down Expand Up @@ -63,6 +67,10 @@ void main() {
expect(config.configurationMap['encryptionEnabled'], true);
expect(config.configurationMap['logLevel'], 'debug');
expect(config.configurationMap['readyTimeout'], 1);
expect(config.configurationMap['certificatePinningConfiguration']['pins'], {
'host1': ['pin1', 'pin2'],
'host2': ['pin3']
});
});

test('no special values leaves map empty', () async {
Expand All @@ -74,7 +82,7 @@ void main() {

test('sets values are mapped correctly', () async {
final SplitConfiguration config = SplitConfiguration(
syncConfig: SyncConfig.flagSets(['one', 'two']),
syncConfig: SyncConfig.flagSets(['one', 'two']),
);

expect(config.configurationMap['syncConfig']['syncConfigNames'], []);
Expand Down