1515MAX_LENGTH = 250
1616EVENT_TYPE_PATTERN = r'^[a-zA-Z0-9][-_.:a-zA-Z0-9]{0,79}$'
1717MAX_PROPERTIES_LENGTH_BYTES = 32768
18+ _FLAG_SETS_REGEX = '^[a-z0-9][_a-z0-9]{0,49}$'
1819
1920
2021def _check_not_null (value , name , operation ):
@@ -79,7 +80,7 @@ def _check_string_not_empty(value, name, operation):
7980 return True
8081
8182
82- def _check_string_matches (value , operation , pattern ):
83+ def _check_string_matches (value , operation , pattern , name , length ):
8384 """
8485 Check if value is adhere to a regular expression passed.
8586
@@ -92,14 +93,14 @@ def _check_string_matches(value, operation, pattern):
9293 :return: The result of validation
9394 :rtype: True|False
9495 """
95- if not re .match (pattern , value ):
96+ if re . search ( pattern , value ) is None or re .search (pattern , value ). group () != value :
9697 _LOGGER .error (
9798 '%s: you passed %s, event_type must ' +
9899 'adhere to the regular expression %s. ' +
99- 'This means an event name must be alphanumeric, cannot be more ' +
100- 'than 80 characters long, and can only include a dash, underscore, ' +
100+ 'This means %s must be alphanumeric, cannot be more ' +
101+ 'than %s characters long, and can only include a dash, underscore, ' +
101102 'period, or colon as separators of alphanumeric characters.' ,
102- operation , value , pattern
103+ operation , value , pattern , name , length
103104 )
104105 return False
105106 return True
@@ -165,10 +166,7 @@ def _check_valid_object_key(key, name, operation):
165166 :return: The result of validation
166167 :rtype: str|None
167168 """
168- if key is None :
169- _LOGGER .error (
170- '%s: you passed a null %s, %s must be a non-empty string.' ,
171- operation , name , name )
169+ if not _check_not_null (key , 'key' , operation ):
172170 return None
173171 if isinstance (key , str ):
174172 if not _check_string_not_empty (key , name , operation ):
@@ -179,7 +177,7 @@ def _check_valid_object_key(key, name, operation):
179177 return key_str
180178
181179
182- def _remove_empty_spaces (value , operation ):
180+ def _remove_empty_spaces (value , name , operation ):
183181 """
184182 Check if an string has whitespaces.
185183
@@ -192,10 +190,17 @@ def _remove_empty_spaces(value, operation):
192190 """
193191 strip_value = value .strip ()
194192 if value != strip_value :
195- _LOGGER .warning ("%s: feature flag name '%s' has extra whitespace, trimming." , operation , value )
193+ _LOGGER .warning ("%s: %s '%s' has extra whitespace, trimming." , operation , name , value )
196194 return strip_value
197195
198196
197+ def _convert_str_to_lower (value , name , operation ):
198+ lower_value = value .lower ()
199+ if value != lower_value :
200+ _LOGGER .warning ("%s: %s '%s' should be all lowercase - converting string to lowercase" % (operation , name , value ))
201+ return lower_value
202+
203+
199204def validate_key (key , method_name ):
200205 """
201206 Validate Key parameter for get_treatment/s.
@@ -211,8 +216,7 @@ def validate_key(key, method_name):
211216 """
212217 matching_key_result = None
213218 bucketing_key_result = None
214- if key is None :
215- _LOGGER .error ('%s: you passed a null key, key must be a non-empty string.' , method_name )
219+ if not _check_not_null (key , 'key' , method_name ):
216220 return None , None
217221
218222 if isinstance (key , Key ):
@@ -255,7 +259,7 @@ def validate_feature_flag_name(feature_flag_name, should_validate_existance, fea
255259 )
256260 return None
257261
258- return _remove_empty_spaces (feature_flag_name , method_name )
262+ return _remove_empty_spaces (feature_flag_name , 'feature flag name' , method_name )
259263
260264
261265def validate_track_key (key ):
@@ -294,10 +298,7 @@ def validate_traffic_type(traffic_type, should_validate_existance, feature_flag_
294298 (not _check_is_string (traffic_type , 'traffic_type' , 'track' )) or \
295299 (not _check_string_not_empty (traffic_type , 'traffic_type' , 'track' )):
296300 return None
297- if not traffic_type .islower ():
298- _LOGGER .warning ('track: %s should be all lowercase - converting string to lowercase.' ,
299- traffic_type )
300- traffic_type = traffic_type .lower ()
301+ traffic_type = _convert_str_to_lower (traffic_type , 'traffic type' , 'track' )
301302
302303 if should_validate_existance and not feature_flag_storage .is_valid_traffic_type (traffic_type ):
303304 _LOGGER .warning (
@@ -322,7 +323,7 @@ def validate_event_type(event_type):
322323 if (not _check_not_null (event_type , 'event_type' , 'track' )) or \
323324 (not _check_is_string (event_type , 'event_type' , 'track' )) or \
324325 (not _check_string_not_empty (event_type , 'event_type' , 'track' )) or \
325- (not _check_string_matches (event_type , 'track' , EVENT_TYPE_PATTERN )):
326+ (not _check_string_matches (event_type , 'track' , EVENT_TYPE_PATTERN , 'an event name' , 80 )):
326327 return None
327328 return event_type
328329
@@ -390,7 +391,7 @@ def validate_feature_flags_get_treatments( # pylint: disable=invalid-name
390391 _LOGGER .error ("%s: feature flag names must be a non-empty array." , method_name )
391392 return None , None
392393 filtered_feature_flags = set (
393- _remove_empty_spaces (feature_flag , method_name ) for feature_flag in feature_flags
394+ _remove_empty_spaces (feature_flag , 'feature flag name' , method_name ) for feature_flag in feature_flags
394395 if feature_flag is not None and
395396 _check_is_string (feature_flag , 'feature flag name' , method_name ) and
396397 _check_string_not_empty (feature_flag , 'feature flag name' , method_name )
@@ -566,3 +567,33 @@ def validate_pluggable_adapter(config):
566567 _LOGGER .error ("Pluggable adapter method %s has less than required arguments count: %s : " % (exp_method , len (get_method_args )))
567568 return False
568569 return True
570+
571+ def validate_flag_sets (flag_sets , method_name ):
572+ """
573+ Validate flag sets list
574+
575+ :param flag_set: list of flag sets
576+ :type flag_set: list[str]
577+
578+ :returns: Sanitized and sorted flag sets
579+ :rtype: list[str]
580+ """
581+ if not isinstance (flag_sets , list ):
582+ _LOGGER .warning ("%s: flag sets parameter type should be list object, parameter is discarded" % (method_name ))
583+ return []
584+
585+ sanitized_flag_sets = set ()
586+ for flag_set in flag_sets :
587+ if not _check_not_null (flag_set , 'flag set' , method_name ):
588+ continue
589+ if not _check_is_string (flag_set , 'flag set' , method_name ):
590+ continue
591+ flag_set = _remove_empty_spaces (flag_set , 'flag set' , method_name )
592+ flag_set = _convert_str_to_lower (flag_set , 'flag set' , method_name )
593+
594+ if not _check_string_matches (flag_set , method_name , _FLAG_SETS_REGEX , 'a flag set' , 50 ):
595+ continue
596+
597+ sanitized_flag_sets .add (flag_set )
598+
599+ return sorted (list (sanitized_flag_sets ))
0 commit comments