From fb0332ad15105dd0f8d592d2d0f5545cb1e260e3 Mon Sep 17 00:00:00 2001 From: Adam Simon Date: Fri, 20 Oct 2023 12:54:21 +0200 Subject: [PATCH] Add clear text comparators --- .../Evaluation/EvaluateLogHelper.cs | 114 ++++++----- .../Evaluation/RolloutEvaluator.cs | 190 +++++++++++++----- src/ConfigCatClient/Models/UserComparator.cs | 108 +++++++--- src/ConfigCatClient/Models/UserCondition.cs | 2 +- 4 files changed, 282 insertions(+), 132 deletions(-) diff --git a/src/ConfigCatClient/Evaluation/EvaluateLogHelper.cs b/src/ConfigCatClient/Evaluation/EvaluateLogHelper.cs index 2750d0d6..c0b1fa80 100644 --- a/src/ConfigCatClient/Evaluation/EvaluateLogHelper.cs +++ b/src/ConfigCatClient/Evaluation/EvaluateLogHelper.cs @@ -24,12 +24,12 @@ private static IndentedTextBuilder AppendUserCondition(this IndentedTextBuilder return builder.Append($"User.{comparisonAttribute} {comparator.ToDisplayText()} '{comparisonValue ?? InvalidValuePlaceholder}'"); } - private static IndentedTextBuilder AppendUserCondition(this IndentedTextBuilder builder, string? comparisonAttribute, UserComparator comparator, string? comparisonValue, bool isSensitive = false) + private static IndentedTextBuilder AppendUserCondition(this IndentedTextBuilder builder, string? comparisonAttribute, UserComparator comparator, string? comparisonValue, bool isSensitive) { return builder.AppendUserCondition(comparisonAttribute, comparator, !isSensitive ? (object?)comparisonValue : ""); } - private static IndentedTextBuilder AppendUserCondition(this IndentedTextBuilder builder, string? comparisonAttribute, UserComparator comparator, string[]? comparisonValue, bool isSensitive = false) + private static IndentedTextBuilder AppendUserCondition(this IndentedTextBuilder builder, string? comparisonAttribute, UserComparator comparator, string[]? comparisonValue, bool isSensitive) { if (comparisonValue is null) { @@ -67,34 +67,44 @@ public static IndentedTextBuilder AppendUserCondition(this IndentedTextBuilder b { return condition.Comparator switch { - UserComparator.Contains or - UserComparator.NotContains or - UserComparator.SemVerOneOf or - UserComparator.SemVerNotOneOf => - builder.AppendUserCondition(condition.ComparisonAttribute, condition.Comparator, condition.StringListValue), - - UserComparator.SemVerLessThan or - UserComparator.SemVerLessThanEqual or - UserComparator.SemVerGreaterThan or - UserComparator.SemVerGreaterThanEqual => - builder.AppendUserCondition(condition.ComparisonAttribute, condition.Comparator, condition.StringValue), - - UserComparator.NumberEqual or - UserComparator.NumberNotEqual or - UserComparator.NumberLessThan or - UserComparator.NumberLessThanEqual or - UserComparator.NumberGreaterThan or - UserComparator.NumberGreaterThanEqual => + UserComparator.IsOneOf or + UserComparator.IsNotOneOf or + UserComparator.ContainsAnyOf or + UserComparator.NotContainsAnyOf or + UserComparator.SemVerIsOneOf or + UserComparator.SemVerIsNotOneOf or + UserComparator.TextStartsWithAnyOf or + UserComparator.TextNotStartsWithAnyOf or + UserComparator.TextEndsWithAnyOf or + UserComparator.TextNotEndsWithAnyOf or + UserComparator.ArrayContainsAnyOf or + UserComparator.ArrayNotContainsAnyOf => + builder.AppendUserCondition(condition.ComparisonAttribute, condition.Comparator, condition.StringListValue, isSensitive: false), + + UserComparator.SemVerLess or + UserComparator.SemVerLessOrEquals or + UserComparator.SemVerGreater or + UserComparator.SemVerGreaterOrEquals or + UserComparator.TextEquals or + UserComparator.TextNotEquals => + builder.AppendUserCondition(condition.ComparisonAttribute, condition.Comparator, condition.StringValue, isSensitive: false), + + UserComparator.NumberEquals or + UserComparator.NumberNotEquals or + UserComparator.NumberLess or + UserComparator.NumberLessOrEquals or + UserComparator.NumberGreater or + UserComparator.NumberGreaterOrEquals => builder.AppendUserCondition(condition.ComparisonAttribute, condition.Comparator, condition.DoubleValue), - UserComparator.SensitiveOneOf or - UserComparator.SensitiveNotOneOf or - UserComparator.SensitiveTextStartsWith or - UserComparator.SensitiveTextNotStartsWith or - UserComparator.SensitiveTextEndsWith or - UserComparator.SensitiveTextNotEndsWith or - UserComparator.SensitiveArrayContains or - UserComparator.SensitiveArrayNotContains => + UserComparator.SensitiveIsOneOf or + UserComparator.SensitiveIsNotOneOf or + UserComparator.SensitiveTextStartsWithAnyOf or + UserComparator.SensitiveTextNotStartsWithAnyOf or + UserComparator.SensitiveTextEndsWithAnyOf or + UserComparator.SensitiveTextNotEndsWithAnyOf or + UserComparator.SensitiveArrayContainsAnyOf or + UserComparator.SensitiveArrayNotContainsAnyOf => builder.AppendUserCondition(condition.ComparisonAttribute, condition.Comparator, condition.StringListValue, isSensitive: true), UserComparator.DateTimeBefore or @@ -295,32 +305,32 @@ public static string ToDisplayText(this UserComparator comparator) { return comparator switch { - UserComparator.Contains => "CONTAINS ANY OF", - UserComparator.NotContains => "NOT CONTAINS ANY OF", - UserComparator.SemVerOneOf => "IS ONE OF", - UserComparator.SemVerNotOneOf => "IS NOT ONE OF", - UserComparator.SemVerLessThan => "<", - UserComparator.SemVerLessThanEqual => "<=", - UserComparator.SemVerGreaterThan => ">", - UserComparator.SemVerGreaterThanEqual => ">=", - UserComparator.NumberEqual => "=", - UserComparator.NumberNotEqual => "!=", - UserComparator.NumberLessThan => "<", - UserComparator.NumberLessThanEqual => "<=", - UserComparator.NumberGreaterThan => ">", - UserComparator.NumberGreaterThanEqual => ">=", - UserComparator.SensitiveOneOf => "IS ONE OF", - UserComparator.SensitiveNotOneOf => "IS NOT ONE OF", + UserComparator.IsOneOf or UserComparator.SensitiveIsOneOf => "IS ONE OF", + UserComparator.IsNotOneOf or UserComparator.SensitiveIsNotOneOf => "IS NOT ONE OF", + UserComparator.ContainsAnyOf => "CONTAINS ANY OF", + UserComparator.NotContainsAnyOf => "NOT CONTAINS ANY OF", + UserComparator.SemVerIsOneOf => "IS ONE OF", + UserComparator.SemVerIsNotOneOf => "IS NOT ONE OF", + UserComparator.SemVerLess => "<", + UserComparator.SemVerLessOrEquals => "<=", + UserComparator.SemVerGreater => ">", + UserComparator.SemVerGreaterOrEquals => ">=", + UserComparator.NumberEquals => "=", + UserComparator.NumberNotEquals => "!=", + UserComparator.NumberLess => "<", + UserComparator.NumberLessOrEquals => "<=", + UserComparator.NumberGreater => ">", + UserComparator.NumberGreaterOrEquals => ">=", UserComparator.DateTimeBefore => "BEFORE", UserComparator.DateTimeAfter => "AFTER", - UserComparator.SensitiveTextEquals => "EQUALS", - UserComparator.SensitiveTextNotEquals => "NOT EQUALS", - UserComparator.SensitiveTextStartsWith => "STARTS WITH ANY OF", - UserComparator.SensitiveTextNotStartsWith => "NOT STARTS WITH ANY OF", - UserComparator.SensitiveTextEndsWith => "ENDS WITH ANY OF", - UserComparator.SensitiveTextNotEndsWith => "NOT ENDS WITH ANY OF", - UserComparator.SensitiveArrayContains => "ARRAY CONTAINS ANY OF", - UserComparator.SensitiveArrayNotContains => "ARRAY NOT CONTAINS ANY OF", + UserComparator.TextEquals or UserComparator.SensitiveTextEquals => "EQUALS", + UserComparator.TextNotEquals or UserComparator.SensitiveTextNotEquals => "NOT EQUALS", + UserComparator.TextStartsWithAnyOf or UserComparator.SensitiveTextStartsWithAnyOf => "STARTS WITH ANY OF", + UserComparator.TextNotStartsWithAnyOf or UserComparator.SensitiveTextNotStartsWithAnyOf => "NOT STARTS WITH ANY OF", + UserComparator.TextEndsWithAnyOf or UserComparator.SensitiveTextEndsWithAnyOf => "ENDS WITH ANY OF", + UserComparator.TextNotEndsWithAnyOf or UserComparator.SensitiveTextNotEndsWithAnyOf => "NOT ENDS WITH ANY OF", + UserComparator.ArrayContainsAnyOf or UserComparator.SensitiveArrayContainsAnyOf => "ARRAY CONTAINS ANY OF", + UserComparator.ArrayNotContainsAnyOf or UserComparator.SensitiveArrayNotContainsAnyOf => "ARRAY NOT CONTAINS ANY OF", _ => InvalidOperatorPlaceholder }; } diff --git a/src/ConfigCatClient/Evaluation/RolloutEvaluator.cs b/src/ConfigCatClient/Evaluation/RolloutEvaluator.cs index b29fac3d..120216e7 100644 --- a/src/ConfigCatClient/Evaluation/RolloutEvaluator.cs +++ b/src/ConfigCatClient/Evaluation/RolloutEvaluator.cs @@ -327,43 +327,59 @@ private bool EvaluateUserCondition(UserCondition condition, string contextSalt, var comparator = condition.Comparator; switch (comparator) { + case UserComparator.TextEquals: + case UserComparator.TextNotEquals: + return EvaluateTextEquals(userAttributeValue!, condition.StringValue, negate: comparator == UserComparator.TextNotEquals); + case UserComparator.SensitiveTextEquals: case UserComparator.SensitiveTextNotEquals: return EvaluateSensitiveTextEquals(userAttributeValue!, condition.StringValue, EnsureConfigJsonSalt(context.Setting.ConfigJsonSalt), contextSalt, negate: comparator == UserComparator.SensitiveTextNotEquals); - case UserComparator.SensitiveOneOf: - case UserComparator.SensitiveNotOneOf: - return EvaluateSensitiveOneOf(userAttributeValue!, condition.StringListValue, - EnsureConfigJsonSalt(context.Setting.ConfigJsonSalt), contextSalt, negate: comparator == UserComparator.SensitiveNotOneOf); + case UserComparator.IsOneOf: + case UserComparator.IsNotOneOf: + return EvaluateIsOneOf(userAttributeValue!, condition.StringListValue, negate: comparator == UserComparator.IsNotOneOf); + + case UserComparator.SensitiveIsOneOf: + case UserComparator.SensitiveIsNotOneOf: + return EvaluateSensitiveIsOneOf(userAttributeValue!, condition.StringListValue, + EnsureConfigJsonSalt(context.Setting.ConfigJsonSalt), contextSalt, negate: comparator == UserComparator.SensitiveIsNotOneOf); + + case UserComparator.TextStartsWithAnyOf: + case UserComparator.TextNotStartsWithAnyOf: + return EvaluateTextSliceEqualsAnyOf(userAttributeValue!, condition.StringListValue, startsWith: true, negate: comparator == UserComparator.TextNotStartsWithAnyOf); - case UserComparator.SensitiveTextStartsWith: - case UserComparator.SensitiveTextNotStartsWith: - return EvaluateSensitiveTextSliceEquals(userAttributeValue!, condition.StringListValue, - EnsureConfigJsonSalt(context.Setting.ConfigJsonSalt), contextSalt, startsWith: true, negate: comparator == UserComparator.SensitiveTextNotStartsWith); + case UserComparator.SensitiveTextStartsWithAnyOf: + case UserComparator.SensitiveTextNotStartsWithAnyOf: + return EvaluateSensitiveTextSliceEqualsAnyOf(userAttributeValue!, condition.StringListValue, + EnsureConfigJsonSalt(context.Setting.ConfigJsonSalt), contextSalt, startsWith: true, negate: comparator == UserComparator.SensitiveTextNotStartsWithAnyOf); - case UserComparator.SensitiveTextEndsWith: - case UserComparator.SensitiveTextNotEndsWith: - return EvaluateSensitiveTextSliceEquals(userAttributeValue!, condition.StringListValue, - EnsureConfigJsonSalt(context.Setting.ConfigJsonSalt), contextSalt, startsWith: false, negate: comparator == UserComparator.SensitiveTextNotEndsWith); + case UserComparator.TextEndsWithAnyOf: + case UserComparator.TextNotEndsWithAnyOf: + return EvaluateTextSliceEqualsAnyOf(userAttributeValue!, condition.StringListValue, startsWith: false, negate: comparator == UserComparator.TextNotEndsWithAnyOf); - case UserComparator.Contains: - case UserComparator.NotContains: - return EvaluateContains(userAttributeValue!, condition.StringListValue, negate: comparator == UserComparator.NotContains); + case UserComparator.SensitiveTextEndsWithAnyOf: + case UserComparator.SensitiveTextNotEndsWithAnyOf: + return EvaluateSensitiveTextSliceEqualsAnyOf(userAttributeValue!, condition.StringListValue, + EnsureConfigJsonSalt(context.Setting.ConfigJsonSalt), contextSalt, startsWith: false, negate: comparator == UserComparator.SensitiveTextNotEndsWithAnyOf); - case UserComparator.SemVerOneOf: - case UserComparator.SemVerNotOneOf: + case UserComparator.ContainsAnyOf: + case UserComparator.NotContainsAnyOf: + return EvaluateContainsAnyOf(userAttributeValue!, condition.StringListValue, negate: comparator == UserComparator.NotContainsAnyOf); + + case UserComparator.SemVerIsOneOf: + case UserComparator.SemVerIsNotOneOf: if (!SemVersion.TryParse(userAttributeValue!.Trim(), out var version, strict: true)) { error = HandleInvalidUserAttribute(condition, context.Key, userAttributeName, $"'{userAttributeValue}' is not a valid semantic version"); return false; } - return EvaluateSemVerOneOf(version, condition.StringListValue, negate: comparator == UserComparator.SemVerNotOneOf); + return EvaluateSemVerIsOneOf(version, condition.StringListValue, negate: comparator == UserComparator.SemVerIsNotOneOf); - case UserComparator.SemVerLessThan: - case UserComparator.SemVerLessThanEqual: - case UserComparator.SemVerGreaterThan: - case UserComparator.SemVerGreaterThanEqual: + case UserComparator.SemVerLess: + case UserComparator.SemVerLessOrEquals: + case UserComparator.SemVerGreater: + case UserComparator.SemVerGreaterOrEquals: if (!SemVersion.TryParse(userAttributeValue!.Trim(), out version, strict: true)) { error = HandleInvalidUserAttribute(condition, context.Key, userAttributeName, $"'{userAttributeValue}' is not a valid semantic version"); @@ -371,12 +387,12 @@ private bool EvaluateUserCondition(UserCondition condition, string contextSalt, } return EvaluateSemVerRelation(version, comparator, condition.StringValue); - case UserComparator.NumberEqual: - case UserComparator.NumberNotEqual: - case UserComparator.NumberLessThan: - case UserComparator.NumberLessThanEqual: - case UserComparator.NumberGreaterThan: - case UserComparator.NumberGreaterThanEqual: + case UserComparator.NumberEquals: + case UserComparator.NumberNotEquals: + case UserComparator.NumberLess: + case UserComparator.NumberLessOrEquals: + case UserComparator.NumberGreater: + case UserComparator.NumberGreaterOrEquals: if (!double.TryParse(userAttributeValue!.Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out var number)) { error = HandleInvalidUserAttribute(condition, context.Key, userAttributeName, $"'{userAttributeValue}' is not a valid decimal number"); @@ -393,26 +409,41 @@ private bool EvaluateUserCondition(UserCondition condition, string contextSalt, } return EvaluateDateTimeRelation(number, condition.DoubleValue, before: comparator == UserComparator.DateTimeBefore); - case UserComparator.SensitiveArrayContains: - case UserComparator.SensitiveArrayNotContains: - string[]? array; - try { array = userAttributeValue!.Deserialize(); } - catch { array = null; } + case UserComparator.ArrayContainsAnyOf: + case UserComparator.ArrayNotContainsAnyOf: + var array = userAttributeValue!.DeserializeOrDefault(); + if (array is null) + { + error = HandleInvalidUserAttribute(condition, context.Key, userAttributeName, $"'{userAttributeValue}' is not a valid JSON string array"); + return false; + } + return EvaluateArrayContainsAnyOf(array, condition.StringListValue, negate: comparator == UserComparator.ArrayNotContainsAnyOf); + + case UserComparator.SensitiveArrayContainsAnyOf: + case UserComparator.SensitiveArrayNotContainsAnyOf: + array = userAttributeValue!.DeserializeOrDefault(); if (array is null) { error = HandleInvalidUserAttribute(condition, context.Key, userAttributeName, $"'{userAttributeValue}' is not a valid JSON string array"); return false; } - return EvaluateSensitiveArrayContains(array, condition.StringListValue, - EnsureConfigJsonSalt(context.Setting.ConfigJsonSalt), contextSalt, negate: comparator == UserComparator.SensitiveArrayNotContains); + return EvaluateSensitiveArrayContainsAnyOf(array, condition.StringListValue, + EnsureConfigJsonSalt(context.Setting.ConfigJsonSalt), contextSalt, negate: comparator == UserComparator.SensitiveArrayNotContainsAnyOf); default: throw new InvalidOperationException("Comparison operator is invalid."); } } + private static bool EvaluateTextEquals(string text, string? comparisonValue, bool negate) + { + EnsureComparisonValue(comparisonValue); + + return text.Equals(comparisonValue) ^ negate; + } + private static bool EvaluateSensitiveTextEquals(string text, string? comparisonValue, string configJsonSalt, string contextSalt, bool negate) { EnsureComparisonValue(comparisonValue); @@ -422,7 +453,22 @@ private static bool EvaluateSensitiveTextEquals(string text, string? comparisonV return hash.Equals(hexString: comparisonValue.AsSpan()) ^ negate; } - private static bool EvaluateSensitiveOneOf(string text, string[]? comparisonValues, string configJsonSalt, string contextSalt, bool negate) + private static bool EvaluateIsOneOf(string text, string[]? comparisonValues, bool negate) + { + EnsureComparisonValue(comparisonValues); + + for (var i = 0; i < comparisonValues.Length; i++) + { + if (text.Equals(EnsureComparisonValue(comparisonValues[i]))) + { + return !negate; + } + } + + return negate; + } + + private static bool EvaluateSensitiveIsOneOf(string text, string[]? comparisonValues, string configJsonSalt, string contextSalt, bool negate) { EnsureComparisonValue(comparisonValues); @@ -439,7 +485,31 @@ private static bool EvaluateSensitiveOneOf(string text, string[]? comparisonValu return negate; } - private static bool EvaluateSensitiveTextSliceEquals(string text, string[]? comparisonValues, string configJsonSalt, string contextSalt, bool startsWith, bool negate) + private static bool EvaluateTextSliceEqualsAnyOf(string text, string[]? comparisonValues, bool startsWith, bool negate) + { + EnsureComparisonValue(comparisonValues); + + for (var i = 0; i < comparisonValues.Length; i++) + { + var item = EnsureComparisonValue(comparisonValues[i]); + + if (text.Length < item.Length) + { + continue; + } + + var slice = startsWith ? text.AsSpan(0, item.Length) : text.AsSpan(text.Length - item.Length); + + if (slice.SequenceEqual(item.AsSpan())) + { + return !negate; + } + } + + return negate; + } + + private static bool EvaluateSensitiveTextSliceEqualsAnyOf(string text, string[]? comparisonValues, string configJsonSalt, string contextSalt, bool startsWith, bool negate) { EnsureComparisonValue(comparisonValues); @@ -475,7 +545,7 @@ private static bool EvaluateSensitiveTextSliceEquals(string text, string[]? comp return negate; } - private static bool EvaluateContains(string text, string[]? comparisonValues, bool negate) + private static bool EvaluateContainsAnyOf(string text, string[]? comparisonValues, bool negate) { EnsureComparisonValue(comparisonValues); @@ -490,7 +560,7 @@ private static bool EvaluateContains(string text, string[]? comparisonValues, bo return negate; } - private static bool EvaluateSemVerOneOf(SemVersion version, string[]? comparisonValues, bool negate) + private static bool EvaluateSemVerIsOneOf(SemVersion version, string[]? comparisonValues, bool negate) { EnsureComparisonValue(comparisonValues); @@ -539,10 +609,10 @@ private static bool EvaluateSemVerRelation(SemVersion version, UserComparator co return comparator switch { - UserComparator.SemVerLessThan => comparisonResult < 0, - UserComparator.SemVerLessThanEqual => comparisonResult <= 0, - UserComparator.SemVerGreaterThan => comparisonResult > 0, - UserComparator.SemVerGreaterThanEqual => comparisonResult >= 0, + UserComparator.SemVerLess => comparisonResult < 0, + UserComparator.SemVerLessOrEquals => comparisonResult <= 0, + UserComparator.SemVerGreater => comparisonResult > 0, + UserComparator.SemVerGreaterOrEquals => comparisonResult >= 0, _ => throw new ArgumentOutOfRangeException(nameof(comparator), comparator, null) }; } @@ -553,12 +623,12 @@ private static bool EvaluateNumberRelation(double number, UserComparator compara return comparator switch { - UserComparator.NumberEqual => number == number2, - UserComparator.NumberNotEqual => number != number2, - UserComparator.NumberLessThan => number < number2, - UserComparator.NumberLessThanEqual => number <= number2, - UserComparator.NumberGreaterThan => number > number2, - UserComparator.NumberGreaterThanEqual => number >= number2, + UserComparator.NumberEquals => number == number2, + UserComparator.NumberNotEquals => number != number2, + UserComparator.NumberLess => number < number2, + UserComparator.NumberLessOrEquals => number <= number2, + UserComparator.NumberGreater => number > number2, + UserComparator.NumberGreaterOrEquals => number >= number2, _ => throw new ArgumentOutOfRangeException(nameof(comparator), comparator, null) }; } @@ -570,7 +640,27 @@ private static bool EvaluateDateTimeRelation(double number, double? comparisonVa return before ? number < number2 : number > number2; } - private static bool EvaluateSensitiveArrayContains(string[] array, string[]? comparisonValues, string configJsonSalt, string contextSalt, bool negate) + private static bool EvaluateArrayContainsAnyOf(string[] array, string[]? comparisonValues, bool negate) + { + EnsureComparisonValue(comparisonValues); + + for (var i = 0; i < array.Length; i++) + { + var text = array[i]; + + for (var j = 0; j < comparisonValues.Length; j++) + { + if (text.Equals(EnsureComparisonValue(comparisonValues[j]))) + { + return !negate; + } + } + } + + return negate; + } + + private static bool EvaluateSensitiveArrayContainsAnyOf(string[] array, string[]? comparisonValues, string configJsonSalt, string contextSalt, bool negate) { EnsureComparisonValue(comparisonValues); diff --git a/src/ConfigCatClient/Models/UserComparator.cs b/src/ConfigCatClient/Models/UserComparator.cs index 6e48ad17..0ea2273a 100644 --- a/src/ConfigCatClient/Models/UserComparator.cs +++ b/src/ConfigCatClient/Models/UserComparator.cs @@ -6,84 +6,94 @@ namespace ConfigCat.Client; public enum UserComparator : byte { /// - /// CONTAINS ANY OF - It matches when the comparison attribute contains any comparison values as a substring. + /// IS ONE OF (cleartext) - It matches when the comparison attribute is equal to any of the comparison values. /// - Contains = 2, + IsOneOf = 0, /// - /// NOT CONTAINS ANY OF - It matches when the comparison attribute does not contain any comparison values as a substring. + /// IS NOT ONE OF (cleartext) - It matches when the comparison attribute is not equal to any of the comparison values. /// - NotContains = 3, + IsNotOneOf = 1, + + /// + /// CONTAINS ANY OF (cleartext) - It matches when the comparison attribute contains any comparison values as a substring. + /// + ContainsAnyOf = 2, + + /// + /// NOT CONTAINS ANY OF (cleartext) - It matches when the comparison attribute does not contain any comparison values as a substring. + /// + NotContainsAnyOf = 3, /// /// IS ONE OF (semver) - It matches when the comparison attribute interpreted as a semantic version is equal to any of the comparison values. /// - SemVerOneOf = 4, + SemVerIsOneOf = 4, /// /// IS NOT ONE OF (semver) - It matches when the comparison attribute interpreted as a semantic version is not equal to any of the comparison values. /// - SemVerNotOneOf = 5, + SemVerIsNotOneOf = 5, /// /// < (semver) - It matches when the comparison attribute interpreted as a semantic version is less than the comparison value. /// - SemVerLessThan = 6, + SemVerLess = 6, /// /// <= (semver) - It matches when the comparison attribute interpreted as a semantic version is less than or equal to the comparison value. /// - SemVerLessThanEqual = 7, + SemVerLessOrEquals = 7, /// /// > (semver) - It matches when the comparison attribute interpreted as a semantic version is greater than the comparison value. /// - SemVerGreaterThan = 8, + SemVerGreater = 8, /// /// >= (semver) - It matches when the comparison attribute interpreted as a semantic version is greater than or equal to the comparison value. /// - SemVerGreaterThanEqual = 9, + SemVerGreaterOrEquals = 9, /// /// = (number) - It matches when the comparison attribute interpreted as a decimal number is equal to the comparison value. /// - NumberEqual = 10, + NumberEquals = 10, /// /// != (number) - It matches when the comparison attribute interpreted as a decimal number is not equal to the comparison value. /// - NumberNotEqual = 11, + NumberNotEquals = 11, /// /// < (number) - It matches when the comparison attribute interpreted as a decimal number is less than the comparison value. /// - NumberLessThan = 12, + NumberLess = 12, /// /// <= (number) - It matches when the comparison attribute interpreted as a decimal number is less than or equal to the comparison value. /// - NumberLessThanEqual = 13, + NumberLessOrEquals = 13, /// /// > (number) - It matches when the comparison attribute interpreted as a decimal number is greater than the comparison value. /// - NumberGreaterThan = 14, + NumberGreater = 14, /// /// >= (number) - It matches when the comparison attribute interpreted as a decimal number is greater than or equal to the comparison value. /// - NumberGreaterThanEqual = 15, + NumberGreaterOrEquals = 15, /// - /// IS ONE OF (hashed) - It matches when the comparison attribute is equal to any of the comparison values (where the comparison is performed using the SHA256 hashes of the values). + /// IS ONE OF (hashed) - It matches when the comparison attribute is equal to any of the comparison values (where the comparison is performed using the salted SHA256 hashes of the values). /// - SensitiveOneOf = 16, + SensitiveIsOneOf = 16, /// - /// IS NOT ONE OF (hashed) - It matches when the comparison attribute is not equal to any of the comparison values (where the comparison is performed using the SHA256 hashes of the values). + /// IS NOT ONE OF (hashed) - It matches when the comparison attribute is not equal to any of the comparison values (where the comparison is performed using the salted SHA256 hashes of the values). /// - SensitiveNotOneOf = 17, + SensitiveIsNotOneOf = 17, /// /// BEFORE (UTC datetime) - It matches when the comparison attribute interpreted as the seconds elapsed since Unix Epoch is less than the comparison value. @@ -96,42 +106,82 @@ public enum UserComparator : byte DateTimeAfter = 19, /// - /// EQUALS (hashed) - It matches when the comparison attribute is equal to the comparison value (where the comparison is performed using the SHA256 hashes of the values). + /// EQUALS (hashed) - It matches when the comparison attribute is equal to the comparison value (where the comparison is performed using the salted SHA256 hashes of the values). /// SensitiveTextEquals = 20, /// - /// NOT EQUALS (hashed) - It matches when the comparison attribute is not equal to the comparison value (where the comparison is performed using the SHA256 hashes of the values). + /// NOT EQUALS (hashed) - It matches when the comparison attribute is not equal to the comparison value (where the comparison is performed using the salted SHA256 hashes of the values). /// SensitiveTextNotEquals = 21, /// - /// STARTS WITH ANY OF (hashed) - It matches when the comparison attribute starts with any of the comparison values (where the comparison is performed using the SHA256 hashes of the values). + /// STARTS WITH ANY OF (hashed) - It matches when the comparison attribute starts with any of the comparison values (where the comparison is performed using the salted SHA256 hashes of the values). /// - SensitiveTextStartsWith = 22, + SensitiveTextStartsWithAnyOf = 22, /// /// NOT STARTS WITH ANY OF (hashed) - It matches when the comparison attribute does not start with any of the comparison values (where the comparison is performed using the salted SHA256 hashes of the values). /// - SensitiveTextNotStartsWith = 23, + SensitiveTextNotStartsWithAnyOf = 23, /// /// ENDS WITH ANY OF (hashed) - It matches when the comparison attribute ends with any of the comparison values (where the comparison is performed using the salted SHA256 hashes of the values). /// - SensitiveTextEndsWith = 24, + SensitiveTextEndsWithAnyOf = 24, /// /// NOT ENDS WITH ANY OF (hashed) - It matches when the comparison attribute does not end with any of the comparison values (where the comparison is performed using the salted SHA256 hashes of the values). /// - SensitiveTextNotEndsWith = 25, + SensitiveTextNotEndsWithAnyOf = 25, /// /// ARRAY CONTAINS ANY OF (hashed) - It matches when the comparison attribute interpreted as a comma-separated list contains any of the comparison values (where the comparison is performed using the salted SHA256 hashes of the values). /// - SensitiveArrayContains = 26, + SensitiveArrayContainsAnyOf = 26, /// /// ARRAY NOT CONTAINS ANY OF (hashed) - It matches when the comparison attribute interpreted as a comma-separated list does not contain any of the comparison values (where the comparison is performed using the salted SHA256 hashes of the values). /// - SensitiveArrayNotContains = 27, + SensitiveArrayNotContainsAnyOf = 27, + + /// + /// EQUALS (cleartext) - It matches when the comparison attribute is equal to the comparison value. + /// + TextEquals = 28, + + /// + /// NOT EQUALS (cleartext) - It matches when the comparison attribute is not equal to the comparison value. + /// + TextNotEquals = 29, + + /// + /// STARTS WITH ANY OF (cleartext) - It matches when the comparison attribute starts with any of the comparison values. + /// + TextStartsWithAnyOf = 30, + + /// + /// NOT STARTS WITH ANY OF (cleartext) - It matches when the comparison attribute does not start with any of the comparison values. + /// + TextNotStartsWithAnyOf = 31, + + /// + /// ENDS WITH ANY OF (cleartext) - It matches when the comparison attribute ends with any of the comparison values. + /// + TextEndsWithAnyOf = 32, + + /// + /// NOT ENDS WITH ANY OF (cleartext) - It matches when the comparison attribute does not end with any of the comparison values. + /// + TextNotEndsWithAnyOf = 33, + + /// + /// ARRAY CONTAINS ANY OF (cleartext) - It matches when the comparison attribute interpreted as a comma-separated list contains any of the comparison values. + /// + ArrayContainsAnyOf = 34, + + /// + /// ARRAY NOT CONTAINS ANY OF (cleartext) - It matches when the comparison attribute interpreted as a comma-separated list does not contain any of the comparison values. + /// + ArrayNotContainsAnyOf = 35, } diff --git a/src/ConfigCatClient/Models/UserCondition.cs b/src/ConfigCatClient/Models/UserCondition.cs index f90d10f5..654176ae 100644 --- a/src/ConfigCatClient/Models/UserCondition.cs +++ b/src/ConfigCatClient/Models/UserCondition.cs @@ -18,7 +18,7 @@ namespace ConfigCat.Client; public interface IUserCondition : ICondition { /// - /// The User Object attribute that the condition is based on. Can be "User ID", "Email", "Country" or any custom attribute. + /// The User Object attribute that the condition is based on. Can be "Identifier", "Email", "Country" or any custom attribute. /// string ComparisonAttribute { get; }