From 781865cd7d2f7f11d0b9cfe72556adb588b17019 Mon Sep 17 00:00:00 2001 From: Kilemonn Date: Sat, 14 Dec 2024 17:45:38 +0900 Subject: [PATCH] Allow for multiple instances of the unique constraint since it must hold state. --- .../condition-action/condition_action.go | 12 +++++++++- condition/condition.go | 4 ++-- condition/condition_test.go | 22 ++++++++++++------- condition/condition_type.go | 8 +++---- validator/validator.go | 2 +- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/condition/condition-action/condition_action.go b/condition/condition-action/condition_action.go index 7a94773..7cc8370 100644 --- a/condition/condition-action/condition_action.go +++ b/condition/condition-action/condition_action.go @@ -3,9 +3,19 @@ package condition_action var ( // TODO: Create a new instance for each different constraint definition that uses Unique // Need to create and hold this variable, since it's state needs to be retained - UniqueConditionActionObj UniqueConditionAction = NewUniqueConditionAction() + uniqueActionsMap map[string]UniqueConditionAction = make(map[string]UniqueConditionAction) ) +func GetUniqueInstance(id string) UniqueConditionAction { + if entry, exists := uniqueActionsMap[id]; exists { + return entry + } else { + uniqueAction := NewUniqueConditionAction() + uniqueActionsMap[id] = uniqueAction + return uniqueAction + } +} + type ConditionAction interface { CheckCondition(input string, args []string) bool } diff --git a/condition/condition.go b/condition/condition.go index 5f9c2d0..221f0f3 100644 --- a/condition/condition.go +++ b/condition/condition.go @@ -63,6 +63,6 @@ func getArguments(arg string, expectedArgsCount uint) (args []string, err error) return } -func (c Condition) ApplyCondition(input string) bool { - return c.Type.getConditionAction().CheckCondition(input, c.Args) +func (c Condition) ApplyCondition(id string, input string) bool { + return c.Type.getConditionAction(id).CheckCondition(input, c.Args) } diff --git a/condition/condition_test.go b/condition/condition_test.go index 359b11c..21fda42 100644 --- a/condition/condition_test.go +++ b/condition/condition_test.go @@ -73,18 +73,24 @@ func TestNewCondition(t *testing.T) { func TestApplyCondition(t *testing.T) { var cases = []struct { conditionString string + id string expectError bool successInputs []string failInputs []string }{ - {"IsNumeric", false, []string{"-19", "40", "9999999999999"}, []string{"wow", "-", "!@!#$!"}}, - {"IsBoolean", false, []string{"true", "false"}, []string{"yes", "-", "222159", "!@!#$!"}}, - {"Unique", false, []string{"unique1", "unique2", "unique3"}, []string{"unique1", "unique2", "unique3"}}, - {"HasPrefix(test-)", false, []string{"test-scenario1", "test-case1", "test-please"}, []string{"not-test-", "ttest-failed"}}, - {"HasSuffix(-test)", false, []string{"some-test", "another-test"}, []string{"not-test-", "failing-tests"}}, + {"IsNumeric", "is-numeric", false, []string{"-19", "40", "9999999999999"}, []string{"wow", "-", "!@!#$!"}}, + {"IsBoolean", "is-boolean", false, []string{"true", "false"}, []string{"yes", "-", "222159", "!@!#$!"}}, + {"Unique", "is-unique1", false, []string{"unique1", "unique2", "unique3"}, []string{"unique1", "unique2", "unique3"}}, + + // Duplicate the unique entry with the same ID to make sure that the same unique instance is used + {"Unique", "is-unique1", false, []string{"unique4", "unique5", "unique6"}, []string{"unique1", "unique2", "unique3", "unique4", "unique5", "unique6"}}, + // Using a different ID should give us a different validator and not collide with the other unique instances + {"Unique", "is-unique2", false, []string{"unique1", "unique2", "unique3"}, []string{"unique1", "unique2", "unique3"}}, + {"HasPrefix(test-)", "has-prefix", false, []string{"test-scenario1", "test-case1", "test-please"}, []string{"not-test-", "ttest-failed"}}, + {"HasSuffix(-test)", "has-suffix", false, []string{"some-test", "another-test"}, []string{"not-test-", "failing-tests"}}, // Make sure an invalid constraint is forced to validate false to everything - {"SomethingInvalid(arg1, arg2)", true, []string{}, []string{"test test test", "1237532123", "true", "$!&@#($)"}}, + {"SomethingInvalid(arg1, arg2)", "invalid", true, []string{}, []string{"test test test", "1237532123", "true", "$!&@#($)"}}, } for _, c := range cases { @@ -96,10 +102,10 @@ func TestApplyCondition(t *testing.T) { } for _, successTest := range c.successInputs { - require.True(t, condition.ApplyCondition(successTest)) + require.True(t, condition.ApplyCondition(c.id, successTest)) } for _, failTest := range c.failInputs { - require.False(t, condition.ApplyCondition(failTest)) + require.False(t, condition.ApplyCondition(c.id, failTest)) } } } diff --git a/condition/condition_type.go b/condition/condition_type.go index ebe7829..128d8e6 100644 --- a/condition/condition_type.go +++ b/condition/condition_type.go @@ -40,10 +40,10 @@ func (c ConditionType) expectedArgsCount() uint { return args[uint(c)] } -func (c ConditionType) conditionActions() []condition_action.ConditionAction { +func (c ConditionType) conditionActions(id string) []condition_action.ConditionAction { return []condition_action.ConditionAction{ condition_action.InvalidConditionAction{}, - condition_action.UniqueConditionActionObj, + condition_action.GetUniqueInstance(id), condition_action.HasPrefixConditionAction{}, condition_action.HasSuffixConditionAction{}, condition_action.IsNumericConditionAction{}, @@ -51,6 +51,6 @@ func (c ConditionType) conditionActions() []condition_action.ConditionAction { } } -func (c ConditionType) getConditionAction() condition_action.ConditionAction { - return c.conditionActions()[uint(c)] +func (c ConditionType) getConditionAction(id string) condition_action.ConditionAction { + return c.conditionActions(id)[uint(c)] } diff --git a/validator/validator.go b/validator/validator.go index 439bad9..29c4d7d 100644 --- a/validator/validator.go +++ b/validator/validator.go @@ -27,7 +27,7 @@ func ExecuteConstraintsAgainstProviders(providers []credential_provider.Credenti if debugLog { fmt.Printf("Credential [%s] matched pattern for constraint [%s], applying condition...\n", credentialName, constraint.Name) } - if !constraint.Condition.ApplyCondition(credential) { + if !constraint.Condition.ApplyCondition(constraint.Name, credential) { if debugLog { fmt.Printf("Fail - Provider [%s], Constraint [%s], Credential [%s].\n", provider.Identifier.String(), constraint.Name, credentialName) }