From be21ee2fa20e0eb622103c5f15b13fef4e53d9e0 Mon Sep 17 00:00:00 2001 From: Bilal Al-Shahwany Date: Mon, 28 Aug 2023 13:38:39 -0700 Subject: [PATCH] added flag set validations to config --- splitio/client/config.py | 37 ++++++++++++++++++++++++++++++++++--- tests/client/test_config.py | 21 +++++++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/splitio/client/config.py b/splitio/client/config.py index 4531e40a..cd171319 100644 --- a/splitio/client/config.py +++ b/splitio/client/config.py @@ -1,13 +1,14 @@ """Default settings for the Split.IO SDK Python client.""" import os.path import logging +import re from splitio.engine.impressions import ImpressionsMode _LOGGER = logging.getLogger(__name__) DEFAULT_DATA_SAMPLING = 1 - +_FLAG_SETS_REGEX = '^[a-z0-9][_a-z0-9]{0,49}$' DEFAULT_CONFIG = { 'operationMode': 'standalone', @@ -58,10 +59,10 @@ 'dataSampling': DEFAULT_DATA_SAMPLING, 'storageWrapper': None, 'storagePrefix': None, - 'storageType': None + 'storageType': None, + 'FlagSets': None } - def _parse_operation_mode(sdk_key, config): """ Process incoming config to determine operation mode and storage type @@ -119,6 +120,34 @@ def _sanitize_impressions_mode(storage_type, mode, refresh_rate=None): return mode, refresh_rate +def _sanitize_flag_sets(flag_sets): + """ + Check supplied flag sets list + + :param flag_set: list of flag sets + :type flag_set: list[str] + + :returns: Sanitized and sorted flag sets + :rtype: list[str] + """ + sanitized_flag_sets = set() + for flag_set in flag_sets: + if flag_set != flag_set.strip(): + _LOGGER.warning("SDK config: Flag Set name %s has extra whitespace, trimming" % (flag_set)) + flag_set = flag_set.strip() + + if flag_set != flag_set.lower(): + _LOGGER.warning("SDK config: Flag Set name %s should be all lowercase - converting string to lowercase" % (flag_set)) + flag_set = flag_set.lower() + + if re.search(_FLAG_SETS_REGEX, flag_set) is None or re.search(_FLAG_SETS_REGEX, flag_set).group() != flag_set: + _LOGGER.warning("SDK config: you passed %s, Flag Set must adhere to the regular expressions %s. This means a Flag Set must start with a letter, be in lowercase, alphanumeric and have a max length of 50 characteres. %s was discarded.", flag_set, _FLAG_SETS_REGEX, flag_set) + continue + + sanitized_flag_sets.add(flag_set.strip()) + + return sorted(list(sanitized_flag_sets)) + def sanitize(sdk_key, config): """ Look for inconsistencies or ill-formed configs and tune it accordingly. @@ -143,4 +172,6 @@ def sanitize(sdk_key, config): _LOGGER.warning('metricRefreshRate parameter minimum value is 60 seconds, defaulting to 3600 seconds.') processed['metricsRefreshRate'] = 3600 + processed['FlagSets'] = _sanitize_flag_sets(processed['FlagSets']) if processed['FlagSets'] is not None else None + return processed diff --git a/tests/client/test_config.py b/tests/client/test_config.py index 0d96b478..e9a1c284 100644 --- a/tests/client/test_config.py +++ b/tests/client/test_config.py @@ -1,5 +1,6 @@ """Configuration unit tests.""" # pylint: disable=protected-access,no-self-use,line-too-long +import pytest from splitio.client import config from splitio.engine.impressions.impressions import ImpressionsMode @@ -68,3 +69,23 @@ def test_sanitize(self): processed = config.sanitize('some', configs) assert processed['redisLocalCacheEnabled'] # check default is True + + def test_sanitize_flag_sets(self): + """Test sanitization for flag sets.""" + flag_sets = config._sanitize_flag_sets([' set1', 'set2 ', 'set3']) + assert flag_sets == ['set1', 'set2', 'set3'] + + flag_sets = config._sanitize_flag_sets(['1set', '_set2']) + assert flag_sets == ['1set'] + + flag_sets = config._sanitize_flag_sets(['Set1', 'SET2']) + assert flag_sets == ['set1', 'set2'] + + flag_sets = config._sanitize_flag_sets(['se\t1', 's/et2', 's*et3', 's!et4', 'se@t5', 'se#t5', 'se$t5', 'se^t5', 'se%t5', 'se&t5']) + assert flag_sets == [] + + flag_sets = config._sanitize_flag_sets(['set4', 'set1', 'set3', 'set1']) + assert flag_sets == ['set1', 'set3', 'set4'] + + flag_sets = config._sanitize_flag_sets(['w' * 50, 's' * 51]) + assert flag_sets == ['w' * 50]